| 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 |