Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/libjpeg/rdrle.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * rdrle.c | |
| 3 * | |
| 4 * Copyright (C) 1991-1996, Thomas G. Lane. | |
| 5 * Modified 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 read input images in Utah 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 input from | |
| 14 * an ordinary stdio stream. They further assume that reading begins | |
| 15 * at the start of the file; start_input may need work if the | |
| 16 * user interface has already read some data (e.g., to determine that | |
| 17 * the file is indeed RLE format). | |
| 18 * | |
| 19 * Based on code contributed by Mike Lijewski, | |
| 20 * with updates from Robert Hutchinson. | |
| 21 */ | |
| 22 | |
| 23 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ | |
| 24 | |
| 25 #ifdef RLE_SUPPORTED | |
| 26 | |
| 27 /* rle.h is provided by the Utah Raster Toolkit. */ | |
| 28 | |
| 29 #include <rle.h> | |
| 30 | |
| 31 /* | |
| 32 * We assume that JSAMPLE has the same representation as rle_pixel, | |
| 33 * to wit, "unsigned char". Hence we can't cope with 12- or 16-bit samples. | |
| 34 */ | |
| 35 | |
| 36 #if BITS_IN_JSAMPLE != 8 | |
| 37 Sorry, this code only copes with 8-bit JSAMPLEs. /* deliberate syntax err */ | |
| 38 #endif | |
| 39 | |
| 40 /* | |
| 41 * We support the following types of RLE files: | |
| 42 * | |
| 43 * GRAYSCALE - 8 bits, no colormap | |
| 44 * MAPPEDGRAY - 8 bits, 1 channel colomap | |
| 45 * PSEUDOCOLOR - 8 bits, 3 channel colormap | |
| 46 * TRUECOLOR - 24 bits, 3 channel colormap | |
| 47 * DIRECTCOLOR - 24 bits, no colormap | |
| 48 * | |
| 49 * For now, we ignore any alpha channel in the image. | |
| 50 */ | |
| 51 | |
| 52 typedef enum | |
| 53 { GRAYSCALE, MAPPEDGRAY, PSEUDOCOLOR, TRUECOLOR, DIRECTCOLOR } rle_kind; | |
| 54 | |
| 55 | |
| 56 /* | |
| 57 * Since RLE stores scanlines bottom-to-top, we have to invert the image | |
| 58 * to conform to JPEG's top-to-bottom order. To do this, we read the | |
| 59 * incoming image into a virtual array on the first get_pixel_rows call, | |
| 60 * then fetch the required row from the virtual array on subsequent calls. | |
| 61 */ | |
| 62 | |
| 63 typedef struct _rle_source_struct * rle_source_ptr; | |
| 64 | |
| 65 typedef struct _rle_source_struct { | |
| 66 struct cjpeg_source_struct pub; /* public fields */ | |
| 67 | |
| 68 rle_kind visual; /* actual type of input file */ | |
| 69 jvirt_sarray_ptr image; /* virtual array to hold the image */ | |
| 70 JDIMENSION row; /* current row # in the virtual array */ | |
| 71 rle_hdr header; /* Input file information */ | |
| 72 rle_pixel **rle_row; /* holds a row returned by rle_getrow() */ | |
| 73 | |
| 74 } rle_source_struct; | |
| 75 | |
| 76 | |
| 77 /* | |
| 78 * Read the file header; return image size and component count. | |
| 79 */ | |
| 80 | |
| 81 METHODDEF(void) | |
| 82 start_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | |
| 83 { | |
| 84 rle_source_ptr source = (rle_source_ptr) sinfo; | |
| 85 JDIMENSION width, height; | |
| 86 #ifdef PROGRESS_REPORT | |
| 87 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; | |
| 88 #endif | |
| 89 | |
| 90 /* Use RLE library routine to get the header info */ | |
| 91 source->header = *rle_hdr_init(NULL); | |
| 92 source->header.rle_file = source->pub.input_file; | |
| 93 switch (rle_get_setup(&(source->header))) { | |
| 94 case RLE_SUCCESS: | |
| 95 /* A-OK */ | |
| 96 break; | |
| 97 case RLE_NOT_RLE: | |
| 98 ERREXIT(cinfo, JERR_RLE_NOT); | |
| 99 case RLE_NO_SPACE: | |
| 100 ERREXIT(cinfo, JERR_RLE_MEM); | |
| 101 case RLE_EMPTY: | |
| 102 ERREXIT(cinfo, JERR_RLE_EMPTY); | |
| 103 case RLE_EOF: | |
| 104 ERREXIT(cinfo, JERR_RLE_EOF); | |
| 105 default: | |
| 106 ERREXIT(cinfo, JERR_RLE_BADERROR); | |
| 107 } | |
| 108 | |
| 109 /* Figure out what we have, set private vars and return values accordingly */ | |
| 110 | |
| 111 width = source->header.xmax - source->header.xmin + 1; | |
| 112 height = source->header.ymax - source->header.ymin + 1; | |
| 113 source->header.xmin = 0; /* realign horizontally */ | |
| 114 source->header.xmax = width-1; | |
| 115 | |
| 116 cinfo->image_width = width; | |
| 117 cinfo->image_height = height; | |
| 118 cinfo->data_precision = 8; /* we can only handle 8 bit data */ | |
| 119 | |
| 120 if (source->header.ncolors == 1 && source->header.ncmap == 0) { | |
| 121 source->visual = GRAYSCALE; | |
| 122 TRACEMS2(cinfo, 1, JTRC_RLE_GRAY, width, height); | |
| 123 } else if (source->header.ncolors == 1 && source->header.ncmap == 1) { | |
| 124 source->visual = MAPPEDGRAY; | |
| 125 TRACEMS3(cinfo, 1, JTRC_RLE_MAPGRAY, width, height, | |
| 126 1 << source->header.cmaplen); | |
| 127 } else if (source->header.ncolors == 1 && source->header.ncmap == 3) { | |
| 128 source->visual = PSEUDOCOLOR; | |
| 129 TRACEMS3(cinfo, 1, JTRC_RLE_MAPPED, width, height, | |
| 130 1 << source->header.cmaplen); | |
| 131 } else if (source->header.ncolors == 3 && source->header.ncmap == 3) { | |
| 132 source->visual = TRUECOLOR; | |
| 133 TRACEMS3(cinfo, 1, JTRC_RLE_FULLMAP, width, height, | |
| 134 1 << source->header.cmaplen); | |
| 135 } else if (source->header.ncolors == 3 && source->header.ncmap == 0) { | |
| 136 source->visual = DIRECTCOLOR; | |
| 137 TRACEMS2(cinfo, 1, JTRC_RLE, width, height); | |
| 138 } else | |
| 139 ERREXIT(cinfo, JERR_RLE_UNSUPPORTED); | |
| 140 | |
| 141 if (source->visual == GRAYSCALE || source->visual == MAPPEDGRAY) { | |
| 142 cinfo->in_color_space = JCS_GRAYSCALE; | |
| 143 cinfo->input_components = 1; | |
| 144 } else { | |
| 145 cinfo->in_color_space = JCS_RGB; | |
| 146 cinfo->input_components = 3; | |
| 147 } | |
| 148 | |
| 149 /* | |
| 150 * A place to hold each scanline while it's converted. | |
| 151 * (GRAYSCALE scanlines don't need converting) | |
| 152 */ | |
| 153 if (source->visual != GRAYSCALE) { | |
| 154 source->rle_row = (rle_pixel **) (*cinfo->mem->alloc_sarray) | |
| 155 ((j_common_ptr) cinfo, JPOOL_IMAGE, | |
| 156 width, (JDIMENSION) cinfo->input_components); | |
| 157 } | |
| 158 | |
| 159 /* request a virtual array to hold the image */ | |
| 160 source->image = (*cinfo->mem->request_virt_sarray) | |
| 161 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, | |
| 162 width * (JDIMENSION) source->header.ncolors, height, (JDIMENSION) 1); | |
| 163 | |
| 164 #ifdef PROGRESS_REPORT | |
| 165 if (progress != NULL) { | |
| 166 /* count file input as separate pass */ | |
| 167 progress->total_extra_passes++; | |
| 168 } | |
| 169 #endif | |
| 170 | |
| 171 source->pub.buffer_height = 1; | |
| 172 } | |
| 173 | |
| 174 | |
| 175 /* | |
| 176 * Read one row of pixels. | |
| 177 * Called only after load_image has read the image into the virtual array. | |
| 178 * Used for GRAYSCALE, MAPPEDGRAY, TRUECOLOR, and DIRECTCOLOR images. | |
| 179 */ | |
| 180 | |
| 181 METHODDEF(JDIMENSION) | |
| 182 get_rle_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | |
| 183 { | |
| 184 rle_source_ptr source = (rle_source_ptr) sinfo; | |
| 185 | |
| 186 source->row--; | |
| 187 source->pub.buffer = (*cinfo->mem->access_virt_sarray) | |
| 188 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); | |
| 189 | |
| 190 return 1; | |
| 191 } | |
| 192 | |
| 193 /* | |
| 194 * Read one row of pixels. | |
| 195 * Called only after load_image has read the image into the virtual array. | |
| 196 * Used for PSEUDOCOLOR images. | |
| 197 */ | |
| 198 | |
| 199 METHODDEF(JDIMENSION) | |
| 200 get_pseudocolor_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | |
| 201 { | |
| 202 rle_source_ptr source = (rle_source_ptr) sinfo; | |
| 203 JSAMPROW src_row, dest_row; | |
| 204 JDIMENSION col; | |
| 205 rle_map *colormap; | |
| 206 int val; | |
| 207 | |
| 208 colormap = source->header.cmap; | |
| 209 dest_row = source->pub.buffer[0]; | |
| 210 source->row--; | |
| 211 src_row = * (*cinfo->mem->access_virt_sarray) | |
| 212 ((j_common_ptr) cinfo, source->image, source->row, (JDIMENSION) 1, FALSE); | |
| 213 | |
| 214 for (col = cinfo->image_width; col > 0; col--) { | |
| 215 val = GETJSAMPLE(*src_row++); | |
| 216 *dest_row++ = (JSAMPLE) (colormap[val ] >> 8); | |
| 217 *dest_row++ = (JSAMPLE) (colormap[val + 256] >> 8); | |
| 218 *dest_row++ = (JSAMPLE) (colormap[val + 512] >> 8); | |
| 219 } | |
| 220 | |
| 221 return 1; | |
| 222 } | |
| 223 | |
| 224 | |
| 225 /* | |
| 226 * Load the image into a virtual array. We have to do this because RLE | |
| 227 * files start at the lower left while the JPEG standard has them starting | |
| 228 * in the upper left. This is called the first time we want to get a row | |
| 229 * of input. What we do is load the RLE data into the array and then call | |
| 230 * the appropriate routine to read one row from the array. Before returning, | |
| 231 * we set source->pub.get_pixel_rows so that subsequent calls go straight to | |
| 232 * the appropriate row-reading routine. | |
| 233 */ | |
| 234 | |
| 235 METHODDEF(JDIMENSION) | |
| 236 load_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | |
| 237 { | |
| 238 rle_source_ptr source = (rle_source_ptr) sinfo; | |
| 239 JDIMENSION row, col; | |
| 240 JSAMPROW scanline, red_ptr, green_ptr, blue_ptr; | |
| 241 rle_pixel **rle_row; | |
| 242 rle_map *colormap; | |
| 243 char channel; | |
| 244 #ifdef PROGRESS_REPORT | |
| 245 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; | |
| 246 #endif | |
| 247 | |
| 248 /* Read the RLE data into our virtual array. | |
| 249 * We assume here that (a) rle_pixel is represented the same as JSAMPLE, | |
| 250 * and (b) we are not on a machine where FAR pointers differ from regular. | |
| 251 */ | |
| 252 RLE_CLR_BIT(source->header, RLE_ALPHA); /* don't read the alpha channel */ | |
| 253 | |
| 254 #ifdef PROGRESS_REPORT | |
| 255 if (progress != NULL) { | |
| 256 progress->pub.pass_limit = cinfo->image_height; | |
| 257 progress->pub.pass_counter = 0; | |
| 258 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | |
| 259 } | |
| 260 #endif | |
| 261 | |
| 262 switch (source->visual) { | |
| 263 | |
| 264 case GRAYSCALE: | |
| 265 case PSEUDOCOLOR: | |
| 266 for (row = 0; row < cinfo->image_height; row++) { | |
| 267 rle_row = (rle_pixel **) (*cinfo->mem->access_virt_sarray) | |
| 268 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); | |
| 269 rle_getrow(&source->header, rle_row); | |
| 270 #ifdef PROGRESS_REPORT | |
| 271 if (progress != NULL) { | |
| 272 progress->pub.pass_counter++; | |
| 273 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | |
| 274 } | |
| 275 #endif | |
| 276 } | |
| 277 break; | |
| 278 | |
| 279 case MAPPEDGRAY: | |
| 280 case TRUECOLOR: | |
| 281 rle_row = source->rle_row; | |
| 282 colormap = source->header.cmap; | |
| 283 for (row = 0; row < cinfo->image_height; row++) { | |
| 284 rle_getrow(&source->header, rle_row); | |
| 285 scanline = * (*cinfo->mem->access_virt_sarray) | |
| 286 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); | |
| 287 | |
| 288 for (col = 0; col < cinfo->image_width; col++) { | |
| 289 for (channel = 0; channel < source->header.ncolors; channel++) { | |
| 290 *scanline++ = (JSAMPLE) | |
| 291 (colormap[GETJSAMPLE(rle_row[channel][col]) + 256 * channel] >> 8); | |
| 292 } | |
| 293 } | |
| 294 | |
| 295 #ifdef PROGRESS_REPORT | |
| 296 if (progress != NULL) { | |
| 297 progress->pub.pass_counter++; | |
| 298 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | |
| 299 } | |
| 300 #endif | |
| 301 } | |
| 302 break; | |
| 303 | |
| 304 case DIRECTCOLOR: | |
| 305 rle_row = source->rle_row; | |
| 306 for (row = 0; row < cinfo->image_height; row++) { | |
| 307 rle_getrow(&source->header, rle_row); | |
| 308 scanline = * (*cinfo->mem->access_virt_sarray) | |
| 309 ((j_common_ptr) cinfo, source->image, row, (JDIMENSION) 1, TRUE); | |
| 310 | |
| 311 red_ptr = rle_row[0]; | |
| 312 green_ptr = rle_row[1]; | |
| 313 blue_ptr = rle_row[2]; | |
| 314 | |
| 315 for (col = cinfo->image_width; col > 0; col--) { | |
| 316 *scanline++ = *red_ptr++; | |
| 317 *scanline++ = *green_ptr++; | |
| 318 *scanline++ = *blue_ptr++; | |
| 319 } | |
| 320 | |
| 321 #ifdef PROGRESS_REPORT | |
| 322 if (progress != NULL) { | |
| 323 progress->pub.pass_counter++; | |
| 324 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo); | |
| 325 } | |
| 326 #endif | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 #ifdef PROGRESS_REPORT | |
| 331 if (progress != NULL) | |
| 332 progress->completed_extra_passes++; | |
| 333 #endif | |
| 334 | |
| 335 /* Set up to call proper row-extraction routine in future */ | |
| 336 if (source->visual == PSEUDOCOLOR) { | |
| 337 source->pub.buffer = source->rle_row; | |
| 338 source->pub.get_pixel_rows = get_pseudocolor_row; | |
| 339 } else { | |
| 340 source->pub.get_pixel_rows = get_rle_row; | |
| 341 } | |
| 342 source->row = cinfo->image_height; | |
| 343 | |
| 344 /* And fetch the topmost (bottommost) row */ | |
| 345 return (*source->pub.get_pixel_rows) (cinfo, sinfo); | |
| 346 } | |
| 347 | |
| 348 | |
| 349 /* | |
| 350 * Finish up at the end of the file. | |
| 351 */ | |
| 352 | |
| 353 METHODDEF(void) | |
| 354 finish_input_rle (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) | |
| 355 { | |
| 356 /* no work */ | |
| 357 } | |
| 358 | |
| 359 | |
| 360 /* | |
| 361 * The module selection routine for RLE format input. | |
| 362 */ | |
| 363 | |
| 364 GLOBAL(cjpeg_source_ptr) | |
| 365 jinit_read_rle (j_compress_ptr cinfo) | |
| 366 { | |
| 367 rle_source_ptr source; | |
| 368 | |
| 369 /* Create module interface object */ | |
| 370 source = (rle_source_ptr) (*cinfo->mem->alloc_small) | |
| 371 ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(rle_source_struct)); | |
| 372 /* Fill in method ptrs */ | |
| 373 source->pub.start_input = start_input_rle; | |
| 374 source->pub.finish_input = finish_input_rle; | |
| 375 source->pub.get_pixel_rows = load_image; | |
| 376 | |
| 377 return &source->pub; | |
| 378 } | |
| 379 | |
| 380 #endif /* RLE_SUPPORTED */ |
