OLD | NEW |
1 /* | 1 /* |
2 * rdrle.c | 2 * rdrle.c |
3 * | 3 * |
| 4 * This file was part of the Independent JPEG Group's software: |
4 * Copyright (C) 1991-1996, Thomas G. Lane. | 5 * Copyright (C) 1991-1996, Thomas G. Lane. |
5 * This file is part of the Independent JPEG Group's software. | 6 * It was modified by The libjpeg-turbo Project to include only code and |
6 * For conditions of distribution and use, see the accompanying README file. | 7 * information relevant to libjpeg-turbo. |
| 8 * For conditions of distribution and use, see the accompanying README.ijg |
| 9 * file. |
7 * | 10 * |
8 * This file contains routines to read input images in Utah RLE format. | 11 * This file contains routines to read input images in Utah RLE format. |
9 * The Utah Raster Toolkit library is required (version 3.1 or later). | 12 * The Utah Raster Toolkit library is required (version 3.1 or later). |
10 * | 13 * |
11 * These routines may need modification for non-Unix environments or | 14 * These routines may need modification for non-Unix environments or |
12 * specialized applications. As they stand, they assume input from | 15 * specialized applications. As they stand, they assume input from |
13 * an ordinary stdio stream. They further assume that reading begins | 16 * an ordinary stdio stream. They further assume that reading begins |
14 * at the start of the file; start_input may need work if the | 17 * at the start of the file; start_input may need work if the |
15 * user interface has already read some data (e.g., to determine that | 18 * user interface has already read some data (e.g., to determine that |
16 * the file is indeed RLE format). | 19 * the file is indeed RLE format). |
17 * | 20 * |
18 * Based on code contributed by Mike Lijewski, | 21 * Based on code contributed by Mike Lijewski, |
19 * with updates from Robert Hutchinson. | 22 * with updates from Robert Hutchinson. |
20 */ | 23 */ |
21 | 24 |
22 #include "cdjpeg.h"» » /* Common decls for cjpeg/djpeg applications */ | 25 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ |
23 | 26 |
24 #ifdef RLE_SUPPORTED | 27 #ifdef RLE_SUPPORTED |
25 | 28 |
26 /* rle.h is provided by the Utah Raster Toolkit. */ | 29 /* rle.h is provided by the Utah Raster Toolkit. */ |
27 | 30 |
28 #include <rle.h> | 31 #include <rle.h> |
29 | 32 |
30 /* | 33 /* |
31 * We assume that JSAMPLE has the same representation as rle_pixel, | 34 * We assume that JSAMPLE has the same representation as rle_pixel, |
32 * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. | 35 * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. |
33 */ | 36 */ |
34 | 37 |
35 #if BITS_IN_JSAMPLE != 8 | 38 #if BITS_IN_JSAMPLE != 8 |
36 Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ | 39 Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ |
37 #endif | 40 #endif |
38 | 41 |
39 /* | 42 /* |
40 * We support the following types of RLE files: | 43 * We support the following types of RLE files: |
41 * | 44 * |
42 * GRAYSCALE - 8 bits, no colormap | 45 * GRAYSCALE - 8 bits, no colormap |
43 * MAPPEDGRAY - 8 bits, 1 channel colomap | 46 * MAPPEDGRAY - 8 bits, 1 channel colomap |
44 * PSEUDOCOLOR - 8 bits, 3 channel colormap | 47 * PSEUDOCOLOR - 8 bits, 3 channel colormap |
45 * TRUECOLOR - 24 bits, 3 channel colormap | 48 * TRUECOLOR - 24 bits, 3 channel colormap |
46 * DIRECTCOLOR - 24 bits, no colormap | 49 * DIRECTCOLOR - 24 bits, no colormap |
47 * | 50 * |
48 * For now, we ignore any alpha channel in the image. | 51 * For now, we ignore any alpha channel in the image. |
49 */ | 52 */ |
50 | 53 |
51 typedef enum | 54 typedef enum |
52 { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; | 55 { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; |
53 | 56 |
54 | 57 |
55 /* | 58 /* |
56 * Since RLE stores scanlines bottom-to-top, we have to invert the image | 59 * Since RLE stores scanlines bottom-to-top, we have to invert the image |
57 * to conform to JPEG's top-to-bottom order. To do this, we read the | 60 * to conform to JPEG's top-to-bottom order. To do this, we read the |
58 * incoming image into a virtual array on the first get_pixel_rows call, | 61 * incoming image into a virtual array on the first get_pixel_rows call, |
59 * then fetch the required row from the virtual array on subsequent calls. | 62 * then fetch the required row from the virtual array on subsequent calls. |
60 */ | 63 */ |
61 | 64 |
62 typedef struct _rle_source_struct * rle_source_ptr; | 65 typedef struct _rle_source_struct *rle_source_ptr; |
63 | 66 |
64 typedef struct _rle_source_struct { | 67 typedef struct _rle_source_struct { |
65 struct cjpeg_source_struct pub; /* public fields */ | 68 struct cjpeg_source_struct pub; /* public fields */ |
66 | 69 |
67 rle_kind visual; /* actual type of input file */ | 70 rle_kind visual; /* actual type of input file */ |
68 jvirt_sarray_ptr image; /* virtual array to hold the image */ | 71 jvirt_sarray_ptr image; /* virtual array to hold the image */ |
69 JDIMENSION row;» » /* current row # in the virtual array */ | 72 JDIMENSION row; /* current row # in the virtual array */ |
70 rle_hdr header; /* Input file information */ | 73 rle_hdr header; /* Input file information */ |
71 rle_pixel** rle_row; /* holds a row returned by rle_getrow() */ | 74 rle_pixel **rle_row; /* holds a row returned by rle_getrow() */ |
72 | 75 |
73 } rle_source_struct; | 76 } rle_source_struct; |
74 | 77 |
75 | 78 |
76 /* | 79 /* |
77 * Read the file header; return image size and component count. | 80 * Read the file header; return image size and component count. |
78 */ | 81 */ |
79 | 82 |
80 METHODDEF(void) | 83 METHODDEF(void) |
81 start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 84 start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
(...skipping 22 matching lines...) Expand all Loading... |
104 break; | 107 break; |
105 case RLE_EOF: | 108 case RLE_EOF: |
106 ERREXIT(cinfo, JERR_RLE_EOF); | 109 ERREXIT(cinfo, JERR_RLE_EOF); |
107 break; | 110 break; |
108 default: | 111 default: |
109 ERREXIT(cinfo, JERR_RLE_BADERROR); | 112 ERREXIT(cinfo, JERR_RLE_BADERROR); |
110 break; | 113 break; |
111 } | 114 } |
112 | 115 |
113 /* Figure out what we have, set private vars and return values accordingly */ | 116 /* Figure out what we have, set private vars and return values accordingly */ |
114 | 117 |
115 width = source->header.xmax - source->header.xmin + 1; | 118 width = source->header.xmax - source->header.xmin + 1; |
116 height = source->header.ymax - source->header.ymin + 1; | 119 height = source->header.ymax - source->header.ymin + 1; |
117 source->header.xmin = 0;» » /* realign horizontally */ | 120 source->header.xmin = 0; /* realign horizontally */ |
118 source->header.xmax = width-1; | 121 source->header.xmax = width-1; |
119 | 122 |
120 cinfo->image_width = width; | 123 cinfo->image_width = width; |
121 cinfo->image_height = height; | 124 cinfo->image_height = height; |
122 cinfo->data_precision = 8; /* we can only handle 8 bit data */ | 125 cinfo->data_precision = 8; /* we can only handle 8 bit data */ |
123 | 126 |
124 if (source->header.ncolors == 1 && source->header.ncmap == 0) { | 127 if (source->header.ncolors == 1 && source->header.ncmap == 0) { |
125 source->visual = GRAYSCALE; | 128 source->visual = GRAYSCALE; |
126 TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); | 129 TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); |
127 } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { | 130 } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { |
128 source->visual = MAPPEDGRAY; | 131 source->visual = MAPPEDGRAY; |
129 TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, | 132 TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, |
130 1 << source->header.cmaplen); | 133 1 << source->header.cmaplen); |
131 } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { | 134 } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { |
132 source->visual = PSEUDOCOLOR; | 135 source->visual = PSEUDOCOLOR; |
133 TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, | 136 TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, |
134 » 1 << source->header.cmaplen); | 137 1 << source->header.cmaplen); |
135 } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { | 138 } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { |
136 source->visual = TRUECOLOR; | 139 source->visual = TRUECOLOR; |
137 TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, | 140 TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, |
138 » 1 << source->header.cmaplen); | 141 1 << source->header.cmaplen); |
139 } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { | 142 } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { |
140 source->visual = DIRECTCOLOR; | 143 source->visual = DIRECTCOLOR; |
141 TRACEMS2(cinfo, 1, JTRC_RLE, width, height); | 144 TRACEMS2(cinfo, 1, JTRC_RLE, width, height); |
142 } else | 145 } else |
143 ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); | 146 ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); |
144 | 147 |
145 if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { | 148 if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { |
146 cinfo->in_color_space = JCS_GRAYSCALE; | 149 cinfo->in_color_space = JCS_GRAYSCALE; |
147 cinfo->input_components = 1; | 150 cinfo->input_components = 1; |
148 } else { | 151 } else { |
149 cinfo->in_color_space = JCS_RGB; | 152 cinfo->in_color_space = JCS_RGB; |
150 cinfo->input_components = 3; | 153 cinfo->input_components = 3; |
151 } | 154 } |
152 | 155 |
153 /* | 156 /* |
154 * A place to hold each scanline while it's converted. | 157 * A place to hold each scanline while it's converted. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 { | 209 { |
207 rle_source_ptr source = (rle_source_ptr) sinfo; | 210 rle_source_ptr source = (rle_source_ptr) sinfo; |
208 JSAMPROW src_row, dest_row; | 211 JSAMPROW src_row, dest_row; |
209 JDIMENSION col; | 212 JDIMENSION col; |
210 rle_map *colormap; | 213 rle_map *colormap; |
211 int val; | 214 int val; |
212 | 215 |
213 colormap = source->header.cmap; | 216 colormap = source->header.cmap; |
214 dest_row = source->pub.buffer[0]; | 217 dest_row = source->pub.buffer[0]; |
215 source->row--; | 218 source->row--; |
216 src_row = * (*cinfo->mem->access_virt_sarray) | 219 src_row = *(*cinfo->mem->access_virt_sarray) |
217 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); | 220 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); |
218 | 221 |
219 for (col = cinfo->image_width; col > 0; col--) { | 222 for (col = cinfo->image_width; col > 0; col--) { |
220 val = GETJSAMPLE(*src_row++); | 223 val = GETJSAMPLE(*src_row++); |
221 *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); | 224 *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); |
222 *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); | 225 *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); |
223 *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); | 226 *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); |
224 } | 227 } |
225 | 228 |
226 return 1; | 229 return 1; |
(...skipping 20 matching lines...) Expand all Loading... |
247 rle_map *colormap; | 250 rle_map *colormap; |
248 char channel; | 251 char channel; |
249 #ifdef PROGRESS_REPORT | 252 #ifdef PROGRESS_REPORT |
250 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; | 253 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; |
251 #endif | 254 #endif |
252 | 255 |
253 colormap = source->header.cmap; | 256 colormap = source->header.cmap; |
254 rle_row = source->rle_row; | 257 rle_row = source->rle_row; |
255 | 258 |
256 /* Read the RLE data into our virtual array. | 259 /* Read the RLE data into our virtual array. |
257 * We assume here that (a) rle_pixel is represented the same as JSAMPLE, | 260 * We assume here that rle_pixel is represented the same as JSAMPLE. |
258 * and (b) we are not on a machine where FAR pointers differ from regular. | |
259 */ | 261 */ |
260 RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ | 262 RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ |
261 | 263 |
262 #ifdef PROGRESS_REPORT | 264 #ifdef PROGRESS_REPORT |
263 if (progress != NULL) { | 265 if (progress != NULL) { |
264 progress->pub.pass_limit = cinfo->image_height; | 266 progress->pub.pass_limit = cinfo->image_height; |
265 progress->pub.pass_counter = 0; | 267 progress->pub.pass_counter = 0; |
266 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | 268 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); |
267 } | 269 } |
268 #endif | 270 #endif |
(...skipping 11 matching lines...) Expand all Loading... |
280 progress->pub.pass_counter++; | 282 progress->pub.pass_counter++; |
281 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | 283 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); |
282 } | 284 } |
283 #endif | 285 #endif |
284 } | 286 } |
285 break; | 287 break; |
286 | 288 |
287 case MAPPEDGRAY: | 289 case MAPPEDGRAY: |
288 case TRUECOLOR: | 290 case TRUECOLOR: |
289 for (row = 0; row < cinfo->image_height; row++) { | 291 for (row = 0; row < cinfo->image_height; row++) { |
290 scanline = * (*cinfo->mem->access_virt_sarray) | 292 scanline = *(*cinfo->mem->access_virt_sarray) |
291 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); | 293 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); |
292 rle_row = source->rle_row; | 294 rle_row = source->rle_row; |
293 rle_getrow(&source->header, rle_row); | 295 rle_getrow(&source->header, rle_row); |
294 | 296 |
295 for (col = 0; col < cinfo->image_width; col++) { | 297 for (col = 0; col < cinfo->image_width; col++) { |
296 for (channel = 0; channel < source->header.ncolors; channel++) { | 298 for (channel = 0; channel < source->header.ncolors; channel++) { |
297 *scanline++ = (JSAMPLE) | 299 *scanline++ = (JSAMPLE) |
298 (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); | 300 (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); |
299 } | 301 } |
300 } | 302 } |
301 | 303 |
302 #ifdef PROGRESS_REPORT | 304 #ifdef PROGRESS_REPORT |
303 if (progress != NULL) { | 305 if (progress != NULL) { |
304 progress->pub.pass_counter++; | 306 progress->pub.pass_counter++; |
305 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | 307 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); |
306 } | 308 } |
307 #endif | 309 #endif |
308 } | 310 } |
309 break; | 311 break; |
310 | 312 |
311 case DIRECTCOLOR: | 313 case DIRECTCOLOR: |
312 for (row = 0; row < cinfo->image_height; row++) { | 314 for (row = 0; row < cinfo->image_height; row++) { |
313 scanline = * (*cinfo->mem->access_virt_sarray) | 315 scanline = *(*cinfo->mem->access_virt_sarray) |
314 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); | 316 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); |
315 rle_getrow(&source->header, rle_row); | 317 rle_getrow(&source->header, rle_row); |
316 | 318 |
317 red_ptr = rle_row[0]; | 319 red_ptr = rle_row[0]; |
318 green_ptr = rle_row[1]; | 320 green_ptr = rle_row[1]; |
319 blue_ptr = rle_row[2]; | 321 blue_ptr = rle_row[2]; |
320 | 322 |
321 for (col = cinfo->image_width; col > 0; col--) { | 323 for (col = cinfo->image_width; col > 0; col--) { |
322 *scanline++ = *red_ptr++; | 324 *scanline++ = *red_ptr++; |
323 *scanline++ = *green_ptr++; | 325 *scanline++ = *green_ptr++; |
(...skipping 17 matching lines...) Expand all Loading... |
341 /* Set up to call proper row-extraction routine in future */ | 343 /* Set up to call proper row-extraction routine in future */ |
342 if (source->visual == PSEUDOCOLOR) { | 344 if (source->visual == PSEUDOCOLOR) { |
343 source->pub.buffer = source->rle_row; | 345 source->pub.buffer = source->rle_row; |
344 source->pub.get_pixel_rows = get_pseudocolor_row; | 346 source->pub.get_pixel_rows = get_pseudocolor_row; |
345 } else { | 347 } else { |
346 source->pub.get_pixel_rows = get_rle_row; | 348 source->pub.get_pixel_rows = get_rle_row; |
347 } | 349 } |
348 source->row = cinfo->image_height; | 350 source->row = cinfo->image_height; |
349 | 351 |
350 /* And fetch the topmost (bottommost) row */ | 352 /* And fetch the topmost (bottommost) row */ |
351 return (*source->pub.get_pixel_rows) (cinfo, sinfo); | 353 return (*source->pub.get_pixel_rows) (cinfo, sinfo); |
352 } | 354 } |
353 | 355 |
354 | 356 |
355 /* | 357 /* |
356 * Finish up at the end of the file. | 358 * Finish up at the end of the file. |
357 */ | 359 */ |
358 | 360 |
359 METHODDEF(void) | 361 METHODDEF(void) |
360 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | 362 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) |
361 { | 363 { |
362 /* no work */ | 364 /* no work */ |
363 } | 365 } |
364 | 366 |
365 | 367 |
366 /* | 368 /* |
367 * The module selection routine for RLE format input. | 369 * The module selection routine for RLE format input. |
368 */ | 370 */ |
369 | 371 |
370 GLOBAL(cjpeg_source_ptr) | 372 GLOBAL(cjpeg_source_ptr) |
371 jinit_read_rle (j_compress_ptr cinfo) | 373 jinit_read_rle (j_compress_ptr cinfo) |
372 { | 374 { |
373 rle_source_ptr source; | 375 rle_source_ptr source; |
374 | 376 |
375 /* Create module interface object */ | 377 /* Create module interface object */ |
376 source = (rle_source_ptr) | 378 source = (rle_source_ptr) |
377 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, | 379 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, |
378 SIZEOF(rle_source_struct)); | 380 sizeof(rle_source_struct)); |
379 /* Fill in method ptrs */ | 381 /* Fill in method ptrs */ |
380 source->pub.start_input = start_input_rle; | 382 source->pub.start_input = start_input_rle; |
381 source->pub.finish_input = finish_input_rle; | 383 source->pub.finish_input = finish_input_rle; |
382 source->pub.get_pixel_rows = load_image; | 384 source->pub.get_pixel_rows = load_image; |
383 | 385 |
384 return (cjpeg_source_ptr) source; | 386 return (cjpeg_source_ptr) source; |
385 } | 387 } |
386 | 388 |
387 #endif /* RLE_SUPPORTED */ | 389 #endif /* RLE_SUPPORTED */ |
OLD | NEW |