diff --git a/.gitattributes b/.gitattributes index 372116a4d1..96c37fbfe4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -927,7 +927,10 @@ packages/bzip2/Makefile.fpc svneol=native#text/plain packages/bzip2/examples/pasbzip.pas svneol=native#text/plain packages/bzip2/fpmake.pp svneol=native#text/plain packages/bzip2/src/bzip2.pas svneol=native#text/plain +packages/bzip2/src/bzip2comn.pp svneol=native#text/plain packages/bzip2/src/bzip2i386.inc svneol=native#text/plain +packages/bzip2/src/bzip2si386.inc svneol=native#text/plain +packages/bzip2/src/bzip2stream.pp svneol=native#text/plain packages/cairo/Makefile svneol=native#text/plain packages/cairo/Makefile.fpc svneol=native#text/plain packages/cairo/fpmake.pp svneol=native#text/plain diff --git a/packages/bzip2/Makefile b/packages/bzip2/Makefile index 94ec0f8f5f..8a3c5068f6 100644 --- a/packages/bzip2/Makefile +++ b/packages/bzip2/Makefile @@ -1,5 +1,5 @@ # -# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/10/22] +# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/06/27] # default: all MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded @@ -265,178 +265,178 @@ PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(F override PACKAGE_NAME=bzip2 override PACKAGE_VERSION=2.2.2 ifeq ($(FULL_TARGET),i386-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-go32v2) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-win32) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-os2) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-freebsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-beos) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-haiku) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-netbsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-solaris) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-qnx) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-netware) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-openbsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-wdosx) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-darwin) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-emx) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-watcom) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-netwlibc) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-wince) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),i386-symbian) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-freebsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-netbsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-amiga) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-atari) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-openbsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-palmos) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),m68k-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-netbsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-amiga) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-macos) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-darwin) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-morphos) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),sparc-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),sparc-netbsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),sparc-solaris) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),sparc-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),x86_64-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),x86_64-freebsd) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),x86_64-darwin) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),x86_64-win64) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),x86_64-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-palmos) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-darwin) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-wince) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-gba) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-nds) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),arm-symbian) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc64-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc64-darwin) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),powerpc64-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),avr-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),armeb-linux) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif ifeq ($(FULL_TARGET),armeb-embedded) -override TARGET_UNITS+=bzip2 +override TARGET_UNITS+=bzip2comn bzip2 bzip2stream endif override INSTALL_FPCPACKAGE=y ifeq ($(FULL_TARGET),i386-linux) @@ -1007,6 +1007,7 @@ endif ifeq ($(OS_TARGET),go32v2) STATICLIBPREFIX= SHORTSUFFIX=dos +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),watcom) STATICLIBPREFIX= @@ -1014,6 +1015,7 @@ OEXT=.obj ASMEXT=.asm SHAREDLIBEXT=.dll SHORTSUFFIX=wat +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),linux) BATCHEXT=.sh @@ -1050,6 +1052,7 @@ STATICLIBPREFIX= SHAREDLIBEXT=.dll SHORTSUFFIX=os2 ECHO=echo +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),emx) BATCHEXT=.cmd @@ -1058,6 +1061,7 @@ STATICLIBPREFIX= SHAREDLIBEXT=.dll SHORTSUFFIX=emx ECHO=echo +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),amiga) EXEEXT= @@ -1097,17 +1101,20 @@ ifeq ($(OS_TARGET),netware) EXEEXT=.nlm STATICLIBPREFIX= SHORTSUFFIX=nw +IMPORTLIBPREFIX=imp endif ifeq ($(OS_TARGET),netwlibc) EXEEXT=.nlm STATICLIBPREFIX= SHORTSUFFIX=nwl +IMPORTLIBPREFIX=imp endif ifeq ($(OS_TARGET),macos) BATCHEXT= EXEEXT= DEBUGSYMEXT=.xcoff SHORTSUFFIX=mac +IMPORTLIBPREFIX=imp endif ifeq ($(OS_TARGET),darwin) BATCHEXT=.sh @@ -1134,14 +1141,17 @@ STATICLIBEXT=.a1 SHAREDLIBEXT=.so1 STATICLIBPREFIX= SHORTSUFFIX=v1 +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),go32v2) STATICLIBPREFIX= SHORTSUFFIX=dos +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),watcom) STATICLIBPREFIX= SHORTSUFFIX=wat +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),linux) BATCHEXT=.sh @@ -1188,6 +1198,7 @@ STATICLIBEXT=.ao2 SHAREDLIBEXT=.dll SHORTSUFFIX=os2 ECHO=echo +IMPORTLIBPREFIX= endif ifeq ($(OS_TARGET),amiga) EXEEXT= @@ -1248,6 +1259,7 @@ STATICLIBEXT=.a SHAREDLIBEXT=.nlm EXEEXT=.nlm SHORTSUFFIX=nw +IMPORTLIBPREFIX=imp endif ifeq ($(OS_TARGET),netwlibc) STATICLIBPREFIX= @@ -1259,6 +1271,7 @@ STATICLIBEXT=.a SHAREDLIBEXT=.nlm EXEEXT=.nlm SHORTSUFFIX=nwl +IMPORTLIBPREFIX=imp endif ifeq ($(OS_TARGET),macos) BATCHEXT= @@ -1270,6 +1283,7 @@ STATICLIBEXT=.a EXEEXT= DEBUGSYMEXT=.xcoff SHORTSUFFIX=mac +IMPORTLIBPREFIX=imp endif endif ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),) diff --git a/packages/bzip2/Makefile.fpc b/packages/bzip2/Makefile.fpc index 892c8ea345..8d86f52c78 100644 --- a/packages/bzip2/Makefile.fpc +++ b/packages/bzip2/Makefile.fpc @@ -7,7 +7,7 @@ name=bzip2 version=2.2.2 [target] -units=bzip2 +units=bzip2comn bzip2 bzip2stream [require] package=rtl diff --git a/packages/bzip2/src/bzip2.pas b/packages/bzip2/src/bzip2.pas index b577dc1796..331463ddc3 100644 --- a/packages/bzip2/src/bzip2.pas +++ b/packages/bzip2/src/bzip2.pas @@ -26,25 +26,9 @@ interface {$goto on} -uses objects; - -const max_groups=6; - max_alpha_size=258; - max_code_len=23; - group_size=50; - iter_count=4; - max_selectors=2+(900000 div group_size); - -const mtfa_size=4096; - mtfl_size=16; - -type Tcardinal_array=array [0..899999] of cardinal; - Pcardinal_array=^Tcardinal_array; - - Pcardinal=^cardinal; - Thuffarray=array[0..max_alpha_size] of cardinal; - Phuffarray=^Thuffarray; +uses objects, bzip2comn; +Type Tbzip2_decode_stream=object(Tstream) short:cardinal; readstream:Pstream; @@ -100,14 +84,6 @@ type Tcardinal_array=array [0..899999] of cardinal; destructor done;virtual; end; -{A bzip2 stream starts with this:} -const bzip2_stream_magic='BZh'; - -{Error codes for stream errorinfo.} -const bzip2_bad_header_magic =1; - bzip2_bad_block_magic =2; - bzip2_endoffile =3; - bzip2_data_error =4; implementation @@ -115,41 +91,6 @@ implementation {$i bzip2i386.inc} {$endif} -procedure hb_create_decode_tables(var limit,base,perm:array of cardinal; - var length:array of byte; - minlen,maxlen:byte;alphasize:cardinal); - -var pp,i,j,vec:cardinal; - -begin - pp:=0; - for i:=minlen to maxlen do - for j:=0 to alphasize-1 do - if length[j]=i then - begin - perm[pp]:=j; - inc(pp); - end; - for i:=0 to max_code_len-1 do - begin - base[i]:=0; - limit[i]:=0; - end; - for i:=0 to alphasize-1 do - inc(base[length[i]+1]); - for i:=1 to max_code_len-1 do - inc(base[i],base[i-1]); - vec:=0; - for i:=minlen to maxlen do - begin - inc(vec,base[i+1]-base[i]); - limit[i]:=vec-1; - vec:=vec shl 1; - end; - for i:=minlen+1 to maxlen do - base[i]:=((limit[i-1]+1) shl 1)-base[i]; -end; - {***************************************************************************** Tbzip2_decode_stream *****************************************************************************} diff --git a/packages/bzip2/src/bzip2comn.pp b/packages/bzip2/src/bzip2comn.pp new file mode 100644 index 0000000000..e7c233ac71 --- /dev/null +++ b/packages/bzip2/src/bzip2comn.pp @@ -0,0 +1,76 @@ +unit bzip2comn; + +interface + +const + max_groups = 6; + max_alpha_size = 258; + max_code_len = 23; + group_size = 50; + iter_count = 4; + max_selectors = 2+(900000 div group_size); + + mtfa_size = 4096; + mtfl_size = 16; + +type + TCardinal_array = array [0..899999] of Cardinal; + PCardinal_array = ^TCardinal_array; + + PCardinal = ^Cardinal; + Thuffarray = array[0..max_alpha_size] of Cardinal; + Phuffarray = ^Thuffarray; + +{A bzip2 stream starts with this:} +const bzip2_stream_magic='BZh'; + +{Error codes for stream errorinfo.} +const + bzip2_bad_header_magic = 1; + bzip2_bad_block_magic = 2; + bzip2_endoffile = 3; + bzip2_data_error = 4; + +procedure hb_create_decode_tables(var limit,base,perm:array of cardinal; + var length:array of byte; + minlen,maxlen:byte;alphasize:cardinal); + + +implementation + +procedure hb_create_decode_tables(var limit,base,perm:array of cardinal; + var length:array of byte; + minlen,maxlen:byte;alphasize:cardinal); + +var pp,i,j,vec:cardinal; + +begin + pp:=0; + for i:=minlen to maxlen do + for j:=0 to alphasize-1 do + if length[j]=i then + begin + perm[pp]:=j; + inc(pp); + end; + for i:=0 to max_code_len-1 do + begin + base[i]:=0; + limit[i]:=0; + end; + for i:=0 to alphasize-1 do + inc(base[length[i]+1]); + for i:=1 to max_code_len-1 do + inc(base[i],base[i-1]); + vec:=0; + for i:=minlen to maxlen do + begin + inc(vec,base[i+1]-base[i]); + limit[i]:=vec-1; + vec:=vec shl 1; + end; + for i:=minlen+1 to maxlen do + base[i]:=((limit[i-1]+1) shl 1)-base[i]; +end; + +end. \ No newline at end of file diff --git a/packages/bzip2/src/bzip2si386.inc b/packages/bzip2/src/bzip2si386.inc new file mode 100644 index 0000000000..3199a4ec75 --- /dev/null +++ b/packages/bzip2/src/bzip2si386.inc @@ -0,0 +1,31 @@ +{$ASMMODE intel} + +{$define HAVE_DETRANSFORM} + +procedure TDecompressBzip2Stream.detransform;assembler; + +asm +{ mov edx,offset c + call mcount} + xor edx,edx + lea ebx,[esi+TDecompressBzip2Stream.cftab] + mov ecx,[esi+TDecompressBzip2Stream.tt_count] + push esi + push ebp + mov esi,[esi+TDecompressBzip2Stream.tt] + mov edi,esi + lea ebp,[4*ecx+esi] + jmp @a2 +@a1: + movzx eax,byte [esi] + mov ecx,[ebx+4*eax] + inc dword [ebx+4*eax] + or [edi+4*ecx],edx + add edx,$100 + add esi,4 +@a2: + cmp esi,ebp + jne @a1 + pop ebp + pop esi +end ['eax','ebx','ecx','edx','edi']; diff --git a/packages/bzip2/src/bzip2stream.pp b/packages/bzip2/src/bzip2stream.pp new file mode 100644 index 0000000000..eaed1513ec --- /dev/null +++ b/packages/bzip2/src/bzip2stream.pp @@ -0,0 +1,669 @@ +{$mode objfpc} +{$h+} +unit bzip2stream; +{**************************************************************************** + + BZIP2 decompression unit + + Copyright (C) 2002 by Daniel Mantione + Class port (C) 2009 by Michael Van Canneyt + +This unit provides a decompression stream to decode .bz2 files. It is +inpired by Julian R. Seward's libbzip2 library and therefore you should +send credits to him and bug reports to me :) + +This code is licensed under the same terms as the original libbz2 library, +which is decsribed in the file LICENSE. If you don't have this file, look +at http://www.freepascal.org for this bzip2 unit, the LICENSE file will +be included. In case of problems, contact the author. + +E-mail addresses: + +Michael Van Canneyt +Daniel Mantione +Julian R. Seward + +Please do not contact Julian about this Pascal library, he didn't wrote it. + +****************************************************************************} +interface + +{$goto on} + +uses Classes,SysUtils, bzip2comn; + +Type + TDecompressBzip2Stream=Class(TOwnerStream) + Private + block_randomized:boolean; + blocksize:byte; + tt:Pcardinal_array; + tt_count:cardinal; + rle_run_left,rle_run_data:byte; + nextrle:Pbyte; + decode_available:cardinal; + block_origin:cardinal; + current_block:cardinal; + read_data,bits_available:byte; + inuse16:set of 0..15; + inuse:set of 0..255; + inuse_count:cardinal; + seq_to_unseq:array[0..255] of byte; + alphasize:cardinal; + group_count,group_pos,gsel,gminlen:byte; + group_no:cardinal; + glimit,gperm,gbase:Phuffarray; + selector_count:cardinal; + selector,selector_mtf:array[0..max_selectors] of byte; + len:array[0..max_groups,0..max_alpha_size] of byte; + limit:array[0..max_groups,0..max_alpha_size] of cardinal; + base:array[0..max_groups,0..max_alpha_size] of cardinal; + perm:array[0..max_groups,0..max_alpha_size] of cardinal; + minlens:array[0..max_groups] of byte; + cftab:array[0..257] of cardinal; + mtfbase:array[0..256 div mtfl_size-1] of cardinal; + mtfa:array[0..mtfa_size-1] of byte; + + function get_bits(n:byte):byte; + function get_boolean:boolean; + function get_byte:byte; + function get_cardinal24:cardinal; + function get_cardinal:cardinal; + procedure receive_mapping_table; + procedure receive_selectors; + procedure undo_mtf_values; + procedure receive_coding_tables; + procedure make_hufftab; + procedure init_mtf; + function get_mtf_value:cardinal; + procedure move_mtf_block; + procedure receive_mtf_values; + procedure detransform; + function decode_block : boolean; + Function new_block : boolean; + Function consume_rle : Boolean; inline; + Function rle_read(bufptr:Pbyte;count:Longint) : longint; + Procedure Error(Msg : String; ACode : Integer); + Public + Constructor Create(ASource : TStream); + Destructor Destroy; override; + function Read(var Buffer; Count: Longint): Longint; override; + end; + + EBzip2 = Class(Exception) + ErrCode : Integer; + end; + +implementation + +{$ifdef i386} + {$i bzip2si386.inc} +{$endif} + +{***************************************************************************** + TDecompressBzip2Stream +*****************************************************************************} + +Resourcestring + BZip2Initialize = 'Invalid BZip2 stream: invalid header'; + SDecodingError = 'Decoding error'; + SErrUnimplemented = 'Feature not implemented'; + +Constructor TDecompressBzip2Stream.Create(ASource: TStream); + +var magic:array[1..3] of char; + c:char; + +begin + Inherited Create(ASource); + {Read the magic.} + Source.ReadBuffer(magic,sizeof(magic)); + if magic<>bzip2_stream_magic then + Error(BZip2Initialize,bzip2_bad_header_magic); + {Read the block size and allocate the working array.} + Source.ReadBuffer(c,1); + blocksize:=byte(c)-byte('0'); + GetMem(tt,blocksize*100000*sizeof(cardinal)); + decode_available:=high(decode_available); +end; + +Procedure TDecompressBzip2Stream.Error(Msg : String; ACode : Integer); + +Var + BE : EBzip2; + +begin + BE:=EBzip2.Create(Msg); + BE.ErrCode:=ACode; + Raise BE; +end; + +function TDecompressBzip2Stream.get_bits(n:byte):byte; + +var data:byte; + +begin + if n>bits_available then + begin + Source.ReadBuffer(data,1); + get_bits:=(read_data shr (8-n)) or data shr (8-(n-bits_available)); + read_data:=data shl (n-bits_available); + inc(bits_available,8); + end + else + begin + get_bits:=read_data shr (8-n); + read_data:=read_data shl n; + end; + dec(bits_available,n); +end; + +function TDecompressBzip2Stream.get_boolean:boolean; + +begin + get_boolean:=boolean(get_bits(1)); +end; + +function TDecompressBzip2Stream.get_byte:byte; + +begin + get_byte:=get_bits(8); +end; + +function TDecompressBzip2Stream.get_cardinal24:cardinal; + +begin + get_cardinal24:=get_bits(8) shl 16 or get_bits(8) shl 8 or get_bits(8); +end; + + +function TDecompressBzip2Stream.get_cardinal:cardinal; + +begin + get_cardinal:=get_bits(8) shl 24 or get_bits(8) shl 16 or get_bits(8) shl 8 or + get_bits(8); +end; + +procedure TDecompressBzip2Stream.receive_mapping_table; + +{Receive the mapping table. To save space, the inuse set is stored in pieces + of 16 bits. First 16 bits are stored which pieces of 16 bits are used, then + the pieces follow.} + +var i,j:byte; + +begin + inuse16:=[]; + {Receive the first 16 bits which tell which pieces are stored.} + for i:=0 to 15 do + if get_boolean then + include(inuse16,i); + + {Receive the used pieces.} + inuse:=[]; + inuse_count:=0; + for i:=0 to 15 do + if i in inuse16 then + for j:=0 to 15 do + if get_boolean then + begin + include(inuse,16*i+j); + seq_to_unseq[inuse_count]:=16*i+j; + inc(inuse_count); + end; +{ system.write('Mapping table: '); + for i:=0 to 255 do + if i in inuse then + system.write(i,' '); + writeln;} +end; + +procedure TDecompressBzip2Stream.receive_selectors; + +{Receives the selectors.} + +var i:cardinal; + j:byte; + +begin + group_count:=get_bits(3); + selector_count:=get_bits(8) shl 7 or get_bits(7); + for i:=0 to selector_count-1 do + begin + j:=0; + while get_boolean do + begin + inc(j); + if j>5 then + error(SDecodingError,bzip2_data_error); + end; + selector_mtf[i]:=j; + end; +{ system.write('Selector_mtf: '); + for i:=0 to selector_count-1 do + system.write(selector_mtf[i],' '); + writeln;} +end; + +procedure TDecompressBzip2Stream.undo_mtf_values; + +{Undo the MTF values for the selectors.} + +var pos:array[0..max_groups] of byte; + i:cardinal; + v,tmp:byte; + +begin + for v:=0 to group_count-1 do + pos[v]:=v; + for i:=0 to selector_count-1 do + begin + v:=selector_mtf[i]; + tmp:=pos[v]; + while v<>0 do + begin + pos[v]:=pos[v-1]; + dec(v); + end; + pos[0]:=tmp; + selector[i]:=tmp; + end; +end; + +procedure TDecompressBzip2Stream.receive_coding_tables; + +var t,curr:byte; + i:cardinal; + +begin + for t:=0 to group_count-1 do + begin + curr:=get_bits(5); + for i:=0 to alphasize-1 do + begin + repeat + if not(curr in [1..20]) then + error(SDecodingError,bzip2_data_error); + if not get_boolean then + break; + if get_boolean then + dec(curr) + else + inc(curr); + until false; + len[t,i]:=curr; + end; + end; +end; + +procedure TDecompressBzip2Stream.make_hufftab; + +{Builds the Huffman tables.} + +var i:cardinal; + t,minlen,maxlen:byte; + +begin + for t:=0 to group_count-1 do + begin + minlen:=32; + maxlen:=0; + for i:=0 to alphasize-1 do + begin + if len[t,i]>maxlen then + maxlen:=len[t,i]; + if len[t,i]glimit^[zn] do + begin + inc(zn); + zvec:=zvec shl 1 or byte(get_boolean); + end; + get_mtf_value:=gperm^[zvec-gbase^[zn]]; +end; + +procedure TDecompressBzip2Stream.move_mtf_block; + +var i:byte; + j,k:cardinal; + +begin + k:=MTFA_SIZE; + for i:=256 div MTFL_SIZE-1 downto 0 do + begin + j:=mtfbase[i]; + Pcardinal(@mtfa[k- 4])^:=Pcardinal(@mtfa[j+12])^; + Pcardinal(@mtfa[k- 8])^:=Pcardinal(@mtfa[j+ 8])^; + Pcardinal(@mtfa[k-12])^:=Pcardinal(@mtfa[j+ 4])^; + dec(k,16); + Pcardinal(@mtfa[k ])^:=Pcardinal(@mtfa[j ])^; + mtfbase[i]:=k; + end; +end; + +procedure TDecompressBzip2Stream.receive_mtf_values; + +const run_a=0; + run_b=1; + +var t,next_sym:cardinal; + es:cardinal; + n:byte; + nn,i:cardinal; + p,q:Pbyte; + u,v:Pcardinal; + lno,off:cardinal; + +begin + group_no:=high(group_no); + group_pos:=0; + t:=0; + for i:=0 to 257 do + cftab[i]:=0; + init_mtf; + next_sym:=get_mtf_value; + while next_sym<>inuse_count+1 do + begin +{ writeln(t,' ',next_sym); + if t=22296 then + t:=t; } + if next_sym<=run_b then + begin + es:=0; + n:=0; + repeat + inc(es,(next_sym+1) shl n); + inc(n); + next_sym:=get_mtf_value; + until next_sym>run_b; + n:=seq_to_unseq[mtfa[mtfbase[0]]]; + inc(cftab[n],es); + if t+es>100000*blocksize then + error(SDecodingError,bzip2_data_error); + while es>0 do + begin + tt^[t]:=n; + dec(es); + inc(t); + end; + end + else + begin + nn:=next_sym-1; + if nnp) do + begin + q^:=(q-1)^; + dec(q); + end; + u:=@mtfbase; + v:=u+lno; + repeat + mtfa[v^]:=mtfa[(v-1)^+MTFL_SIZE-1]; + dec(v); + dec(v^); + until v=u; + mtfa[v^]:=n; + if v^=0 then + move_mtf_block; + end; + inc(cftab[seq_to_unseq[n]]); + tt^[t]:=cardinal(seq_to_unseq[n]); + inc(t); + if t>100000*blocksize then + error(SDecodingError,bzip2_data_error); + next_sym:=get_mtf_value; + end; + end; + tt_count:=t; + {Setup cftab to facilitate generation of T^(-1).} + t:=0; + for i:=0 to 256 do + begin + nn:=cftab[i]; + cftab[i]:=t; +{ writeln(i,' ',t);} + inc(t,nn); + end; +end; + +{$ifndef HAVE_DETRANSFORM} + +procedure TDecompressBzip2Stream.detransform; + +var a:cardinal; + p,q,r:Pcardinal; + +begin + a:=0; + p:=@tt^[0]; + q:=p+tt_count; + while p<>q do + begin + r:=@tt^[cftab[p^ and $ff]]; + inc(cftab[p^ and $ff]); + r^:=r^ or a; + inc(a,256); + inc(p); + end; +end; + +{$endif} + +function TDecompressBzip2Stream.decode_block:boolean; + +{Decode a new compressed block.} + +var magic:array[1..6] of char; + stored_blockcrc:cardinal; + i:byte; + +begin + for i:=1 to 6 do + magic[i]:=char(get_byte); + if magic='1AY&SY' then + begin + inc(current_block); + stored_blockcrc:=get_cardinal; + block_randomized:=get_boolean; + block_origin:=get_cardinal24; + + {Receive the mapping table.} + receive_mapping_table; + alphasize:=cardinal(inuse_count)+2; + + {Receive the selectors. Raises exception} + receive_selectors; + {Undo the MTF values for the selectors.} + undo_mtf_values; + {Receive the coding tables.} + receive_coding_tables; + {Build the Huffman tables.} + make_hufftab; + {Receive the MTF values.} + receive_mtf_values; + {Undo the Burrows Wheeler transformation.} + detransform; + decode_available:=tt_count; + Result:=True; + end + else + begin + if magic<>#$17'rE8P'#$90 then + error(SDecodingError,bzip2_bad_block_magic); + Result:=false; + end; +end; + +Function TDecompressBzip2Stream.new_block : Boolean; + +begin + Result:=decode_block; + If result then + nextrle:=@tt^[tt^[block_origin] shr 8] + else + nextrle:=nil; +end; + +Function TDecompressBzip2Stream.consume_rle : Boolean;inline; + +{Make nextrle point to the next decoded byte. If nextrle did point to the last + byte in the current block, decode the next block.} + +begin +{ Pcardinal(nextrle)^:=Pcardinal(nextrle)^ shr 8;} + nextrle:=@tt^[Pcardinal(nextrle)^ shr 8]; + dec(decode_available); + if decode_available=0 then + Result:=new_block + else + Result:=True; +end; + +Function TDecompressBzip2Stream.rle_read(bufptr:Pbyte;Count:Longint) : LongInt; + +var rle_len:cardinal; + data:byte; + +label rle_write; + +begin + Result:=0; + rle_len:=rle_run_left; + data:=rle_run_data; + if block_randomized then + {Not yet implemented.} + Error(SErrUnimplemented,-1) + else + begin + if rle_len<>0 then + {Speed is important. Instead of an if statement within the + repeat loop use a goto outside the loop.} + goto rle_write; + repeat + if decode_available=0 then + break; + rle_len:=1; + data:=nextrle^; + if consume_rle and (decode_available>0) and (data=nextrle^) then + begin + inc(rle_len); + if consume_rle and (decode_available>0) and (data=nextrle^) then + begin + inc(rle_len); + if consume_rle and (decode_available>0) and (data=nextrle^) then + begin + if consume_rle then + inc(rle_len,nextrle^+1); + consume_rle; + end; + end; + end; +rle_write: + repeat + bufptr^:=data; + inc(bufptr); + dec(count); + dec(rle_len); + inc(Result); + until (rle_len=0) or (count=0); + until count=0; + end; + rle_run_data:=data; + rle_run_left:=rle_len; +end; + +Function TDecompressBzip2Stream.Read(var Buffer; Count : Longint) : LongInt; + +var bufptr:Pbyte; + +begin + bufptr:=@buffer; + if decode_available=high(decode_available) then + begin + {Initialize the rle process: + - Decode a block + - Initialize pointer.} + system.Write('.'); + if not decode_block then + begin + nextrle:=nil; + error(SDecodingError,bzip2_endoffile); + end; + nextrle:=@tt^[tt^[block_origin] shr 8]; + end; + Result:=rle_read(bufptr,count); +end; + +Destructor TDecompressBzip2Stream.Destroy; + +begin + if tt<>nil then + FreeMem(tt,blocksize*100000*sizeof(cardinal)); + Inherited; +end; + +end.