Browse Source

* Added Classes version of BZip2 Stream

git-svn-id: trunk@13430 -
michael 16 years ago
parent
commit
5b58c9aea6

+ 3 - 0
.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

+ 73 - 59
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)),)

+ 1 - 1
packages/bzip2/Makefile.fpc

@@ -7,7 +7,7 @@ name=bzip2
 version=2.2.2
 
 [target]
-units=bzip2
+units=bzip2comn bzip2 bzip2stream
 
 [require]
 package=rtl

+ 2 - 61
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
 *****************************************************************************}

+ 76 - 0
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.

+ 31 - 0
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'];

+ 669 - 0
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 <[email protected]>
+Daniel Mantione     <[email protected]>
+Julian R. Seward    <[email protected]>
+
+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]<minlen then
+            minlen:=len[t,i];
+        end;
+      hb_create_decode_tables(limit[t],base[t],perm[t],len[t],
+                              minlen,maxlen,alphasize);
+      minlens[t]:=minlen;
+    end;
+end;
+
+procedure TDecompressBzip2Stream.init_mtf;
+
+var i,j:byte;
+    k:cardinal;
+
+begin
+  k:=mtfa_size-1;
+  for i:=256 div mtfl_size-1 downto 0 do
+    begin
+      for j:=mtfl_size-1 downto 0 do
+        begin
+          mtfa[k]:=i*mtfl_size+j;
+          dec(k);
+        end;
+      mtfbase[i]:=k+1;
+    end;
+end;
+
+function TDecompressBzip2Stream.get_mtf_value:cardinal;
+
+var zn:byte;
+    zvec:cardinal;
+
+begin
+  if group_pos=0 then
+    begin
+      inc(group_no);
+      group_pos:=group_size;
+      gsel:=selector[group_no];
+      gminlen:=minlens[gsel];
+      glimit:=@limit[gsel];
+      gperm:=@perm[gsel];
+      gbase:=@base[gsel];
+    end;
+  dec(group_pos);
+  zn:=gminlen;
+  zvec:=get_bits(zn);
+  while zvec>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 nn<mtfl_size then
+            begin
+              {Avoid the costs of the general case.}
+              p:=@mtfa[mtfbase[0]];
+              q:=p+nn;
+              n:=q^;
+              repeat
+                q^:=(q-1)^;
+                dec(q);
+              until q=p;
+              q^:=n;
+            end
+          else
+            begin
+              {General case.}
+              lno:=nn div MTFL_SIZE;
+              off:=nn and (MTFL_SIZE-1);
+              p:=@mtfa[mtfbase[lno]];
+              q:=p+off;
+              n:=q^;
+              while(q<>p) 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.