ReactOS 0.4.15-dev-8390-g075894b
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
54typedef 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
63typedef rle_dest_struct * rle_dest_ptr;
64
65
66/* Forward declarations */
67METHODDEF(void) rle_put_pixel_rows
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
78METHODDEF(void)
79start_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
154METHODDEF(void)
155rle_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
174METHODDEF(void)
175finish_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,
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,
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
280jinit_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 */
#define SIZEOF(_ar)
Definition: calc.h:97
cd_progress_ptr progress
Definition: cdjpeg.h:152
struct cdjpeg_progress_mgr * cd_progress_ptr
Definition: cdjpeg.h:90
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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
GLeglImageOES image
Definition: gl.h:2204
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
Sorry
Definition: jdcolor.c:19
jpeg_calc_output_dimensions(j_decompress_ptr cinfo)
Definition: jdmaster.c:101
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:212
#define ERREXIT2(cinfo, code, p1, p2)
Definition: jerror.h:216
#define JFFLUSH(file)
Definition: jinclude.h:96
#define JFERROR(file)
Definition: jinclude.h:97
unsigned int JDIMENSION
Definition: jmorecfg.h:229
#define METHODDEF(type)
Definition: jmorecfg.h:287
#define GLOBAL(type)
Definition: jmorecfg.h:291
#define GETJSAMPLE(value)
Definition: jmorecfg.h:78
JBLOCKROW output_row
Definition: jpegint.h:422
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:284
#define JPP(arglist)
Definition: jpeglib.h:877
@ JCS_GRAYSCALE
Definition: jpeglib.h:222
@ JCS_RGB
Definition: jpeglib.h:223
JSAMPLE FAR * JSAMPROW
Definition: jpeglib.h:75
#define JPOOL_IMAGE
Definition: jpeglib.h:808
if(dx< 0)
Definition: linetemp.h:194
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static char * dest
Definition: rtl.c:135
#define ERREXIT(msg)
Definition: rdjpgcom.c:72
int total_extra_passes
Definition: cdjpeg.h:85
struct jpeg_progress_mgr pub
Definition: cdjpeg.h:83
int completed_extra_passes
Definition: cdjpeg.h:84
Definition: inflate.c:139
JDIMENSION output_height
Definition: jpeglib.h:508
JSAMPARRAY colormap
Definition: jpeglib.h:527
boolean quantize_colors
Definition: jpeglib.h:491
J_COLOR_SPACE out_color_space
Definition: jpeglib.h:478
JDIMENSION output_width
Definition: jpeglib.h:507
JDIMENSION output_scanline
Definition: jpeglib.h:537
#define MEMZERO(addr, type, size)
Definition: svc_dg.c:324