summaryrefslogtreecommitdiff
path: root/packages/base/pasjpeg/jdmarker.pas
diff options
context:
space:
mode:
Diffstat (limited to 'packages/base/pasjpeg/jdmarker.pas')
-rw-r--r--packages/base/pasjpeg/jdmarker.pas2644
1 files changed, 0 insertions, 2644 deletions
diff --git a/packages/base/pasjpeg/jdmarker.pas b/packages/base/pasjpeg/jdmarker.pas
deleted file mode 100644
index ee6430fbee..0000000000
--- a/packages/base/pasjpeg/jdmarker.pas
+++ /dev/null
@@ -1,2644 +0,0 @@
-Unit JdMarker;
-
-{ This file contains routines to decode JPEG datastream markers.
- Most of the complexity arises from our desire to support input
- suspension: if not all of the data for a marker is available;
- we must exit back to the application. On resumption; we reprocess
- the marker. }
-
-{ Original: jdmarker.c; Copyright (C) 1991-1998; Thomas G. Lane. }
-{ History
- 9.7.96 Conversion to pascal started jnn
- 22.3.98 updated to 6b jnn }
-
-
-interface
-
-{$I jconfig.inc}
-
-uses
- jmorecfg,
- jinclude,
- jdeferr,
- jerror,
- jcomapi,
- jpeglib;
-
-const { JPEG marker codes }
- M_SOF0 = $c0;
- M_SOF1 = $c1;
- M_SOF2 = $c2;
- M_SOF3 = $c3;
-
- M_SOF5 = $c5;
- M_SOF6 = $c6;
- M_SOF7 = $c7;
-
- M_JPG = $c8;
- M_SOF9 = $c9;
- M_SOF10 = $ca;
- M_SOF11 = $cb;
-
- M_SOF13 = $cd;
- M_SOF14 = $ce;
- M_SOF15 = $cf;
-
- M_DHT = $c4;
-
- M_DAC = $cc;
-
- M_RST0 = $d0;
- M_RST1 = $d1;
- M_RST2 = $d2;
- M_RST3 = $d3;
- M_RST4 = $d4;
- M_RST5 = $d5;
- M_RST6 = $d6;
- M_RST7 = $d7;
-
- M_SOI = $d8;
- M_EOI = $d9;
- M_SOS = $da;
- M_DQT = $db;
- M_DNL = $dc;
- M_DRI = $dd;
- M_DHP = $de;
- M_EXP = $df;
-
- M_APP0 = $e0;
- M_APP1 = $e1;
- M_APP2 = $e2;
- M_APP3 = $e3;
- M_APP4 = $e4;
- M_APP5 = $e5;
- M_APP6 = $e6;
- M_APP7 = $e7;
- M_APP8 = $e8;
- M_APP9 = $e9;
- M_APP10 = $ea;
- M_APP11 = $eb;
- M_APP12 = $ec;
- M_APP13 = $ed;
- M_APP14 = $ee;
- M_APP15 = $ef;
-
- M_JPG0 = $f0;
- M_JPG13 = $fd;
- M_COM = $fe;
-
- M_TEM = $01;
-
- M_ERROR = $100;
-
-type
- JPEG_MARKER = uint; { JPEG marker codes }
-
-{ Private state }
-
-type
- my_marker_ptr = ^my_marker_reader;
- my_marker_reader = record
- pub : jpeg_marker_reader; { public fields }
-
- { Application-overridable marker processing methods }
- process_COM : jpeg_marker_parser_method;
- process_APPn : array[0..16-1] of jpeg_marker_parser_method;
-
- { Limit on marker data length to save for each marker type }
- length_limit_COM : uint;
- length_limit_APPn : array[0..16-1] of uint;
-
- { Status of COM/APPn marker saving }
- cur_marker : jpeg_saved_marker_ptr; { NIL if not processing a marker }
- bytes_read : uint; { data bytes read so far in marker }
- { Note: cur_marker is not linked into marker_list until it's all read. }
- end;
-
-{GLOBAL}
-function jpeg_resync_to_restart(cinfo : j_decompress_ptr;
- desired : int) : boolean;
-{GLOBAL}
-procedure jinit_marker_reader (cinfo : j_decompress_ptr);
-
-{$ifdef SAVE_MARKERS_SUPPORTED}
-
-{GLOBAL}
-procedure jpeg_save_markers (cinfo : j_decompress_ptr;
- marker_code : int;
- length_limit : uint);
-{$ENDIF}
-
-{GLOBAL}
-procedure jpeg_set_marker_processor (cinfo : j_decompress_ptr;
- marker_code : int;
- routine : jpeg_marker_parser_method);
-
-implementation
-
-uses
- jutils;
-
-{ At all times, cinfo1.src.next_input_byte and .bytes_in_buffer reflect
- the current restart point; we update them only when we have reached a
- suitable place to restart if a suspension occurs. }
-
-
-{ Routines to process JPEG markers.
-
- Entry condition: JPEG marker itself has been read and its code saved
- in cinfo^.unread_marker; input restart point is just after the marker.
-
- Exit: if return TRUE, have read and processed any parameters, and have
- updated the restart point to point after the parameters.
- If return FALSE, was forced to suspend before reaching end of
- marker parameters; restart point has not been moved. Same routine
- will be called again after application supplies more input data.
-
- This approach to suspension assumes that all of a marker's parameters
- can fit into a single input bufferload. This should hold for "normal"
- markers. Some COM/APPn markers might have large parameter segments
- that might not fit. If we are simply dropping such a marker, we use
- skip_input_data to get past it, and thereby put the problem on the
- source manager's shoulders. If we are saving the marker's contents
- into memory, we use a slightly different convention: when forced to
- suspend, the marker processor updates the restart point to the end of
- what it's consumed (ie, the end of the buffer) before returning FALSE.
- On resumption, cinfo->unread_marker still contains the marker code,
- but the data source will point to the next chunk of marker data.
- The marker processor must retain internal state to deal with this.
-
- Note that we don't bother to avoid duplicate trace messages if a
- suspension occurs within marker parameters. Other side effects
- require more care. }
-
-{LOCAL}
-function get_soi (cinfo : j_decompress_ptr) : boolean;
-{ Process an SOI marker }
-var
- i : int;
-begin
- {$IFDEF DEBUG}
- TRACEMS(j_common_ptr(cinfo), 1, JTRC_SOI);
- {$ENDIF}
-
- if (cinfo^.marker^.saw_SOI) then
- ERREXIT(j_common_ptr(cinfo), JERR_SOI_DUPLICATE);
-
- { Reset all parameters that are defined to be reset by SOI }
-
- for i := 0 to Pred(NUM_ARITH_TBLS) do
- with cinfo^ do
- begin
- arith_dc_L[i] := 0;
- arith_dc_U[i] := 1;
- arith_ac_K[i] := 5;
- end;
- cinfo^.restart_interval := 0;
-
- { Set initial assumptions for colorspace etc }
-
- with cinfo^ do
- begin
- jpeg_color_space := JCS_UNKNOWN;
- CCIR601_sampling := FALSE; { Assume non-CCIR sampling??? }
-
- saw_JFIF_marker := FALSE;
- JFIF_major_version := 1; { set default JFIF APP0 values }
- JFIF_minor_version := 1;
- density_unit := 0;
- X_density := 1;
- Y_density := 1;
- saw_Adobe_marker := FALSE;
- Adobe_transform := 0;
-
- marker^.saw_SOI := TRUE;
- end;
- get_soi := TRUE;
-end; { get_soi }
-
-
-{LOCAL}
-function get_sof(cinfo : j_decompress_ptr;
- is_prog : boolean;
- is_arith : boolean) : boolean;
-{ Process a SOFn marker }
-var
- length : INT32;
- c, ci : int;
- compptr : jpeg_component_info_ptr;
-{ Declare and initialize local copies of input pointer/count }
-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;
-{}
- cinfo^.progressive_mode := is_prog;
- cinfo^.arith_code := is_arith;
-
-{ Read two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_sof := 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
- get_sof := 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 );
-
-
- { Read a byte into variable cinfo^.data_precision.
- 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
- get_sof := 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 );
-
- cinfo^.data_precision := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
-{ Read two bytes interpreted as an unsigned 16-bit integer.
- cinfo^.image_height should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_sof := 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 );
-
- cinfo^.image_height := (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
- get_sof := 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( cinfo^.image_height, GETJOCTET( next_input_byte^));
- Inc( next_input_byte );
-
-{ Read two bytes interpreted as an unsigned 16-bit integer.
- cinfo^.image_width should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_sof := 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 );
-
- cinfo^.image_width := (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
- get_sof := 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( cinfo^.image_width, GETJOCTET( next_input_byte^));
- Inc( next_input_byte );
-
- { Read a byte into variable cinfo^.num_components.
- 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
- get_sof := 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 );
-
- cinfo^.num_components := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- Dec(length, 8);
-
- {$IFDEF DEBUG}
- TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOF, cinfo^.unread_marker,
- int(cinfo^.image_width), int(cinfo^.image_height),
- cinfo^.num_components);
- {$ENDIF}
-
- if (cinfo^.marker^.saw_SOF) then
- ERREXIT(j_common_ptr(cinfo), JERR_SOF_DUPLICATE);
-
- { We don't support files in which the image height is initially specified }
- { as 0 and is later redefined by DNL. As long as we have to check that, }
- { might as well have a general sanity check. }
- if (cinfo^.image_height <= 0) or (cinfo^.image_width <= 0)
- or (cinfo^.num_components <= 0) then
- ERREXIT(j_common_ptr(cinfo), JERR_EMPTY_IMAGE);
-
- if (length <> (cinfo^.num_components * 3)) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
-
- if (cinfo^.comp_info = NIL) then { do only once, even if suspend }
- cinfo^.comp_info := jpeg_component_info_list_ptr(
- cinfo^.mem^.alloc_small(j_common_ptr(cinfo), JPOOL_IMAGE,
- cinfo^.num_components * SIZEOF(jpeg_component_info)));
-
- compptr := jpeg_component_info_ptr(cinfo^.comp_info);
- for ci := 0 to pred(cinfo^.num_components) do
- begin
- compptr^.component_index := ci;
-
- { Read a byte into variable compptr^.component_id.
- 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
- get_sof := 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 );
-
- compptr^.component_id := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- { 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
- get_sof := 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);
-
- compptr^.h_samp_factor := (c shr 4) and 15;
- compptr^.v_samp_factor := (c ) and 15;
-
- { Read a byte into variable compptr^.quant_tbl_no.
- 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
- get_sof := 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 );
-
- compptr^.quant_tbl_no := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- {$IFDEF DEBUG}
- TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOF_COMPONENT,
- compptr^.component_id, compptr^.h_samp_factor,
- compptr^.v_samp_factor, compptr^.quant_tbl_no);
- {$ENDIF}
-
- Inc(compptr);
- end;
-
- cinfo^.marker^.saw_SOF := TRUE;
-
- { 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;
-
- get_sof := TRUE;
-end; { get_sof }
-
-
-{LOCAL}
-function get_sos (cinfo : j_decompress_ptr) : boolean;
-{ Process a SOS marker }
-label
- id_found;
-var
- length : INT32;
- i, ci, n, c, cc : int;
- compptr : jpeg_component_info_ptr;
-{ Declare and initialize local copies of input pointer/count }
-var
- datasrc : jpeg_source_mgr_ptr;
- next_input_byte : JOCTETptr; { Array[] of JOCTET; }
- bytes_in_buffer : size_t;
-begin
- datasrc := cinfo^.src;
- next_input_byte := datasrc^.next_input_byte;
- bytes_in_buffer := datasrc^.bytes_in_buffer;
-
-{}
-
- if not cinfo^.marker^.saw_SOF then
- ERREXIT(j_common_ptr(cinfo), JERR_SOS_NO_SOF);
-
-{ Read two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_sos := 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
- get_sos := 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 );
-
-
- { Read a byte into variable n (Number of components).
- 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
- get_sos := 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 );
-
- n := GETJOCTET(next_input_byte^); { Number of components }
- Inc(next_input_byte);
-
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_SOS, n);
- {$ENDIF}
-
- if ((length <> (n * 2 + 6)) or (n < 1) or (n > MAX_COMPS_IN_SCAN)) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
-
- cinfo^.comps_in_scan := n;
-
- { Collect the component-spec parameters }
-
- for i := 0 to Pred(n) do
- begin
- { Read a byte into variable cc. 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
- get_sos := 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 );
-
- cc := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- { 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
- get_sos := 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);
-
- compptr := jpeg_component_info_ptr(cinfo^.comp_info);
- for ci := 0 to Pred(cinfo^.num_components) do
- begin
- if (cc = compptr^.component_id) then
- goto id_found;
- Inc(compptr);
- end;
-
- ERREXIT1(j_common_ptr(cinfo), JERR_BAD_COMPONENT_ID, cc);
-
- id_found:
-
- cinfo^.cur_comp_info[i] := compptr;
- compptr^.dc_tbl_no := (c shr 4) and 15;
- compptr^.ac_tbl_no := (c ) and 15;
-
- {$IFDEF DEBUG}
- TRACEMS3(j_common_ptr(cinfo), 1, JTRC_SOS_COMPONENT, cc,
- compptr^.dc_tbl_no, compptr^.ac_tbl_no);
- {$ENDIF}
- end;
-
- { Collect the additional scan parameters Ss, Se, Ah/Al. }
- { 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
- get_sos := 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);
-
- cinfo^.Ss := c;
-
- { 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
- get_sos := 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);
-
- cinfo^.Se := c;
-
- { 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
- get_sos := 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);
-
- cinfo^.Ah := (c shr 4) and 15;
- cinfo^.Al := (c ) and 15;
-
- {$IFDEF DEBUG}
- TRACEMS4(j_common_ptr(cinfo), 1, JTRC_SOS_PARAMS, cinfo^.Ss, cinfo^.Se,
- cinfo^.Ah, cinfo^.Al);
- {$ENDIF}
-
- { Prepare to scan data & restart markers }
- cinfo^.marker^.next_restart_num := 0;
-
- { Count another SOS marker }
- Inc( cinfo^.input_scan_number );
-
- { 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;
-
- get_sos := TRUE;
-end; { get_sos }
-
-
-{METHODDEF}
-function skip_variable (cinfo : j_decompress_ptr) : boolean; far;
-{ Skip over an unknown or uninteresting variable-length marker }
-var
- length : INT32;
-var
- datasrc : jpeg_source_mgr_ptr;
- next_input_byte : JOCTETptr; { Array[] of JOCTET; }
- bytes_in_buffer : size_t;
-begin
- datasrc := cinfo^.src;
- next_input_byte := datasrc^.next_input_byte;
- bytes_in_buffer := datasrc^.bytes_in_buffer;
-
-{ Read two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- skip_variable := 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
- skip_variable := 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);
-
- {$IFDEF DEBUG}
- TRACEMS2(j_common_ptr(cinfo), 1, JTRC_MISC_MARKER,
- cinfo^.unread_marker, int(length));
- {$ENDIF}
-
- { Unload the local copies --- do this only at a restart boundary }
- { 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));
-
- skip_variable := TRUE;
-end; { skip_variable }
-
-
-{$IFDEF D_ARITH_CODING_SUPPORTED}
-
-{LOCAL}
-function get_dac (cinfo : j_decompress_ptr) : boolean;
-{ Process a DAC marker }
-var
- length : INT32;
- index, val : 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 two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_dac := 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
- get_dac := 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);
-
- while (length > 0) do
- begin
- { Read a byte into variable index. 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
- get_dac := 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 );
-
- index := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- { Read a byte into variable val. 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
- get_dac := 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 );
-
- val := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- Dec( length, 2);
-
- {$IFDEF DEBUG}
- TRACEMS2(j_common_ptr(cinfo), 1, JTRC_DAC, index, val);
- {$ENDIF}
-
- if (index < 0) or (index >= (2*NUM_ARITH_TBLS)) then
- ERREXIT1(j_common_ptr(cinfo) , JERR_DAC_INDEX, index);
-
- if (index >= NUM_ARITH_TBLS) then
- begin { define AC table }
- cinfo^.arith_ac_K[index-NUM_ARITH_TBLS] := UINT8(val);
- end
- else
- begin { define DC table }
- cinfo^.arith_dc_L[index] := UINT8(val and $0F);
- cinfo^.arith_dc_U[index] := UINT8(val shr 4);
- if (cinfo^.arith_dc_L[index] > cinfo^.arith_dc_U[index]) then
- ERREXIT1(j_common_ptr(cinfo) , JERR_DAC_VALUE, val);
- end;
- end;
-
- if (length <> 0) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
-
- { 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;
-
- get_dac := TRUE;
-end; { get_dac }
-
-{$ELSE}
-
-{LOCAL}
-function get_dac (cinfo : j_decompress_ptr) : boolean;
-begin
- get_dac := skip_variable(cinfo);
-end;
-
-{$ENDIF}
-
-{LOCAL}
-function get_dht (cinfo : j_decompress_ptr) : boolean;
-{ Process a DHT marker }
-var
- length : INT32;
- bits : Array[0..17-1] of UINT8;
- huffval : Array[0..256-1] of UINT8;
- i, index, count : int;
- htblptr : ^JHUFF_TBL_PTR;
-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 two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_dht := 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
- get_dht := 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);
-
- while (length > 16) do
- begin
- { Read a byte into variable index. 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
- get_dht := 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 );
-
- index := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DHT, index);
- {$ENDIF}
-
- bits[0] := 0;
- count := 0;
- for i := 1 to 16 do
- begin
- { Read a byte into variable bits[i]. 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
- get_dht := 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 );
-
- bits[i] := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- Inc( count, bits[i] );
- end;
-
- Dec( length, (1 + 16) );
-
- {$IFDEF DEBUG}
- TRACEMS8(j_common_ptr(cinfo), 2, JTRC_HUFFBITS,
- bits[1], bits[2], bits[3], bits[4],
- bits[5], bits[6], bits[7], bits[8]);
- TRACEMS8(j_common_ptr(cinfo), 2, JTRC_HUFFBITS,
- bits[9], bits[10], bits[11], bits[12],
- bits[13], bits[14], bits[15], bits[16]);
- {$ENDIF}
-
- { Here we just do minimal validation of the counts to avoid walking
- off the end of our table space. jdhuff.c will check more carefully. }
-
- if (count > 256) or (INT32(count) > length) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_HUFF_TABLE);
-
- for i := 0 to Pred(count) do
- begin
- { Read a byte into variable huffval[i]. 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
- get_dht := 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 );
-
- huffval[i] := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
- end;
-
- Dec( length, count );
-
- if (index and $10)<>0 then
- begin { AC table definition }
- Dec( index, $10 );
- htblptr := @cinfo^.ac_huff_tbl_ptrs[index];
- end
- else
- begin { DC table definition }
- htblptr := @cinfo^.dc_huff_tbl_ptrs[index];
- end;
-
- if (index < 0) or (index >= NUM_HUFF_TBLS) then
- ERREXIT1(j_common_ptr(cinfo), JERR_DHT_INDEX, index);
-
- if (htblptr^ = NIL) then
- htblptr^ := jpeg_alloc_huff_table(j_common_ptr(cinfo));
-
- MEMCOPY(@(htblptr^)^.bits, @bits, SIZEOF((htblptr^)^.bits));
- MEMCOPY(@(htblptr^)^.huffval, @huffval, SIZEOF((htblptr^)^.huffval));
- end;
-
- if (length <> 0) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
-
- { 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;
-
- get_dht := TRUE;
-end; { get_dht }
-
-
-{LOCAL}
-function get_dqt (cinfo : j_decompress_ptr) : boolean;
-{ Process a DQT marker }
-var
- length : INT32;
- n, i, prec : int;
- tmp : uint;
- quant_ptr : JQUANT_TBL_PTR;
-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 two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_dqt := 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
- get_dqt := 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 );
-
- while (length > 0) do
- begin
- { Read a byte into variable n. 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
- get_dqt := 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 );
-
- n := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
-
- prec := n shr 4;
- n := n and $0F;
-
- {$IFDEF DEBUG}
- TRACEMS2(j_common_ptr(cinfo), 1, JTRC_DQT, n, prec);
- {$ENDIF}
-
- if (n >= NUM_QUANT_TBLS) then
- ERREXIT1(j_common_ptr(cinfo) , JERR_DQT_INDEX, n);
-
- if (cinfo^.quant_tbl_ptrs[n] = NIL) then
- cinfo^.quant_tbl_ptrs[n] := jpeg_alloc_quant_table(j_common_ptr(cinfo));
- quant_ptr := cinfo^.quant_tbl_ptrs[n];
-
- for i := 0 to Pred(DCTSIZE2) do
- begin
- if (prec <> 0) then
- begin
- { Read two bytes interpreted as an unsigned 16-bit integer.
- tmp should be declared unsigned int or perhaps INT32. }
-
- { 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
- get_dqt := 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 );
-
- tmp := (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
- get_dqt := 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( tmp, GETJOCTET( next_input_byte^));
- Inc( next_input_byte );
-
- end
- else
- begin
- { Read a byte into variable tmp. 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
- get_dqt := 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 );
-
- tmp := GETJOCTET(next_input_byte^);
- Inc(next_input_byte);
- end;
-
- { We convert the zigzag-order table to natural array order. }
- quant_ptr^.quantval[jpeg_natural_order[i]] := UINT16(tmp);
- end;
-
- if (cinfo^.err^.trace_level >= 2) then
- begin
- i := 0;
- while i < Pred(DCTSIZE2) do
- begin
- {$IFDEF DEBUG}
- TRACEMS8(j_common_ptr(cinfo), 2, JTRC_QUANTVALS,
- quant_ptr^.quantval[i], quant_ptr^.quantval[i+1],
- quant_ptr^.quantval[i+2], quant_ptr^.quantval[i+3],
- quant_ptr^.quantval[i+4], quant_ptr^.quantval[i+5],
- quant_ptr^.quantval[i+6], quant_ptr^.quantval[i+7]);
- {$ENDIF}
- Inc(i, 8);
- end;
- end;
-
- Dec( length, DCTSIZE2+1 );
- if (prec <> 0) then
- Dec( length, DCTSIZE2 );
- end;
-
- if (length <> 0) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
-
- { 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;
-
- get_dqt := TRUE;
-end; { get_dqt }
-
-
-{LOCAL}
-function get_dri (cinfo : j_decompress_ptr) : boolean;
-{ Process a DRI marker }
-var
- length : INT32;
- tmp : uint;
-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 two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_dri := 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
- get_dri := 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 );
-
- if (length <> 4) then
- ERREXIT(j_common_ptr(cinfo), JERR_BAD_LENGTH);
-
-{ Read two bytes interpreted as an unsigned 16-bit integer.
- tmp should be declared unsigned int or perhaps INT32. }
-
-{ 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
- get_dri := 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 );
-
- tmp := (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
- get_dri := 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( tmp, GETJOCTET( next_input_byte^));
- Inc( next_input_byte );
-
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_DRI, tmp);
- {$ENDIF}
-
- cinfo^.restart_interval := tmp;
-
- { 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;
-
- get_dri := TRUE;
-end; { get_dri }
-
-
-{ Routines for processing APPn and COM markers.
- These are either saved in memory or discarded, per application request.
- APP0 and APP14 are specially checked to see if they are
- JFIF and Adobe markers, respectively. }
-
-const
- APP0_DATA_LEN = 14; { Length of interesting data in APP0 }
- APP14_DATA_LEN = 12; { Length of interesting data in APP14 }
- APPN_DATA_LEN = 14; { Must be the largest of the above!! }
-
-
-{LOCAL}
-procedure examine_app0 (cinfo : j_decompress_ptr;
- var data : array of JOCTET;
- datalen : uint;
- remaining : INT32);
-
-{ Examine first few bytes from an APP0.
- Take appropriate action if it is a JFIF marker.
- datalen is # of bytes at data[], remaining is length of rest of marker data.
-}
-{$IFDEF DEBUG}
-var
- totallen : INT32;
-{$ENDIF}
-begin
- {$IFDEF DEBUG}
- totallen := INT32(datalen) + remaining;
- {$ENDIF}
- if (datalen >= APP0_DATA_LEN) and
- (GETJOCTET(data[0]) = $4A) and
- (GETJOCTET(data[1]) = $46) and
- (GETJOCTET(data[2]) = $49) and
- (GETJOCTET(data[3]) = $46) and
- (GETJOCTET(data[4]) = 0) then
- begin
- { Found JFIF APP0 marker: save info }
- cinfo^.saw_JFIF_marker := TRUE;
- cinfo^.JFIF_major_version := GETJOCTET(data[5]);
- cinfo^.JFIF_minor_version := GETJOCTET(data[6]);
- cinfo^.density_unit := GETJOCTET(data[7]);
- cinfo^.X_density := (GETJOCTET(data[8]) shl 8) + GETJOCTET(data[9]);
- cinfo^.Y_density := (GETJOCTET(data[10]) shl 8) + GETJOCTET(data[11]);
- { Check version.
- Major version must be 1, anything else signals an incompatible change.
- (We used to treat this as an error, but now it's a nonfatal warning,
- because some bozo at Hijaak couldn't read the spec.)
- Minor version should be 0..2, but process anyway if newer. }
-
- if (cinfo^.JFIF_major_version <> 1) then
- WARNMS2(j_common_ptr(cinfo), JWRN_JFIF_MAJOR,
- cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version);
- { Generate trace messages }
- {$IFDEF DEBUG}
- TRACEMS5(j_common_ptr(cinfo), 1, JTRC_JFIF,
- cinfo^.JFIF_major_version, cinfo^.JFIF_minor_version,
- cinfo^.X_density, cinfo^.Y_density, cinfo^.density_unit);
- { Validate thumbnail dimensions and issue appropriate messages }
- if (GETJOCTET(data[12]) or GETJOCTET(data[13])) <> 0 then
- TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_THUMBNAIL,
- GETJOCTET(data[12]), GETJOCTET(data[13]));
- Dec(totallen, APP0_DATA_LEN);
- if (totallen <>
- ( INT32(GETJOCTET(data[12])) * INT32(GETJOCTET(data[13])) * INT32(3) )) then
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_JFIF_BADTHUMBNAILSIZE, int(totallen));
- {$ENDIF}
- end
- else
- if (datalen >= 6) and
- (GETJOCTET(data[0]) = $4A) and
- (GETJOCTET(data[1]) = $46) and
- (GETJOCTET(data[2]) = $58) and
- (GETJOCTET(data[3]) = $58) and
- (GETJOCTET(data[4]) = 0) then
- begin
- { Found JFIF "JFXX" extension APP0 marker }
- { The library doesn't actually do anything with these,
- but we try to produce a helpful trace message. }
- {$IFDEF DEBUG}
- case (GETJOCTET(data[5])) of
- $10:
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_JPEG, int(totallen));
- $11:
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_PALETTE, int(totallen));
- $13:
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_THUMB_RGB, int(totallen));
- else
- TRACEMS2(j_common_ptr(cinfo), 1, JTRC_JFIF_EXTENSION,
- GETJOCTET(data[5]), int(totallen));
- end;
- {$ENDIF}
- end
- else
- begin
- { Start of APP0 does not match "JFIF" or "JFXX", or too short }
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP0, int(totallen));
- {$ENDIF}
- end;
-end;
-
-
-{LOCAL}
-procedure examine_app14 (cinfo : j_decompress_ptr;
- var data : array of JOCTET;
- datalen : uint;
- remaining : INT32);
-{ Examine first few bytes from an APP14.
- Take appropriate action if it is an Adobe marker.
- datalen is # of bytes at data[], remaining is length of rest of marker data.
- }
-var
- {$IFDEF DEBUG}
- version, flags0, flags1,
- {$ENDIF}
- transform : uint;
-begin
- if (datalen >= APP14_DATA_LEN) and
- (GETJOCTET(data[0]) = $41) and
- (GETJOCTET(data[1]) = $64) and
- (GETJOCTET(data[2]) = $6F) and
- (GETJOCTET(data[3]) = $62) and
- (GETJOCTET(data[4]) = $65) then
- begin
- { Found Adobe APP14 marker }
- {$IFDEF DEBUG}
- version := (GETJOCTET(data[5]) shl 8) + GETJOCTET(data[6]);
- flags0 := (GETJOCTET(data[7]) shl 8) + GETJOCTET(data[8]);
- flags1 := (GETJOCTET(data[9]) shl 8) + GETJOCTET(data[10]);
- {$ENDIF}
- transform := GETJOCTET(data[11]);
- {$IFDEF DEBUG}
- TRACEMS4(j_common_ptr(cinfo), 1, JTRC_ADOBE, version, flags0, flags1, transform);
- {$ENDIF}
- cinfo^.saw_Adobe_marker := TRUE;
- cinfo^.Adobe_transform := UINT8 (transform);
- end
- else
- begin
- { Start of APP14 does not match "Adobe", or too short }
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_APP14, int (datalen + remaining));
- {$ENDIF}
- end;
-end;
-
-
-{METHODDEF}
-function get_interesting_appn (cinfo : j_decompress_ptr) : boolean; far;
-{ Process an APP0 or APP14 marker without saving it }
-var
- length : INT32;
- b : array[0..APPN_DATA_LEN-1] of JOCTET;
- i, numtoread : uint;
-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 two bytes interpreted as an unsigned 16-bit integer.
- length should be declared unsigned int or perhaps INT32. }
-
- { 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
- get_interesting_appn := 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
- get_interesting_appn := 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);
-
- { get the interesting part of the marker data }
- if (length >= APPN_DATA_LEN) then
- numtoread := APPN_DATA_LEN
- else
- if (length > 0) then
- numtoread := uint(length)
- else
- numtoread := 0;
- for i := 0 to numtoread-1 do
- begin
- { Read a byte into b[i]. 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
- get_interesting_appn := 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 );
-
- 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 --- do this only at a restart boundary }
- datasrc^.next_input_byte := next_input_byte;
- datasrc^.bytes_in_buffer := bytes_in_buffer;
-
- first_marker := TRUE;
-end; { first_marker }
-
-
-{ Read markers until SOS or EOI.
-
- Returns same codes as are defined for jpeg_consume_input:
- JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. }
-
-{METHODDEF}
-function read_markers (cinfo : j_decompress_ptr) : int; far;
-begin
- { Outer loop repeats once for each marker. }
- repeat
- { Collect the marker proper, unless we already did. }
- { NB: first_marker() enforces the requirement that SOI appear first. }
- if (cinfo^.unread_marker = 0) then
- begin
- if not cinfo^.marker^.saw_SOI then
- begin
- if not first_marker(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
- end
- else
- begin
- if not next_marker(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
- end;
- end;
- { At this point cinfo^.unread_marker contains the marker code and the
- input point is just past the marker proper, but before any parameters.
- A suspension will cause us to return with this state still true. }
-
- case (cinfo^.unread_marker) of
- M_SOI:
- if not get_soi(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_SOF0, { Baseline }
- M_SOF1: { Extended sequential, Huffman }
- if not get_sof(cinfo, FALSE, FALSE) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
- M_SOF2: { Progressive, Huffman }
- if not get_sof(cinfo, TRUE, FALSE) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_SOF9: { Extended sequential, arithmetic }
- if not get_sof(cinfo, FALSE, TRUE) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_SOF10: { Progressive, arithmetic }
- if not get_sof(cinfo, TRUE, TRUE) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- { Currently unsupported SOFn types }
- M_SOF3, { Lossless, Huffman }
- M_SOF5, { Differential sequential, Huffman }
- M_SOF6, { Differential progressive, Huffman }
- M_SOF7, { Differential lossless, Huffman }
- M_JPG, { Reserved for JPEG extensions }
- M_SOF11, { Lossless, arithmetic }
- M_SOF13, { Differential sequential, arithmetic }
- M_SOF14, { Differential progressive, arithmetic }
- M_SOF15: { Differential lossless, arithmetic }
- ERREXIT1(j_common_ptr(cinfo), JERR_SOF_UNSUPPORTED, cinfo^.unread_marker);
-
- M_SOS:
- begin
- if not get_sos(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
- cinfo^.unread_marker := 0; { processed the marker }
- read_markers := JPEG_REACHED_SOS;
- exit;
- end;
-
- M_EOI:
- begin
- {$IFDEF DEBUG}
- TRACEMS(j_common_ptr(cinfo), 1, JTRC_EOI);
- {$ENDIF}
- cinfo^.unread_marker := 0; { processed the marker }
- read_markers := JPEG_REACHED_EOI;
- exit;
- end;
-
- M_DAC:
- if not get_dac(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_DHT:
- if not get_dht(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_DQT:
- if not get_dqt(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_DRI:
- if not get_dri(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_APP0,
- M_APP1,
- M_APP2,
- M_APP3,
- M_APP4,
- M_APP5,
- M_APP6,
- M_APP7,
- M_APP8,
- M_APP9,
- M_APP10,
- M_APP11,
- M_APP12,
- M_APP13,
- M_APP14,
- M_APP15:
- if not my_marker_ptr(cinfo^.marker)^.
- process_APPn[cinfo^.unread_marker - int(M_APP0)](cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_COM:
- if not my_marker_ptr(cinfo^.marker)^.process_COM (cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- M_RST0, { these are all parameterless }
- M_RST1,
- M_RST2,
- M_RST3,
- M_RST4,
- M_RST5,
- M_RST6,
- M_RST7,
- M_TEM:
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 1, JTRC_PARMLESS_MARKER,
- cinfo^.unread_marker)
- {$ENDIF}
- ;
-
- M_DNL: { Ignore DNL ... perhaps the wrong thing }
- if not skip_variable(cinfo) then
- begin
- read_markers := JPEG_SUSPENDED;
- exit;
- end;
-
- else { must be DHP, EXP, JPGn, or RESn }
- { For now, we treat the reserved markers as fatal errors since they are
- likely to be used to signal incompatible JPEG Part 3 extensions.
- Once the JPEG 3 version-number marker is well defined, this code
- ought to change! }
- ERREXIT1(j_common_ptr(cinfo) , JERR_UNKNOWN_MARKER,
- cinfo^.unread_marker);
- end; { end of case }
- { Successfully processed marker, so reset state variable }
- cinfo^.unread_marker := 0;
- Until false;
-end; { read_markers }
-
-
-{ Read a restart marker, which is expected to appear next in the datastream;
- if the marker is not there, take appropriate recovery action.
- Returns FALSE if suspension is required.
-
- This is called by the entropy decoder after it has read an appropriate
- number of MCUs. cinfo^.unread_marker may be nonzero if the entropy decoder
- has already read a marker from the data source. Under normal conditions
- cinfo^.unread_marker will be reset to 0 before returning; if not reset,
- it holds a marker which the decoder will be unable to read past. }
-
-{METHODDEF}
-function read_restart_marker (cinfo : j_decompress_ptr) :boolean; far;
-begin
- { Obtain a marker unless we already did. }
- { Note that next_marker will complain if it skips any data. }
- if (cinfo^.unread_marker = 0) then
- begin
- if not next_marker(cinfo) then
- begin
- read_restart_marker := FALSE;
- exit;
- end;
- end;
-
- if (cinfo^.unread_marker = (int(M_RST0) + cinfo^.marker^.next_restart_num)) then
- begin
- { Normal case --- swallow the marker and let entropy decoder continue }
- {$IFDEF DEBUG}
- TRACEMS1(j_common_ptr(cinfo), 3, JTRC_RST,
- cinfo^.marker^.next_restart_num);
- {$ENDIF}
- cinfo^.unread_marker := 0;
- end
- else
- begin
- { Uh-oh, the restart markers have been messed up. }
- { Let the data source manager determine how to resync. }
- if not cinfo^.src^.resync_to_restart(cinfo,
- cinfo^.marker^.next_restart_num) then
- begin
- read_restart_marker := FALSE;
- exit;
- end;
- end;
-
- { Update next-restart state }
- with cinfo^.marker^ do
- next_restart_num := (next_restart_num + 1) and 7;
-
- read_restart_marker := TRUE;
-end; { read_restart_marker }
-
-
-{ This is the default resync_to_restart method for data source managers
- to use if they don't have any better approach. Some data source managers
- may be able to back up, or may have additional knowledge about the data
- which permits a more intelligent recovery strategy; such managers would
- presumably supply their own resync method.
-
- read_restart_marker calls resync_to_restart if it finds a marker other than
- the restart marker it was expecting. (This code is *not* used unless
- a nonzero restart interval has been declared.) cinfo^.unread_marker is
- the marker code actually found (might be anything, except 0 or FF).
- The desired restart marker number (0..7) is passed as a parameter.
- This routine is supposed to apply whatever error recovery strategy seems
- appropriate in order to position the input stream to the next data segment.
- Note that cinfo^.unread_marker is treated as a marker appearing before
- the current data-source input point; usually it should be reset to zero
- before returning.
- Returns FALSE if suspension is required.
-
- This implementation is substantially constrained by wanting to treat the
- input as a data stream; this means we can't back up. Therefore, we have
- only the following actions to work with:
- 1. Simply discard the marker and let the entropy decoder resume at next
- byte of file.
- 2. Read forward until we find another marker, discarding intervening
- data. (In theory we could look ahead within the current bufferload,
- without having to discard data if we don't find the desired marker.
- This idea is not implemented here, in part because it makes behavior
- dependent on buffer size and chance buffer-boundary positions.)
- 3. Leave the marker unread (by failing to zero cinfo^.unread_marker).
- This will cause the entropy decoder to process an empty data segment,
- inserting dummy zeroes, and then we will reprocess the marker.
-
- #2 is appropriate if we think the desired marker lies ahead, while #3 is
- appropriate if the found marker is a future restart marker (indicating
- that we have missed the desired restart marker, probably because it got
- corrupted).
- We apply #2 or #3 if the found marker is a restart marker no more than
- two counts behind or ahead of the expected one. We also apply #2 if the
- found marker is not a legal JPEG marker code (it's certainly bogus data).
- If the found marker is a restart marker more than 2 counts away, we do #1
- (too much risk that the marker is erroneous; with luck we will be able to
- resync at some future point).
- For any valid non-restart JPEG marker, we apply #3. This keeps us from
- overrunning the end of a scan. An implementation limited to single-scan
- files might find it better to apply #2 for markers other than EOI, since
- any other marker would have to be bogus data in that case. }
-
-
-{GLOBAL}
-function jpeg_resync_to_restart(cinfo : j_decompress_ptr;
- desired : int) : boolean;
-var
- marker : int;
- action : int;
-begin
- marker := cinfo^.unread_marker;
- action := 1; { never used }
- { Always put up a warning. }
- WARNMS2(j_common_ptr(cinfo), JWRN_MUST_RESYNC, marker, desired);
-
- { Outer loop handles repeated decision after scanning forward. }
- repeat
- if (marker < int(M_SOF0)) then
- action := 2 { invalid marker }
- else
- if (marker < int(M_RST0)) or (marker > int(M_RST7)) then
- action := 3 { valid non-restart marker }
- else
- begin
- if (marker = (int(M_RST0) + ((desired+1) and 7))) or
- (marker = (int(M_RST0) + ((desired+2) and 7))) then
- action := 3 { one of the next two expected restarts }
- else
- if (marker = (int(M_RST0) + ((desired-1) and 7))) or
- (marker = (int(M_RST0) + ((desired-2) and 7))) then
- action := 2 { a prior restart, so advance }
- else
- action := 1; { desired restart or too far away }
- end;
-
- {$IFDEF DEBUG}
- TRACEMS2(j_common_ptr(cinfo), 4, JTRC_RECOVERY_ACTION, marker, action);
- {$ENDIF}
- case action of
- 1:
- { Discard marker and let entropy decoder resume processing. }
- begin
- cinfo^.unread_marker := 0;
- jpeg_resync_to_restart := TRUE;
- exit;
- end;
- 2:
- { Scan to the next marker, and repeat the decision loop. }
- begin
- if not next_marker(cinfo) then
- begin
- jpeg_resync_to_restart := FALSE;
- exit;
- end;
- marker := cinfo^.unread_marker;
- end;
- 3:
- { Return without advancing past this marker. }
- { Entropy decoder will be forced to process an empty segment. }
- begin
- jpeg_resync_to_restart := TRUE;
- exit;
- end;
- end; { case }
- Until false; { end loop }
-end; { jpeg_resync_to_restart }
-
-
-{ Reset marker processing state to begin a fresh datastream. }
-
-{METHODDEF}
-procedure reset_marker_reader (cinfo : j_decompress_ptr); far;
-var
- marker : my_marker_ptr;
-begin
- marker := my_marker_ptr (cinfo^.marker);
- with cinfo^ do
- begin
- comp_info := NIL; { until allocated by get_sof }
- input_scan_number := 0; { no SOS seen yet }
- unread_marker := 0; { no pending marker }
- end;
- marker^.pub.saw_SOI := FALSE; { set internal state too }
- marker^.pub.saw_SOF := FALSE;
- marker^.pub.discarded_bytes := 0;
- marker^.cur_marker := NIL;
-end; { reset_marker_reader }
-
-
-{ Initialize the marker reader module.
- This is called only once, when the decompression object is created. }
-
-{GLOBAL}
-procedure jinit_marker_reader (cinfo : j_decompress_ptr);
-var
- marker : my_marker_ptr;
- i : int;
-begin
- { Create subobject in permanent pool }
- marker := my_marker_ptr(
- cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_PERMANENT,
- SIZEOF(my_marker_reader))
- );
- cinfo^.marker := jpeg_marker_reader_ptr(marker);
- { Initialize method pointers }
- marker^.pub.reset_marker_reader := reset_marker_reader;
- marker^.pub.read_markers := read_markers;
- marker^.pub.read_restart_marker := read_restart_marker;
- { Initialize COM/APPn processing.
- By default, we examine and then discard APP0 and APP14,
- but simply discard COM and all other APPn. }
-
- marker^.process_COM := skip_variable;
- marker^.length_limit_COM := 0;
- for i := 0 to 16-1 do
- begin
- marker^.process_APPn[i] := skip_variable;
- marker^.length_limit_APPn[i] := 0;
- end;
- marker^.process_APPn[0] := get_interesting_appn;
- marker^.process_APPn[14] := get_interesting_appn;
- { Reset marker processing state }
- reset_marker_reader(cinfo);
-end; { jinit_marker_reader }
-
-
-{ Control saving of COM and APPn markers into marker_list. }
-
-
-{$ifdef SAVE_MARKERS_SUPPORTED}
-
-{GLOBAL}
-procedure jpeg_save_markers (cinfo : j_decompress_ptr;
- marker_code : int;
- length_limit : uint);
-var
- marker : my_marker_ptr;
- maxlength : long;
- processor : jpeg_marker_parser_method;
-begin
- marker := my_marker_ptr (cinfo^.marker);
-
- { Length limit mustn't be larger than what we can allocate
- (should only be a concern in a 16-bit environment). }
-
- maxlength := cinfo^.mem^.max_alloc_chunk - SIZEOF(jpeg_marker_struct);
- if (long(length_limit) > maxlength) then
- length_limit := uint(maxlength);
-
- { Choose processor routine to use.
- APP0/APP14 have special requirements. }
-
- if (length_limit <> 0) then
- begin
- processor := save_marker;
- { If saving APP0/APP14, save at least enough for our internal use. }
- if (marker_code = int(M_APP0)) and (length_limit < APP0_DATA_LEN) then
- length_limit := APP0_DATA_LEN
- else
- if (marker_code = int(M_APP14)) and (length_limit < APP14_DATA_LEN) then
- length_limit := APP14_DATA_LEN;
- end
- else
- begin
- processor := skip_variable;
- { If discarding APP0/APP14, use our regular on-the-fly processor. }
- if (marker_code = int(M_APP0)) or (marker_code = int(M_APP14)) then
- processor := get_interesting_appn;
- end;
-
- if (marker_code = int(M_COM)) then
- begin
- marker^.process_COM := processor;
- marker^.length_limit_COM := length_limit;
- end
- else
- if (marker_code >= int(M_APP0)) and (marker_code <= int(M_APP15)) then
- begin
- marker^.process_APPn[marker_code - int(M_APP0)] := processor;
- marker^.length_limit_APPn[marker_code - int(M_APP0)] := length_limit;
- end
- else
- ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, marker_code);
-end;
-
-{$endif} { SAVE_MARKERS_SUPPORTED }
-
-{ Install a special processing method for COM or APPn markers. }
-
-{GLOBAL}
-
-procedure jpeg_set_marker_processor (cinfo : j_decompress_ptr;
- marker_code : int;
- routine : jpeg_marker_parser_method);
-var
- marker : my_marker_ptr;
-begin
- marker := my_marker_ptr (cinfo^.marker);
- if (marker_code = int(M_COM)) then
- marker^.process_COM := routine
- else
- if (marker_code >= int(M_APP0)) and (marker_code <= int(M_APP15)) then
- marker^.process_APPn[marker_code - int(M_APP0)] := routine
- else
- ERREXIT1(j_common_ptr(cinfo), JERR_UNKNOWN_MARKER, marker_code);
-end;
-
-end.