| OLD | NEW |
| 1 /* | 1 /* |
| 2 * djpeg.c | 2 * djpeg.c |
| 3 * | 3 * |
| 4 * This file was part of the Independent JPEG Group's software: | 4 * This file was part of the Independent JPEG Group's software: |
| 5 * Copyright (C) 1991-1997, Thomas G. Lane. | 5 * Copyright (C) 1991-1997, Thomas G. Lane. |
| 6 * Modified 2013 by Guido Vollbeding. |
| 6 * libjpeg-turbo Modifications: | 7 * libjpeg-turbo Modifications: |
| 7 * Copyright (C) 2010-2011, 2013-2015, D. R. Commander. | 8 * Copyright (C) 2010-2011, 2013-2016, D. R. Commander. |
| 8 * Copyright (C) 2015, Google, Inc. | 9 * Copyright (C) 2015, Google, Inc. |
| 9 * For conditions of distribution and use, see the accompanying README file. | 10 * For conditions of distribution and use, see the accompanying README.ijg |
| 11 * file. |
| 10 * | 12 * |
| 11 * This file contains a command-line user interface for the JPEG decompressor. | 13 * This file contains a command-line user interface for the JPEG decompressor. |
| 12 * It should work on any system with Unix- or MS-DOS-style command lines. | 14 * It should work on any system with Unix- or MS-DOS-style command lines. |
| 13 * | 15 * |
| 14 * Two different command line styles are permitted, depending on the | 16 * Two different command line styles are permitted, depending on the |
| 15 * compile-time switch TWO_FILE_COMMANDLINE: | 17 * compile-time switch TWO_FILE_COMMANDLINE: |
| 16 *» djpeg [options] inputfile outputfile | 18 * djpeg [options] inputfile outputfile |
| 17 *» djpeg [options] [inputfile] | 19 * djpeg [options] [inputfile] |
| 18 * In the second style, output is always to standard output, which you'd | 20 * In the second style, output is always to standard output, which you'd |
| 19 * normally redirect to a file or pipe to some other program. Input is | 21 * normally redirect to a file or pipe to some other program. Input is |
| 20 * either from a named file or from standard input (typically redirected). | 22 * either from a named file or from standard input (typically redirected). |
| 21 * The second style is convenient on Unix but is unhelpful on systems that | 23 * The second style is convenient on Unix but is unhelpful on systems that |
| 22 * don't support pipes. Also, you MUST use the first style if your system | 24 * don't support pipes. Also, you MUST use the first style if your system |
| 23 * doesn't do binary I/O to stdin/stdout. | 25 * doesn't do binary I/O to stdin/stdout. |
| 24 * To simplify script writing, the "-outfile" switch is provided. The syntax | 26 * To simplify script writing, the "-outfile" switch is provided. The syntax |
| 25 *» djpeg [options] -outfile outputfile inputfile | 27 * djpeg [options] -outfile outputfile inputfile |
| 26 * works regardless of which command line style is used. | 28 * works regardless of which command line style is used. |
| 27 */ | 29 */ |
| 28 | 30 |
| 29 #include "cdjpeg.h"» » /* Common decls for cjpeg/djpeg applications */ | 31 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */ |
| 30 #include "jversion.h"» » /* for version message */ | 32 #include "jversion.h" /* for version message */ |
| 31 #include "config.h" | 33 #include "jconfigint.h" |
| 34 #include "wrppm.h" |
| 32 | 35 |
| 33 #include <ctype.h>» » /* to declare isprint() */ | 36 #include <ctype.h> /* to declare isprint() */ |
| 34 | 37 |
| 35 #ifdef USE_CCOMMAND» » /* command-line reader for Macintosh */ | 38 #ifdef USE_CCOMMAND /* command-line reader for Macintosh */ |
| 36 #ifdef __MWERKS__ | 39 #ifdef __MWERKS__ |
| 37 #include <SIOUX.h> /* Metrowerks needs this */ | 40 #include <SIOUX.h> /* Metrowerks needs this */ |
| 38 #include <console.h>» » /* ... and this */ | 41 #include <console.h> /* ... and this */ |
| 39 #endif | 42 #endif |
| 40 #ifdef THINK_C | 43 #ifdef THINK_C |
| 41 #include <console.h>» » /* Think declares it here */ | 44 #include <console.h> /* Think declares it here */ |
| 42 #endif | 45 #endif |
| 43 #endif | 46 #endif |
| 44 | 47 |
| 45 | 48 |
| 46 /* Create the add-on message string table. */ | 49 /* Create the add-on message string table. */ |
| 47 | 50 |
| 48 #define JMESSAGE(code,string)» string , | 51 #define JMESSAGE(code,string) string , |
| 49 | 52 |
| 50 static const char * const cdjpeg_message_table[] = { | 53 static const char * const cdjpeg_message_table[] = { |
| 51 #include "cderror.h" | 54 #include "cderror.h" |
| 52 NULL | 55 NULL |
| 53 }; | 56 }; |
| 54 | 57 |
| 55 | 58 |
| 56 /* | 59 /* |
| 57 * This list defines the known output image formats | 60 * This list defines the known output image formats |
| 58 * (not all of which need be supported by a given version). | 61 * (not all of which need be supported by a given version). |
| 59 * You can change the default output format by defining DEFAULT_FMT; | 62 * You can change the default output format by defining DEFAULT_FMT; |
| 60 * indeed, you had better do so if you undefine PPM_SUPPORTED. | 63 * indeed, you had better do so if you undefine PPM_SUPPORTED. |
| 61 */ | 64 */ |
| 62 | 65 |
| 63 typedef enum { | 66 typedef enum { |
| 64 » FMT_BMP,» » /* BMP format (Windows flavor) */ | 67 FMT_BMP, /* BMP format (Windows flavor) */ |
| 65 » FMT_GIF,» » /* GIF format */ | 68 FMT_GIF, /* GIF format */ |
| 66 » FMT_OS2,» » /* BMP format (OS/2 flavor) */ | 69 FMT_OS2, /* BMP format (OS/2 flavor) */ |
| 67 » FMT_PPM,» » /* PPM/PGM (PBMPLUS formats) */ | 70 FMT_PPM, /* PPM/PGM (PBMPLUS formats) */ |
| 68 » FMT_RLE,» » /* RLE format */ | 71 FMT_RLE, /* RLE format */ |
| 69 » FMT_TARGA,» » /* Targa format */ | 72 FMT_TARGA, /* Targa format */ |
| 70 » FMT_TIFF» » /* TIFF format */ | 73 FMT_TIFF /* TIFF format */ |
| 71 } IMAGE_FORMATS; | 74 } IMAGE_FORMATS; |
| 72 | 75 |
| 73 #ifndef DEFAULT_FMT» » /* so can override from CFLAGS in Makefile */ | 76 #ifndef DEFAULT_FMT /* so can override from CFLAGS in Makefile */ |
| 74 #define DEFAULT_FMT» FMT_PPM | 77 #define DEFAULT_FMT FMT_PPM |
| 75 #endif | 78 #endif |
| 76 | 79 |
| 77 static IMAGE_FORMATS requested_fmt; | 80 static IMAGE_FORMATS requested_fmt; |
| 78 | 81 |
| 79 | 82 |
| 80 /* | 83 /* |
| 81 * Argument-parsing code. | 84 * Argument-parsing code. |
| 82 * The switch parser is designed to be useful with DOS-style command line | 85 * The switch parser is designed to be useful with DOS-style command line |
| 83 * syntax, ie, intermixed switches and file names, where only the switches | 86 * syntax, ie, intermixed switches and file names, where only the switches |
| 84 * to the left of a given file name affect processing of that file. | 87 * to the left of a given file name affect processing of that file. |
| 85 * The main program in this file doesn't actually use this capability... | 88 * The main program in this file doesn't actually use this capability... |
| 86 */ | 89 */ |
| 87 | 90 |
| 88 | 91 |
| 89 static const char * progname;» /* program name for error messages */ | 92 static const char *progname; /* program name for error messages */ |
| 90 static char * outfilename;» /* for -outfile switch */ | 93 static char *outfilename; /* for -outfile switch */ |
| 91 boolean memsrc; /* for -memsrc switch */ | 94 boolean memsrc; /* for -memsrc switch */ |
| 92 boolean strip, skip; | 95 boolean skip, crop; |
| 93 JDIMENSION startY, endY; | 96 JDIMENSION skip_start, skip_end; |
| 97 JDIMENSION crop_x, crop_y, crop_width, crop_height; |
| 94 #define INPUT_BUF_SIZE 4096 | 98 #define INPUT_BUF_SIZE 4096 |
| 95 | 99 |
| 96 | 100 |
| 97 LOCAL(void) | 101 LOCAL(void) |
| 98 usage (void) | 102 usage (void) |
| 99 /* complain about bad command line */ | 103 /* complain about bad command line */ |
| 100 { | 104 { |
| 101 fprintf(stderr, "usage: %s [switches] ", progname); | 105 fprintf(stderr, "usage: %s [switches] ", progname); |
| 102 #ifdef TWO_FILE_COMMANDLINE | 106 #ifdef TWO_FILE_COMMANDLINE |
| 103 fprintf(stderr, "inputfile outputfile\n"); | 107 fprintf(stderr, "inputfile outputfile\n"); |
| 104 #else | 108 #else |
| 105 fprintf(stderr, "[inputfile]\n"); | 109 fprintf(stderr, "[inputfile]\n"); |
| 106 #endif | 110 #endif |
| 107 | 111 |
| 108 fprintf(stderr, "Switches (names may be abbreviated):\n"); | 112 fprintf(stderr, "Switches (names may be abbreviated):\n"); |
| 109 fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); | 113 fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); |
| 110 fprintf(stderr, " -fast Fast, low-quality processing\n"); | 114 fprintf(stderr, " -fast Fast, low-quality processing\n"); |
| 111 fprintf(stderr, " -grayscale Force grayscale output\n"); | 115 fprintf(stderr, " -grayscale Force grayscale output\n"); |
| 112 fprintf(stderr, " -rgb Force RGB output\n"); | 116 fprintf(stderr, " -rgb Force RGB output\n"); |
| 113 fprintf(stderr, " -rgb565 Force RGB565 output\n"); | 117 fprintf(stderr, " -rgb565 Force RGB565 output\n"); |
| 114 #ifdef IDCT_SCALING_SUPPORTED | 118 #ifdef IDCT_SCALING_SUPPORTED |
| 115 fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\
n"); | 119 fprintf(stderr, " -scale M/N Scale output image by fraction M/N, eg, 1/8\
n"); |
| 116 #endif | 120 #endif |
| 117 #ifdef BMP_SUPPORTED | 121 #ifdef BMP_SUPPORTED |
| 118 fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n
", | 122 fprintf(stderr, " -bmp Select BMP output format (Windows style)%s\n
", |
| 119 » (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); | 123 (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); |
| 120 #endif | 124 #endif |
| 121 #ifdef GIF_SUPPORTED | 125 #ifdef GIF_SUPPORTED |
| 122 fprintf(stderr, " -gif Select GIF output format%s\n", | 126 fprintf(stderr, " -gif Select GIF output format%s\n", |
| 123 » (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); | 127 (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); |
| 124 #endif | 128 #endif |
| 125 #ifdef BMP_SUPPORTED | 129 #ifdef BMP_SUPPORTED |
| 126 fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", | 130 fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", |
| 127 » (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); | 131 (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); |
| 128 #endif | 132 #endif |
| 129 #ifdef PPM_SUPPORTED | 133 #ifdef PPM_SUPPORTED |
| 130 fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", | 134 fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n", |
| 131 » (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); | 135 (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); |
| 132 #endif | 136 #endif |
| 133 #ifdef RLE_SUPPORTED | 137 #ifdef RLE_SUPPORTED |
| 134 fprintf(stderr, " -rle Select Utah RLE output format%s\n", | 138 fprintf(stderr, " -rle Select Utah RLE output format%s\n", |
| 135 » (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); | 139 (DEFAULT_FMT == FMT_RLE ? " (default)" : "")); |
| 136 #endif | 140 #endif |
| 137 #ifdef TARGA_SUPPORTED | 141 #ifdef TARGA_SUPPORTED |
| 138 fprintf(stderr, " -targa Select Targa output format%s\n", | 142 fprintf(stderr, " -targa Select Targa output format%s\n", |
| 139 » (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); | 143 (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); |
| 140 #endif | 144 #endif |
| 141 fprintf(stderr, "Switches for advanced users:\n"); | 145 fprintf(stderr, "Switches for advanced users:\n"); |
| 142 #ifdef DCT_ISLOW_SUPPORTED | 146 #ifdef DCT_ISLOW_SUPPORTED |
| 143 fprintf(stderr, " -dct int Use integer DCT method%s\n", | 147 fprintf(stderr, " -dct int Use integer DCT method%s\n", |
| 144 » (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); | 148 (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : "")); |
| 145 #endif | 149 #endif |
| 146 #ifdef DCT_IFAST_SUPPORTED | 150 #ifdef DCT_IFAST_SUPPORTED |
| 147 fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", | 151 fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n", |
| 148 » (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); | 152 (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : "")); |
| 149 #endif | 153 #endif |
| 150 #ifdef DCT_FLOAT_SUPPORTED | 154 #ifdef DCT_FLOAT_SUPPORTED |
| 151 fprintf(stderr, " -dct float Use floating-point DCT method%s\n", | 155 fprintf(stderr, " -dct float Use floating-point DCT method%s\n", |
| 152 » (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); | 156 (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); |
| 153 #endif | 157 #endif |
| 154 fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); | 158 fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); |
| 155 fprintf(stderr, " -dither none Don't use dithering in quantization\n"); | 159 fprintf(stderr, " -dither none Don't use dithering in quantization\n"); |
| 156 fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)
\n"); | 160 fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)
\n"); |
| 157 #ifdef QUANT_2PASS_SUPPORTED | 161 #ifdef QUANT_2PASS_SUPPORTED |
| 158 fprintf(stderr, " -map FILE Map to colors used in named image file\n"); | 162 fprintf(stderr, " -map FILE Map to colors used in named image file\n"); |
| 159 #endif | 163 #endif |
| 160 fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); | 164 fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); |
| 161 #ifdef QUANT_1PASS_SUPPORTED | 165 #ifdef QUANT_1PASS_SUPPORTED |
| 162 fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\
n"); | 166 fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\
n"); |
| 163 #endif | 167 #endif |
| 164 fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); | 168 fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); |
| 165 fprintf(stderr, " -outfile name Specify name for output file\n"); | 169 fprintf(stderr, " -outfile name Specify name for output file\n"); |
| 166 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) | 170 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) |
| 167 fprintf(stderr, " -memsrc Load input file into memory before decompres
sing\n"); | 171 fprintf(stderr, " -memsrc Load input file into memory before decompres
sing\n"); |
| 168 #endif | 172 #endif |
| 169 | 173 |
| 170 fprintf(stderr, " -skip Y0,Y1 Decode all rows except those between Y0 and
Y1 (inclusive)\n"); | 174 fprintf(stderr, " -skip Y0,Y1 Decompress all rows except those between Y0
and Y1 (inclusive)\n"); |
| 171 fprintf(stderr, " -strip Y0,Y1 Decode only rows between Y0 and Y1 (inclusiv
e)\n"); | 175 fprintf(stderr, " -crop WxH+X+Y Decompress only a rectangular subregion of t
he image\n"); |
| 172 fprintf(stderr, " -verbose or -debug Emit debug output\n"); | 176 fprintf(stderr, " -verbose or -debug Emit debug output\n"); |
| 177 fprintf(stderr, " -version Print version information and exit\n"); |
| 173 exit(EXIT_FAILURE); | 178 exit(EXIT_FAILURE); |
| 174 } | 179 } |
| 175 | 180 |
| 176 | 181 |
| 177 LOCAL(int) | 182 LOCAL(int) |
| 178 parse_switches (j_decompress_ptr cinfo, int argc, char **argv, | 183 parse_switches (j_decompress_ptr cinfo, int argc, char **argv, |
| 179 » » int last_file_arg_seen, boolean for_real) | 184 int last_file_arg_seen, boolean for_real) |
| 180 /* Parse optional switches. | 185 /* Parse optional switches. |
| 181 * Returns argv[] index of first file-name argument (== argc if none). | 186 * Returns argv[] index of first file-name argument (== argc if none). |
| 182 * Any file names with indexes <= last_file_arg_seen are ignored; | 187 * Any file names with indexes <= last_file_arg_seen are ignored; |
| 183 * they have presumably been processed in a previous iteration. | 188 * they have presumably been processed in a previous iteration. |
| 184 * (Pass 0 for last_file_arg_seen on the first or only iteration.) | 189 * (Pass 0 for last_file_arg_seen on the first or only iteration.) |
| 185 * for_real is FALSE on the first (dummy) pass; we may skip any expensive | 190 * for_real is FALSE on the first (dummy) pass; we may skip any expensive |
| 186 * processing. | 191 * processing. |
| 187 */ | 192 */ |
| 188 { | 193 { |
| 189 int argn; | 194 int argn; |
| 190 char * arg; | 195 char *arg; |
| 191 | 196 |
| 192 /* Set up default JPEG parameters. */ | 197 /* Set up default JPEG parameters. */ |
| 193 requested_fmt = DEFAULT_FMT;» /* set default output file format */ | 198 requested_fmt = DEFAULT_FMT; /* set default output file format */ |
| 194 outfilename = NULL; | 199 outfilename = NULL; |
| 195 memsrc = FALSE; | 200 memsrc = FALSE; |
| 196 strip = FALSE; | |
| 197 skip = FALSE; | 201 skip = FALSE; |
| 202 crop = FALSE; |
| 198 cinfo->err->trace_level = 0; | 203 cinfo->err->trace_level = 0; |
| 199 | 204 |
| 200 /* Scan command line options, adjust parameters */ | 205 /* Scan command line options, adjust parameters */ |
| 201 | 206 |
| 202 for (argn = 1; argn < argc; argn++) { | 207 for (argn = 1; argn < argc; argn++) { |
| 203 arg = argv[argn]; | 208 arg = argv[argn]; |
| 204 if (*arg != '-') { | 209 if (*arg != '-') { |
| 205 /* Not a switch, must be a file name argument */ | 210 /* Not a switch, must be a file name argument */ |
| 206 if (argn <= last_file_arg_seen) { | 211 if (argn <= last_file_arg_seen) { |
| 207 » outfilename = NULL;» /* -outfile applies to just one input file */ | 212 outfilename = NULL; /* -outfile applies to just one input file */ |
| 208 » continue;» » /* ignore this name if previously processed */ | 213 continue; /* ignore this name if previously processed */ |
| 209 } | 214 } |
| 210 break;» » » /* else done parsing switches */ | 215 break; /* else done parsing switches */ |
| 211 } | 216 } |
| 212 arg++;» » » /* advance past switch marker character */ | 217 arg++; /* advance past switch marker character */ |
| 213 | 218 |
| 214 if (keymatch(arg, "bmp", 1)) { | 219 if (keymatch(arg, "bmp", 1)) { |
| 215 /* BMP output format. */ | 220 /* BMP output format. */ |
| 216 requested_fmt = FMT_BMP; | 221 requested_fmt = FMT_BMP; |
| 217 | 222 |
| 218 } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || | 223 } else if (keymatch(arg, "colors", 1) || keymatch(arg, "colours", 1) || |
| 219 » keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { | 224 keymatch(arg, "quantize", 1) || keymatch(arg, "quantise", 1)) { |
| 220 /* Do color quantization. */ | 225 /* Do color quantization. */ |
| 221 int val; | 226 int val; |
| 222 | 227 |
| 223 if (++argn >= argc)» /* advance to next argument */ | 228 if (++argn >= argc) /* advance to next argument */ |
| 224 » usage(); | 229 usage(); |
| 225 if (sscanf(argv[argn], "%d", &val) != 1) | 230 if (sscanf(argv[argn], "%d", &val) != 1) |
| 226 » usage(); | 231 usage(); |
| 227 cinfo->desired_number_of_colors = val; | 232 cinfo->desired_number_of_colors = val; |
| 228 cinfo->quantize_colors = TRUE; | 233 cinfo->quantize_colors = TRUE; |
| 229 | 234 |
| 230 } else if (keymatch(arg, "dct", 2)) { | 235 } else if (keymatch(arg, "dct", 2)) { |
| 231 /* Select IDCT algorithm. */ | 236 /* Select IDCT algorithm. */ |
| 232 if (++argn >= argc)» /* advance to next argument */ | 237 if (++argn >= argc) /* advance to next argument */ |
| 233 » usage(); | 238 usage(); |
| 234 if (keymatch(argv[argn], "int", 1)) { | 239 if (keymatch(argv[argn], "int", 1)) { |
| 235 » cinfo->dct_method = JDCT_ISLOW; | 240 cinfo->dct_method = JDCT_ISLOW; |
| 236 } else if (keymatch(argv[argn], "fast", 2)) { | 241 } else if (keymatch(argv[argn], "fast", 2)) { |
| 237 » cinfo->dct_method = JDCT_IFAST; | 242 cinfo->dct_method = JDCT_IFAST; |
| 238 } else if (keymatch(argv[argn], "float", 2)) { | 243 } else if (keymatch(argv[argn], "float", 2)) { |
| 239 » cinfo->dct_method = JDCT_FLOAT; | 244 cinfo->dct_method = JDCT_FLOAT; |
| 240 } else | 245 } else |
| 241 » usage(); | 246 usage(); |
| 242 | 247 |
| 243 } else if (keymatch(arg, "dither", 2)) { | 248 } else if (keymatch(arg, "dither", 2)) { |
| 244 /* Select dithering algorithm. */ | 249 /* Select dithering algorithm. */ |
| 245 if (++argn >= argc)» /* advance to next argument */ | 250 if (++argn >= argc) /* advance to next argument */ |
| 246 » usage(); | 251 usage(); |
| 247 if (keymatch(argv[argn], "fs", 2)) { | 252 if (keymatch(argv[argn], "fs", 2)) { |
| 248 » cinfo->dither_mode = JDITHER_FS; | 253 cinfo->dither_mode = JDITHER_FS; |
| 249 } else if (keymatch(argv[argn], "none", 2)) { | 254 } else if (keymatch(argv[argn], "none", 2)) { |
| 250 » cinfo->dither_mode = JDITHER_NONE; | 255 cinfo->dither_mode = JDITHER_NONE; |
| 251 } else if (keymatch(argv[argn], "ordered", 2)) { | 256 } else if (keymatch(argv[argn], "ordered", 2)) { |
| 252 » cinfo->dither_mode = JDITHER_ORDERED; | 257 cinfo->dither_mode = JDITHER_ORDERED; |
| 253 } else | 258 } else |
| 254 » usage(); | 259 usage(); |
| 255 | 260 |
| 256 } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { | 261 } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) { |
| 257 /* Enable debug printouts. */ | 262 /* Enable debug printouts. */ |
| 258 /* On first -d, print version identification */ | 263 /* On first -d, print version identification */ |
| 259 static boolean printed_version = FALSE; | 264 static boolean printed_version = FALSE; |
| 260 | 265 |
| 261 if (! printed_version) { | 266 if (! printed_version) { |
| 262 » fprintf(stderr, "%s version %s (build %s)\n", | 267 fprintf(stderr, "%s version %s (build %s)\n", |
| 263 » » PACKAGE_NAME, VERSION, BUILD); | 268 PACKAGE_NAME, VERSION, BUILD); |
| 264 » fprintf(stderr, "%s\n\n", JCOPYRIGHT); | 269 fprintf(stderr, "%s\n\n", JCOPYRIGHT); |
| 265 » fprintf(stderr, "Emulating The Independent JPEG Group's software, versio
n %s\n\n", | 270 fprintf(stderr, "Emulating The Independent JPEG Group's software, versio
n %s\n\n", |
| 266 » » JVERSION); | 271 JVERSION); |
| 267 » printed_version = TRUE; | 272 printed_version = TRUE; |
| 268 } | 273 } |
| 269 cinfo->err->trace_level++; | 274 cinfo->err->trace_level++; |
| 270 | 275 |
| 276 } else if (keymatch(arg, "version", 4)) { |
| 277 fprintf(stderr, "%s version %s (build %s)\n", |
| 278 PACKAGE_NAME, VERSION, BUILD); |
| 279 exit(EXIT_SUCCESS); |
| 280 |
| 271 } else if (keymatch(arg, "fast", 1)) { | 281 } else if (keymatch(arg, "fast", 1)) { |
| 272 /* Select recommended processing options for quick-and-dirty output. */ | 282 /* Select recommended processing options for quick-and-dirty output. */ |
| 273 cinfo->two_pass_quantize = FALSE; | 283 cinfo->two_pass_quantize = FALSE; |
| 274 cinfo->dither_mode = JDITHER_ORDERED; | 284 cinfo->dither_mode = JDITHER_ORDERED; |
| 275 if (! cinfo->quantize_colors) /* don't override an earlier -colors */ | 285 if (! cinfo->quantize_colors) /* don't override an earlier -colors */ |
| 276 » cinfo->desired_number_of_colors = 216; | 286 cinfo->desired_number_of_colors = 216; |
| 277 cinfo->dct_method = JDCT_FASTEST; | 287 cinfo->dct_method = JDCT_FASTEST; |
| 278 cinfo->do_fancy_upsampling = FALSE; | 288 cinfo->do_fancy_upsampling = FALSE; |
| 279 | 289 |
| 280 } else if (keymatch(arg, "gif", 1)) { | 290 } else if (keymatch(arg, "gif", 1)) { |
| 281 /* GIF output format. */ | 291 /* GIF output format. */ |
| 282 requested_fmt = FMT_GIF; | 292 requested_fmt = FMT_GIF; |
| 283 | 293 |
| 284 } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { | 294 } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) { |
| 285 /* Force monochrome output. */ | 295 /* Force monochrome output. */ |
| 286 cinfo->out_color_space = JCS_GRAYSCALE; | 296 cinfo->out_color_space = JCS_GRAYSCALE; |
| 287 | 297 |
| 288 } else if (keymatch(arg, "rgb", 2)) { | 298 } else if (keymatch(arg, "rgb", 2)) { |
| 289 /* Force RGB output. */ | 299 /* Force RGB output. */ |
| 290 cinfo->out_color_space = JCS_RGB; | 300 cinfo->out_color_space = JCS_RGB; |
| 291 | 301 |
| 292 } else if (keymatch(arg, "rgb565", 2)) { | 302 } else if (keymatch(arg, "rgb565", 2)) { |
| 293 /* Force RGB565 output. */ | 303 /* Force RGB565 output. */ |
| 294 cinfo->out_color_space = JCS_RGB565; | 304 cinfo->out_color_space = JCS_RGB565; |
| 295 | 305 |
| 296 } else if (keymatch(arg, "map", 3)) { | 306 } else if (keymatch(arg, "map", 3)) { |
| 297 /* Quantize to a color map taken from an input file. */ | 307 /* Quantize to a color map taken from an input file. */ |
| 298 if (++argn >= argc)» /* advance to next argument */ | 308 if (++argn >= argc) /* advance to next argument */ |
| 299 » usage(); | 309 usage(); |
| 300 if (for_real) {» » /* too expensive to do twice! */ | 310 if (for_real) { /* too expensive to do twice! */ |
| 301 #ifdef QUANT_2PASS_SUPPORTED» /* otherwise can't quantize to supplied map */ | 311 #ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */ |
| 302 » FILE * mapfile; | 312 FILE *mapfile; |
| 303 | 313 |
| 304 » if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { | 314 if ((mapfile = fopen(argv[argn], READ_BINARY)) == NULL) { |
| 305 » fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); | 315 fprintf(stderr, "%s: can't open %s\n", progname, argv[argn]); |
| 306 » exit(EXIT_FAILURE); | 316 exit(EXIT_FAILURE); |
| 307 » } | 317 } |
| 308 » read_color_map(cinfo, mapfile); | 318 read_color_map(cinfo, mapfile); |
| 309 » fclose(mapfile); | 319 fclose(mapfile); |
| 310 » cinfo->quantize_colors = TRUE; | 320 cinfo->quantize_colors = TRUE; |
| 311 #else | 321 #else |
| 312 » ERREXIT(cinfo, JERR_NOT_COMPILED); | 322 ERREXIT(cinfo, JERR_NOT_COMPILED); |
| 313 #endif | 323 #endif |
| 314 } | 324 } |
| 315 | 325 |
| 316 } else if (keymatch(arg, "maxmemory", 3)) { | 326 } else if (keymatch(arg, "maxmemory", 3)) { |
| 317 /* Maximum memory in Kb (or Mb with 'm'). */ | 327 /* Maximum memory in Kb (or Mb with 'm'). */ |
| 318 long lval; | 328 long lval; |
| 319 char ch = 'x'; | 329 char ch = 'x'; |
| 320 | 330 |
| 321 if (++argn >= argc)» /* advance to next argument */ | 331 if (++argn >= argc) /* advance to next argument */ |
| 322 » usage(); | 332 usage(); |
| 323 if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) | 333 if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1) |
| 324 » usage(); | 334 usage(); |
| 325 if (ch == 'm' || ch == 'M') | 335 if (ch == 'm' || ch == 'M') |
| 326 » lval *= 1000L; | 336 lval *= 1000L; |
| 327 cinfo->mem->max_memory_to_use = lval * 1000L; | 337 cinfo->mem->max_memory_to_use = lval * 1000L; |
| 328 | 338 |
| 329 } else if (keymatch(arg, "nosmooth", 3)) { | 339 } else if (keymatch(arg, "nosmooth", 3)) { |
| 330 /* Suppress fancy upsampling */ | 340 /* Suppress fancy upsampling */ |
| 331 cinfo->do_fancy_upsampling = FALSE; | 341 cinfo->do_fancy_upsampling = FALSE; |
| 332 | 342 |
| 333 } else if (keymatch(arg, "onepass", 3)) { | 343 } else if (keymatch(arg, "onepass", 3)) { |
| 334 /* Use fast one-pass quantization. */ | 344 /* Use fast one-pass quantization. */ |
| 335 cinfo->two_pass_quantize = FALSE; | 345 cinfo->two_pass_quantize = FALSE; |
| 336 | 346 |
| 337 } else if (keymatch(arg, "os2", 3)) { | 347 } else if (keymatch(arg, "os2", 3)) { |
| 338 /* BMP output format (OS/2 flavor). */ | 348 /* BMP output format (OS/2 flavor). */ |
| 339 requested_fmt = FMT_OS2; | 349 requested_fmt = FMT_OS2; |
| 340 | 350 |
| 341 } else if (keymatch(arg, "outfile", 4)) { | 351 } else if (keymatch(arg, "outfile", 4)) { |
| 342 /* Set output file name. */ | 352 /* Set output file name. */ |
| 343 if (++argn >= argc)» /* advance to next argument */ | 353 if (++argn >= argc) /* advance to next argument */ |
| 344 » usage(); | 354 usage(); |
| 345 outfilename = argv[argn];»/* save it away for later use */ | 355 outfilename = argv[argn]; /* save it away for later use */ |
| 346 | 356 |
| 347 } else if (keymatch(arg, "memsrc", 2)) { | 357 } else if (keymatch(arg, "memsrc", 2)) { |
| 348 /* Use in-memory source manager */ | 358 /* Use in-memory source manager */ |
| 349 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) | 359 #if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED) |
| 350 memsrc = TRUE; | 360 memsrc = TRUE; |
| 351 #else | 361 #else |
| 352 fprintf(stderr, "%s: sorry, in-memory source manager was not compiled in\n
", | 362 fprintf(stderr, "%s: sorry, in-memory source manager was not compiled in\n
", |
| 353 progname); | 363 progname); |
| 354 exit(EXIT_FAILURE); | 364 exit(EXIT_FAILURE); |
| 355 #endif | 365 #endif |
| 356 | 366 |
| 357 } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { | 367 } else if (keymatch(arg, "pnm", 1) || keymatch(arg, "ppm", 1)) { |
| 358 /* PPM/PGM output format. */ | 368 /* PPM/PGM output format. */ |
| 359 requested_fmt = FMT_PPM; | 369 requested_fmt = FMT_PPM; |
| 360 | 370 |
| 361 } else if (keymatch(arg, "rle", 1)) { | 371 } else if (keymatch(arg, "rle", 1)) { |
| 362 /* RLE output format. */ | 372 /* RLE output format. */ |
| 363 requested_fmt = FMT_RLE; | 373 requested_fmt = FMT_RLE; |
| 364 | 374 |
| 365 } else if (keymatch(arg, "scale", 2)) { | 375 } else if (keymatch(arg, "scale", 2)) { |
| 366 /* Scale the output image by a fraction M/N. */ | 376 /* Scale the output image by a fraction M/N. */ |
| 367 if (++argn >= argc)» /* advance to next argument */ | 377 if (++argn >= argc) /* advance to next argument */ |
| 368 » usage(); | |
| 369 if (sscanf(argv[argn], "%d/%d", | |
| 370 » » &cinfo->scale_num, &cinfo->scale_denom) != 2) | |
| 371 » usage(); | |
| 372 | |
| 373 } else if (keymatch(arg, "strip", 2)) { | |
| 374 if (++argn >= argc) | |
| 375 usage(); | 378 usage(); |
| 376 if (sscanf(argv[argn], "%d,%d", &startY, &endY) != 2 || startY > endY) | 379 if (sscanf(argv[argn], "%u/%u", |
| 380 &cinfo->scale_num, &cinfo->scale_denom) != 2) |
| 377 usage(); | 381 usage(); |
| 378 strip = TRUE; | |
| 379 | 382 |
| 380 } else if (keymatch(arg, "skip", 2)) { | 383 } else if (keymatch(arg, "skip", 2)) { |
| 381 if (++argn >= argc) | 384 if (++argn >= argc) |
| 382 usage(); | 385 usage(); |
| 383 if (sscanf(argv[argn], "%d,%d", &startY, &endY) != 2 || startY > endY) | 386 if (sscanf(argv[argn], "%u,%u", &skip_start, &skip_end) != 2 || |
| 387 skip_start > skip_end) |
| 384 usage(); | 388 usage(); |
| 385 skip = TRUE; | 389 skip = TRUE; |
| 386 | 390 |
| 391 } else if (keymatch(arg, "crop", 2)) { |
| 392 char c; |
| 393 if (++argn >= argc) |
| 394 usage(); |
| 395 if (sscanf(argv[argn], "%u%c%u+%u+%u", &crop_width, &c, &crop_height, |
| 396 &crop_x, &crop_y) != 5 || |
| 397 (c != 'X' && c != 'x') || crop_width < 1 || crop_height < 1) |
| 398 usage(); |
| 399 crop = TRUE; |
| 400 |
| 387 } else if (keymatch(arg, "targa", 1)) { | 401 } else if (keymatch(arg, "targa", 1)) { |
| 388 /* Targa output format. */ | 402 /* Targa output format. */ |
| 389 requested_fmt = FMT_TARGA; | 403 requested_fmt = FMT_TARGA; |
| 390 | 404 |
| 391 } else { | 405 } else { |
| 392 usage();» » » /* bogus switch */ | 406 usage(); /* bogus switch */ |
| 393 } | 407 } |
| 394 } | 408 } |
| 395 | 409 |
| 396 return argn;» » » /* return index of next arg (file name) */ | 410 return argn; /* return index of next arg (file name) */ |
| 397 } | 411 } |
| 398 | 412 |
| 399 | 413 |
| 400 /* | 414 /* |
| 401 * Marker processor for COM and interesting APPn markers. | 415 * Marker processor for COM and interesting APPn markers. |
| 402 * This replaces the library's built-in processor, which just skips the marker. | 416 * This replaces the library's built-in processor, which just skips the marker. |
| 403 * We want to print out the marker as text, to the extent possible. | 417 * We want to print out the marker as text, to the extent possible. |
| 404 * Note this code relies on a non-suspending data source. | 418 * Note this code relies on a non-suspending data source. |
| 405 */ | 419 */ |
| 406 | 420 |
| 407 LOCAL(unsigned int) | 421 LOCAL(unsigned int) |
| 408 jpeg_getc (j_decompress_ptr cinfo) | 422 jpeg_getc (j_decompress_ptr cinfo) |
| 409 /* Read next byte */ | 423 /* Read next byte */ |
| 410 { | 424 { |
| 411 struct jpeg_source_mgr * datasrc = cinfo->src; | 425 struct jpeg_source_mgr *datasrc = cinfo->src; |
| 412 | 426 |
| 413 if (datasrc->bytes_in_buffer == 0) { | 427 if (datasrc->bytes_in_buffer == 0) { |
| 414 if (! (*datasrc->fill_input_buffer) (cinfo)) | 428 if (! (*datasrc->fill_input_buffer) (cinfo)) |
| 415 ERREXIT(cinfo, JERR_CANT_SUSPEND); | 429 ERREXIT(cinfo, JERR_CANT_SUSPEND); |
| 416 } | 430 } |
| 417 datasrc->bytes_in_buffer--; | 431 datasrc->bytes_in_buffer--; |
| 418 return GETJOCTET(*datasrc->next_input_byte++); | 432 return GETJOCTET(*datasrc->next_input_byte++); |
| 419 } | 433 } |
| 420 | 434 |
| 421 | 435 |
| 422 METHODDEF(boolean) | 436 METHODDEF(boolean) |
| 423 print_text_marker (j_decompress_ptr cinfo) | 437 print_text_marker (j_decompress_ptr cinfo) |
| 424 { | 438 { |
| 425 boolean traceit = (cinfo->err->trace_level >= 1); | 439 boolean traceit = (cinfo->err->trace_level >= 1); |
| 426 INT32 length; | 440 long length; |
| 427 unsigned int ch; | 441 unsigned int ch; |
| 428 unsigned int lastch = 0; | 442 unsigned int lastch = 0; |
| 429 | 443 |
| 430 length = jpeg_getc(cinfo) << 8; | 444 length = jpeg_getc(cinfo) << 8; |
| 431 length += jpeg_getc(cinfo); | 445 length += jpeg_getc(cinfo); |
| 432 length -= 2;» » » /* discount the length word itself */ | 446 length -= 2; /* discount the length word itself */ |
| 433 | 447 |
| 434 if (traceit) { | 448 if (traceit) { |
| 435 if (cinfo->unread_marker == JPEG_COM) | 449 if (cinfo->unread_marker == JPEG_COM) |
| 436 fprintf(stderr, "Comment, length %ld:\n", (long) length); | 450 fprintf(stderr, "Comment, length %ld:\n", (long) length); |
| 437 else» » » /* assume it is an APPn otherwise */ | 451 else /* assume it is an APPn otherwise */ |
| 438 fprintf(stderr, "APP%d, length %ld:\n", | 452 fprintf(stderr, "APP%d, length %ld:\n", |
| 439 » cinfo->unread_marker - JPEG_APP0, (long) length); | 453 cinfo->unread_marker - JPEG_APP0, (long) length); |
| 440 } | 454 } |
| 441 | 455 |
| 442 while (--length >= 0) { | 456 while (--length >= 0) { |
| 443 ch = jpeg_getc(cinfo); | 457 ch = jpeg_getc(cinfo); |
| 444 if (traceit) { | 458 if (traceit) { |
| 445 /* Emit the character in a readable form. | 459 /* Emit the character in a readable form. |
| 446 * Nonprintables are converted to \nnn form, | 460 * Nonprintables are converted to \nnn form, |
| 447 * while \ is converted to \\. | 461 * while \ is converted to \\. |
| 448 * Newlines in CR, CR/LF, or LF form will be printed as one newline. | 462 * Newlines in CR, CR/LF, or LF form will be printed as one newline. |
| 449 */ | 463 */ |
| 450 if (ch == '\r') { | 464 if (ch == '\r') { |
| 451 » fprintf(stderr, "\n"); | 465 fprintf(stderr, "\n"); |
| 452 } else if (ch == '\n') { | 466 } else if (ch == '\n') { |
| 453 » if (lastch != '\r') | 467 if (lastch != '\r') |
| 454 » fprintf(stderr, "\n"); | 468 fprintf(stderr, "\n"); |
| 455 } else if (ch == '\\') { | 469 } else if (ch == '\\') { |
| 456 » fprintf(stderr, "\\\\"); | 470 fprintf(stderr, "\\\\"); |
| 457 } else if (isprint(ch)) { | 471 } else if (isprint(ch)) { |
| 458 » putc(ch, stderr); | 472 putc(ch, stderr); |
| 459 } else { | 473 } else { |
| 460 » fprintf(stderr, "\\%03o", ch); | 474 fprintf(stderr, "\\%03o", ch); |
| 461 } | 475 } |
| 462 lastch = ch; | 476 lastch = ch; |
| 463 } | 477 } |
| 464 } | 478 } |
| 465 | 479 |
| 466 if (traceit) | 480 if (traceit) |
| 467 fprintf(stderr, "\n"); | 481 fprintf(stderr, "\n"); |
| 468 | 482 |
| 469 return TRUE; | 483 return TRUE; |
| 470 } | 484 } |
| 471 | 485 |
| 472 | 486 |
| 473 /* | 487 /* |
| 474 * The main program. | 488 * The main program. |
| 475 */ | 489 */ |
| 476 | 490 |
| 477 int | 491 int |
| 478 main (int argc, char **argv) | 492 main (int argc, char **argv) |
| 479 { | 493 { |
| 480 struct jpeg_decompress_struct cinfo; | 494 struct jpeg_decompress_struct cinfo; |
| 481 struct jpeg_error_mgr jerr; | 495 struct jpeg_error_mgr jerr; |
| 482 #ifdef PROGRESS_REPORT | 496 #ifdef PROGRESS_REPORT |
| 483 struct cdjpeg_progress_mgr progress; | 497 struct cdjpeg_progress_mgr progress; |
| 484 #endif | 498 #endif |
| 485 int file_index; | 499 int file_index; |
| 486 djpeg_dest_ptr dest_mgr = NULL; | 500 djpeg_dest_ptr dest_mgr = NULL; |
| 487 FILE * input_file; | 501 FILE *input_file; |
| 488 FILE * output_file; | 502 FILE *output_file; |
| 489 unsigned char *inbuffer = NULL; | 503 unsigned char *inbuffer = NULL; |
| 490 unsigned long insize = 0; | 504 unsigned long insize = 0; |
| 491 JDIMENSION num_scanlines; | 505 JDIMENSION num_scanlines; |
| 492 | 506 |
| 493 /* On Mac, fetch a command line. */ | 507 /* On Mac, fetch a command line. */ |
| 494 #ifdef USE_CCOMMAND | 508 #ifdef USE_CCOMMAND |
| 495 argc = ccommand(&argv); | 509 argc = ccommand(&argv); |
| 496 #endif | 510 #endif |
| 497 | 511 |
| 498 progname = argv[0]; | 512 progname = argv[0]; |
| 499 if (progname == NULL || progname[0] == 0) | 513 if (progname == NULL || progname[0] == 0) |
| 500 progname = "djpeg";»» /* in case C library doesn't provide it */ | 514 progname = "djpeg"; /* in case C library doesn't provide it */ |
| 501 | 515 |
| 502 /* Initialize the JPEG decompression object with default error handling. */ | 516 /* Initialize the JPEG decompression object with default error handling. */ |
| 503 cinfo.err = jpeg_std_error(&jerr); | 517 cinfo.err = jpeg_std_error(&jerr); |
| 504 jpeg_create_decompress(&cinfo); | 518 jpeg_create_decompress(&cinfo); |
| 505 /* Add some application-specific error messages (from cderror.h) */ | 519 /* Add some application-specific error messages (from cderror.h) */ |
| 506 jerr.addon_message_table = cdjpeg_message_table; | 520 jerr.addon_message_table = cdjpeg_message_table; |
| 507 jerr.first_addon_message = JMSG_FIRSTADDONCODE; | 521 jerr.first_addon_message = JMSG_FIRSTADDONCODE; |
| 508 jerr.last_addon_message = JMSG_LASTADDONCODE; | 522 jerr.last_addon_message = JMSG_LASTADDONCODE; |
| 509 | 523 |
| 510 /* Insert custom marker processor for COM and APP12. | 524 /* Insert custom marker processor for COM and APP12. |
| 511 * APP12 is used by some digital camera makers for textual info, | 525 * APP12 is used by some digital camera makers for textual info, |
| 512 * so we provide the ability to display it as text. | 526 * so we provide the ability to display it as text. |
| 513 * If you like, additional APPn marker types can be selected for display, | 527 * If you like, additional APPn marker types can be selected for display, |
| 514 * but don't try to override APP0 or APP14 this way (see libjpeg.txt). | 528 * but don't try to override APP0 or APP14 this way (see libjpeg.txt). |
| 515 */ | 529 */ |
| 516 jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); | 530 jpeg_set_marker_processor(&cinfo, JPEG_COM, print_text_marker); |
| 517 jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); | 531 jpeg_set_marker_processor(&cinfo, JPEG_APP0+12, print_text_marker); |
| 518 | 532 |
| 519 /* Now safe to enable signal catcher. */ | |
| 520 #ifdef NEED_SIGNAL_CATCHER | |
| 521 enable_signal_catcher((j_common_ptr) &cinfo); | |
| 522 #endif | |
| 523 | |
| 524 /* Scan command line to find file names. */ | 533 /* Scan command line to find file names. */ |
| 525 /* It is convenient to use just one switch-parsing routine, but the switch | 534 /* It is convenient to use just one switch-parsing routine, but the switch |
| 526 * values read here are ignored; we will rescan the switches after opening | 535 * values read here are ignored; we will rescan the switches after opening |
| 527 * the input file. | 536 * the input file. |
| 528 * (Exception: tracing level set here controls verbosity for COM markers | 537 * (Exception: tracing level set here controls verbosity for COM markers |
| 529 * found during jpeg_read_header...) | 538 * found during jpeg_read_header...) |
| 530 */ | 539 */ |
| 531 | 540 |
| 532 file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); | 541 file_index = parse_switches(&cinfo, argc, argv, 0, FALSE); |
| 533 | 542 |
| 534 #ifdef TWO_FILE_COMMANDLINE | 543 #ifdef TWO_FILE_COMMANDLINE |
| 535 /* Must have either -outfile switch or explicit output file name */ | 544 /* Must have either -outfile switch or explicit output file name */ |
| 536 if (outfilename == NULL) { | 545 if (outfilename == NULL) { |
| 537 if (file_index != argc-2) { | 546 if (file_index != argc-2) { |
| 538 fprintf(stderr, "%s: must name one input and one output file\n", | 547 fprintf(stderr, "%s: must name one input and one output file\n", |
| 539 » progname); | 548 progname); |
| 540 usage(); | 549 usage(); |
| 541 } | 550 } |
| 542 outfilename = argv[file_index+1]; | 551 outfilename = argv[file_index+1]; |
| 543 } else { | 552 } else { |
| 544 if (file_index != argc-1) { | 553 if (file_index != argc-1) { |
| 545 fprintf(stderr, "%s: must name one input and one output file\n", | 554 fprintf(stderr, "%s: must name one input and one output file\n", |
| 546 » progname); | 555 progname); |
| 547 usage(); | 556 usage(); |
| 548 } | 557 } |
| 549 } | 558 } |
| 550 #else | 559 #else |
| 551 /* Unix style: expect zero or one file name */ | 560 /* Unix style: expect zero or one file name */ |
| 552 if (file_index < argc-1) { | 561 if (file_index < argc-1) { |
| 553 fprintf(stderr, "%s: only one input file\n", progname); | 562 fprintf(stderr, "%s: only one input file\n", progname); |
| 554 usage(); | 563 usage(); |
| 555 } | 564 } |
| 556 #endif /* TWO_FILE_COMMANDLINE */ | 565 #endif /* TWO_FILE_COMMANDLINE */ |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 #endif | 656 #endif |
| 648 default: | 657 default: |
| 649 ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); | 658 ERREXIT(&cinfo, JERR_UNSUPPORTED_FORMAT); |
| 650 break; | 659 break; |
| 651 } | 660 } |
| 652 dest_mgr->output_file = output_file; | 661 dest_mgr->output_file = output_file; |
| 653 | 662 |
| 654 /* Start decompressor */ | 663 /* Start decompressor */ |
| 655 (void) jpeg_start_decompress(&cinfo); | 664 (void) jpeg_start_decompress(&cinfo); |
| 656 | 665 |
| 657 /* Strip decode */ | 666 /* Skip rows */ |
| 658 if (strip || skip) { | 667 if (skip) { |
| 659 JDIMENSION tmp; | 668 JDIMENSION tmp; |
| 660 | 669 |
| 661 /* Check for valid endY. We cannot check this value until after | 670 /* Check for valid skip_end. We cannot check this value until after |
| 662 * jpeg_start_decompress() is called. Note that we have already verified | 671 * jpeg_start_decompress() is called. Note that we have already verified |
| 663 * that startY <= endY. | 672 * that skip_start <= skip_end. |
| 664 */ | 673 */ |
| 665 if (endY > cinfo.output_height - 1) { | 674 if (skip_end > cinfo.output_height - 1) { |
| 666 fprintf(stderr, "%s: strip %d-%d exceeds image height %d\n", progname, | 675 fprintf(stderr, "%s: skip region exceeds image height %d\n", progname, |
| 667 startY, endY, cinfo.output_height); | 676 cinfo.output_height); |
| 668 exit(EXIT_FAILURE); | 677 exit(EXIT_FAILURE); |
| 669 } | 678 } |
| 670 | 679 |
| 671 /* Write output file header. This is a hack to ensure that the destination | 680 /* Write output file header. This is a hack to ensure that the destination |
| 672 * manager creates an image of the proper size for the partial decode. | 681 * manager creates an output image of the proper size. |
| 673 */ | 682 */ |
| 674 tmp = cinfo.output_height; | 683 tmp = cinfo.output_height; |
| 675 cinfo.output_height = endY - startY + 1; | 684 cinfo.output_height -= (skip_end - skip_start + 1); |
| 676 if (skip) | |
| 677 cinfo.output_height = tmp - cinfo.output_height; | |
| 678 (*dest_mgr->start_output) (&cinfo, dest_mgr); | 685 (*dest_mgr->start_output) (&cinfo, dest_mgr); |
| 679 cinfo.output_height = tmp; | 686 cinfo.output_height = tmp; |
| 680 | 687 |
| 681 /* Process data */ | 688 /* Process data */ |
| 682 if (skip) { | 689 while (cinfo.output_scanline < skip_start) { |
| 683 while (cinfo.output_scanline < startY) { | 690 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, |
| 684 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, | 691 dest_mgr->buffer_height); |
| 685 dest_mgr->buffer_height); | 692 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); |
| 686 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); | 693 } |
| 687 } | 694 jpeg_skip_scanlines(&cinfo, skip_end - skip_start + 1); |
| 688 jpeg_skip_scanlines(&cinfo, endY - startY + 1); | 695 while (cinfo.output_scanline < cinfo.output_height) { |
| 689 while (cinfo.output_scanline < cinfo.output_height) { | 696 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, |
| 690 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, | 697 dest_mgr->buffer_height); |
| 691 dest_mgr->buffer_height); | 698 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); |
| 692 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); | |
| 693 } | |
| 694 } else { | |
| 695 jpeg_skip_scanlines(&cinfo, startY); | |
| 696 while (cinfo.output_scanline <= endY) { | |
| 697 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, | |
| 698 dest_mgr->buffer_height); | |
| 699 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); | |
| 700 } | |
| 701 jpeg_skip_scanlines(&cinfo, cinfo.output_height - endY + 1); | |
| 702 } | 699 } |
| 703 | 700 |
| 704 /* Normal full image decode */ | 701 /* Decompress a subregion */ |
| 702 } else if (crop) { |
| 703 JDIMENSION tmp; |
| 704 |
| 705 /* Check for valid crop dimensions. We cannot check these values until |
| 706 * after jpeg_start_decompress() is called. |
| 707 */ |
| 708 if (crop_x + crop_width > cinfo.output_width || |
| 709 crop_y + crop_height > cinfo.output_height) { |
| 710 fprintf(stderr, "%s: crop dimensions exceed image dimensions %d x %d\n", |
| 711 progname, cinfo.output_width, cinfo.output_height); |
| 712 exit(EXIT_FAILURE); |
| 713 } |
| 714 |
| 715 jpeg_crop_scanline(&cinfo, &crop_x, &crop_width); |
| 716 ((ppm_dest_ptr) dest_mgr)->buffer_width = cinfo.output_width * |
| 717 cinfo.out_color_components * |
| 718 sizeof(JSAMPLE); |
| 719 |
| 720 /* Write output file header. This is a hack to ensure that the destination |
| 721 * manager creates an output image of the proper size. |
| 722 */ |
| 723 tmp = cinfo.output_height; |
| 724 cinfo.output_height = crop_height; |
| 725 (*dest_mgr->start_output) (&cinfo, dest_mgr); |
| 726 cinfo.output_height = tmp; |
| 727 |
| 728 /* Process data */ |
| 729 jpeg_skip_scanlines(&cinfo, crop_y); |
| 730 while (cinfo.output_scanline < crop_y + crop_height) { |
| 731 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, |
| 732 dest_mgr->buffer_height); |
| 733 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); |
| 734 } |
| 735 jpeg_skip_scanlines(&cinfo, cinfo.output_height - crop_y - crop_height); |
| 736 |
| 737 /* Normal full-image decompress */ |
| 705 } else { | 738 } else { |
| 706 /* Write output file header */ | 739 /* Write output file header */ |
| 707 (*dest_mgr->start_output) (&cinfo, dest_mgr); | 740 (*dest_mgr->start_output) (&cinfo, dest_mgr); |
| 708 | 741 |
| 709 /* Process data */ | 742 /* Process data */ |
| 710 while (cinfo.output_scanline < cinfo.output_height) { | 743 while (cinfo.output_scanline < cinfo.output_height) { |
| 711 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, | 744 num_scanlines = jpeg_read_scanlines(&cinfo, dest_mgr->buffer, |
| 712 dest_mgr->buffer_height); | 745 dest_mgr->buffer_height); |
| 713 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); | 746 (*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines); |
| 714 } | 747 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 737 | 770 |
| 738 #ifdef PROGRESS_REPORT | 771 #ifdef PROGRESS_REPORT |
| 739 end_progress_monitor((j_common_ptr) &cinfo); | 772 end_progress_monitor((j_common_ptr) &cinfo); |
| 740 #endif | 773 #endif |
| 741 | 774 |
| 742 if (memsrc && inbuffer != NULL) | 775 if (memsrc && inbuffer != NULL) |
| 743 free(inbuffer); | 776 free(inbuffer); |
| 744 | 777 |
| 745 /* All done. */ | 778 /* All done. */ |
| 746 exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); | 779 exit(jerr.num_warnings ? EXIT_WARNING : EXIT_SUCCESS); |
| 747 return 0;» » » /* suppress no-return-value warnings */ | 780 return 0; /* suppress no-return-value warnings */ |
| 748 } | 781 } |
| OLD | NEW |