comparison mupdf-source/thirdparty/libjpeg/cjpegalt.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 * alternate cjpeg.c
3 *
4 * Copyright (C) 1991-1998, Thomas G. Lane.
5 * Modified 2009-2023 by Guido Vollbeding.
6 * This file is part of the Independent JPEG Group's software.
7 * For conditions of distribution and use, see the accompanying README file.
8 *
9 * This file contains an alternate user interface for the JPEG compressor.
10 * One or more input files are named on the command line, and output file
11 * names are created by substituting ".jpg" for the input file's extension.
12 */
13
14 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
15 #include "jversion.h" /* for version message */
16
17 #ifdef USE_CCOMMAND /* command-line reader for Macintosh */
18 #ifdef __MWERKS__
19 #include <SIOUX.h> /* Metrowerks needs this */
20 #include <console.h> /* ... and this */
21 #endif
22 #ifdef THINK_C
23 #include <console.h> /* Think declares it here */
24 #endif
25 #endif
26
27 #ifndef PATH_MAX /* ANSI maximum-pathname-length constant */
28 #define PATH_MAX 256
29 #endif
30
31
32 /* Create the add-on message string table. */
33
34 #define JMESSAGE(code,string) string ,
35
36 static const char * const cdjpeg_message_table[] = {
37 #include "cderror.h"
38 NULL
39 };
40
41
42 /*
43 * Automatic determination of available memory.
44 */
45
46 static long default_maxmem; /* saves value determined at startup, or 0 */
47
48 #ifndef FREE_MEM_ESTIMATE /* may be defined from command line */
49
50 #ifdef MSDOS /* For MS-DOS (unless flat-memory model) */
51
52 #include <dos.h> /* for access to intdos() call */
53
54 LOCAL(long)
55 unused_dos_memory (void)
56 /* Obtain total amount of unallocated DOS memory */
57 {
58 union REGS regs;
59 long nparas;
60
61 regs.h.ah = 0x48; /* DOS function Allocate Memory Block */
62 regs.x.bx = 0xFFFF; /* Ask for more memory than DOS can have */
63 (void) intdos(&regs, &regs);
64 /* DOS will fail and return # of paragraphs actually available in BX. */
65 nparas = (unsigned int) regs.x.bx;
66 /* Times 16 to convert to bytes. */
67 return nparas << 4;
68 }
69
70 /* The default memory setting is 95% of the available space. */
71 #define FREE_MEM_ESTIMATE ((unused_dos_memory() * 95L) / 100L)
72
73 #endif /* MSDOS */
74
75 #ifdef ATARI /* For Atari ST/Mega/STE/TT/Falcon, Pure C or Turbo C */
76
77 #include <ext.h>
78
79 /* The default memory setting is 90% of the available space. */
80 #define FREE_MEM_ESTIMATE (((long) coreleft() * 90L) / 100L)
81
82 #endif /* ATARI */
83
84 /* Add memory-estimation procedures for other operating systems here,
85 * with appropriate #ifdef's around them.
86 */
87
88 #endif /* !FREE_MEM_ESTIMATE */
89
90
91 /*
92 * This routine determines what format the input file is,
93 * and selects the appropriate input-reading module.
94 *
95 * To determine which family of input formats the file belongs to,
96 * we may look only at the first byte of the file, since C does not
97 * guarantee that more than one character can be pushed back with ungetc.
98 * Looking at additional bytes would require one of these approaches:
99 * 1) assume we can fseek() the input file (fails for piped input);
100 * 2) assume we can push back more than one character (works in
101 * some C implementations, but unportable);
102 * 3) provide our own buffering (breaks input readers that want to use
103 * stdio directly, such as the RLE library);
104 * or 4) don't put back the data, and modify the input_init methods to assume
105 * they start reading after the start of file (also breaks RLE library).
106 * #1 is attractive for MS-DOS but is untenable on Unix.
107 *
108 * The most portable solution for file types that can't be identified by their
109 * first byte is to make the user tell us what they are. This is also the
110 * only approach for "raw" file types that contain only arbitrary values.
111 * We presently apply this method for Targa files. Most of the time Targa
112 * files start with 0x00, so we recognize that case. Potentially, however,
113 * a Targa file could start with any byte value (byte 0 is the length of the
114 * seldom-used ID field), so we provide a switch to force Targa input mode.
115 */
116
117 static boolean is_targa; /* records user -targa switch */
118
119
120 LOCAL(cjpeg_source_ptr)
121 select_file_type (j_compress_ptr cinfo, FILE * infile)
122 {
123 int c;
124
125 if (is_targa) {
126 #ifdef TARGA_SUPPORTED
127 return jinit_read_targa(cinfo);
128 #else
129 ERREXIT(cinfo, JERR_TGA_NOTCOMP);
130 #endif
131 }
132
133 if ((c = getc(infile)) == EOF)
134 ERREXIT(cinfo, JERR_INPUT_EMPTY);
135 if (ungetc(c, infile) == EOF)
136 ERREXIT(cinfo, JERR_UNGETC_FAILED);
137
138 switch (c) {
139 #ifdef BMP_SUPPORTED
140 case 'B':
141 return jinit_read_bmp(cinfo);
142 #endif
143 #ifdef GIF_SUPPORTED
144 case 'G':
145 return jinit_read_gif(cinfo);
146 #endif
147 #ifdef PPM_SUPPORTED
148 case 'P':
149 return jinit_read_ppm(cinfo);
150 #endif
151 #ifdef RLE_SUPPORTED
152 case 'R':
153 return jinit_read_rle(cinfo);
154 #endif
155 #ifdef TARGA_SUPPORTED
156 case 0x00:
157 return jinit_read_targa(cinfo);
158 #endif
159 default:
160 ERREXIT(cinfo, JERR_UNKNOWN_FORMAT);
161 break;
162 }
163
164 return NULL; /* suppress compiler warnings */
165 }
166
167
168 /*
169 * Argument-parsing code.
170 * The switch parser is designed to be useful with DOS-style command line
171 * syntax, ie, intermixed switches and file names, where only the switches
172 * to the left of a given file name affect processing of that file.
173 */
174
175
176 static const char * progname; /* program name for error messages */
177 static char * outfilename; /* for -outfile switch */
178
179
180 LOCAL(void)
181 usage (void)
182 /* complain about bad command line */
183 {
184 fprintf(stderr, "usage: %s [switches] inputfile(s)\n", progname);
185 fprintf(stderr, "List of input files may use wildcards (* and ?)\n");
186 fprintf(stderr, "Output filename is same as input filename, but extension .jpg\n");
187
188 fprintf(stderr, "Switches (names may be abbreviated):\n");
189 fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n");
190 fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
191 fprintf(stderr, " -rgb Create RGB JPEG file\n");
192 #ifdef ENTROPY_OPT_SUPPORTED
193 fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
194 #endif
195 #ifdef C_PROGRESSIVE_SUPPORTED
196 fprintf(stderr, " -progressive Create progressive JPEG file\n");
197 #endif
198 #ifdef DCT_SCALING_SUPPORTED
199 fprintf(stderr, " -scale M/N Scale image by fraction M/N, eg, 1/2\n");
200 #endif
201 #ifdef TARGA_SUPPORTED
202 fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
203 #endif
204 fprintf(stderr, "Switches for advanced users:\n");
205 #ifdef C_ARITH_CODING_SUPPORTED
206 fprintf(stderr, " -arithmetic Use arithmetic coding\n");
207 #endif
208 #ifdef DCT_SCALING_SUPPORTED
209 fprintf(stderr, " -block N DCT block size (1..16; default is 8)\n");
210 #endif
211 #if JPEG_LIB_VERSION_MAJOR >= 9
212 fprintf(stderr, " -rgb1 Create RGB JPEG file with reversible color transform\n");
213 fprintf(stderr, " -bgycc Create big gamut YCC JPEG file\n");
214 #endif
215 #ifdef DCT_ISLOW_SUPPORTED
216 fprintf(stderr, " -dct int Use integer DCT method%s\n",
217 (JDCT_DEFAULT == JDCT_ISLOW ? " (default)" : ""));
218 #endif
219 #ifdef DCT_IFAST_SUPPORTED
220 fprintf(stderr, " -dct fast Use fast integer DCT (less accurate)%s\n",
221 (JDCT_DEFAULT == JDCT_IFAST ? " (default)" : ""));
222 #endif
223 #ifdef DCT_FLOAT_SUPPORTED
224 fprintf(stderr, " -dct float Use floating-point DCT method%s\n",
225 (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
226 #endif
227 fprintf(stderr, " -nosmooth Don't use high-quality downsampling\n");
228 fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
229 #ifdef INPUT_SMOOTHING_SUPPORTED
230 fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
231 #endif
232 #ifndef FREE_MEM_ESTIMATE
233 fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n");
234 #endif
235 fprintf(stderr, " -outfile name Specify name for output file\n");
236 fprintf(stderr, " -verbose or -debug Emit debug output\n");
237 fprintf(stderr, "Switches for wizards:\n");
238 fprintf(stderr, " -baseline Force baseline quantization tables\n");
239 fprintf(stderr, " -qtables file Use quantization tables given in file\n");
240 fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
241 fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
242 #ifdef C_MULTISCAN_FILES_SUPPORTED
243 fprintf(stderr, " -scans file Create multi-scan JPEG per script file\n");
244 #endif
245 exit(EXIT_FAILURE);
246 }
247
248
249 LOCAL(int)
250 parse_switches (j_compress_ptr cinfo, int argc, char **argv,
251 int last_file_arg_seen, boolean for_real)
252 /* Parse optional switches.
253 * Returns argv[] index of first file-name argument (== argc if none).
254 * Any file names with indexes <= last_file_arg_seen are ignored;
255 * they have presumably been processed in a previous iteration.
256 * (Pass 0 for last_file_arg_seen on the first or only iteration.)
257 * for_real is FALSE on the first (dummy) pass; we may skip any expensive
258 * processing.
259 */
260 {
261 int argn;
262 char * arg;
263 boolean force_baseline;
264 boolean simple_progressive;
265 char * qualityarg = NULL; /* saves -quality parm if any */
266 char * qtablefile = NULL; /* saves -qtables filename if any */
267 char * qslotsarg = NULL; /* saves -qslots parm if any */
268 char * samplearg = NULL; /* saves -sample parm if any */
269 char * scansarg = NULL; /* saves -scans parm if any */
270
271 /* Set up default JPEG parameters. */
272
273 force_baseline = FALSE; /* by default, allow 16-bit quantizers */
274 simple_progressive = FALSE;
275 is_targa = FALSE;
276 outfilename = NULL;
277 cinfo->err->trace_level = 0;
278 if (default_maxmem > 0) /* override library's default value */
279 cinfo->mem->max_memory_to_use = default_maxmem;
280
281 /* Scan command line options, adjust parameters */
282
283 for (argn = 1; argn < argc; argn++) {
284 arg = argv[argn];
285 if (*arg != '-') {
286 /* Not a switch, must be a file name argument */
287 if (argn <= last_file_arg_seen) {
288 outfilename = NULL; /* -outfile applies to just one input file */
289 continue; /* ignore this name if previously processed */
290 }
291 break; /* else done parsing switches */
292 }
293 arg++; /* advance past switch marker character */
294
295 if (keymatch(arg, "arithmetic", 1)) {
296 /* Use arithmetic coding. */
297 #ifdef C_ARITH_CODING_SUPPORTED
298 cinfo->arith_code = TRUE;
299 #else
300 fprintf(stderr, "%s: sorry, arithmetic coding not supported\n",
301 progname);
302 exit(EXIT_FAILURE);
303 #endif
304
305 } else if (keymatch(arg, "baseline", 2)) {
306 /* Force baseline-compatible output (8-bit quantizer values). */
307 force_baseline = TRUE;
308
309 } else if (keymatch(arg, "block", 2)) {
310 /* Set DCT block size. */
311 #if defined DCT_SCALING_SUPPORTED && JPEG_LIB_VERSION_MAJOR >= 8 && \
312 (JPEG_LIB_VERSION_MAJOR > 8 || JPEG_LIB_VERSION_MINOR >= 3)
313 int val;
314
315 if (++argn >= argc) /* advance to next argument */
316 usage();
317 if (sscanf(argv[argn], "%d", &val) != 1)
318 usage();
319 if (val < 1 || val > 16)
320 usage();
321 cinfo->block_size = val;
322 #else
323 fprintf(stderr, "%s: sorry, block size setting not supported\n",
324 progname);
325 exit(EXIT_FAILURE);
326 #endif
327
328 } else if (keymatch(arg, "dct", 2)) {
329 /* Select DCT algorithm. */
330 if (++argn >= argc) /* advance to next argument */
331 usage();
332 if (keymatch(argv[argn], "int", 1)) {
333 cinfo->dct_method = JDCT_ISLOW;
334 } else if (keymatch(argv[argn], "fast", 2)) {
335 cinfo->dct_method = JDCT_IFAST;
336 } else if (keymatch(argv[argn], "float", 2)) {
337 cinfo->dct_method = JDCT_FLOAT;
338 } else
339 usage();
340
341 } else if (keymatch(arg, "debug", 1) || keymatch(arg, "verbose", 1)) {
342 /* Enable debug printouts. */
343 /* On first -d, print version identification */
344 static boolean printed_version = FALSE;
345
346 if (! printed_version) {
347 fprintf(stderr, "Independent JPEG Group's CJPEG, version %s\n%s\n",
348 JVERSION, JCOPYRIGHT);
349 printed_version = TRUE;
350 }
351 cinfo->err->trace_level++;
352
353 } else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
354 /* Force a monochrome JPEG file to be generated. */
355 jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
356
357 } else if (keymatch(arg, "rgb", 3) || keymatch(arg, "rgb1", 4)) {
358 /* Force an RGB JPEG file to be generated. */
359 #if JPEG_LIB_VERSION_MAJOR >= 9
360 /* Note: Entropy table assignment in jpeg_set_colorspace depends
361 * on color_transform.
362 */
363 cinfo->color_transform = arg[3] ? JCT_SUBTRACT_GREEN : JCT_NONE;
364 #endif
365 jpeg_set_colorspace(cinfo, JCS_RGB);
366
367 } else if (keymatch(arg, "bgycc", 5)) {
368 /* Force a big gamut YCC JPEG file to be generated. */
369 #if JPEG_LIB_VERSION_MAJOR >= 9 && \
370 (JPEG_LIB_VERSION_MAJOR > 9 || JPEG_LIB_VERSION_MINOR >= 1)
371 jpeg_set_colorspace(cinfo, JCS_BG_YCC);
372 #else
373 fprintf(stderr, "%s: sorry, BG_YCC colorspace not supported\n",
374 progname);
375 exit(EXIT_FAILURE);
376 #endif
377
378 } else if (keymatch(arg, "maxmemory", 3)) {
379 /* Maximum memory in Kb (or Mb with 'm'). */
380 long lval;
381 char ch = 'x';
382
383 if (++argn >= argc) /* advance to next argument */
384 usage();
385 if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
386 usage();
387 if (ch == 'm' || ch == 'M')
388 lval *= 1000L;
389 cinfo->mem->max_memory_to_use = lval * 1000L;
390
391 } else if (keymatch(arg, "nosmooth", 3)) {
392 /* Suppress fancy downsampling. */
393 cinfo->do_fancy_downsampling = FALSE;
394
395 } else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
396 /* Enable entropy parm optimization. */
397 #ifdef ENTROPY_OPT_SUPPORTED
398 cinfo->optimize_coding = TRUE;
399 #else
400 fprintf(stderr, "%s: sorry, entropy optimization was not compiled\n",
401 progname);
402 exit(EXIT_FAILURE);
403 #endif
404
405 } else if (keymatch(arg, "outfile", 4)) {
406 /* Set output file name. */
407 if (++argn >= argc) /* advance to next argument */
408 usage();
409 outfilename = argv[argn]; /* save it away for later use */
410
411 } else if (keymatch(arg, "progressive", 1)) {
412 /* Select simple progressive mode. */
413 #ifdef C_PROGRESSIVE_SUPPORTED
414 simple_progressive = TRUE;
415 /* We must postpone execution until num_components is known. */
416 #else
417 fprintf(stderr, "%s: sorry, progressive output was not compiled\n",
418 progname);
419 exit(EXIT_FAILURE);
420 #endif
421
422 } else if (keymatch(arg, "quality", 1)) {
423 /* Quality ratings (quantization table scaling factors). */
424 if (++argn >= argc) /* advance to next argument */
425 usage();
426 qualityarg = argv[argn];
427
428 } else if (keymatch(arg, "qslots", 2)) {
429 /* Quantization table slot numbers. */
430 if (++argn >= argc) /* advance to next argument */
431 usage();
432 qslotsarg = argv[argn];
433 /* Must delay setting qslots until after we have processed any
434 * colorspace-determining switches, since jpeg_set_colorspace sets
435 * default quant table numbers.
436 */
437
438 } else if (keymatch(arg, "qtables", 2)) {
439 /* Quantization tables fetched from file. */
440 if (++argn >= argc) /* advance to next argument */
441 usage();
442 qtablefile = argv[argn];
443 /* We postpone actually reading the file in case -quality comes later. */
444
445 } else if (keymatch(arg, "restart", 1)) {
446 /* Restart interval in MCU rows (or in MCUs with 'b'). */
447 long lval;
448 char ch = 'x';
449
450 if (++argn >= argc) /* advance to next argument */
451 usage();
452 if (sscanf(argv[argn], "%ld%c", &lval, &ch) < 1)
453 usage();
454 if (lval < 0 || lval > 65535L)
455 usage();
456 if (ch == 'b' || ch == 'B') {
457 cinfo->restart_interval = (unsigned int) lval;
458 cinfo->restart_in_rows = 0; /* else prior '-restart n' overrides me */
459 } else {
460 cinfo->restart_in_rows = (int) lval;
461 /* restart_interval will be computed during startup */
462 }
463
464 } else if (keymatch(arg, "sample", 2)) {
465 /* Set sampling factors. */
466 if (++argn >= argc) /* advance to next argument */
467 usage();
468 samplearg = argv[argn];
469 /* Must delay setting sample factors until after we have processed any
470 * colorspace-determining switches, since jpeg_set_colorspace sets
471 * default sampling factors.
472 */
473
474 } else if (keymatch(arg, "scale", 4)) {
475 /* Scale the image by a fraction M/N. */
476 if (++argn >= argc) /* advance to next argument */
477 usage();
478 if (sscanf(argv[argn], "%d/%d",
479 &cinfo->scale_num, &cinfo->scale_denom) != 2)
480 usage();
481
482 } else if (keymatch(arg, "scans", 4)) {
483 /* Set scan script. */
484 #ifdef C_MULTISCAN_FILES_SUPPORTED
485 if (++argn >= argc) /* advance to next argument */
486 usage();
487 scansarg = argv[argn];
488 /* We must postpone reading the file in case -progressive appears. */
489 #else
490 fprintf(stderr, "%s: sorry, multi-scan output was not compiled\n",
491 progname);
492 exit(EXIT_FAILURE);
493 #endif
494
495 } else if (keymatch(arg, "smooth", 2)) {
496 /* Set input smoothing factor. */
497 int val;
498
499 if (++argn >= argc) /* advance to next argument */
500 usage();
501 if (sscanf(argv[argn], "%d", &val) != 1)
502 usage();
503 if (val < 0 || val > 100)
504 usage();
505 cinfo->smoothing_factor = val;
506
507 } else if (keymatch(arg, "targa", 1)) {
508 /* Input file is Targa format. */
509 is_targa = TRUE;
510
511 } else {
512 usage(); /* bogus switch */
513 }
514 }
515
516 /* Post-switch-scanning cleanup */
517
518 if (for_real) {
519
520 /* Set quantization tables for selected quality. */
521 /* Some or all may be overridden if -qtables is present. */
522 if (qualityarg != NULL) /* process -quality if it was present */
523 if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
524 usage();
525
526 if (qtablefile != NULL) /* process -qtables if it was present */
527 if (! read_quant_tables(cinfo, qtablefile, force_baseline))
528 usage();
529
530 if (qslotsarg != NULL) /* process -qslots if it was present */
531 if (! set_quant_slots(cinfo, qslotsarg))
532 usage();
533
534 if (samplearg != NULL) /* process -sample if it was present */
535 if (! set_sample_factors(cinfo, samplearg))
536 usage();
537
538 #ifdef C_PROGRESSIVE_SUPPORTED
539 if (simple_progressive) /* process -progressive; -scans can override */
540 jpeg_simple_progression(cinfo);
541 #endif
542
543 #ifdef C_MULTISCAN_FILES_SUPPORTED
544 if (scansarg != NULL) /* process -scans if it was present */
545 if (! read_scan_script(cinfo, scansarg))
546 usage();
547 #endif
548 }
549
550 return argn; /* return index of next arg (file name) */
551 }
552
553
554 /*
555 * Check for overwrite of an existing file; clear it with user
556 */
557
558 #ifndef NO_OVERWRITE_CHECK
559
560 LOCAL(boolean)
561 is_write_ok (char * outfname)
562 {
563 FILE * ofile;
564 int ch;
565
566 ofile = fopen(outfname, READ_BINARY);
567 if (ofile == NULL)
568 return TRUE; /* not present */
569 fclose(ofile); /* oops, it is present */
570
571 for (;;) {
572 fprintf(stderr, "%s already exists, overwrite it? [y/n] ",
573 outfname);
574 fflush(stderr);
575 ch = getc(stdin);
576 if (ch != '\n') /* flush rest of line */
577 while (getc(stdin) != '\n')
578 /* nothing */;
579
580 switch (ch) {
581 case 'Y':
582 case 'y':
583 return TRUE;
584 case 'N':
585 case 'n':
586 return FALSE;
587 /* otherwise, ask again */
588 }
589 }
590 }
591
592 #endif
593
594
595 /*
596 * Process a single input file name, and return its index in argv[].
597 * File names at or to left of old_file_index have been processed already.
598 */
599
600 LOCAL(int)
601 process_one_file (int argc, char **argv, int old_file_index)
602 {
603 struct jpeg_compress_struct cinfo;
604 struct jpeg_error_mgr jerr;
605 char *infilename;
606 char workfilename[PATH_MAX];
607 #ifdef PROGRESS_REPORT
608 struct cdjpeg_progress_mgr progress;
609 #endif
610 int file_index;
611 cjpeg_source_ptr src_mgr;
612 FILE * input_file = NULL;
613 FILE * output_file = NULL;
614 JDIMENSION num_scanlines;
615
616 /* Initialize the JPEG compression object with default error handling. */
617 cinfo.err = jpeg_std_error(&jerr);
618 jpeg_create_compress(&cinfo);
619 /* Add some application-specific error messages (from cderror.h) */
620 jerr.addon_message_table = cdjpeg_message_table;
621 jerr.first_addon_message = JMSG_FIRSTADDONCODE;
622 jerr.last_addon_message = JMSG_LASTADDONCODE;
623
624 /* Now safe to enable signal catcher. */
625 #ifdef NEED_SIGNAL_CATCHER
626 enable_signal_catcher((j_common_ptr) &cinfo);
627 #endif
628
629 /* Initialize JPEG parameters.
630 * Much of this may be overridden later.
631 * In particular, we don't yet know the input file's color space,
632 * but we need to provide some value for jpeg_set_defaults() to work.
633 */
634
635 cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
636 jpeg_set_defaults(&cinfo);
637
638 /* Scan command line to find next file name.
639 * It is convenient to use just one switch-parsing routine, but the switch
640 * values read here are ignored; we will rescan the switches after opening
641 * the input file.
642 */
643
644 file_index = parse_switches(&cinfo, argc, argv, old_file_index, FALSE);
645 if (file_index >= argc) {
646 fprintf(stderr, "%s: missing input file name\n", progname);
647 usage();
648 }
649
650 /* Open the input file. */
651 infilename = argv[file_index];
652 if ((input_file = fopen(infilename, READ_BINARY)) == NULL) {
653 fprintf(stderr, "%s: can't open %s\n", progname, infilename);
654 goto fail;
655 }
656
657 #ifdef PROGRESS_REPORT
658 start_progress_monitor((j_common_ptr) &cinfo, &progress);
659 #endif
660
661 /* Figure out the input file format, and set up to read it. */
662 src_mgr = select_file_type(&cinfo, input_file);
663 src_mgr->input_file = input_file;
664
665 /* Read the input file header to obtain file size & colorspace. */
666 (*src_mgr->start_input) (&cinfo, src_mgr);
667
668 /* Now that we know input colorspace, fix colorspace-dependent defaults */
669 jpeg_default_colorspace(&cinfo);
670
671 /* Adjust default compression parameters by re-parsing the options */
672 file_index = parse_switches(&cinfo, argc, argv, old_file_index, TRUE);
673
674 /* If user didn't supply -outfile switch, select output file name. */
675 if (outfilename == NULL) {
676 int i;
677
678 outfilename = workfilename;
679 /* Make outfilename be infilename with .jpg substituted for extension */
680 strcpy(outfilename, infilename);
681 for (i = (int)strlen(outfilename)-1; i >= 0; i--) {
682 switch (outfilename[i]) {
683 case ':':
684 case '/':
685 case '\\':
686 i = 0; /* stop scanning */
687 break;
688 case '.':
689 outfilename[i] = '\0'; /* lop off existing extension */
690 i = 0; /* stop scanning */
691 break;
692 default:
693 break; /* keep scanning */
694 }
695 }
696 strcat(outfilename, ".jpg");
697 }
698
699 fprintf(stderr, "Compressing %s => %s\n", infilename, outfilename);
700 #ifndef NO_OVERWRITE_CHECK
701 if (! is_write_ok(outfilename))
702 goto fail;
703 #endif
704
705 /* Open the output file. */
706 if ((output_file = fopen(outfilename, WRITE_BINARY)) == NULL) {
707 fprintf(stderr, "%s: can't create %s\n", progname, outfilename);
708 goto fail;
709 }
710
711 /* Specify data destination for compression */
712 jpeg_stdio_dest(&cinfo, output_file);
713
714 /* Start compressor */
715 jpeg_start_compress(&cinfo, TRUE);
716
717 /* Process data */
718 while (cinfo.next_scanline < cinfo.image_height) {
719 num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
720 (void) jpeg_write_scanlines(&cinfo, src_mgr->buffer, num_scanlines);
721 }
722
723 /* Finish compression and release memory */
724 (*src_mgr->finish_input) (&cinfo, src_mgr);
725 jpeg_finish_compress(&cinfo);
726
727 /* Clean up and exit */
728 fail:
729 jpeg_destroy_compress(&cinfo);
730
731 if (input_file != NULL) fclose(input_file);
732 if (output_file != NULL) fclose(output_file);
733
734 #ifdef PROGRESS_REPORT
735 end_progress_monitor((j_common_ptr) &cinfo);
736 #endif
737
738 /* Disable signal catcher. */
739 #ifdef NEED_SIGNAL_CATCHER
740 enable_signal_catcher((j_common_ptr) NULL);
741 #endif
742
743 return file_index;
744 }
745
746
747 /*
748 * The main program.
749 */
750
751 int
752 main (int argc, char **argv)
753 {
754 int file_index;
755
756 /* On Mac, fetch a command line. */
757 #ifdef USE_CCOMMAND
758 argc = ccommand(&argv);
759 #endif
760
761 #ifdef MSDOS
762 progname = "cjpeg"; /* DOS tends to be too verbose about argv[0] */
763 #else
764 progname = argv[0];
765 if (progname == NULL || progname[0] == 0)
766 progname = "cjpeg"; /* in case C library doesn't provide it */
767 #endif
768
769 /* The default maxmem must be computed only once at program startup,
770 * since releasing memory with free() won't give it back to the OS.
771 */
772 #ifdef FREE_MEM_ESTIMATE
773 default_maxmem = FREE_MEM_ESTIMATE;
774 #else
775 default_maxmem = 0;
776 #endif
777
778 /* Scan command line, parse switches and locate input file names */
779
780 if (argc < 2)
781 usage(); /* nothing on the command line?? */
782
783 file_index = 0;
784
785 while (file_index < argc-1)
786 file_index = process_one_file(argc, argv, file_index);
787
788 /* All done. */
789 exit(EXIT_SUCCESS);
790 return 0; /* suppress no-return-value warnings */
791 }