ReactOS  0.4.15-dev-3720-g4cf9b79
wrrle.c
Go to the documentation of this file.
1 /*
2  * wrrle.c
3  *
4  * Copyright (C) 1991-1996, Thomas G. Lane.
5  * Modified 2017-2019 by Guido Vollbeding.
6  * This file is part of the Independent JPEG Group's software.
7  * For conditions of distribution and use, see the accompanying README file.
8  *
9  * This file contains routines to write output images in RLE format.
10  * The Utah Raster Toolkit library is required (version 3.1 or later).
11  *
12  * These routines may need modification for non-Unix environments or
13  * specialized applications. As they stand, they assume output to
14  * an ordinary stdio stream.
15  *
16  * Based on code contributed by Mike Lijewski,
17  * with updates from Robert Hutchinson.
18  */
19 
20 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
21 
22 #ifdef RLE_SUPPORTED
23 
24 /* rle.h is provided by the Utah Raster Toolkit. */
25 
26 #include <rle.h>
27 
28 /*
29  * We assume that JSAMPLE has the same representation as rle_pixel,
30  * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples.
31  */
32 
33 #if BITS_IN_JSAMPLE != 8
34  Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */
35 #endif
36 
37 
38 /*
39  * Since RLE stores scanlines bottom-to-top, we have to invert the image
40  * from JPEG's top-to-bottom order. To do this, we save the outgoing data
41  * in a virtual array during put_pixel_row calls, then actually emit the
42  * RLE file during finish_output.
43  */
44 
45 
46 /*
47  * For now, if we emit an RLE color map then it is always 256 entries long,
48  * though not all of the entries need be used.
49  */
50 
51 #define CMAPBITS 8
52 #define CMAPLENGTH (1<<(CMAPBITS))
53 
54 typedef struct {
55  struct djpeg_dest_struct pub; /* public fields */
56 
57  jvirt_sarray_ptr image; /* virtual array to store the output image */
58  rle_map *colormap; /* RLE-style color map, or NULL if none */
59  rle_pixel **rle_row; /* To pass rows to rle_putrow() */
60 
61 } rle_dest_struct;
62 
63 typedef rle_dest_struct * rle_dest_ptr;
64 
65 
66 /* Forward declarations */
67 METHODDEF(void) rle_put_pixel_rows
68  JPP((j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
69  JDIMENSION rows_supplied));
70 
71 
72 /*
73  * Write the file header.
74  *
75  * In this module it's easier to wait till finish_output to write anything.
76  */
77 
78 METHODDEF(void)
79 start_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
80 {
81  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
82  size_t cmapsize;
83  int ci, i;
84 #ifdef PROGRESS_REPORT
85  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
86 #endif
87 
88  /*
89  * Make sure the image can be stored in RLE format.
90  *
91  * - RLE stores image dimensions as *signed* 16 bit integers. JPEG
92  * uses unsigned, so we have to check the width.
93  *
94  * - Colorspace is expected to be grayscale or RGB.
95  *
96  * - The number of channels (components) is expected to be 1 (grayscale/
97  * pseudocolor) or 3 (truecolor/directcolor).
98  * (could be 2 or 4 if using an alpha channel, but we aren't)
99  */
100 
101  if (cinfo->output_width > 32767 || cinfo->output_height > 32767)
102  ERREXIT2(cinfo, JERR_RLE_DIMENSIONS, cinfo->output_width,
103  cinfo->output_height);
104 
105  if (cinfo->out_color_space != JCS_GRAYSCALE &&
106  cinfo->out_color_space != JCS_RGB)
107  ERREXIT(cinfo, JERR_RLE_COLORSPACE);
108 
109  if (cinfo->output_components != 1 && cinfo->output_components != 3)
110  ERREXIT1(cinfo, JERR_RLE_TOOMANYCHANNELS, cinfo->num_components);
111 
112  /* Convert colormap, if any, to RLE format. */
113 
114  dest->colormap = NULL;
115 
116  if (cinfo->quantize_colors) {
117  /* Allocate storage for RLE-style cmap, zero any extra entries */
118  cmapsize = cinfo->out_color_components * CMAPLENGTH * SIZEOF(rle_map);
119  dest->colormap = (rle_map *) (*cinfo->mem->alloc_small)
120  ((j_common_ptr) cinfo, JPOOL_IMAGE, cmapsize);
121  MEMZERO(dest->colormap, cmapsize);
122 
123  /* Save away data in RLE format --- note 8-bit left shift! */
124  /* Shifting would need adjustment for JSAMPLEs wider than 8 bits. */
125  for (ci = 0; ci < cinfo->out_color_components; ci++) {
126  for (i = 0; i < cinfo->actual_number_of_colors; i++) {
127  dest->colormap[ci * CMAPLENGTH + i] =
128  GETJSAMPLE(cinfo->colormap[ci][i]) << 8;
129  }
130  }
131  }
132 
133  /* Set the output buffer to the first row */
134  dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
135  ((j_common_ptr) cinfo, dest->image, (JDIMENSION) 0, (JDIMENSION) 1, TRUE);
136  dest->pub.buffer_height = 1;
137 
138  dest->pub.put_pixel_rows = rle_put_pixel_rows;
139 
140 #ifdef PROGRESS_REPORT
141  if (progress != NULL) {
142  progress->total_extra_passes++; /* count file writing as separate pass */
143  }
144 #endif
145 }
146 
147 
148 /*
149  * Write some pixel data.
150  *
151  * This routine just saves the data away in a virtual array.
152  */
153 
154 METHODDEF(void)
155 rle_put_pixel_rows (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
156  JDIMENSION rows_supplied)
157 {
158  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
159 
160  if (cinfo->output_scanline < cinfo->output_height) {
161  dest->pub.buffer = (*cinfo->mem->access_virt_sarray)
162  ((j_common_ptr) cinfo, dest->image,
163  cinfo->output_scanline, (JDIMENSION) 1, TRUE);
164  }
165 }
166 
167 
168 /*
169  * Finish up at the end of the file.
170  *
171  * Here is where we really output the RLE file.
172  */
173 
174 METHODDEF(void)
175 finish_output_rle (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
176 {
177  rle_dest_ptr dest = (rle_dest_ptr) dinfo;
178  rle_hdr header; /* Output file information */
179  rle_pixel **rle_row, *red_ptr, *green_ptr, *blue_ptr;
181  char cmapcomment[80];
182  int row, col;
183  int ci;
184 #ifdef PROGRESS_REPORT
185  cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
186 #endif
187 
188  /* Initialize the header info */
189  header = *rle_hdr_init(NULL);
190  header.rle_file = dest->pub.output_file;
191  header.xmin = 0;
192  header.xmax = cinfo->output_width - 1;
193  header.ymin = 0;
194  header.ymax = cinfo->output_height - 1;
195  header.alpha = 0;
196  header.ncolors = cinfo->output_components;
197  for (ci = 0; ci < cinfo->output_components; ci++) {
198  RLE_SET_BIT(header, ci);
199  }
200  if (cinfo->quantize_colors) {
201  header.ncmap = cinfo->out_color_components;
202  header.cmaplen = CMAPBITS;
203  header.cmap = dest->colormap;
204  /* Add a comment to the output image with the true colormap length. */
205  sprintf(cmapcomment, "color_map_length=%d", cinfo->actual_number_of_colors);
206  rle_putcom(cmapcomment, &header);
207  }
208 
209  /* Emit the RLE header and color map (if any) */
210  rle_put_setup(&header);
211 
212  /* Now output the RLE data from our virtual array.
213  * We assume here that (a) rle_pixel is represented the same as JSAMPLE,
214  * and (b) we are not on a machine where FAR pointers differ from regular.
215  */
216 
217 #ifdef PROGRESS_REPORT
218  if (progress != NULL) {
219  progress->pub.pass_limit = cinfo->output_height;
220  progress->pub.pass_counter = 0;
221  (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
222  }
223 #endif
224 
225  if (cinfo->output_components == 1) {
226  for (row = cinfo->output_height - 1; row >= 0; row--) {
227  rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray)
228  ((j_common_ptr) cinfo, dest->image,
229  (JDIMENSION) row, (JDIMENSION) 1, FALSE);
230  rle_putrow(rle_row, (int) cinfo->output_width, &header);
231 #ifdef PROGRESS_REPORT
232  if (progress != NULL) {
233  progress->pub.pass_counter++;
234  (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
235  }
236 #endif
237  }
238  } else {
239  for (row = cinfo->output_height - 1; row >= 0; row--) {
240  output_row = * (*cinfo->mem->access_virt_sarray)
241  ((j_common_ptr) cinfo, dest->image,
242  (JDIMENSION) row, (JDIMENSION) 1, FALSE);
243  rle_row = dest->rle_row;
244  red_ptr = rle_row[0];
245  green_ptr = rle_row[1];
246  blue_ptr = rle_row[2];
247  for (col = cinfo->output_width; col > 0; col--) {
248  *red_ptr++ = GETJSAMPLE(*output_row++);
249  *green_ptr++ = GETJSAMPLE(*output_row++);
250  *blue_ptr++ = GETJSAMPLE(*output_row++);
251  }
252  rle_putrow(rle_row, (int) cinfo->output_width, &header);
253 #ifdef PROGRESS_REPORT
254  if (progress != NULL) {
255  progress->pub.pass_counter++;
256  (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
257  }
258 #endif
259  }
260  }
261 
262 #ifdef PROGRESS_REPORT
263  if (progress != NULL)
265 #endif
266 
267  /* Emit file trailer */
268  rle_puteof(&header);
269  JFFLUSH(dest->pub.output_file);
270  if (JFERROR(dest->pub.output_file))
271  ERREXIT(cinfo, JERR_FILE_WRITE);
272 }
273 
274 
275 /*
276  * The module selection routine for RLE format output.
277  */
278 
280 jinit_write_rle (j_decompress_ptr cinfo)
281 {
282  rle_dest_ptr dest;
283 
284  /* Create module interface object, fill in method pointers */
285  dest = (rle_dest_ptr) (*cinfo->mem->alloc_small)
286  ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(rle_dest_struct));
287  dest->pub.start_output = start_output_rle;
288  dest->pub.finish_output = finish_output_rle;
289 
290  /* Calculate output image dimensions so we can allocate space */
292 
293  /* Allocate a work array for output to the RLE library. */
294  dest->rle_row = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
296 
297  /* Allocate a virtual array to hold the image. */
298  dest->image = (*cinfo->mem->request_virt_sarray)
299  ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
300  cinfo->output_width * (JDIMENSION) cinfo->output_components,
301  cinfo->output_height, (JDIMENSION) 1);
302 
303  return &dest->pub;
304 }
305 
306 #endif /* RLE_SUPPORTED */
GLeglImageOES image
Definition: gl.h:2204
JDIMENSION output_height
Definition: jpeglib.h:508
JSAMPLE FAR * JSAMPROW
Definition: jpeglib.h:75
#define ERREXIT(msg)
Definition: rdjpgcom.c:72
#define TRUE
Definition: types.h:120
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:284
boolean quantize_colors
Definition: jpeglib.h:491
#define GETJSAMPLE(value)
Definition: jmorecfg.h:78
#define MEMZERO(addr, type, size)
Definition: svc_dg.c:324
JDIMENSION output_width
Definition: jpeglib.h:507
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define JFERROR(file)
Definition: jinclude.h:97
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define SIZEOF(_ar)
Definition: calc.h:97
jpeg_calc_output_dimensions(j_decompress_ptr cinfo)
Definition: jdmaster.c:101
#define JPOOL_IMAGE
Definition: jpeglib.h:808
#define FALSE
Definition: types.h:117
J_COLOR_SPACE out_color_space
Definition: jpeglib.h:478
int total_extra_passes
Definition: cdjpeg.h:85
#define JFFLUSH(file)
Definition: jinclude.h:96
JBLOCKROW output_row
Definition: jpegint.h:422
struct jpeg_progress_mgr pub
Definition: cdjpeg.h:83
#define JPP(arglist)
Definition: jpeglib.h:877
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:212
Definition: inflate.c:139
JSAMPARRAY colormap
Definition: jpeglib.h:527
JDIMENSION output_scanline
Definition: jpeglib.h:537
#define GLOBAL(type)
Definition: jmorecfg.h:291
#define METHODDEF(type)
Definition: jmorecfg.h:287
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int completed_extra_passes
Definition: cdjpeg.h:84
#define NULL
Definition: types.h:112
cd_progress_ptr progress
Definition: cdjpeg.h:152
unsigned int JDIMENSION
Definition: jmorecfg.h:229
struct cdjpeg_progress_mgr * cd_progress_ptr
Definition: cdjpeg.h:90
static char * dest
Definition: rtl.c:135
#define ERREXIT2(cinfo, code, p1, p2)
Definition: jerror.h:216
Sorry
Definition: jdcolor.c:19
struct CFHEADER header
Definition: fdi.c:101
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78