📄 djpeg.pas
字号:
cinfo^.do_fancy_upsampling := FALSE;
end
else
if (keymatch(arg, '-onepass', 4)) then
begin
{ Use fast one-pass quantization. }
cinfo^.two_pass_quantize := FALSE;
end
else
if (keymatch(arg, '-os2', 4)) then
begin
{ BMP output format (OS/2 flavor). }
requested_fmt := FMT_OS2;
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, '-pnm', 2)) or
(keymatch(arg, '-ppm', 2)) then
begin
{ PPM/PGM output format. }
requested_fmt := FMT_PPM;
end
else
if (keymatch(arg, '-rle', 2)) then
begin
{ RLE output format. }
requested_fmt := FMT_RLE;
end
else
if (keymatch(arg, '-scale', 2)) then
begin
{ Scale the output image by a fraction M/N. }
Inc(argn);
if (argn >= argc) then { advance to next argument }
usage;
arg := ParamStr(argn);
Val(copy(arg, 1, Pos('/', arg)-1),
cinfo^.scale_num, code);
if code = 0 then
Val(copy(arg, Pos('/', arg)+1,
length(arg)-Pos('/', arg)),
cinfo^.scale_denom, code);
if code <> 0 then
usage;
end
else
if (keymatch(arg, '-targa', 2)) then
begin
{ Targa output format. }
requested_fmt := FMT_TARGA;
end
else
usage; { bogus switch }
end;
parse_switches := argn; { return index of next arg (file name) }
end;
{ Marker processor for COM markers.
This replaces the library's built-in processor, which just skips the marker.
We want to print out the marker as text, if possible.
Note this code relies on a non-suspending data source. }
{LOCAL}
function jpeg_getc (cinfo : j_decompress_ptr) : char;
{ Read next byte }
var
datasrc : jpeg_source_mgr_ptr;
begin
datasrc := cinfo^.src;
if (datasrc^.bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer (cinfo)) then
ERREXIT(j_common_ptr(cinfo), JERR_CANT_SUSPEND);
end;
Dec(datasrc^.bytes_in_buffer);
jpeg_getc := char(GETJOCTET(datasrc^.next_input_byte^));
Inc(datasrc^.next_input_byte);
end;
{METHODDEF}
function COM_handler (cinfo : j_decompress_ptr) : boolean; far;
const
LF = #10;
CR = #13;
var
traceit : boolean;
length : INT32;
ch : char;
lastch : char;
begin
traceit := (cinfo^.err^.trace_level >= 1);
lastch := #0;
length := byte(jpeg_getc(cinfo)) shl 8;
Inc(length, byte(jpeg_getc(cinfo)));
Dec(length, 2); { discount the length word itself }
if (traceit) then
WriteLn(output, 'Comment, length :', long(length));
while (length > 0) do
begin
Dec(length);
ch := jpeg_getc(cinfo);
if (traceit) then
begin
{ Emit the character in a readable form.
Nonprintables are converted to \nnn form,
while \ is converted to \\.
Newlines in CR, CR/LF, or LF form will be printed as one newline. }
if (ch = LF) then
WriteLn(output)
else
if (ch = CR) then
begin
if (lastch <> LF) then
WriteLn(output);
end
else
if (ch >= ' ') and (ch <= #127) then
Write(output, ch)
else
WriteLn(output, '\', byte(ch));
lastch := ch;
end;
end;
if (traceit) then
WriteLn(output);
COM_handler := TRUE;
end;
{ The main program. }
var
cinfo : jpeg_decompress_struct;
jerr : jpeg_error_mgr;
{$ifdef PROGRESS_REPORT}
progress : cdjpeg_progress_mgr;
{$endif}
file_index : int;
dest_mgr : djpeg_dest_ptr;
input_file : FILE;
output_file : FILE;
num_scanlines : JDIMENSION;
var
argc : int;
begin
dest_mgr := NIL;
argc := ParamCount;
progname := ParamStr(0);
{ Initialize the JPEG decompression object with default error handling. }
cinfo.err := jpeg_std_error(jerr);
jpeg_create_decompress(@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;
{ Insert custom COM marker processor. }
jpeg_set_marker_processor(@cinfo, JPEG_COM, COM_handler);
{ Now safe to enable signal catcher. }
{$ifdef NEED_SIGNAL_CATCHER}
enable_signal_catcher(j_common_ptr (@cinfo));
{$endif}
{ 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.
(Exception: tracing level set here controls verbosity for COM markers
found during jpeg_read_header...) }
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-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) 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));
{$I-}
Reset(input_file, 1);
{$I+}
if (IOresult <> 0) then
begin
WriteLn(output, progname, ': can''t open ', ParamStr(file_index));
Halt(EXIT_FAILURE);
end;
end
else
begin
{ default input file is stdin }
Assign(input_file, '');
Reset(input_file, 1);
end;
{ Open the output file. }
if (outfilename <> '') then
begin
assign(output_file, outfilename);
{$I-}
rewrite(output_file, 1);
{$I+}
if (IOresult <> 0) then
begin
WriteLn(output, progname, ': can''t open ', outfilename);
Halt(EXIT_FAILURE);
end;
end
else
begin
{ default output file is stdout }
assign(output_file, '');
rewrite(output_file, 1);
end;
{$ifdef PROGRESS_REPORT}
start_progress_monitor(j_common_ptr (@cinfo), &progress);
{$endif}
{ Specify data source for decompression }
jpeg_stdio_src(@cinfo, input_file);
{ Read file header, set default decompression parameters }
{void} jpeg_read_header(@cinfo, TRUE);
{ Adjust default decompression parameters by re-parsing the options }
file_index := parse_switches(@cinfo, 0, TRUE);
{ Initialize the output module now to let it override any crucial
option settings (for instance, GIF wants to force color quantization). }
case (requested_fmt) of
{$ifdef BMP_SUPPORTED}
FMT_BMP:
dest_mgr := jinit_write_bmp(@cinfo, FALSE);
FMT_OS2:
dest_mgr := jinit_write_bmp(@cinfo, TRUE);
{$endif}
{$ifdef GIF_SUPPORTED}
FMT_GIF:
dest_mgr := jinit_write_gif(@cinfo);
{$endif}
{$ifdef PPM_SUPPORTED}
FMT_PPM:
dest_mgr := jinit_write_ppm(@cinfo);
{$endif}
{$ifdef RLE_SUPPORTED}
FMT_RLE:
dest_mgr := jinit_write_rle(@cinfo);
{$endif}
{$ifdef TARGA_SUPPORTED}
FMT_TARGA:
dest_mgr := jinit_write_targa(@cinfo);
{$endif}
else
ERREXIT(j_common_ptr(@cinfo), JERR_UNSUPPORTED_FORMAT);
end;
dest_mgr^.output_file := @output_file;
{ Start decompressor }
{void} jpeg_start_decompress(@cinfo);
{ Write output file header }
dest_mgr^.start_output (@cinfo, dest_mgr);
{ Process data }
while (cinfo.output_scanline < cinfo.output_height) do
begin
num_scanlines := jpeg_read_scanlines(@cinfo, dest_mgr^.buffer,
dest_mgr^.buffer_height);
dest_mgr^.put_pixel_rows (@cinfo, dest_mgr, num_scanlines);
end;
{$ifdef PROGRESS_REPORT}
{ Hack: count final pass as done in case finish_output does an extra pass.
The library won't have updated completed_passes. }
progress.pub.completed_passes := progress.pub.total_passes;
{$endif}
{ Finish decompression and release memory.
I must do it in this order because output module has allocated memory
of lifespan JPOOL_IMAGE; it needs to finish before releasing memory. }
dest_mgr^.finish_output (@cinfo, dest_mgr);
{void} jpeg_finish_decompress(@cinfo);
jpeg_destroy_decompress(@cinfo);
{ Close files, if we opened them }
system.close(input_file);
system.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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -