📄 djpeg.pas
字号:
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 and interesting APPn markers.
This replaces the library's built-in processor, which just skips the marker.
We want to print out the marker as text, to the extent 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 print_text_marker (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
begin
if (cinfo^.unread_marker = JPEG_COM) then
WriteLn('Comment, length ', long(length), ';')
else { assume it is an APPn otherwise }
WriteLn('APP', cinfo^.unread_marker - JPEG_APP0, ' length ',
long(length),':');
end;
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);
print_text_marker := 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 marker processor for COM and APP12.
APP12 is used by some digital camera makers for textual info,
so we provide the ability to display it as text.
If you like, additional APPn marker types can be selected for display,
but don't try to override APP0 or APP14 this way (see libjpeg.doc). }
jpeg_set_marker_processor(@cinfo, JPEG_COM, print_text_marker);
jpeg_set_marker_processor(@cinfo, JPEG_APP0+12, print_text_marker);
{ 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 + -