12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058 |
- 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;
- br_state.next_input_byte := cinfo^.src^.next_input_byte;
- br_state.bytes_in_buffer := cinfo^.src^.bytes_in_buffer;
- get_buffer := entropy^.bitstate.get_buffer;
- bits_left := entropy^.bitstate.bits_left;
- {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];
- tbl := entropy^.derived_tbls[compptr^.dc_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, tbl, return FALSE, label1);}
- if (bits_left < HUFF_LOOKAHEAD) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then
- begin
- decode_mcu_DC_first := 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 := tbl^.look_nbits[look];
- if (nb <> 0) then
- begin
- {DROP_BITS(nb);}
- Dec(bits_left, nb);
- s := tbl^.look_sym[look];
- end
- else
- begin
- nb := HUFF_LOOKAHEAD+1;
- label1:
- s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb);
- if (s < 0) then
- begin
- decode_mcu_DC_first := 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_DC_first := 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;
- { Convert DC difference to actual value, update last_dc_val }
- Inc(s, state.last_dc_val[ci]);
- state.last_dc_val[ci] := s;
- { Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) }
- block^[0] := JCOEF (s shl Al);
- 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;
- entropy^.bitstate.get_buffer := get_buffer;
- entropy^.bitstate.bits_left := bits_left;
- {ASSIGN_STATE(entropy^.saved, state);}
- entropy^.saved := state;
- end;
- { Account for restart interval (no-op if not using restarts) }
- Dec(entropy^.restarts_to_go);
- decode_mcu_DC_first := TRUE;
- end;
- { MCU decoding for AC initial scan (either spectral selection,
- or first pass of successive approximation). }
- {METHODDEF}
- function decode_mcu_AC_first (cinfo : j_decompress_ptr;
- var MCU_data : array of JBLOCKROW) : boolean;
- label
- label2;
- var
- entropy : phuff_entropy_ptr;
- Se : int;
- Al : int;
- {register} s, k, r : int;
- EOBRUN : uInt;
- block : JBLOCK_PTR;
- {BITREAD_STATE_VARS;}
- get_buffer : bit_buf_type ; {register}
- bits_left : int; {register}
- br_state : bitread_working_state;
- tbl : d_derived_tbl_ptr;
- var
- nb, look : int; {register}
- begin
- entropy := phuff_entropy_ptr (cinfo^.entropy);
- Se := cinfo^.Se;
- 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_AC_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.
- We can avoid loading/saving bitread state if in an EOB run. }
- EOBRUN := entropy^.saved.EOBRUN; { only part of saved state we care about }
- { There is always only one block per MCU }
- if (EOBRUN > 0) then { if it's a band of zeroes... }
- Dec(EOBRUN) { ...process it now (we do nothing) }
- else
- begin
- {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;
- get_buffer := entropy^.bitstate.get_buffer;
- bits_left := entropy^.bitstate.bits_left;
- block := JBLOCK_PTR(MCU_data[0]);
- tbl := entropy^.ac_derived_tbl;
- k := cinfo^.Ss;
- while (k <= Se) do
- begin
- {HUFF_DECODE(s, br_state, tbl, 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_AC_first := 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 := tbl^.look_nbits[look];
- if (nb <> 0) then
- begin
- {DROP_BITS(nb);}
- Dec(bits_left, nb);
- s := tbl^.look_sym[look];
- end
- else
- begin
- nb := HUFF_LOOKAHEAD+1;
- label2:
- s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb);
- if (s < 0) then
- begin
- decode_mcu_AC_first := 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_AC_first := 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;
- { Scale and output coefficient in natural (dezigzagged) order }
- block^[jpeg_natural_order[k]] := JCOEF (s shl Al);
- end
- else
- begin
- if (r = 15) then
- begin { ZRL }
- Inc(k, 15); { skip 15 zeroes in band }
- end
- else
- begin { EOBr, run length is 2^r + appended bits }
- EOBRUN := 1 shl r;
- if (r <> 0) then
- begin { EOBr, r > 0 }
- {CHECK_BIT_BUFFER(br_state, r, return FALSE);}
- if (bits_left < r) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,r)) then
- begin
- decode_mcu_AC_first := FALSE;
- exit;
- end;
- get_buffer := br_state.get_buffer;
- bits_left := br_state.bits_left;
- end;
- {r := GET_BITS(r);}
- Dec(bits_left, r);
- r := (int(get_buffer shr bits_left)) and ( pred(1 shl r) );
- Inc(EOBRUN, r);
- end;
- Dec(EOBRUN); { this band is processed at this moment }
- break; { force end-of-band }
- end;
- end;
- Inc(k);
- end;
- {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;
- entropy^.bitstate.get_buffer := get_buffer;
- entropy^.bitstate.bits_left := bits_left;
- end;
- { Completed MCU, so update state }
- entropy^.saved.EOBRUN := EOBRUN; { only part of saved state we care about }
- end;
- { Account for restart interval (no-op if not using restarts) }
- Dec(entropy^.restarts_to_go);
- decode_mcu_AC_first := TRUE;
- end;
- { MCU decoding for DC successive approximation refinement scan.
- Note: we assume such scans can be multi-component, although the spec
- is not very clear on the point. }
- {METHODDEF}
- function decode_mcu_DC_refine (cinfo : j_decompress_ptr;
- var MCU_data : array of JBLOCKROW) : boolean;
- var
- entropy : phuff_entropy_ptr;
- p1 : int; { 1 in the bit position being coded }
- blkn : int;
- block : JBLOCK_PTR;
- {BITREAD_STATE_VARS;}
- get_buffer : bit_buf_type ; {register}
- bits_left : int; {register}
- br_state : bitread_working_state;
- begin
- entropy := phuff_entropy_ptr (cinfo^.entropy);
- p1 := 1 shl 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_refine := FALSE;
- exit;
- end;
- end;
- { Not worth the cycles to check insufficient_data here,
- since we will not change the data anyway if we read zeroes. }
- { 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;
- get_buffer := entropy^.bitstate.get_buffer;
- bits_left := entropy^.bitstate.bits_left;
- { 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]);
- { Encoded data is simply the next bit of the two's-complement DC value }
- {CHECK_BIT_BUFFER(br_state, 1, return FALSE);}
- if (bits_left < 1) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then
- begin
- decode_mcu_DC_refine := FALSE;
- exit;
- end;
- get_buffer := br_state.get_buffer;
- bits_left := br_state.bits_left;
- end;
- {if (GET_BITS(1)) then}
- Dec(bits_left);
- if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) ) <> 0 then
- block^[0] := block^[0] or p1;
- { Note: since we use OR, repeating the assignment later is safe }
- 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;
- entropy^.bitstate.get_buffer := get_buffer;
- entropy^.bitstate.bits_left := bits_left;
- { Account for restart interval (no-op if not using restarts) }
- Dec(entropy^.restarts_to_go);
- decode_mcu_DC_refine := TRUE;
- end;
- { MCU decoding for AC successive approximation refinement scan. }
- {METHODDEF}
- function decode_mcu_AC_refine (cinfo : j_decompress_ptr;
- var MCU_data : array of JBLOCKROW) : boolean;
- label
- undoit, label3;
- var
- entropy : phuff_entropy_ptr;
- Se : int;
- p1 : int; { 1 in the bit position being coded }
- m1 : int; { -1 in the bit position being coded }
- {register} s, k, r : int;
- EOBRUN : uInt;
- block : JBLOCK_PTR;
- thiscoef : JCOEF_PTR;
- {BITREAD_STATE_VARS;}
- get_buffer : bit_buf_type ; {register}
- bits_left : int; {register}
- br_state : bitread_working_state;
- tbl : d_derived_tbl_ptr;
- num_newnz : int;
- newnz_pos : array[0..DCTSIZE2-1] of int;
- var
- pos : int;
- var
- nb, look : int; {register}
- begin
- entropy := phuff_entropy_ptr (cinfo^.entropy);
- Se := cinfo^.Se;
- p1 := 1 shl cinfo^.Al; { 1 in the bit position being coded }
- m1 := (-1) shl cinfo^.Al; { -1 in the bit position being coded }
- { 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_AC_refine := FALSE;
- exit;
- end;
- end;
- { If we've run out of data, don't modify the MCU. }
- if not entropy^.pub.insufficient_data then
- begin
- { 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;
- get_buffer := entropy^.bitstate.get_buffer;
- bits_left := entropy^.bitstate.bits_left;
- EOBRUN := entropy^.saved.EOBRUN; { only part of saved state we care about }
- { There is always only one block per MCU }
- block := JBLOCK_PTR(MCU_data[0]);
- tbl := entropy^.ac_derived_tbl;
- { If we are forced to suspend, we must undo the assignments to any newly
- nonzero coefficients in the block, because otherwise we'd get confused
- next time about which coefficients were already nonzero.
- But we need not undo addition of bits to already-nonzero coefficients;
- instead, we can test the current bit position to see if we already did it.}
- num_newnz := 0;
- { initialize coefficient loop counter to start of band }
- k := cinfo^.Ss;
- if (EOBRUN = 0) then
- begin
- while (k <= Se) do
- begin
- {HUFF_DECODE(s, br_state, tbl, goto undoit, label3);}
- if (bits_left < HUFF_LOOKAHEAD) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left, 0)) then
- goto undoit;
- 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 := tbl^.look_nbits[look];
- if (nb <> 0) then
- begin
- {DROP_BITS(nb);}
- Dec(bits_left, nb);
- s := tbl^.look_sym[look];
- end
- else
- begin
- nb := HUFF_LOOKAHEAD+1;
- label3:
- s := jpeg_huff_decode(br_state,get_buffer,bits_left,tbl,nb);
- if (s < 0) then
- goto undoit;
- 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
- if (s <> 1) then { size of new coef should always be 1 }
- WARNMS(j_common_ptr(cinfo), JWRN_HUFF_BAD_CODE);
- {CHECK_BIT_BUFFER(br_state, 1, goto undoit);}
- if (bits_left < 1) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then
- goto undoit;
- get_buffer := br_state.get_buffer;
- bits_left := br_state.bits_left;
- end;
- {if (GET_BITS(1)) then}
- Dec(bits_left);
- if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then
- s := p1 { newly nonzero coef is positive }
- else
- s := m1; { newly nonzero coef is negative }
- end
- else
- begin
- if (r <> 15) then
- begin
- EOBRUN := 1 shl r; { EOBr, run length is 2^r + appended bits }
- if (r <> 0) then
- begin
- {CHECK_BIT_BUFFER(br_state, r, goto undoit);}
- if (bits_left < r) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,r)) then
- goto undoit;
- get_buffer := br_state.get_buffer;
- bits_left := br_state.bits_left;
- end;
- {r := GET_BITS(r);}
- Dec(bits_left, r);
- r := (int(get_buffer shr bits_left)) and ( pred(1 shl r) );
- Inc(EOBRUN, r);
- end;
- break; { rest of block is handled by EOB logic }
- end;
- { note s := 0 for processing ZRL }
- end;
- { Advance over already-nonzero coefs and r still-zero coefs,
- appending correction bits to the nonzeroes. A correction bit is 1
- if the absolute value of the coefficient must be increased. }
- repeat
- thiscoef :=@(block^[jpeg_natural_order[k]]);
- if (thiscoef^ <> 0) then
- begin
- {CHECK_BIT_BUFFER(br_state, 1, goto undoit);}
- if (bits_left < 1) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then
- goto undoit;
- get_buffer := br_state.get_buffer;
- bits_left := br_state.bits_left;
- end;
- {if (GET_BITS(1)) then}
- Dec(bits_left);
- if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then
- begin
- if ((thiscoef^ and p1) = 0) then
- begin { do nothing if already set it }
- if (thiscoef^ >= 0) then
- Inc(thiscoef^, p1)
- else
- Inc(thiscoef^, m1);
- end;
- end;
- end
- else
- begin
- Dec(r);
- if (r < 0) then
- break; { reached target zero coefficient }
- end;
- Inc(k);
- until (k > Se);
- if (s <> 0) then
- begin
- pos := jpeg_natural_order[k];
- { Output newly nonzero coefficient }
- block^[pos] := JCOEF (s);
- { Remember its position in case we have to suspend }
- newnz_pos[num_newnz] := pos;
- Inc(num_newnz);
- end;
- Inc(k);
- end;
- end;
- if (EOBRUN > 0) then
- begin
- { Scan any remaining coefficient positions after the end-of-band
- (the last newly nonzero coefficient, if any). Append a correction
- bit to each already-nonzero coefficient. A correction bit is 1
- if the absolute value of the coefficient must be increased. }
- while (k <= Se) do
- begin
- thiscoef := @(block^[jpeg_natural_order[k]]);
- if (thiscoef^ <> 0) then
- begin
- {CHECK_BIT_BUFFER(br_state, 1, goto undoit);}
- if (bits_left < 1) then
- begin
- if (not jpeg_fill_bit_buffer(br_state,get_buffer,bits_left,1)) then
- goto undoit;
- get_buffer := br_state.get_buffer;
- bits_left := br_state.bits_left;
- end;
- {if (GET_BITS(1)) then}
- Dec(bits_left);
- if (int(get_buffer shr bits_left)) and ( pred(1 shl 1) )<>0 then
- begin
- if ((thiscoef^ and p1) = 0) then
- begin { do nothing if already changed it }
- if (thiscoef^ >= 0) then
- Inc(thiscoef^, p1)
- else
- Inc(thiscoef^, m1);
- end;
- end;
- end;
- Inc(k);
- end;
- { Count one block completed in EOB run }
- Dec(EOBRUN);
- 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;
- entropy^.bitstate.get_buffer := get_buffer;
- entropy^.bitstate.bits_left := bits_left;
- entropy^.saved.EOBRUN := EOBRUN; { only part of saved state we care about }
- end;
- { Account for restart interval (no-op if not using restarts) }
- Dec(entropy^.restarts_to_go);
- decode_mcu_AC_refine := TRUE;
- exit;
- undoit:
- { Re-zero any output coefficients that we made newly nonzero }
- while (num_newnz > 0) do
- begin
- Dec(num_newnz);
- block^[newnz_pos[num_newnz]] := 0;
- end;
- decode_mcu_AC_refine := FALSE;
- end;
- { Module initialization routine for progressive Huffman entropy decoding. }
- {GLOBAL}
- procedure jinit_phuff_decoder (cinfo : j_decompress_ptr);
- var
- entropy : phuff_entropy_ptr;
- coef_bit_ptr : int_ptr;
- ci, i : int;
- begin
- entropy := phuff_entropy_ptr(
- cinfo^.mem^.alloc_small (j_common_ptr (cinfo), JPOOL_IMAGE,
- SIZEOF(phuff_entropy_decoder)) );
- cinfo^.entropy := jpeg_entropy_decoder_ptr (entropy);
- entropy^.pub.start_pass := start_pass_phuff_decoder;
- { Mark derived tables unallocated }
- for i := 0 to pred(NUM_HUFF_TBLS) do
- begin
- entropy^.derived_tbls[i] := NIL;
- end;
- { Create progression status table }
- cinfo^.coef_bits := coef_bits_ptrrow (
- cinfo^.mem^.alloc_small ( j_common_ptr (cinfo), JPOOL_IMAGE,
- cinfo^.num_components*DCTSIZE2*SIZEOF(int)) );
- coef_bit_ptr := @cinfo^.coef_bits^[0][0];
- for ci := 0 to pred(cinfo^.num_components) do
- for i := 0 to pred(DCTSIZE2) do
- begin
- coef_bit_ptr^ := -1;
- Inc(coef_bit_ptr);
- end;
- end;
- end.
|