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

wrrle.c
Go to the documentation of this file.
00001 /*
00002  * wrrle.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 write output images in 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 output to
00013  * an ordinary stdio stream.
00014  *
00015  * Based on code contributed by Mike Lijewski,
00016  * with updates from Robert Hutchinson.
00017  */
00018 
00019 #include "cdjpeg.h"     /* Common decls for cjpeg/djpeg applications */
00020 
00021 #ifdef RLE_SUPPORTED
00022 
00023 /* rle.h is provided by the Utah Raster Toolkit. */
00024 
00025 #include <rle.h>
00026 
00027 /*
00028  * We assume that JSAMPLE has the same representation as rle_pixel,
00029  * to wit, "unsigned char".  Hence we can't cope with 12- or 16-bit samples.
00030  */
00031 
00032 #if BITS_IN_JSAMPLE != 8
00033   Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
00034 #endif
00035 
00036 
00037 /*
00038  * Since RLE stores scanlines bottom-to-top, we have to invert the image
00039  * from JPEG's top-to-bottom order.  To do this, we save the outgoing data
00040  * in a virtual array during put_pixel_row calls, then actually emit the
00041  * RLE file during finish_output.
00042  */
00043 
00044 
00045 /*
00046  * For now, if we emit an RLE color map then it is always 256 entries long,
00047  * though not all of the entries need be used.
00048  */
00049 
00050 #define CMAPBITS    8
00051 #define CMAPLENGTH  (1<<(CMAPBITS))
00052 
00053 typedef struct {
00054   struct djpeg_dest_struct pub; /* public fields */
00055 
00056   jvirt_sarray_ptr image;   /* virtual array to store the output image */
00057   rle_map *colormap;        /* RLE-style color map, or NULL if none */
00058   rle_pixel **rle_row;      /* To pass rows to rle_putrow() */
00059 
00060 } rle_dest_struct;
00061 
00062 typedef rle_dest_struct * rle_dest_ptr;
00063 
00064 /* Forward declarations */
00065 METHODDEF(void) rle_put_pixel_rows
00066     JPP((j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
00067      JDIMENSION rows_supplied));
00068 
00069 
00070 /*
00071  * Write the file header.
00072  *
00073  * In this module it's easier to wait till finish_output to write anything.
00074  */
00075 
00076 METHODDEF(void)
00077 start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
00078 {
00079   rle_dest_ptr dest = (rle_dest_ptr) dinfo;
00080   size_t cmapsize;
00081   int i, ci;
00082 #ifdef PROGRESS_REPORT
00083   cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00084 #endif
00085 
00086   /*
00087    * Make sure the image can be stored in RLE format.
00088    *
00089    * - RLE stores image dimensions as *signed* 16 bit integers.  JPEG
00090    *   uses unsigned, so we have to check the width.
00091    *
00092    * - Colorspace is expected to be grayscale or RGB.
00093    *
00094    * - The number of channels (components) is expected to be 1 (grayscale/
00095    *   pseudocolor) or 3 (truecolor/directcolor).
00096    *   (could be 2 or 4 if using an alpha channel, but we aren't)
00097    */
00098 
00099   if (cinfo->output_width > 32767 || cinfo->output_height > 32767)
00100     ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width, 
00101          cinfo->output_height);
00102 
00103   if (cinfo->out_color_space != JCS_GRAYSCALE &&
00104       cinfo->out_color_space != JCS_RGB)
00105     ERREXIT(cinfo, JERR_RLE_COLORSPACE);
00106 
00107   if (cinfo->output_components != 1 && cinfo->output_components != 3)
00108     ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components);
00109 
00110   /* Convert colormap, if any, to RLE format. */
00111 
00112   dest->colormap = NULL;
00113 
00114   if (cinfo->quantize_colors) {
00115     /* Allocate storage for RLE-style cmap, zero any extra entries */
00116     cmapsize = cinfo->out_color_components * CMAPLENGTH * SIZEOF(rle_map);
00117     dest->colormap = (rle_map *) (*cinfo->mem->alloc_small)
00118       ((j_common_ptr) cinfo, JPOOL_IMAGE, cmapsize);
00119     MEMZERO(dest->colormap, cmapsize);
00120 
00121     /* Save away data in RLE format --- note 8-bit left shift! */
00122     /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
00123     for (ci = 0; ci < cinfo->out_color_components; ci++) {
00124       for (i = 0; i < cinfo->actual_number_of_colors; i++) {
00125         dest->colormap[ci * CMAPLENGTH + i] =
00126           GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
00127       }
00128     }
00129   }
00130 
00131   /* Set the output buffer to the first row */
00132   dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
00133     ((j_common_ptr) cinfo, dest->image, (JDIMENSION) 0, (JDIMENSION) 1, TRUE);
00134   dest->pub.buffer_height = 1;
00135 
00136   dest->pub.put_pixel_rows = rle_put_pixel_rows;
00137 
00138 #ifdef PROGRESS_REPORT
00139   if (progress != NULL) {
00140     progress->total_extra_passes++;  /* count file writing as separate pass */
00141   }
00142 #endif
00143 }
00144 
00145 
00146 /*
00147  * Write some pixel data.
00148  *
00149  * This routine just saves the data away in a virtual array.
00150  */
00151 
00152 METHODDEF(void)
00153 rle_put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
00154             JDIMENSION rows_supplied)
00155 {
00156   rle_dest_ptr dest = (rle_dest_ptr) dinfo;
00157 
00158   if (cinfo->output_scanline < cinfo->output_height) {
00159     dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
00160       ((j_common_ptr) cinfo, dest->image,
00161        cinfo->output_scanline, (JDIMENSION) 1, TRUE);
00162   }
00163 }
00164 
00165 /*
00166  * Finish up at the end of the file.
00167  *
00168  * Here is where we really output the RLE file.
00169  */
00170 
00171 METHODDEF(void)
00172 finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
00173 {
00174   rle_dest_ptr dest = (rle_dest_ptr) dinfo;
00175   rle_hdr header;       /* Output file information */
00176   rle_pixel **rle_row, *red, *green, *blue;
00177   JSAMPROW output_row;
00178   char cmapcomment[80];
00179   int row, col;
00180   int ci;
00181 #ifdef PROGRESS_REPORT
00182   cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
00183 #endif
00184 
00185   /* Initialize the header info */
00186   header = *rle_hdr_init(NULL);
00187   header.rle_file = dest->pub.output_file;
00188   header.xmin     = 0;
00189   header.xmax     = cinfo->output_width  - 1;
00190   header.ymin     = 0;
00191   header.ymax     = cinfo->output_height - 1;
00192   header.alpha    = 0;
00193   header.ncolors  = cinfo->output_components;
00194   for (ci = 0; ci < cinfo->output_components; ci++) {
00195     RLE_SET_BIT(header, ci);
00196   }
00197   if (cinfo->quantize_colors) {
00198     header.ncmap   = cinfo->out_color_components;
00199     header.cmaplen = CMAPBITS;
00200     header.cmap    = dest->colormap;
00201     /* Add a comment to the output image with the true colormap length. */
00202     sprintf(cmapcomment, "color_map_length=%d", cinfo->actual_number_of_colors);
00203     rle_putcom(cmapcomment, &header);
00204   }
00205 
00206   /* Emit the RLE header and color map (if any) */
00207   rle_put_setup(&header);
00208 
00209   /* Now output the RLE data from our virtual array.
00210    * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
00211    * and (b) we are not on a machine where FAR pointers differ from regular.
00212    */
00213 
00214 #ifdef PROGRESS_REPORT
00215   if (progress != NULL) {
00216     progress->pub.pass_limit = cinfo->output_height;
00217     progress->pub.pass_counter = 0;
00218     (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00219   }
00220 #endif
00221 
00222   if (cinfo->output_components == 1) {
00223     for (row = cinfo->output_height-1; row >= 0; row--) {
00224       rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
00225         ((j_common_ptr) cinfo, dest->image,
00226      (JDIMENSION) row, (JDIMENSION) 1, FALSE);
00227       rle_putrow(rle_row, (int) cinfo->output_width, &header);
00228 #ifdef PROGRESS_REPORT
00229       if (progress != NULL) {
00230         progress->pub.pass_counter++;
00231         (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00232       }
00233 #endif
00234     }
00235   } else {
00236     for (row = cinfo->output_height-1; row >= 0; row--) {
00237       rle_row = (rle_pixel **) dest->rle_row;
00238       output_row = * (*cinfo->mem->access_virt_sarray)
00239         ((j_common_ptr) cinfo, dest->image,
00240      (JDIMENSION) row, (JDIMENSION) 1, FALSE);
00241       red = rle_row[0];
00242       green = rle_row[1];
00243       blue = rle_row[2];
00244       for (col = cinfo->output_width; col > 0; col--) {
00245         *red++ = GETJSAMPLE(*output_row++);
00246         *green++ = GETJSAMPLE(*output_row++);
00247         *blue++ = GETJSAMPLE(*output_row++);
00248       }
00249       rle_putrow(rle_row, (int) cinfo->output_width, &header);
00250 #ifdef PROGRESS_REPORT
00251       if (progress != NULL) {
00252         progress->pub.pass_counter++;
00253         (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
00254       }
00255 #endif
00256     }
00257   }
00258 
00259 #ifdef PROGRESS_REPORT
00260   if (progress != NULL)
00261     progress->completed_extra_passes++;
00262 #endif
00263 
00264   /* Emit file trailer */
00265   rle_puteof(&header);
00266   fflush(dest->pub.output_file);
00267   if (ferror(dest->pub.output_file))
00268     ERREXIT(cinfo, JERR_FILE_WRITE);
00269 }
00270 
00271 
00272 /*
00273  * The module selection routine for RLE format output.
00274  */
00275 
00276 GLOBAL(djpeg_dest_ptr)
00277 jinit_write_rle (j_decompress_ptr cinfo)
00278 {
00279   rle_dest_ptr dest;
00280 
00281   /* Create module interface object, fill in method pointers */
00282   dest = (rle_dest_ptr)
00283       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00284                                   SIZEOF(rle_dest_struct));
00285   dest->pub.start_output = start_output_rle;
00286   dest->pub.finish_output = finish_output_rle;
00287 
00288   /* Calculate output image dimensions so we can allocate space */
00289   jpeg_calc_output_dimensions(cinfo);
00290 
00291   /* Allocate a work array for output to the RLE library. */
00292   dest->rle_row = (*cinfo->mem->alloc_sarray)
00293     ((j_common_ptr) cinfo, JPOOL_IMAGE,
00294      cinfo->output_width, (JDIMENSION) cinfo->output_components);
00295 
00296   /* Allocate a virtual array to hold the image. */
00297   dest->image = (*cinfo->mem->request_virt_sarray)
00298     ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
00299      (JDIMENSION) (cinfo->output_width * cinfo->output_components),
00300      cinfo->output_height, (JDIMENSION) 1);
00301 
00302   return (djpeg_dest_ptr) dest;
00303 }
00304 
00305 #endif /* RLE_SUPPORTED */

Generated on Sun May 27 2012 04:19:28 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.