CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/vncdll/winvnc/libjpeg/djpeg.c
Views: 11784
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
}
617
618