Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/libjpeg/djpeg.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 * djpeg.c | |
| 3 * | |
| 4 * Copyright (C) 1991-1997, Thomas G. Lane. | |
| 5 * Modified 2009-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 a command-line user interface for the JPEG decompressor. | |
| 10 * It should work on any system with Unix- or MS-DOS-style command lines. | |
| 11 * | |
| 12 * Two different command line styles are permitted, depending on the | |
| 13 * compile-time switch TWO_FILE_COMMANDLINE: | |
| 14 * djpeg [options] inputfile outputfile | |
| 15 * djpeg [options] [inputfile] | |
| 16 * In the second style, output is always to standard output, which you'd | |
| 17 * normally redirect to a file or pipe to some other program. Input is | |
| 18 * either from a named file or from standard input (typically redirected). | |
| 19 * The second style is convenient on Unix but is unhelpful on systems that | |
| 20 * don't support pipes. Also, you MUST use the first style if your system | |
| 21 * doesn't do binary I/O to stdin/stdout. | |
| 22 * To simplify script writing, the "-outfile" switch is provided. The syntax | |
| 23 * djpeg [options] -outfile outputfile inputfile | |
| 24 * works regardless of which command line style is used. | |
| 25 */ | |
| 26 | |
| 27 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ | |
| 28 #include "jversion.h" /* for version message */ | |
| 29 | |
| 30 #include <ctype.h> /* to declare isprint() */ | |
| 31 | |
| 32 #ifdef USE_CCOMMAND /* command-line reader for Macintosh */ | |
| 33 #ifdef __MWERKS__ | |
| 34 #include <SIOUX.h> /* Metrowerks needs this */ | |
| 35 #include <console.h> /* ... and this */ | |
| 36 #endif | |
| 37 #ifdef THINK_C | |
| 38 #include <console.h> /* Think declares it here */ | |
| 39 #endif | |
| 40 #endif | |
| 41 | |
| 42 | |
| 43 /* Create the add-on message string table. */ | |
| 44 | |
| 45 #define JMESSAGE(code,string) string , | |
| 46 | |
| 47 static const char * const cdjpeg_message_table[] = { | |
| 48 #include "cderror.h" | |
| 49 NULL | |
| 50 }; | |
| 51 | |
| 52 | |
| 53 /* | |
| 54 * This list defines the known output image formats | |
| 55 * (not all of which need be supported by a given version). | |
| 56 * You can change the default output format by defining DEFAULT_FMT; | |
| 57 * indeed, you had better do so if you undefine PPM_SUPPORTED. | |
| 58 */ | |
| 59 | |
| 60 typedef enum { | |
| 61 FMT_BMP, /* BMP format (Windows flavor) */ | |
| 62 FMT_GIF, /* GIF format (LZW compressed) */ | |
| 63 FMT_GIF0, /* GIF format (uncompressed) */ | |
| 64 FMT_OS2, /* BMP format (OS/2 flavor) */ | |
| 65 FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ | |
| 66 FMT_RLE, /* RLE format */ | |
| 67 FMT_TARGA, /* Targa format */ | |
| 68 FMT_TIFF /* TIFF format */ | |
| 69 } IMAGE_FORMATS; | |
| 70 | |
| 71 #ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ | |
| 72 #define DEFAULT_FMT FMT_PPM | |
| 73 #endif | |
| 74 | |
| 75 static IMAGE_FORMATS requested_fmt; | |
| 76 | |
| 77 | |
| 78 /* | |
| 79 * Argument-parsing code. | |
| 80 * The switch parser is designed to be useful with DOS-style command line | |
| 81 * syntax, ie, intermixed switches and file names, where only the switches | |
| 82 * to the left of a given file name affect processing of that file. | |
| 83 * The main program in this file doesn't actually use this capability... | |
| 84 */ | |
| 85 | |
| 86 | |
| 87 static const char * progname; /* program name for error messages */ | |
| 88 static char * outfilename; /* for -outfile switch */ | |
| 89 | |
| 90 | |
| 91 LOCAL(void) | |
| 92 usage (void) | |
| 93 /* complain about bad command line */ | |
| 94 { | |
| 95 fprintf(stderr, "usage: %s [switches] ", progname); | |
| 96 #ifdef TWO_FILE_COMMANDLINE | |
| 97 fprintf(stderr, "inputfile outputfile\n"); | |
| 98 #else | |
| 99 fprintf(stderr, "[inputfile]\n"); | |
| 100 #endif | |
| 101 | |
| 102 fprintf(stderr, "Switches (names may be abbreviated):\n"); | |
| 103 fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); | |
| 104 fprintf(stderr, " -fast Fast, low-quality processing\n"); | |
| 105 fprintf(stderr, " -grayscale Force grayscale output\n"); | |
| 106 fprintf(stderr, " -rgb Force RGB output\n"); | |
| 107 #ifdef IDCT_SCALING_SUPPORTED | |
| 108 fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\n"); | |
| 109 #endif | |
| 110 #ifdef BMP_SUPPORTED | |
| 111 fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n", | |
| 112 (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); | |
| 113 #endif | |
| 114 #ifdef GIF_SUPPORTED | |
| 115 fprintf(stderr, " -gif Select GIF output format (LZW compressed)%s\n", | |
| 116 (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); | |
| 117 fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s\n", | |
| 118 (DEFAULT_FMT == FMT_GIF0 ? " (default)" : "")); | |
| 119 #endif | |
| 120 #ifdef BMP_SUPPORTED | |
| 121 fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", | |
| 122 (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); | |
| 123 #endif | |
| 124 #ifdef PPM_SUPPORTED | |
| 125 fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", | |
| 126 (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); | |
| 127 #endif | |
| 128 #ifdef RLE_SUPPORTED | |
| 129 fprintf(stderr, " -rle Select Utah RLE output format%s\n", | |
| 130 (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); | |
| 131 #endif | |
| 132 #ifdef TARGA_SUPPORTED | |
| 133 fprintf(stderr, " -targa Select Targa output format%s\n", | |
| 134 (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); | |
| 135 #endif | |
| 136 fprintf(stderr, "Switches for advanced users:\n"); | |
| 137 #ifdef DCT_ISLOW_SUPPORTED | |
| 138 fprintf(stderr, " -dct int Use integer DCT method%s\n", | |
| 139 (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); | |
| 140 #endif | |
| 141 #ifdef DCT_IFAST_SUPPORTED | |
| 142 fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", | |
| 143 (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); | |
| 144 #endif | |
| 145 #ifdef DCT_FLOAT_SUPPORTED | |
| 146 fprintf(stderr, " -dct float Use floating-point DCT method%s\n", | |
| 147 (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); | |
| 148 #endif | |
| 149 fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); | |
| 150 fprintf(stderr, " -dither none Don't use dithering in quantization\n"); | |
| 151 fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n"); | |
| 152 #ifdef QUANT_2PASS_SUPPORTED | |
| 153 fprintf(stderr, " -map FILE Map to colors used in named image file\n"); | |
| 154 #endif | |
| 155 fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); | |
| 156 #ifdef QUANT_1PASS_SUPPORTED | |
| 157 fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n"); | |
| 158 #endif | |
| 159 fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); | |
| 160 fprintf(stderr, " -outfile name Specify name for output file\n"); | |
| 161 fprintf(stderr, " -verbose or -debug Emit debug output\n"); | |
| 162 exit(EXIT_FAILURE); | |
| 163 } | |
| 164 | |
| 165 | |
| 166 LOCAL(int) | |
| 167 parse_switches (j_decompress_ptr cinfo, int argc, char **argv, | |
| 168 int last_file_arg_seen, boolean for_real) | |
| 169 /* Parse optional switches. | |
| 170 * Returns argv[] index of first file-name argument (== argc if none). | |
| 171 * Any file names with indexes <= last_file_arg_seen are ignored; | |
| 172 * they have presumably been processed in a previous iteration. | |
| 173 * (Pass 0 for last_file_arg_seen on the first or only iteration.) | |
| 174 * for_real is FALSE on the first (dummy) pass; we may skip any expensive | |
| 175 * processing. | |
| 176 */ | |
| 177 { | |
| 178 int argn; | |
| 179 char * arg; | |
| 180 | |
| 181 /* Set up default JPEG parameters. */ | |
| 182 requested_fmt = DEFAULT_FMT; /* set default output file format */ | |
| 183 outfilename = NULL; | |
| 184 cinfo->err->trace_level = 0; | |
| 185 | |
| 186 /* Scan command line options, adjust parameters */ | |
| 187 | |
| 188 for (argn = 1; argn < argc; argn++) { | |
| 189 arg = argv[argn]; | |
| 190 if (*arg != '-') { | |
| 191 /* Not a switch, must be a file name argument */ | |
| 192 if (argn <= last_file_arg_seen) { | |
| 193 outfilename = NULL; /* -outfile applies to just one input file */ | |
| 194 continue; /* ignore this name if previously processed */ | |
| 195 } | |
| 196 break; /* else done parsing switches */ | |
| 197 } | |
| 198 arg++; /* advance past switch marker character */ | |
| 199 | |
| 200 if (keymatch(arg, "bmp", 1)) { | |
| 201 /* BMP output format (Windows flavor). */ | |
| 202 requested_fmt = FMT_BMP; | |
| 203 | |
| 204 } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || | |
| 205 keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { | |
| 206 /* Do color quantization. */ | |
| 207 int val; | |
| 208 | |
| 209 if (++argn >= argc) /* advance to next argument */ | |
| 210 usage(); | |
| 211 if (sscanf(argv[argn], "%d", &val) != 1) | |
| 212 usage(); | |
| 213 cinfo->desired_number_of_colors = val; | |
| 214 cinfo->quantize_colors = TRUE; | |
| 215 | |
| 216 } else if (keymatch(arg, "dct", 2)) { | |
| 217 /* Select IDCT algorithm. */ | |
| 218 if (++argn >= argc) /* advance to next argument */ | |
| 219 usage(); | |
| 220 if (keymatch(argv[argn], "int", 1)) { | |
| 221 cinfo->dct_method = JDCT_ISLOW; | |
| 222 } else if (keymatch(argv[argn], "fast", 2)) { | |
| 223 cinfo->dct_method = JDCT_IFAST; | |
| 224 } else if (keymatch(argv[argn], "float", 2)) { | |
| 225 cinfo->dct_method = JDCT_FLOAT; | |
| 226 } else | |
| 227 usage(); | |
| 228 | |
| 229 } else if (keymatch(arg, "dither", 2)) { | |
| 230 /* Select dithering algorithm. */ | |
| 231 if (++argn >= argc) /* advance to next argument */ | |
| 232 usage(); | |
| 233 if (keymatch(argv[argn], "fs", 2)) { | |
| 234 cinfo->dither_mode = JDITHER_FS; | |
| 235 } else if (keymatch(argv[argn], "none", 2)) { | |
| 236 cinfo->dither_mode = JDITHER_NONE; | |
| 237 } else if (keymatch(argv[argn], "ordered", 2)) { | |
| 238 cinfo->dither_mode = JDITHER_ORDERED; | |
| 239 } else | |
| 240 usage(); | |
| 241 | |
| 242 } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { | |
| 243 /* Enable debug printouts. */ | |
| 244 /* On first -d, print version identification */ | |
| 245 static boolean printed_version = FALSE; | |
| 246 | |
| 247 if (! printed_version) { | |
| 248 fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n", | |
| 249 JVERSION, JCOPYRIGHT); | |
| 250 printed_version = TRUE; | |
| 251 } | |
| 252 cinfo->err->trace_level++; | |
| 253 | |
| 254 } else if (keymatch(arg, "fast", 1)) { | |
| 255 /* Select recommended processing options for quick-and-dirty output. */ | |
| 256 cinfo->two_pass_quantize = FALSE; | |
| 257 cinfo->dither_mode = JDITHER_ORDERED; | |
| 258 if (! cinfo->quantize_colors) /* don't override an earlier -colors */ | |
| 259 cinfo->desired_number_of_colors = 216; | |
| 260 cinfo->dct_method = JDCT_FASTEST; | |
| 261 cinfo->do_fancy_upsampling = FALSE; | |
| 262 | |
| 263 } else if (keymatch(arg, "gif", 1)) { | |
| 264 /* GIF output format (LZW compressed). */ | |
| 265 requested_fmt = FMT_GIF; | |
| 266 | |
| 267 } else if (keymatch(arg, "gif0", 4)) { | |
| 268 /* GIF output format (uncompressed). */ | |
| 269 requested_fmt = FMT_GIF0; | |
| 270 | |
| 271 } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { | |
| 272 /* Force monochrome output. */ | |
| 273 cinfo->out_color_space = JCS_GRAYSCALE; | |
| 274 | |
| 275 } else if (keymatch(arg, "rgb", 3)) { | |
| 276 /* Force RGB output. */ | |
| 277 cinfo->out_color_space = JCS_RGB; | |
| 278 | |
| 279 } else if (keymatch(arg, "map", 3)) { | |
| 280 /* Quantize to a color map taken from an input file. */ | |
| 281 if (++argn >= argc) /* advance to next argument */ | |
| 282 usage(); | |
| 283 if (for_real) { /* too expensive to do twice! */ | |
| 284 #ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ | |
| 285 FILE * mapfile; | |
| 286 | |
| 287 if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { | |
| 288 fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); | |
| 289 exit(EXIT_FAILURE); | |
| 290 } | |
| 291 read_color_map(cinfo, mapfile); | |
| 292 fclose(mapfile); | |
| 293 cinfo->quantize_colors = TRUE; | |
| 294 #else | |
| 295 ERREXIT(cinfo, JERR_NOT_COMPILED); | |
| 296 #endif | |
| 297 } | |
| 298 | |
| 299 } else if (keymatch(arg, "maxmemory", 3)) { | |
| 300 /* Maximum memory in Kb (or Mb with 'm'). */ | |
| 301 long lval; | |
| 302 char ch = 'x'; | |
| 303 | |
| 304 if (++argn >= argc) /* advance to next argument */ | |
| 305 usage(); | |
| 306 if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) | |
| 307 usage(); | |
| 308 if (ch == 'm' || ch == 'M') | |
| 309 lval *= 1000L; | |
| 310 cinfo->mem->max_memory_to_use = lval * 1000L; | |
| 311 | |
| 312 } else if (keymatch(arg, "nosmooth", 3)) { | |
| 313 /* Suppress fancy upsampling. */ | |
| 314 cinfo->do_fancy_upsampling = FALSE; | |
| 315 | |
| 316 } else if (keymatch(arg, "onepass", 3)) { | |
| 317 /* Use fast one-pass quantization. */ | |
| 318 cinfo->two_pass_quantize = FALSE; | |
| 319 | |
| 320 } else if (keymatch(arg, "os2", 3)) { | |
| 321 /* BMP output format (OS/2 flavor). */ | |
| 322 requested_fmt = FMT_OS2; | |
| 323 | |
| 324 } else if (keymatch(arg, "outfile", 4)) { | |
| 325 /* Set output file name. */ | |
| 326 if (++argn >= argc) /* advance to next argument */ | |
| 327 usage(); | |
| 328 outfilename = argv[argn]; /* save it away for later use */ | |
| 329 | |
| 330 } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { | |
| 331 /* PPM/PGM output format. */ | |
| 332 requested_fmt = FMT_PPM; | |
| 333 | |
| 334 } else if (keymatch(arg, "rle", 1)) { | |
| 335 /* RLE output format. */ | |
| 336 requested_fmt = FMT_RLE; | |
| 337 | |
| 338 } else if (keymatch(arg, "scale", 1)) { | |
| 339 /* Scale the output image by a fraction M/N. */ | |
| 340 if (++argn >= argc) /* advance to next argument */ | |
| 341 usage(); | |
| 342 if (sscanf(argv[argn], "%u/%u", | |
| 343 &cinfo->scale_num, &cinfo->scale_denom) < 1) | |
| 344 usage(); | |
| 345 | |
| 346 } else if (keymatch(arg, "targa", 1)) { | |
| 347 /* Targa output format. */ | |
| 348 requested_fmt = FMT_TARGA; | |
| 349 | |
| 350 } else { | |
| 351 usage(); /* bogus switch */ | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 return argn; /* return index of next arg (file name) */ | |
| 356 } | |
| 357 | |
| 358 | |
| 359 /* | |
| 360 * Marker processor for COM and interesting APPn markers. | |
| 361 * This replaces the library's built-in processor, which just skips the marker. | |
| 362 * We want to print out the marker as text, to the extent possible. | |
| 363 * Note this code relies on a non-suspending data source. | |
| 364 */ | |
| 365 | |
| 366 LOCAL(unsigned int) | |
| 367 jpeg_getc (j_decompress_ptr cinfo) | |
| 368 /* Read next byte */ | |
| 369 { | |
| 370 struct jpeg_source_mgr * datasrc = cinfo->src; | |
| 371 | |
| 372 if (datasrc->bytes_in_buffer == 0) { | |
| 373 if (! (*datasrc->fill_input_buffer) (cinfo)) | |
| 374 ERREXIT(cinfo, JERR_CANT_SUSPEND); | |
| 375 } | |
| 376 datasrc->bytes_in_buffer--; | |
| 377 return GETJOCTET(*datasrc->next_input_byte++); | |
| 378 } | |
| 379 | |
| 380 | |
| 381 METHODDEF(boolean) | |
| 382 print_text_marker (j_decompress_ptr cinfo) | |
| 383 { | |
| 384 boolean traceit = (cinfo->err->trace_level >= 1); | |
| 385 INT32 length; | |
| 386 unsigned int ch; | |
| 387 unsigned int lastch = 0; | |
| 388 | |
| 389 length = jpeg_getc(cinfo) << 8; | |
| 390 length += jpeg_getc(cinfo); | |
| 391 length -= 2; /* discount the length word itself */ | |
| 392 | |
| 393 if (traceit) { | |
| 394 if (cinfo->unread_marker == JPEG_COM) | |
| 395 fprintf(stderr, "Comment, length %ld:\n", (long) length); | |
| 396 else /* assume it is an APPn otherwise */ | |
| 397 fprintf(stderr, "APP%d, length %ld:\n", | |
| 398 cinfo->unread_marker - JPEG_APP0, (long) length); | |
| 399 } | |
| 400 | |
| 401 while (--length >= 0) { | |
| 402 ch = jpeg_getc(cinfo); | |
| 403 if (traceit) { | |
| 404 /* Emit the character in a readable form. | |
| 405 * Nonprintables are converted to \nnn form, | |
| 406 * while \ is converted to \\. | |
| 407 * Newlines in CR, CR/LF, or LF form will be printed as one newline. | |
| 408 */ | |
| 409 if (ch == '\r') { | |
| 410 fprintf(stderr, "\n"); | |
| 411 } else if (ch == '\n') { | |
| 412 if (lastch != '\r') | |
| 413 fprintf(stderr, "\n"); | |
| 414 } else if (ch == '\\') { | |
| 415 fprintf(stderr, "\\\\"); | |
| 416 } else if (isprint(ch)) { | |
| 417 putc(ch, stderr); | |
| 418 } else { | |
| 419 fprintf(stderr, "\\%03o", ch); | |
| 420 } | |
| 421 lastch = ch; | |
| 422 } | |
| 423 } | |
| 424 | |
| 425 if (traceit) | |
| 426 fprintf(stderr, "\n"); | |
| 427 | |
| 428 return TRUE; | |
| 429 } | |
| 430 | |
| 431 | |
| 432 /* | |
| 433 * The main program. | |
| 434 */ | |
| 435 | |
| 436 int | |
| 437 main (int argc, char **argv) | |
| 438 { | |
| 439 struct jpeg_decompress_struct cinfo; | |
| 440 struct jpeg_error_mgr jerr; | |
| 441 #ifdef PROGRESS_REPORT | |
| 442 struct cdjpeg_progress_mgr progress; | |
| 443 #endif | |
| 444 int file_index; | |
| 445 djpeg_dest_ptr dest_mgr = NULL; | |
| 446 FILE * input_file; | |
| 447 FILE * output_file; | |
| 448 JDIMENSION num_scanlines; | |
| 449 | |
| 450 /* On Mac, fetch a command line. */ | |
| 451 #ifdef USE_CCOMMAND | |
| 452 argc = ccommand(&argv); | |
| 453 #endif | |
| 454 | |
| 455 progname = argv[0]; | |
| 456 if (progname == NULL || progname[0] == 0) | |
| 457 progname = "djpeg"; /* in case C library doesn't provide it */ | |
| 458 | |
| 459 /* Initialize the JPEG decompression object with default error handling. */ | |
| 460 cinfo.err = jpeg_std_error(&jerr); | |
| 461 jpeg_create_decompress(&cinfo); | |
| 462 /* Add some application-specific error messages (from cderror.h) */ | |
| 463 jerr.addon_message_table = cdjpeg_message_table; | |
| 464 jerr.first_addon_message = JMSG_FIRSTADDONCODE; | |
| 465 jerr.last_addon_message = JMSG_LASTADDONCODE; | |
| 466 | |
| 467 /* Insert custom marker processor for COM and APP12. | |
| 468 * APP12 is used by some digital camera makers for textual info, | |
| 469 * so we provide the ability to display it as text. | |
| 470 * If you like, additional APPn marker types can be selected for display, | |
| 471 * but don't try to override APP0 or APP14 this way (see libjpeg.txt). | |
| 472 */ | |
| 473 jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); | |
| 474 jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); | |
| 475 | |
| 476 /* Now safe to enable signal catcher. */ | |
| 477 #ifdef NEED_SIGNAL_CATCHER | |
| 478 enable_signal_catcher((j_common_ptr) &cinfo); | |
| 479 #endif | |
| 480 | |
| 481 /* Scan command line to find file names. */ | |
| 482 /* It is convenient to use just one switch-parsing routine, but the switch | |
| 483 * values read here are ignored; we will rescan the switches after opening | |
| 484 * the input file. | |
| 485 * (Exception: tracing level set here controls verbosity for COM markers | |
| 486 * found during jpeg_read_header...) | |
| 487 */ | |
| 488 | |
| 489 file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); | |
| 490 | |
| 491 #ifdef TWO_FILE_COMMANDLINE | |
| 492 /* Must have either -outfile switch or explicit output file name */ | |
| 493 if (outfilename == NULL) { | |
| 494 if (file_index != argc-2) { | |
| 495 fprintf(stderr, "%s: must name one input and one output file\n", | |
| 496 progname); | |
| 497 usage(); | |
| 498 } | |
| 499 outfilename = argv[file_index+1]; | |
| 500 } else { | |
| 501 if (file_index != argc-1) { | |
| 502 fprintf(stderr, "%s: must name one input and one output file\n", | |
| 503 progname); | |
| 504 usage(); | |
| 505 } | |
| 506 } | |
| 507 #else | |
| 508 /* Unix style: expect zero or one file name */ | |
| 509 if (file_index < argc-1) { | |
| 510 fprintf(stderr, "%s: only one input file\n", progname); | |
| 511 usage(); | |
| 512 } | |
| 513 #endif /* TWO_FILE_COMMANDLINE */ | |
| 514 | |
| 515 /* Open the input file. */ | |
| 516 if (file_index < argc) { | |
| 517 if ((input_file = fopen(argv[file_index], READ_BINARY)) == NULL) { | |
| 518 fprintf(stderr, "%s: can't open %s\n", progname, argv[file_index]); | |
| 519 exit(EXIT_FAILURE); | |
| 520 } | |
| 521 } else { | |
| 522 /* default input file is stdin */ | |
| 523 input_file = read_stdin(); | |
| 524 } | |
| 525 | |
| 526 /* Open the output file. */ | |
| 527 if (outfilename != NULL) { | |
| 528 if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) { | |
| 529 fprintf(stderr, "%s: can't open %s\n", progname, outfilename); | |
| 530 exit(EXIT_FAILURE); | |
| 531 } | |
| 532 } else { | |
| 533 /* default output file is stdout */ | |
| 534 output_file = write_stdout(); | |
| 535 } | |
| 536 | |
| 537 #ifdef PROGRESS_REPORT | |
| 538 start_progress_monitor((j_common_ptr) &cinfo, &progress); | |
| 539 #endif | |
| 540 | |
| 541 /* Specify data source for decompression */ | |
| 542 jpeg_stdio_src(&cinfo, input_file); | |
| 543 | |
| 544 /* Read file header, set default decompression parameters */ | |
| 545 (void) jpeg_read_header(&cinfo, TRUE); | |
| 546 | |
| 547 /* Adjust default decompression parameters by re-parsing the options */ | |
| 548 file_index = parse_switches(&cinfo, argc, argv, 0, TRUE); | |
| 549 | |
| 550 /* Initialize the output module now to let it override any crucial | |
| 551 * option settings (for instance, GIF wants to force color quantization). | |
| 552 */ | |
| 553 switch (requested_fmt) { | |
| 554 #ifdef BMP_SUPPORTED | |
| 555 case FMT_BMP: | |
| 556 dest_mgr = jinit_write_bmp(&cinfo, FALSE); | |
| 557 break; | |
| 558 case FMT_OS2: | |
| 559 dest_mgr = jinit_write_bmp(&cinfo, TRUE); | |
| 560 break; | |
| 561 #endif | |
| 562 #ifdef GIF_SUPPORTED | |
| 563 case FMT_GIF: | |
| 564 dest_mgr = jinit_write_gif(&cinfo, TRUE); | |
| 565 break; | |
| 566 case FMT_GIF0: | |
| 567 dest_mgr = jinit_write_gif(&cinfo, FALSE); | |
| 568 break; | |
| 569 #endif | |
| 570 #ifdef PPM_SUPPORTED | |
| 571 case FMT_PPM: | |
| 572 dest_mgr = jinit_write_ppm(&cinfo); | |
| 573 break; | |
| 574 #endif | |
| 575 #ifdef RLE_SUPPORTED | |
| 576 case FMT_RLE: | |
| 577 dest_mgr = jinit_write_rle(&cinfo); | |
| 578 break; | |
| 579 #endif | |
| 580 #ifdef TARGA_SUPPORTED | |
| 581 case FMT_TARGA: | |
| 582 dest_mgr = jinit_write_targa(&cinfo); | |
| 583 break; | |
| 584 #endif | |
| 585 default: | |
| 586 ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); | |
| 587 } | |
| 588 dest_mgr->output_file = output_file; | |
| 589 | |
| 590 /* Start decompressor */ | |
| 591 (void) jpeg_start_decompress(&cinfo); | |
| 592 | |
| 593 /* Write output file header */ | |
| 594 (*dest_mgr->start_output) (&cinfo, dest_mgr); | |
| 595 | |
| 596 /* Process data */ | |
| 597 while (cinfo.output_scanline < cinfo.output_height) { | |
| 598 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, | |
| 599 dest_mgr->buffer_height); | |
| 600 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); | |
| 601 } | |
| 602 | |
| 603 #ifdef PROGRESS_REPORT | |
| 604 /* Hack: count final pass as done in case finish_output does an extra pass. | |
| 605 * The library won't have updated completed_passes. | |
| 606 */ | |
| 607 progress.pub.completed_passes = progress.pub.total_passes; | |
| 608 #endif | |
| 609 | |
| 610 /* Finish decompression and release memory. | |
| 611 * I must do it in this order because output module has allocated memory | |
| 612 * of lifespan JPOOL_IMAGE; it needs to finish before releasing memory. | |
| 613 */ | |
| 614 (*dest_mgr->finish_output) (&cinfo, dest_mgr); | |
| 615 (void) jpeg_finish_decompress(&cinfo); | |
| 616 jpeg_destroy_decompress(&cinfo); | |
| 617 | |
| 618 /* Close files, if we opened them */ | |
| 619 if (input_file != stdin) | |
| 620 fclose(input_file); | |
| 621 if (output_file != stdout) | |
| 622 fclose(output_file); | |
| 623 | |
| 624 #ifdef PROGRESS_REPORT | |
| 625 end_progress_monitor((j_common_ptr) &cinfo); | |
| 626 #endif | |
| 627 | |
| 628 /* All done. */ | |
| 629 exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); | |
| 630 return 0; /* suppress no-return-value warnings */ | |
| 631 } |
