ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rdrle.c
Go to the documentation of this file.
00001 /*
00002  * rdrle.c
00003  *
00004  * Copyright (C) 1991-1996, Thomas G. Lane.
00005  * This file is part of the Independent JPEG Group's software.
00006  * For conditions of distribution and use, see the accompanying README file.
00007  *
00008  * This file contains routines to read input images in Utah RLE format.
00009  * The Utah Raster Toolkit library is required (version 3.1 or later).
00010  *
00011  * These routines may need modification for non-Unix environments or
00012  * specialized applications.  As they stand, they assume input from
00013  * an ordinary stdio stream.  They further assume that reading begins
00014  * at the start of the file; start_input may need work if the
00015  * user interface has already read some data (e.g., to determine that
00016  * the file is indeed RLE format).
00017  *
00018  * Based on code contributed by Mike Lijewski,
00019  * with updates from Robert Hutchinson.
00020  */
00021 
00022 #include "cdjpeg.h"     /* Common decls for cjpeg/djpeg applications */
00023 
00024 #ifdef RLE_SUPPORTED
00025 
00026 /* rle.h is provided by the Utah Raster Toolkit. */
00027 
00028 #include <rle.h>
00029 
00030 /*
00031  * We assume that JSAMPLE has the same representation as rle_pixel,
00032  * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
00033  */
00034 
00035 #if BITS_IN_JSAMPLE != 8
00036   Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
00037 #endif
00038 
00039 /*
00040  * We support the following types of RLE files:
00041  *   
00042  *   GRAYSCALE   - 8 bits, no colormap
00043  *   MAPPEDGRAY  - 8 bits, 1 channel colomap
00044  *   PSEUDOCOLOR - 8 bits, 3 channel colormap
00045  *   TRUECOLOR   - 24 bits, 3 channel colormap
00046  *   DIRECTCOLOR - 24 bits, no colormap
00047  *
00048  * For now, we ignore any alpha channel in the image.
00049  */
00050 
00051 typedef enum
00052   { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind;
00053 
00054 
00055 /*
00056  * Since RLE stores scanlines bottom-to-top, we have to invert the image
00057  * to conform to JPEG's top-to-bottom order.  To do this, we read the
00058  * incoming image into a virtual array on the first get_pixel_rows call,
00059  * then fetch the required row from the virtual array on subsequent calls.
00060  */
00061 
00062 typedef struct _rle_source_struct * rle_source_ptr;
00063 
00064 typedef struct _rle_source_struct {
00065   struct cjpeg_source_struct pub; /* public fields */
00066 
00067   rle_kind visual;              /* actual type of input file */
00068   jvirt_sarray_ptr image;       /* virtual array to hold the image */
00069   JDIMENSION row;       /* current row # in the virtual array */
00070   rle_hdr header;               /* Input file information */
00071   rle_pixel** rle_row;          /* holds a row returned by rle_getrow() */
00072 
00073 } rle_source_struct;
00074 
00075 
00076 /*
00077  * Read the file header; return image size and component count.
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   /* Use RLE library routine to get the header info */
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     /* A-OK */
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   /* Figure out what we have, set private vars and return values accordingly */
00114   
00115   width  = source->header.xmax - source->header.xmin + 1;
00116   height = source->header.ymax - source->header.ymin + 1;
00117   source->header.xmin = 0;      /* realign horizontally */
00118   source->header.xmax = width-1;
00119 
00120   cinfo->image_width      = width;
00121   cinfo->image_height     = height;
00122   cinfo->data_precision   = 8;  /* we can only handle 8 bit data */
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    * A place to hold each scanline while it's converted.
00155    * (GRAYSCALE scanlines don't need converting)
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   /* request a virtual array to hold the image */
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     /* count file input as separate pass */
00172     progress->total_extra_passes++;
00173   }
00174 #endif
00175 
00176   source->pub.buffer_height = 1;
00177 }
00178 
00179 
00180 /*
00181  * Read one row of pixels.
00182  * Called only after load_image has read the image into the virtual array.
00183  * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images.
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  * Read one row of pixels.
00200  * Called only after load_image has read the image into the virtual array.
00201  * Used for PSEUDOCOLOR images.
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  * Load the image into a virtual array.  We have to do this because RLE
00232  * files start at the lower left while the JPEG standard has them starting
00233  * in the upper left.  This is called the first time we want to get a row
00234  * of input.  What we do is load the RLE data into the array and then call
00235  * the appropriate routine to read one row from the array.  Before returning,
00236  * we set source->pub.get_pixel_rows so that subsequent calls go straight to
00237  * the appropriate row-reading routine.
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   /* Read the RLE data into our virtual array.
00257    * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
00258    * and (b) we are not on a machine where FAR pointers differ from regular.
00259    */
00260   RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */
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   /* Set up to call proper row-extraction routine in future */
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   /* And fetch the topmost (bottommost) row */
00351   return (*source->pub.get_pixel_rows) (cinfo, sinfo);   
00352 }
00353 
00354 
00355 /*
00356  * Finish up at the end of the file.
00357  */
00358 
00359 METHODDEF(void)
00360 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00361 {
00362   /* no work */
00363 }
00364 
00365 
00366 /*
00367  * The module selection routine for RLE format input.
00368  */
00369 
00370 GLOBAL(cjpeg_source_ptr)
00371 jinit_read_rle (j_compress_ptr cinfo)
00372 {
00373   rle_source_ptr source;
00374 
00375   /* Create module interface object */
00376   source = (rle_source_ptr)
00377       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00378                                   SIZEOF(rle_source_struct));
00379   /* Fill in method ptrs */
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 /* RLE_SUPPORTED */

Generated on Sat May 26 2012 04:18:14 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.