?? jdphuff.pas
字號:
Unit JdpHuff;
{ This file contains Huffman entropy decoding routines for progressive JPEG.
Much of the complexity here has to do with supporting input suspension.
If the data source module demands suspension, we want to be able to back
up to the start of the current MCU. To do this, we copy state variables
into local working storage, and update them back to the permanent
storage only upon successful completion of an MCU. }
{ Original: jdphuff.c ; Copyright (C) 1995-1997, Thomas G. Lane. }
interface
{$I jconfig.inc}
uses
jmorecfg,
jinclude,
jpeglib,
jdeferr,
jerror,
jutils,
jdhuff; { Declarations shared with jdhuff.c }
{GLOBAL}
procedure jinit_phuff_decoder (cinfo : j_decompress_ptr);
implementation
{ Expanded entropy decoder object for progressive Huffman decoding.
The savable_state subrecord contains fields that change within an MCU,
but must not be updated permanently until we complete the MCU. }
type
savable_state = record
EOBRUN : uInt; { remaining EOBs in EOBRUN }
last_dc_val : array[00..MAX_COMPS_IN_SCAN-1] of int;
{ last DC coef for each component }
end;
type
phuff_entropy_ptr = ^phuff_entropy_decoder;
phuff_entropy_decoder = record
pub : jpeg_entropy_decoder; { public fields }
{ These fields are loaded into local variables at start of each MCU.
In case of suspension, we exit WITHOUT updating them. }
bitstate : bitread_perm_state; { Bit buffer at start of MCU }
saved : savable_state; { Other state at start of MCU }
{ These fields are NOT loaded into local working state. }
restarts_to_go : uInt; { MCUs left in this restart interval }
{ Pointers to derived tables (these workspaces have image lifespan) }
derived_tbls : array[0..NUM_HUFF_TBLS-1] of d_derived_tbl_ptr;
ac_derived_tbl : d_derived_tbl_ptr; { active table during an AC scan }
end;
{ Forward declarations }
{METHODDEF}
function decode_mcu_DC_first (cinfo : j_decompress_ptr;
var MCU_data : array of JBLOCKROW) : boolean;
far; forward;
{METHODDEF}
function decode_mcu_AC_first (cinfo : j_decompress_ptr;
var MCU_data : array of JBLOCKROW) : boolean;
far; forward;
{METHODDEF}
function decode_mcu_DC_refine (cinfo : j_decompress_ptr;
var MCU_data : array of JBLOCKROW) : boolean;
far; forward;
{METHODDEF}
function decode_mcu_AC_refine (cinfo : j_decompress_ptr;
var MCU_data : array of JBLOCKROW) : boolean;
far; forward;
{ Initialize for a Huffman-compressed scan. }
{METHODDEF}
procedure start_pass_phuff_decoder (cinfo : j_decompress_ptr); far;
var
entropy : phuff_entropy_ptr;
is_DC_band, bad : boolean;
ci, coefi, tbl : int;
coef_bit_ptr : coef_bits_ptr;
compptr : jpeg_component_info_ptr;
var
cindex : int;
expected : int;
begin
entropy := phuff_entropy_ptr (cinfo^.entropy);
is_DC_band := (cinfo^.Ss = 0);
{ Validate scan parameters }
bad := FALSE;
if (is_DC_band) then
begin
if (cinfo^.Se <> 0) then
bad := TRUE;
end
else
begin
{ need not check Ss/Se < 0 since they came from unsigned bytes }
if (cinfo^.Ss > cinfo^.Se) or (cinfo^.Se >= DCTSIZE2) then
bad := TRUE;
{ AC scans may have only one component }
if (cinfo^.comps_in_scan <> 1) then
bad := TRUE;
end;
if (cinfo^.Ah <> 0) then
begin
{ Successive approximation refinement scan: must have Al = Ah-1. }
if (cinfo^.Al <> cinfo^.Ah-1) then
bad := TRUE;
end;
if (cinfo^.Al > 13) then { need not check for < 0 }
bad := TRUE;
{ Arguably the maximum Al value should be less than 13 for 8-bit precision,
but the spec doesn't say so, and we try to be liberal about what we
accept. Note: large Al values could result in out-of-range DC
coefficients during early scans, leading to bizarre displays due to
overflows in the IDCT math. But we won't crash. }
if (bad) then
ERREXIT4(j_common_ptr(cinfo), JERR_BAD_PROGRESSION,
cinfo^.Ss, cinfo^.Se, cinfo^.Ah, cinfo^.Al);
{ Update progression status, and verify that scan order is legal.
Note that inter-scan inconsistencies are treated as warnings
not fatal errors ... not clear if this is right way to behave. }
for ci := 0 to pred(cinfo^.comps_in_scan) do
begin
cindex := cinfo^.cur_comp_info[ci]^.component_index;
coef_bit_ptr := coef_bits_ptr(@(cinfo^.coef_bits^[cindex])); {^[0] ???
Nomssi }
if (not is_DC_band) and (coef_bit_ptr^[0] < 0) then
{ AC without prior DC scan }
WARNMS2(j_common_ptr(cinfo), JWRN_BOGUS_PROGRESSION, cindex, 0);
for coefi := cinfo^.Ss to cinfo^.Se do
begin
if (coef_bit_ptr^[coefi] < 0) then
expected := 0
else
expected := coef_bit_ptr^[coefi];
if (cinfo^.Ah <> expected) then
WARNMS2(j_common_ptr(cinfo), JWRN_BOGUS_PROGRESSION, cindex, coefi);
coef_bit_ptr^[coefi] := cinfo^.Al;
end;
end;
{ Select MCU decoding routine }
if (cinfo^.Ah = 0) then
begin
if (is_DC_band) then
entropy^.pub.decode_mcu := decode_mcu_DC_first
else
entropy^.pub.decode_mcu := decode_mcu_AC_first;
end
else
begin
if (is_DC_band) then
entropy^.pub.decode_mcu := decode_mcu_DC_refine
else
entropy^.pub.decode_mcu := decode_mcu_AC_refine;
end;
for ci := 0 to pred(cinfo^.comps_in_scan) do
begin
compptr := cinfo^.cur_comp_info[ci];
{ Make sure requested tables are present, and compute derived tables.
We may build same derived table more than once, but it's not expensive. }
if (is_DC_band) then
begin
if (cinfo^.Ah = 0) then
begin { DC refinement needs no table }
tbl := compptr^.dc_tbl_no;
jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
entropy^.derived_tbls[tbl]);
end;
end
else
begin
tbl := compptr^.ac_tbl_no;
jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
entropy^.derived_tbls[tbl]);
{ remember the single active table }
entropy^.ac_derived_tbl := entropy^.derived_tbls[tbl];
end;
{ Initialize DC predictions to 0 }
entropy^.saved.last_dc_val[ci] := 0;
end;
{ Initialize bitread state variables }
entropy^.bitstate.bits_left := 0;
entropy^.bitstate.get_buffer := 0; { unnecessary, but keeps Purify quiet }
entropy^.pub.insufficient_data := FALSE;
{ Initialize private state variables }
entropy^.saved.EOBRUN := 0;
{ Initialize restart counter }
entropy^.restarts_to_go := cinfo^.restart_interval;
end;
{ Figure F.12: extend sign bit.
On some machines, a shift and add will be faster than a table lookup. }
{$ifdef AVOID_TABLES}
#define HUFF_EXTEND(x,s)
((x) < (1shl((s)-1)) ? (x) + (((-1)shl(s)) + 1) : (x))
{$else}
{ #define HUFF_EXTEND(x,s)
if (x) < extend_test[s] then
(x) + extend_offset[s]
else
(x)}
const
extend_test : Array[0..16-1] of int = { entry n is 2**(n-1) }
($0000, $0001, $0002, $0004, $0008, $0010, $0020, $0040,
$0080, $0100, $0200, $0400, $0800, $1000, $2000, $4000);
const
extend_offset : array[0..16-1] of int = { entry n is (-1 shl n) + 1 }
( 0, ((-1) shl 1) + 1, ((-1) shl 2) + 1, ((-1) shl 3) + 1, ((-1) shl 4) + 1,
((-1) shl 5) + 1, ((-1) shl 6) + 1, ((-1) shl 7) + 1, ((-1) shl 8) + 1,
((-1) shl 9) + 1, ((-1) shl 10) + 1, ((-1) shl 11) + 1, ((-1) shl 12) + 1,
((-1) shl 13) + 1, ((-1) shl 14) + 1, ((-1) shl 15) + 1 );
{$endif} { AVOID_TABLES }
{ Check for a restart marker & resynchronize decoder.
return:=s FALSE if must suspend. }
{LOCAL}
function process_restart (cinfo : j_decompress_ptr) : boolean;
var
entropy : phuff_entropy_ptr;
ci : int;
begin
entropy := phuff_entropy_ptr (cinfo^.entropy);
{ Throw away any unused bits remaining in bit buffer; }
{ include any full bytes in next_marker's count of discarded bytes }
Inc(cinfo^.marker^.discarded_bytes, entropy^.bitstate.bits_left div 8);
entropy^.bitstate.bits_left := 0;
{ Advance past the RSTn marker }
if (not cinfo^.marker^.read_restart_marker (cinfo)) then
begin
process_restart := FALSE;
exit;
end;
{ Re-initialize DC predictions to 0 }
for ci := 0 to pred(cinfo^.comps_in_scan) do
entropy^.saved.last_dc_val[ci] := 0;
{ Re-init EOB run count, too }
entropy^.saved.EOBRUN := 0;
{ Reset restart counter }
entropy^.restarts_to_go := cinfo^.restart_interval;
{ Reset out-of-data flag, unless read_restart_marker left us smack up
against a marker. In that case we will end up treating the next data
segment as empty, and we can avoid producing bogus output pixels by
leaving the flag set. }
if (cinfo^.unread_marker = 0) then
entropy^.pub.insufficient_data := FALSE;
process_restart := TRUE;
end;
{ Huffman MCU decoding.
Each of these routines decodes and returns one MCU's worth of
Huffman-compressed coefficients.
The coefficients are reordered from zigzag order into natural array order,
but are not dequantized.
The i'th block of the MCU is stored into the block pointed to by
MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
We return FALSE if data source requested suspension. In that case no
changes have been made to permanent state. (Exception: some output
coefficients may already have been assigned. This is harmless for
spectral selection, since we'll just re-assign them on the next call.
Successive approximation AC refinement has to be more careful, however.) }
{ MCU decoding for DC initial scan (either spectral selection,
or first pass of successive approximation). }
{METHODDEF}
function decode_mcu_DC_first (cinfo : j_decompress_ptr;
var MCU_data : array of JBLOCKROW) : boolean;
label
label1;
var
entropy : phuff_entropy_ptr;
Al : int;
{register} s, r : int;
blkn, ci : int;
block : JBLOCK_PTR;
{BITREAD_STATE_VARS;}
get_buffer : bit_buf_type ; {register}
bits_left : int; {register}
br_state : bitread_working_state;
state : savable_state;
tbl : d_derived_tbl_ptr;
compptr : jpeg_component_info_ptr;
var
nb, look : int; {register}
begin
entropy := phuff_entropy_ptr (cinfo^.entropy);
Al := cinfo^.Al;
{ Process restart marker if needed; may have to suspend }
if (cinfo^.restart_interval <> 0) then
begin
if (entropy^.restarts_to_go = 0) then
if (not process_restart(cinfo)) then
begin
decode_mcu_DC_first := FALSE;
exit;
end;
end;
{ If we've run out of data, just leave the MCU set to zeroes.
This way, we return uniform gray for the remainder of the segment. }
if not entropy^.pub.insufficient_data then
begin
{ Load up working state }
{BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);}
br_state.cinfo := cinfo;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -