~ubuntu-branches/ubuntu/jaunty/freeimage/jaunty

« back to all changes in this revision

Viewing changes to FreeImage/Source/LibJPEG/djpeg.c

  • Committer: Bazaar Package Importer
  • Author(s): Federico Di Gregorio
  • Date: 2007-05-07 15:35:21 UTC
  • Revision ID: james.westby@ubuntu.com-20070507153521-m4lx765bzxxug9qf
Tags: upstream-3.9.3
ImportĀ upstreamĀ versionĀ 3.9.3

Show diffs side-by-side

added added

removed removed

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