📄 jdhuff.pas
字号:
The i'th block of the MCU is stored into the block pointed to by
MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
(Wholesale zeroing is usually a little faster than retail...)
Returns 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
this module, since we'll just re-assign them on the next call.) }
{METHODDEF}
function decode_mcu (cinfo : j_decompress_ptr;
var MCU_data : array of JBLOCKROW) : boolean; far;
label
skip_ACs, label1, label2, label3;
var
entropy : huff_entropy_ptr;
{register} s, k, 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;
dctbl : d_derived_tbl_ptr;
actbl : d_derived_tbl_ptr;
compptr : jpeg_component_info_ptr;
var
nb, look : int; {register}
begin
entropy := huff_entropy_ptr (cinfo^.entropy);
{ 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 := FALSE;
exit;
end;
end;
{ Load up working state }
{BITREAD_LOAD_STATE(cinfo,entropy^.bitstate);}
br_state.cinfo := cinfo;
br_state.next_input_byte := cinfo^.src^.next_input_byte;
br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer;
br_state.unread_marker := cinfo^.unread_marker;
get_buffer := entropy^.bitstate.get_buffer;
bits_left := entropy^.bitstate.bits_left;
br_state.printed_eod_ptr := @entropy^.bitstate.printed_eod;
{ASSIGN_STATE(state, entropy^.saved);}
state := entropy^.saved;
{ Outer loop handles each block in the MCU }
for blkn := 0 to pred(cinfo^.blocks_in_MCU) do
begin
block := JBLOCK_PTR(MCU_data[blkn]);
ci := cinfo^.MCU_membership[blkn];
compptr := cinfo^.cur_comp_info[ci];
dctbl := entropy^.dc_derived_tbls[compptr^.dc_tbl_no];
actbl := entropy^.ac_derived_tbls[compptr^.ac_tbl_no];
{ Decode a single block's worth of coefficients }
{ Section F.2.2.1: decode the DC coefficient difference }
{HUFF_DECODE(s, br_state, dctbl, return FALSE, showlabel);}
if (bits_left < HUFF_LOOKAHEAD) then
begin
if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then
begin
decode_mcu := False;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
if (bits_left < HUFF_LOOKAHEAD) then
begin
nb := 1;
goto label1;
end;
end;
{look := PEEK_BITS(HUFF_LOOKAHEAD);}
look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and
pred(1 shl HUFF_LOOKAHEAD);
nb := dctbl^.look_nbits[look];
if (nb <> 0) then
begin
{DROP_BITS(nb);}
Dec(bits_left, nb);
s := dctbl^.look_sym[look];
end
else
begin
nb := HUFF_LOOKAHEAD+1;
label1:
s := jpeg_huff_decode(br_state,get_buffer,bits_left,dctbl,nb);
if (s < 0) then
begin
decode_mcu := FALSE;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
end;
if (s <> 0) then
begin
{CHECK_BIT_BUFFER(br_state, s, return FALSE);}
if (bits_left < s) then
begin
if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then
begin
decode_mcu := FALSE;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
end;
{r := GET_BITS(s);}
Dec(bits_left, s);
r := ( int(get_buffer shr bits_left)) and ( pred(1 shl s) );
{s := HUFF_EXTEND(r, s);}
if (r < extend_test[s]) then
s := r + extend_offset[s]
else
s := r;
end;
{ Shortcut if component's values are not interesting }
if (not compptr^.component_needed) then
goto skip_ACs;
{ Convert DC difference to actual value, update last_dc_val }
Inc(s, state.last_dc_val[ci]);
state.last_dc_val[ci] := s;
{ Output the DC coefficient (assumes jpeg_natural_order[0] := 0) }
block^[0] := JCOEF (s);
{ Do we need to decode the AC coefficients for this component? }
if (compptr^.DCT_scaled_size > 1) then
begin
{ Section F.2.2.2: decode the AC coefficients }
{ Since zeroes are skipped, output area must be cleared beforehand }
k := 1;
while (k < DCTSIZE2) do { don't use "for loop", since the induction }
begin { variable is incremented in the loop }
{HUFF_DECODE(s, br_state, actbl, return FALSE, label2);}
if (bits_left < HUFF_LOOKAHEAD) then
begin
if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then
begin
decode_mcu := False;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
if (bits_left < HUFF_LOOKAHEAD) then
begin
nb := 1;
goto label2;
end;
end;
{look := PEEK_BITS(HUFF_LOOKAHEAD);}
look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and
pred(1 shl HUFF_LOOKAHEAD);
nb := actbl^.look_nbits[look];
if (nb <> 0) then
begin
{DROP_BITS(nb);}
Dec(bits_left, nb);
s := actbl^.look_sym[look];
end
else
begin
nb := HUFF_LOOKAHEAD+1;
label2:
s := jpeg_huff_decode(br_state,get_buffer,bits_left,actbl,nb);
if (s < 0) then
begin
decode_mcu := FALSE;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
end;
r := s shr 4;
s := s and 15;
if (s <> 0) then
begin
Inc(k, r);
{CHECK_BIT_BUFFER(br_state, s, return FALSE);}
if (bits_left < s) then
begin
if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then
begin
decode_mcu := FALSE;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
end;
{r := GET_BITS(s);}
Dec(bits_left, s);
r := (int(get_buffer shr bits_left)) and ( pred(1 shl s) );
{s := HUFF_EXTEND(r, s);}
if (r < extend_test[s]) then
s := r + extend_offset[s]
else
s := r;
{ Output coefficient in natural (dezigzagged) order.
Note: the extra entries in jpeg_natural_order[] will save us
if k >= DCTSIZE2, which could happen if the data is corrupted. }
block^[jpeg_natural_order[k]] := JCOEF (s);
end
else
begin
if (r <> 15) then
break;
Inc(k, 15);
end;
Inc(k);
end;
end
else
begin
skip_ACs:
{ Section F.2.2.2: decode the AC coefficients }
{ In this path we just discard the values }
k := 1;
while (k < DCTSIZE2) do
begin
{HUFF_DECODE(s, br_state, actbl, return FALSE, label3);}
if (bits_left < HUFF_LOOKAHEAD) then
begin
if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then
begin
decode_mcu := False;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
if (bits_left < HUFF_LOOKAHEAD) then
begin
nb := 1;
goto label3;
end;
end;
{look := PEEK_BITS(HUFF_LOOKAHEAD);}
look := int(get_buffer shr (bits_left - HUFF_LOOKAHEAD)) and
pred(1 shl HUFF_LOOKAHEAD);
nb := actbl^.look_nbits[look];
if (nb <> 0) then
begin
{DROP_BITS(nb);}
Dec(bits_left, nb);
s := actbl^.look_sym[look];
end
else
begin
nb := HUFF_LOOKAHEAD+1;
label3:
s := jpeg_huff_decode(br_state,get_buffer,bits_left,actbl,nb);
if (s < 0) then
begin
decode_mcu := FALSE;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
end;
r := s shr 4;
s := s and 15;
if (s <> 0) then
begin
Inc(k, r);
{CHECK_BIT_BUFFER(br_state, s, return FALSE);}
if (bits_left < s) then
begin
if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,s)) then
begin
decode_mcu := FALSE;
exit;
end;
get_buffer := br_state.get_buffer;
bits_left := br_state.bits_left;
end;
{DROP_BITS(s);}
Dec(bits_left, s);
end
else
begin
if (r <> 15) then
break;
Inc(k, 15);
end;
Inc(k);
end;
end;
end;
{ Completed MCU, so update state }
{BITREAD_SAVE_STATE(cinfo,entropy^.bitstate);}
cinfo^.src^.next_input_byte := br_state.next_input_byte;
cinfo^.src^.bytes_in_buffer := br_state.bytes_in_buffer;
cinfo^.unread_marker := br_state.unread_marker;
entropy^.bitstate.get_buffer := get_buffer;
entropy^.bitstate.bits_left := bits_left;
{ASSIGN_STATE(entropy^.saved, state);}
entropy^.saved := state;
{ Account for restart interval (no-op if not using restarts) }
Dec(entropy^.restarts_to_go);
decode_mcu := TRUE;
end;
{ Module initialization routine for Huffman entropy decoding. }
{GLOBAL}
procedure jinit_huff_decoder (cinfo : j_decompress_ptr);
var
entropy : huff_entropy_ptr;
i : int;
begin
entropy := huff_entropy_ptr(
cinfo^.mem^.alloc_small (j_common_ptr(cinfo), JPOOL_IMAGE,
SIZEOF(huff_entropy_decoder)) );
cinfo^.entropy := jpeg_entropy_decoder_ptr (entropy);
entropy^.pub.start_pass := start_pass_huff_decoder;
entropy^.pub.decode_mcu := decode_mcu;
{ Mark tables unallocated }
for i := 0 to pred(NUM_HUFF_TBLS) do
begin
entropy^.dc_derived_tbls[i] := NIL;
entropy^.ac_derived_tbls[i] := NIL;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -