📄 jdmarker.pas
字号:
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
b[i] := GETJOCTET(next_input_byte^);
Inc(next_input_byte);
end;
Dec(length, numtoread);
{ process it }
case (cinfo^.unread_marker) of
M_APP0:
examine_app0(cinfo, b, numtoread, length);
M_APP14:
examine_app14(cinfo, b, numtoread, length);
else
{ can't get here unless jpeg_save_markers chooses wrong processor }
ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, cinfo^.unread_marker);
end;
{ skip any remaining data -- could be lots }
{ Unload the local copies --- do this only at a restart boundary }
datasrc^.next_input_byte := next_input_byte;
datasrc^.bytes_in_buffer := bytes_in_buffer;
if (length > 0) then
cinfo^.src^.skip_input_data(cinfo, long(length));
get_interesting_appn := TRUE;
end;
{$ifdef SAVE_MARKERS_SUPPORTED}
{METHODDEF}
function save_marker (cinfo : j_decompress_ptr) : boolean; far;
{ Save an APPn or COM marker into the marker list }
var
marker : my_marker_ptr;
cur_marker : jpeg_saved_marker_ptr;
bytes_read, data_length : uint;
data : JOCTET_FIELD_PTR;
length : INT32;
var
datasrc : jpeg_source_mgr_ptr;
next_input_byte : JOCTETptr;
bytes_in_buffer : size_t;
var
limit : uint;
var
prev : jpeg_saved_marker_ptr;
begin
{ local copies of input pointer/count }
datasrc := cinfo^.src;
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
marker := my_marker_ptr(cinfo^.marker);
cur_marker := marker^.cur_marker;
length := 0;
if (cur_marker = NIL) then
begin
{ begin reading a marker }
{ Read two bytes interpreted as an unsigned 16-bit integer. }
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
save_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
length := (uint( GETJOCTET(next_input_byte^)) shl 8);
Inc( next_input_byte );
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
save_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
Inc( length, GETJOCTET(next_input_byte^));
Inc( next_input_byte );
Dec(length, 2);
if (length >= 0) then
begin { watch out for bogus length word }
{ figure out how much we want to save }
if (cinfo^.unread_marker = int(M_COM)) then
limit := marker^.length_limit_COM
else
limit := marker^.length_limit_APPn[cinfo^.unread_marker - int(M_APP0)];
if (uint(length) < limit) then
limit := uint(length);
{ allocate and initialize the marker item }
cur_marker := jpeg_saved_marker_ptr(
cinfo^.mem^.alloc_large (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(jpeg_marker_struct) + limit) );
cur_marker^.next := NIL;
cur_marker^.marker := UINT8 (cinfo^.unread_marker);
cur_marker^.original_length := uint(length);
cur_marker^.data_length := limit;
{ data area is just beyond the jpeg_marker_struct }
cur_marker^.data := JOCTET_FIELD_PTR(cur_marker);
Inc(jpeg_saved_marker_ptr(cur_marker^.data));
data := cur_marker^.data;
marker^.cur_marker := cur_marker;
marker^.bytes_read := 0;
bytes_read := 0;
data_length := limit;
end
else
begin
{ deal with bogus length word }
data_length := 0;
bytes_read := 0;
data := NIL;
end
end
else
begin
{ resume reading a marker }
bytes_read := marker^.bytes_read;
data_length := cur_marker^.data_length;
data := cur_marker^.data;
Inc(data, bytes_read);
end;
while (bytes_read < data_length) do
begin
{ move the restart point to here }
datasrc^.next_input_byte := next_input_byte;
datasrc^.bytes_in_buffer := bytes_in_buffer;
marker^.bytes_read := bytes_read;
{ If there's not at least one byte in buffer, suspend }
if (bytes_in_buffer = 0) then
begin
if not datasrc^.fill_input_buffer (cinfo) then
begin
save_marker := FALSE;
exit;
end;
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
{ Copy bytes with reasonable rapidity }
while (bytes_read < data_length) and (bytes_in_buffer > 0) do
begin
JOCTETPTR(data)^ := next_input_byte^;
Inc(JOCTETPTR(data));
Inc(next_input_byte);
Dec(bytes_in_buffer);
Inc(bytes_read);
end;
end;
{ Done reading what we want to read }
if (cur_marker <> NIL) then
begin { will be NIL if bogus length word }
{ Add new marker to end of list }
if (cinfo^.marker_list = NIL) then
begin
cinfo^.marker_list := cur_marker
end
else
begin
prev := cinfo^.marker_list;
while (prev^.next <> NIL) do
prev := prev^.next;
prev^.next := cur_marker;
end;
{ Reset pointer & calc remaining data length }
data := cur_marker^.data;
length := cur_marker^.original_length - data_length;
end;
{ Reset to initial state for next marker }
marker^.cur_marker := NIL;
{ Process the marker if interesting; else just make a generic trace msg }
case (cinfo^.unread_marker) of
M_APP0:
examine_app0(cinfo, data^, data_length, length);
M_APP14:
examine_app14(cinfo, data^, data_length, length);
else
{$IFDEF DEBUG}
TRACEMS2(j_common_ptr(cinfo), 1, JTRC_MISC_MARKER, cinfo^.unread_marker,
int(data_length + length));
{$ENDIF}
end;
{ skip any remaining data -- could be lots }
{ do before skip_input_data }
datasrc^.next_input_byte := next_input_byte;
datasrc^.bytes_in_buffer := bytes_in_buffer;
if (length > 0) then
cinfo^.src^.skip_input_data (cinfo, long(length) );
save_marker := TRUE;
end;
{$endif} { SAVE_MARKERS_SUPPORTED }
{ Find the next JPEG marker, save it in cinfo^.unread_marker.
Returns FALSE if had to suspend before reaching a marker;
in that case cinfo^.unread_marker is unchanged.
Note that the result might not be a valid marker code,
but it will never be 0 or FF. }
{LOCAL}
function next_marker (cinfo : j_decompress_ptr) : boolean;
var
c : int;
var
datasrc : jpeg_source_mgr_ptr;
next_input_byte : JOCTETptr;
bytes_in_buffer : size_t;
begin
datasrc := cinfo^.src;
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
{while TRUE do}
repeat
{ Read a byte into variable c. If must suspend, return FALSE. }
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
next_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
c := GETJOCTET(next_input_byte^);
Inc(next_input_byte);
{ Skip any non-FF bytes.
This may look a bit inefficient, but it will not occur in a valid file.
We sync after each discarded byte so that a suspending data source
can discard the byte from its buffer. }
while (c <> $FF) do
begin
Inc(cinfo^.marker^.discarded_bytes);
{ Unload the local copies --- do this only at a restart boundary }
datasrc^.next_input_byte := next_input_byte;
datasrc^.bytes_in_buffer := bytes_in_buffer;
{ Read a byte into variable c. If must suspend, return FALSE. }
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
next_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
c := GETJOCTET(next_input_byte^);
Inc(next_input_byte);
end;
{ This loop swallows any duplicate FF bytes. Extra FFs are legal as
pad bytes, so don't count them in discarded_bytes. We assume there
will not be so many consecutive FF bytes as to overflow a suspending
data source's input buffer. }
repeat
{ Read a byte into variable c. If must suspend, return FALSE. }
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
next_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
c := GETJOCTET(next_input_byte^);
Inc(next_input_byte);
Until (c <> $FF);
if (c <> 0) then
break; { found a valid marker, exit loop }
{ Reach here if we found a stuffed-zero data sequence (FF/00).
Discard it and loop back to try again. }
Inc(cinfo^.marker^.discarded_bytes, 2);
{ Unload the local copies --- do this only at a restart boundary }
datasrc^.next_input_byte := next_input_byte;
datasrc^.bytes_in_buffer := bytes_in_buffer;
Until False;
if (cinfo^.marker^.discarded_bytes <> 0) then
begin
WARNMS2(j_common_ptr(cinfo), JWRN_EXTRANEOUS_DATA,
cinfo^.marker^.discarded_bytes, c);
cinfo^.marker^.discarded_bytes := 0;
end;
cinfo^.unread_marker := c;
{ Unload the local copies --- do this only at a restart boundary }
datasrc^.next_input_byte := next_input_byte;
datasrc^.bytes_in_buffer := bytes_in_buffer;
next_marker := TRUE;
end; { next_marker }
{LOCAL}
function first_marker (cinfo : j_decompress_ptr) : boolean;
{ Like next_marker, but used to obtain the initial SOI marker. }
{ For this marker, we do not allow preceding garbage or fill; otherwise,
we might well scan an entire input file before realizing it ain't JPEG.
If an application wants to process non-JFIF files, it must seek to the
SOI before calling the JPEG library. }
var
c, c2 : int;
var
datasrc : jpeg_source_mgr_ptr;
next_input_byte : JOCTETptr;
bytes_in_buffer : size_t;
begin
datasrc := cinfo^.src;
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
{ Read a byte into variable c. If must suspend, return FALSE. }
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
first_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
c := GETJOCTET(next_input_byte^);
Inc(next_input_byte);
{ Read a byte into variable c2. If must suspend, return FALSE. }
{ make a byte available.
Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
but we must reload the local copies after a successful fill. }
if (bytes_in_buffer = 0) then
begin
if (not datasrc^.fill_input_buffer(cinfo)) then
begin
first_marker := FALSE;
exit;
end;
{ Reload the local copies }
next_input_byte := datasrc^.next_input_byte;
bytes_in_buffer := datasrc^.bytes_in_buffer;
end;
Dec( bytes_in_buffer );
c2 := GETJOCTET(next_input_byte^);
Inc(next_input_byte);
if (c <> $FF) or (c2 <> int(M_SOI)) then
ERREXIT2(j_common_ptr(cinfo), JERR_NO_SOI, c, c2);
cinfo^.unread_marker := c2;
{ Unload the local copies -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -