123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- Program cjpeg;
- { Original: cjpeg.c ; Copyright (C) 1991-1996, Thomas G. Lane. }
- { This file contains a command-line user interface for the JPEG compressor. }
- { Two different command line styles are permitted, depending on the
- compile-time switch TWO_FILE_COMMANDLINE:
- cjpeg [options] inputfile outputfile
- cjpeg [options] [inputfile]
- In the second style, output is always to standard output, which you'd
- normally redirect to a file or pipe to some other program. Input is
- either from a named file or from standard input (typically redirected).
- The second style is convenient on Unix but is unhelpful on systems that
- don't support pipes. Also, you MUST use the first style if your system
- doesn't do binary I/O to stdin/stdout.
- To simplify script writing, the "-outfile" switch is provided. The syntax
- cjpeg [options] -outfile outputfile inputfile
- works regardless of which command line style is used. }
- {$I jconfig.inc}
- {$undef PPM_SUPPORTED}
- uses
- jmorecfg,
- cdjpeg, { Common decls for cjpeg/djpeg applications }
- {jversion,} { for version message }
- jpeglib,
- jerror,
- jinclude, JDataDst,
- JcAPImin, JcAPIstd, JcParam,
- {$ifdef TARGA_SUPPORTED} rdtarga, {$endif}
- {$ifdef BMP_SUPPORTED} rdbmp, {$endif}
- {$ifdef EXT_SWITCH} rdswitch, {$endif}
- {cderror,}
- jdeferr;
- { This routine determines what format the input file is,
- and selects the appropriate input-reading module.
- To determine which family of input formats the file belongs to,
- we may look only at the first byte of the file, since C does not
- guarantee that more than one character can be pushed back with ungetc.
- Looking at additional bytes would require one of these approaches:
- 1) assume we can fseek() the input file (fails for piped input);
- 2) assume we can push back more than one character (works in
- some C implementations, but unportable);
- 3) provide our own buffering (breaks input readers that want to use
- stdio directly, such as the RLE library);
- or 4) don't put back the data, and modify the input_init methods to assume
- they start reading after the start of file (also breaks RLE library).
- #1 is attractive for MS-DOS but is untenable on Unix.
- The most portable solution for file types that can't be identified by their
- first byte is to make the user tell us what they are. This is also the
- only approach for "raw" file types that contain only arbitrary values.
- We presently apply this method for Targa files. Most of the time Targa
- files start with $00, so we recognize that case. Potentially, however,
- a Targa file could start with any byte value (byte 0 is the length of the
- seldom-used ID field), so we provide a switch to force Targa input mode. }
- var
- is_targa : boolean; { records user -targa switch }
- function GetFirstChar(cinfo : j_compress_ptr;
- fptr : fileptr) : char;
- var
- c : char;
- begin
- if JFREAD(fptr, @c, 1) <> 1 then
- ERREXIT(j_common_ptr(cinfo), JERR_INPUT_EMPTY);
- {$ifndef delphi_stream}
- Seek(fptr^, 0); { Nomssi: probably not portable }
- {$else}
- Fptr^.Seek(0,0);
- {$endif}
- if (IOresult <> 0) then
- ERREXIT(j_common_ptr(cinfo), JERR_UNGETC_FAILED);
- GetFirstChar := c;
- end;
- {LOCAL}
- function select_file_type (cinfo : j_compress_ptr;
- var infile : FILE) : cjpeg_source_ptr;
- var
- c : char;
- begin
- if (is_targa) then
- begin
- {$ifdef TARGA_SUPPORTED}
- select_file_type := jinit_read_targa(cinfo);
- exit;
- {$else}
- ERREXIT(j_common_ptr(cinfo), JERR_TGA_NOTCOMP);
- {$endif}
- end;
- c := GetFirstChar(cinfo, @infile);
- select_file_type := NIL; { suppress compiler warnings }
- case c of
- {$ifdef BMP_SUPPORTED}
- 'B': select_file_type := jinit_read_bmp(cinfo);
- {$endif}
- {$ifdef GIF_SUPPORTED}
- 'G': select_file_type := jinit_read_gif(cinfo);
- {$endif}
- {$ifdef PPM_SUPPORTED}
- 'P': select_file_type := jinit_read_ppm(cinfo);
- {$endif}
- {$ifdef RLE_SUPPORTED}
- 'R': select_file_type := jinit_read_rle(cinfo);
- {$endif}
- {$ifdef TARGA_SUPPORTED}
- char($00): select_file_type := jinit_read_targa(cinfo);
- {$endif}
- else
- ERREXIT(j_common_ptr(cinfo), JERR_UNKNOWN_FORMAT);
- end;
- end;
- { Argument-parsing code.
- The switch parser is designed to be useful with DOS-style command line
- syntax, ie, intermixed switches and file names, where only the switches
- to the left of a given file name affect processing of that file.
- The main program in this file doesn't actually use this capability... }
- var
- progname, { program name for error messages }
- outfilename : string[79]; { for -outfile switch }
- {LOCAL}
- procedure usage;
- { complain about bad command line }
- begin
- Write(output, 'usage: ', progname, ' [switches] ');
- {$ifdef TWO_FILE_COMMANDLINE}
- WriteLn(output, 'inputfile outputfile');
- {$else}
- WriteLn(output, '[inputfile]');
- {$endif}
- WriteLn(output, 'Switches (names may be abbreviated):');
- WriteLn(output, ' -quality N Compression quality (0..100; 5-95 is useful range)');
- WriteLn(output, ' -grayscale Create monochrome JPEG file');
- {$ifdef ENTROPY_OPT_SUPPORTED}
- WriteLn(output, ' -optimize Optimize Huffman table (smaller file, but slow compression)');
- {$endif}
- {$ifdef C_PROGRESSIVE_SUPPORTED}
- WriteLn(output, ' -progressive Create progressive JPEG file');
- {$endif}
- {$ifdef TARGA_SUPPORTED}
- WriteLn(output, ' -targa Input file is Targa format (usually not needed)');
- {$endif}
- WriteLn(output, 'Switches for advanced users:');
- {$ifdef DCT_ISLOW_SUPPORTED}
- if (JDCT_DEFAULT = JDCT_ISLOW) then
- WriteLn(output, ' -dct int Use integer DCT method (default)')
- else
- WriteLn(output, ' -dct int Use integer DCT method');
- {$endif}
- {$ifdef DCT_IFAST_SUPPORTED}
- if (JDCT_DEFAULT = JDCT_IFAST) then
- WriteLn(output, ' -dct fast Use fast integer DCT (less accurate) (default)')
- else
- WriteLn(output, ' -dct fast Use fast integer DCT (less accurate)');
- {$endif}
- {$ifdef DCT_FLOAT_SUPPORTED}
- if (JDCT_DEFAULT = JDCT_FLOAT) then
- WriteLn(output, ' -dct float Use floating-point DCT method (default)')
- else
- WriteLn(output, ' -dct float Use floating-point DCT method');
- {$endif}
- WriteLn(output, ' -restart N Set restart interval in rows, or in blocks with B');
- {$ifdef INPUT_SMOOTHING_SUPPORTED}
- WriteLn(output, ' -smooth N Smooth dithered input (N=1..100 is strength)');
- {$endif}
- WriteLn(output, ' -maxmemory N Maximum memory to use (in kbytes)');
- WriteLn(output, ' -outfile name Specify name for output file');
- WriteLn(output, ' -verbose or -debug Emit debug output');
- {$IFDEF EXT_SWITCH}
- WriteLn(output, 'Switches for wizards:');
- {$ifdef C_ARITH_CODING_SUPPORTED}
- WriteLn(output, ' -arithmetic Use arithmetic coding');
- {$endif}
- WriteLn(output, ' -baseline Force baseline output');
- WriteLn(output, ' -qtables file Use quantization tables given in file');
- WriteLn(output, ' -qslots N[,...] Set component quantization tables');
- WriteLn(output, ' -sample HxV[,...] Set component sampling factors');
- {$ifdef C_MULTISCAN_FILES_SUPPORTED}
- WriteLn(output, ' -scans file Create multi-scan JPEG per script file');
- {$endif}
- {$ENDIF}
- Halt(EXIT_FAILURE);
- end;
- {LOCAL}
- function parse_switches (cinfo : j_compress_ptr;
- last_file_arg_seen : int;
- for_real : boolean) : int;
- { Parse optional switches.
- Returns argv[] index of first file-name argument (== argc if none).
- Any file names with indexes <= last_file_arg_seen are ignored;
- they have presumably been processed in a previous iteration.
- (Pass 0 for last_file_arg_seen on the first or only iteration.)
- for_real is FALSE on the first (dummy) pass; we may skip any expensive
- processing. }
- var
- argn,
- argc : int;
- arg : string;
- var
- value : int;
- code : integer;
- var
- quality : int; { -quality parameter }
- q_scale_factor : int; { scaling percentage for -qtables }
- force_baseline : boolean;
- simple_progressive : boolean;
- qtablefile, { saves -qtables filename if any }
- qslotsarg, { saves -qslots parm if any }
- samplearg, { saves -sample parm if any }
- scansarg : string; { saves -scans parm if any }
- var
- lval : long;
- ch : char;
- const
- printed_version : boolean = FALSE;
- begin
- qtablefile := '';
- qslotsarg := '';
- samplearg := '';
- scansarg := '';
- { Set up default JPEG parameters. }
- { Note that default -quality level need not, and does not,
- match the default scaling for an explicit -qtables argument. }
- quality := 75; { default -quality value }
- q_scale_factor := 100; { default to no scaling for -qtables }
- force_baseline := FALSE; { by default, allow 16-bit quantizers }
- simple_progressive := FALSE;
- is_targa := FALSE;
- outfilename := '';
- cinfo^.err^.trace_level := 0;
- { Scan command line options, adjust parameters }
- argn := 0;
- argc := ParamCount;
- while argn < argc do
- begin
- Inc(argn);
- arg := ParamStr(argn);
- if (arg[1] <> '-') then
- begin
- { Not a switch, must be a file name argument }
- if (argn <= last_file_arg_seen) then
- begin
- outfilename := ''; { -outfile applies to just one input file }
- continue; { ignore this name if previously processed }
- end;
- break; { else done parsing switches }
- end;
- {Inc(arg); - advance past switch marker character }
- if (keymatch(arg, '-arithmetic', 2)) then
- begin
- { Use arithmetic coding. }
- {$ifdef C_ARITH_CODING_SUPPORTED}
- cinfo^.arith_code := TRUE;
- {$else}
- WriteLn(output, progname, ': sorry, arithmetic coding not supported');
- Halt(EXIT_FAILURE);
- {$endif}
- end
- else
- if (keymatch(arg, '-baseline', 2)) then
- begin
- { Force baseline output (8-bit quantizer values). }
- force_baseline := TRUE;
- end
- else
- if (keymatch(arg, '-dct', 3)) then
- begin
- { Select DCT algorithm. }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- if (keymatch(ParamStr(argn), 'int', 1)) then
- begin
- cinfo^.dct_method := JDCT_ISLOW;
- end
- else
- if (keymatch(ParamStr(argn), 'fast', 2)) then
- begin
- cinfo^.dct_method := JDCT_IFAST;
- end
- else
- if (keymatch(ParamStr(argn), 'float', 2)) then
- begin
- cinfo^.dct_method := JDCT_FLOAT;
- end
- else
- usage;
- end
- else
- if keymatch(arg, '-debug', 2) or keymatch(arg, '-verbose', 2) then
- begin
- { Enable debug printouts. }
- { On first -d, print version identification }
- if (not printed_version) then
- begin
- WriteLn(output, 'Independent JPEG Group''s CJPEG, version ', JVERSION);
- WriteLn(output, JCOPYRIGHT);
- WriteLn(output, JNOTICE);
- printed_version := TRUE;
- end;
- Inc(cinfo^.err^.trace_level);
- end
- else
- if (keymatch(arg, '-grayscale', 3)) or (keymatch(arg, '-greyscale',3)) then
- begin
- { Force a monochrome JPEG file to be generated. }
- jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
- end
- else
- if (keymatch(arg, '-maxmemory', 4)) then
- begin
- ch := 'x';
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- arg := ParamStr(argn);
- if (length(arg) > 1) and (arg[length(arg)] in ['m','M']) then
- begin
- ch := arg[length(arg)];
- arg := Copy(arg, 1, Length(arg)-1);
- end;
- Val(arg, lval, code);
- if (code <> 1) then
- usage;
- if (ch = 'm') or (ch = 'M') then
- lval := lval * long(1000);
- cinfo^.mem^.max_memory_to_use := lval * long(1000);
- end
- else
- if (keymatch(arg, '-optimize', 2)) or (keymatch(arg, '-optimise', 2)) then
- begin
- { Enable entropy parm optimization. }
- {$ifdef ENTROPY_OPT_SUPPORTED}
- cinfo^.optimize_coding := TRUE;
- {$else}
- WriteLn(output, progname, ': sorry, entropy optimization was not compiled');
- exit(EXIT_FAILURE);
- {$endif}
- end
- else
- if (keymatch(arg, '-outfile', 5)) then
- begin
- { Set output file name. }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- outfilename := ParamStr(argn); { save it away for later use }
- end
- else
- if (keymatch(arg, '-progressive', 2)) then
- begin
- { Select simple progressive mode. }
- {$ifdef C_PROGRESSIVE_SUPPORTED}
- simple_progressive := TRUE;
- { We must postpone execution until num_components is known. }
- {$else}
- WriteLn(output, progname, ': sorry, progressive output was not compiled');
- Halt(EXIT_FAILURE);
- {$endif}
- end
- else
- if (keymatch(arg, '-quality', 2)) then
- begin
- { Quality factor (quantization table scaling factor). }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- Val(ParamStr(argn), quality, code);
- if code <> 0 then
- usage;
- { Change scale factor in case -qtables is present. }
- q_scale_factor := jpeg_quality_scaling(quality);
- end
- else
- if (keymatch(arg, '-qslots', 3)) then
- begin
- { Quantization table slot numbers. }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- qslotsarg := ParamStr(argn);
- { Must delay setting qslots until after we have processed any
- colorspace-determining switches, since jpeg_set_colorspace sets
- default quant table numbers. }
- end
- else
- if (keymatch(arg, '-qtables', 3)) then
- begin
- { Quantization tables fetched from file. }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- qtablefile := ParamStr(argn);
- { We postpone actually reading the file in case -quality comes later. }
- end
- else
- if (keymatch(arg, '-restart', 2)) then
- begin
- { Restart interval in MCU rows (or in MCUs with 'b'). }
- ch := 'x';
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- arg := ParamStr(argn);
- if (length(arg) > 1) and (arg[length(arg)] in ['b','B']) then
- begin
- ch := arg[length(arg)];
- arg := Copy(arg, 1, Length(arg)-1);
- end;
- Val(arg, lval, Code);
- if (code <> 1) then
- usage;
- if (lval < 0) or (lval > long(65535)) then
- usage;
- if (ch = 'b') or (ch = 'B') then
- begin
- cinfo^.restart_interval := uInt (lval);
- cinfo^.restart_in_rows := 0; { else prior '-restart n' overrides me }
- end
- else
- begin
- cinfo^.restart_in_rows := int (lval);
- { restart_interval will be computed during startup }
- end;
- end
- else
- if (keymatch(arg, '-sample', 3)) then
- begin
- { Set sampling factors. }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- samplearg := ParamStr(argn);
- { Must delay setting sample factors until after we have processed any
- colorspace-determining switches, since jpeg_set_colorspace sets
- default sampling factors. }
- end
- else
- if (keymatch(arg, '-scans', 3)) then
- begin
- { Set scan script. }
- {$ifdef C_MULTISCAN_FILES_SUPPORTED}
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- scansarg := ParamStr(argn);
- { We must postpone reading the file in case -progressive appears. }
- {$else}
- WriteLn(output, progname, ': sorry, multi-scan output was not compiled');
- Halt(EXIT_FAILURE);
- {$endif}
- end
- else
- if (keymatch(arg, '-smooth', 3)) then
- begin
- { Set input smoothing factor. }
- Inc(argn);
- if (argn >= argc) then { advance to next argument }
- usage;
- Val(ParamStr(argn), value, code);
- if (value < 0) or (value > 100)
- or (code <> 0) then
- usage;
- cinfo^.smoothing_factor := value;
- end
- else
- if (keymatch(arg, '-targa', 2)) then
- begin
- { Input file is Targa format. }
- is_targa := TRUE;
- end
- else
- begin
- usage; { bogus switch }
- end;
- end;
- { Post-switch-scanning cleanup }
- if (for_real) then
- begin
- { Set quantization tables for selected quality. }
- { Some or all may be overridden if -qtables is present. }
- jpeg_set_quality(cinfo, quality, force_baseline);
- {$IFDEF EXT_SWITCH}
- if (qtablefile <> '') then { process -qtables if it was present }
- if (not read_quant_tables(cinfo, qtablefile,
- q_scale_factor, force_baseline)) then
- usage;
- if (qslotsarg <> '') then { process -qslots if it was present }
- if (not set_quant_slots(cinfo, qslotsarg)) then
- usage;
- if (samplearg <> '') then { process -sample if it was present }
- if (not set_sample_factors(cinfo, samplearg)) then
- usage;
- {$ENDIF}
- {$ifdef C_PROGRESSIVE_SUPPORTED}
- if (simple_progressive) then { process -progressive; -scans can override }
- jpeg_simple_progression(cinfo);
- {$endif}
- {$IFDEF EXT_SWITCH}
- {$ifdef C_MULTISCAN_FILES_SUPPORTED}
- if (scansarg <> '') then { process -scans if it was present }
- if (not read_scan_script(cinfo, scansarg)) then
- usage;
- {$endif}
- {$ENDIF}
- end;
- parse_switches := argn; { return index of next arg (file name) }
- end;
- { The main program. }
- var
- cinfo : jpeg_compress_struct;
- jerr : jpeg_error_mgr;
- {$ifdef PROGRESS_REPORT}
- progress : cdjpeg_progress_mgr;
- {$endif}
- file_index : int;
- src_mgr : cjpeg_source_ptr;
- input_file : FILE;
- output_file : FILE;
- num_scanlines : JDIMENSION;
- var
- argc : int;
- begin
- argc := ParamCount;
- progname := ParamStr(0);
- { Initialize the JPEG compression object with default error handling. }
- cinfo.err := jpeg_std_error(jerr);
- jpeg_create_compress(@cinfo);
- { Add some application-specific error messages (from cderror.h) }
- {jerr.addon_message_table := cdjpeg_message_table;}
- jerr.first_addon_message := JMSG_FIRSTADDONCODE;
- jerr.last_addon_message := JMSG_LASTADDONCODE;
- { Now safe to enable signal catcher. }
- {$ifdef NEED_SIGNAL_CATCHER}
- enable_signal_catcher(j_common_ptr ( @cinfo);
- {$endif}
- { Initialize JPEG parameters.
- Much of this may be overridden later.
- In particular, we don't yet know the input file's color space,
- but we need to provide some value for jpeg_set_defaults() to work. }
- cinfo.in_color_space := JCS_RGB; { arbitrary guess }
- jpeg_set_defaults(@cinfo);
- { Scan command line to find file names.
- It is convenient to use just one switch-parsing routine, but the switch
- values read here are ignored; we will rescan the switches after opening
- the input file. }
- file_index := parse_switches(@cinfo, 0, FALSE);
- {$ifdef TWO_FILE_COMMANDLINE}
- { Must have either -outfile switch or explicit output file name }
- if (outfilename = '') then
- begin
- if (file_index <> argc-2+1) then
- begin
- WriteLn(output, progname, ': must name one input and one output file');
- usage;
- end;
- outfilename := ParamStr(file_index+1);
- end
- else
- begin
- if (file_index <> argc-1) then
- begin
- WriteLn(output, progname, ': must name one input and one output file');
- usage;
- end;
- end;
- {$else}
- { Unix style: expect zero or one file name }
- if (file_index < argc-1) then
- begin
- WriteLn(output, progname, ': only one input file');
- usage;
- end;
- {$endif} { TWO_FILE_COMMANDLINE }
- { Open the input file. }
- if (file_index < argc) then
- begin
- Assign(input_file, ParamStr(file_index));
- {$push}{$I-}
- Reset(input_file, 1);
- {$pop}
- if (IOresult <> 0) then
- begin
- WriteLn(output, progname, ': can''t open ', ParamStr(file_index));
- Halt(EXIT_FAILURE);
- end;
- end
- else
- begin
- WriteLn(output, progname, ': no input file');
- Halt(EXIT_FAILURE);
- end;
- { Open the output file. }
- if (outfilename <> '') then
- begin
- Assign(output_file, outfilename);
- {$push}{$I-}
- Reset(output_file, 1);
- {$pop}
- if (IOresult = 0) then
- begin
- WriteLn(output, outfilename, ': already exists.');
- close(output_file);
- Halt(EXIT_FAILURE);
- end;
- {$push}{$I-}
- ReWrite(output_file, 1);
- {$pop}
- if (IOresult <> 0) then
- begin
- WriteLn(output, progname, ': can''t create ', outfilename);
- Halt(EXIT_FAILURE);
- end;
- end
- else
- begin
- WriteLn(output, progname, ': no output file');
- Halt(EXIT_FAILURE);
- end;
- {$ifdef PROGRESS_REPORT}
- start_progress_monitor(j_common_ptr (@cinfo), @progress);
- {$endif}
- { Figure out the input file format, and set up to read it. }
- src_mgr := select_file_type(@cinfo, input_file);
- src_mgr^.input_file := @input_file;
- { Read the input file header to obtain file size & colorspace. }
- src_mgr^.start_input (@cinfo, src_mgr);
- { Now that we know input colorspace, fix colorspace-dependent defaults }
- jpeg_default_colorspace(@cinfo);
- { Adjust default compression parameters by re-parsing the options }
- file_index := parse_switches(@cinfo, 0, TRUE);
- { Specify data destination for compression }
- jpeg_stdio_dest(@cinfo, @output_file);
- { Start compressor }
- jpeg_start_compress(@cinfo, TRUE);
- { Process data }
- while (cinfo.next_scanline < cinfo.image_height) do
- begin
- num_scanlines := src_mgr^.get_pixel_rows (@cinfo, src_mgr);
- {void} jpeg_write_scanlines(@cinfo, src_mgr^.buffer, num_scanlines);
- end;
- { Finish compression and release memory }
- src_mgr^.finish_input (@cinfo, src_mgr);
- jpeg_finish_compress(@cinfo);
- jpeg_destroy_compress(@cinfo);
- { Close files, if we opened them }
- close(input_file);
- close(output_file);
- {$ifdef PROGRESS_REPORT}
- end_progress_monitor(j_common_ptr (@cinfo));
- {$endif}
- { All done. }
- if jerr.num_warnings <> 0 then
- Halt(EXIT_WARNING)
- else
- Halt(EXIT_SUCCESS);
- end.
|