Seite 1 von 1

memory packen mit bzip2.dll

Verfasst: 27.05.2006 23:48
von mar
Hi,

hier mal etwas Beschreibung - im Quelltext gibt es so was kaum.
Die bzip2.dll müsst ihr euch natürlich noch runterladen und den Pfad
in includeLibBzip2.pbi anpassen. Ebenso die Pfade in memory-bzip2.pb.

http://prdownloads.sourceforge.net/gnuw ... p?download
Unbedingt diese Version von bzip2 runterladen - klein und funktioniert.

So nun etwas Programmbeschreibung:
Also erst mal läd man ein File in den Speicher.
Nun muss man es komprimieren oder dekomprimieren.
Dann wird es wieder vom Speicher auf die Platte geschoben.

Dies ist nur für relativ kleine Files gedacht (Arbeitspeicher).

Natürlich könnt ihr auch gerne die FileIORoutinen hinzufügen.
Die brauche ich bis jetzt nicht.

mar

Code: Alles auswählen

;includeLibBzip2.pbi
#BZ_RUN               =0
#BZ_FLUSH             =1
#BZ_FINISH            =2

#BZ_OK                =0
#BZ_RUN_OK            =1
#BZ_FLUSH_OK          =2
#BZ_FINISH_OK         =3
#BZ_STREAM_END        =4
#BZ_SEQUENCE_ERROR    =-1
#BZ_PARAM_ERROR       =-2
#BZ_MEM_ERROR         =-3
#BZ_DATA_ERROR        =-4
#BZ_DATA_ERROR_MAGIC  =-5
#BZ_IO_ERROR          =-6
#BZ_UNEXPECTED_EOF    =-7
#BZ_OUTBUFF_FULL      =-8
#BZ_CONFIG_ERROR      =-9

Structure bz_stream
  *next_in.c;
  avail_in.l;
  total_in.q
  *next_out.c;
  avail_out.l;
  total_out.q;
  *state;
  *bzalloc;void *(*bzalloc)(void *,int,int);
  *bzfree;void (*bzfree)(void *,void *);
  *opaque;
EndStructure

;    BZ2_bzlibVersion=GetProcAddress(hLib,"BZ2_bzlibVersion");
;    BZ2_bzopen=GetProcAddress(hLib,"BZ2_bzopen");
;    BZ2_bzdopen=GetProcAddress(hLib,"BZ2_bzdopen");
;    BZ2_bzread=GetProcAddress(hLib,"BZ2_bzread");
;    BZ2_bzwrite=GetProcAddress(hLib,"BZ2_bzwrite");
;    BZ2_bzflush=GetProcAddress(hLib,"BZ2_bzflush");
;    BZ2_bzclose=GetProcAddress(hLib,"BZ2_bzclose");
;    BZ2_bzerror=GetProcAddress(hLib,"BZ2_bzerror");

Global BZ2_bzCompressInit
Global BZ2_bzCompress
Global BZ2_bzCompressEnd
Global BZ2_bzDecompressInit
Global BZ2_bzDecompress
Global BZ2_bzDecompressEnd
Global BZ2_Dll

Procedure libBzip2Init()
  BZ2_DLL = OpenLibrary(#PB_Any,"..\dlls\bzip2.dll")
  If BZ2_DLL
    BZ2_bzCompressInit = GetFunction(BZ2_DLL, "BZ2_bzCompressInit")
    BZ2_bzCompress = GetFunction(BZ2_DLL, "BZ2_bzCompress")
    BZ2_bzCompressEnd = GetFunction(BZ2_DLL, "BZ2_bzCompressEnd")
    BZ2_bzDecompressInit = GetFunction(BZ2_DLL, "BZ2_bzDecompressInit")
    BZ2_bzDecompress = GetFunction(BZ2_DLL, "BZ2_bzDecompress")
    BZ2_bzDecompressEnd = GetFunction(BZ2_DLL, "BZ2_bzDecompressEnd")
  Else
    MessageRequester("error!","Can't open library!",0)
  EndIf
EndProcedure
Procedure.l libBzip2bzCompressInit(*strm,blockSize100k.l,verbosity.l,workFactor.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzCompressInit,*strm,blockSize100k.l,verbosity.l,workFactor.l)
EndProcedure
Procedure.l libBzip2bzCompress(*strm,action.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzCompress,*strm,action.l)
EndProcedure
Procedure.l libBzip2bzCompressEnd(*strm)
  ProcedureReturn CallCFunctionFast(BZ2_bzCompressEnd,*strm)
EndProcedure
Procedure.l libBzip2bzDecompressInit(*strm.l,verbosity.l,small.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzDecompressInit,*strm.l,verbosity.l,small.l)
EndProcedure
Procedure.l libBzip2bzDecompress(strm.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzDecompress,strm.l)
EndProcedure
Procedure.l libBzip2bzDecompressEnd(strm.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzDecompressEnd,strm.l)
EndProcedure
Procedure.l libBzip2FreeLibrary ()
  ProcedureReturn CloseLibrary(BZ2_DLL)
EndProcedure


;-----------------------------------------------
Structure BZ_BufferList
  *buffer.l
  bytesCount.l
EndStructure

Procedure bzLibDecompressMemory(*compressedBuffer)

  If *compressedBuffer=0 : ProcedureReturn 0 : EndIf
  
  NewList bufferList.BZ_BufferList()

  compressedBufferSize=MemorySize(*compressedBuffer)
  *tempBuffer=AllocateMemory(compressedBufferSize>>2)
  tempBufferSize=MemorySize(*tempBuffer)
  array.l 
  ;ok=libBzip2Init()
  ;Debug ok
  state.l=0
  
  strm.bz_stream
  strm\next_in=*compressedBuffer
  strm\avail_in.l=compressedBufferSize
  strm\total_in.q=0
  strm\next_out=*tempBuffer
  strm\avail_out.l=tempBufferSize
  strm\total_out.q=0
  strm\state=@state
  strm\bzalloc=0
  strm\bzfree=0
  strm\opaque=0
  
  Debug "stat Decompress"
  ok=libBzip2bzDecompressInit(@strm,0,0)
  Debug ok
  Debug state
  
  error=0
  While ok<>#BZ_STREAM_END And error=0
    ok=libBzip2bzDecompress(@strm)
    Debug ok
    Debug state
    If ok=#BZ_OK
      AddElement(bufferList())
      bufferList()\buffer=*tempBuffer
      bufferList()\bytesCount=tempBufferSize-strm\avail_out
      *tempBuffer=AllocateMemory(tempBufferSize)
      If *tempBuffer<>0
        strm\next_out=*tempBuffer
        strm\avail_out.l=tempBufferSize
      Else
        error=1
      EndIf
    ElseIf ok=#BZ_STREAM_END
      AddElement(bufferList())
      bufferList()\buffer=*tempBuffer
      bufferList()\bytesCount=tempBufferSize-strm\avail_out
    Else
      error=1
    EndIf  
  Wend
  
  ok=libBzip2bzDecompressEnd(@strm)
  Debug ok
  Debug state
  ;ok= libBzip2FreeLibrary()
  ;Debug ok
  If error=1
    ProcedureReturn 0
  EndIf
  *decompressedBuffer=AllocateMemory(strm\total_out)
  decompressedBufferSize=strm\total_out
  *tempBuffer=*decompressedBuffer
  ResetList(bufferList())
  While NextElement(bufferList())
    CopyMemory(bufferList()\buffer,*tempBuffer,bufferList()\bytesCount)
    *tempBuffer+bufferList()\bytesCount
    FreeMemory( bufferList()\buffer)
  Wend

  ProcedureReturn *decompressedBuffer
EndProcedure

Procedure bzLibCompressMemory(*decompressedBuffer)

  If *decompressedBuffer=0 : ProcedureReturn 0 : EndIf
  
  NewList bufferList.BZ_BufferList()

  decompressedBufferSize=MemorySize(*decompressedBuffer)
  *tempBuffer=AllocateMemory(decompressedBufferSize>>2)
  tempBufferSize=MemorySize(*tempBuffer)
  array.l 
  ;ok=libBzip2Init()
  ;Debug ok
  state.l=0
  
  strm.bz_stream
  strm\next_in=*decompressedBuffer
  strm\avail_in.l=decompressedBufferSize
  strm\total_in.q=0
  strm\next_out=*tempBuffer
  strm\avail_out.l=tempBufferSize
  strm\total_out.q=0
  strm\state=@state
  strm\bzalloc=0
  strm\bzfree=0
  strm\opaque=0
  
  Debug "stat Compress"
  ok=libBzip2bzCompressInit(@strm,9,0,0)
  Debug ok
  Debug state
  
  error=0
  While ok<>#BZ_STREAM_END And error=0
    ok=libBzip2bzCompress(@strm,#BZ_FINISH)
    Debug ok
    Debug state
    If ok=#BZ_FINISH_OK
      AddElement(bufferList())
      bufferList()\buffer=*tempBuffer
      bufferList()\bytesCount=tempBufferSize-strm\avail_out
      *tempBuffer=AllocateMemory(tempBufferSize)
      If *tempBuffer<>0
        strm\next_out=*tempBuffer
        strm\avail_out.l=tempBufferSize
      Else
        error=1
      EndIf
    ElseIf ok=#BZ_STREAM_END
      AddElement(bufferList())
      bufferList()\buffer=*tempBuffer
      bufferList()\bytesCount=tempBufferSize-strm\avail_out
    Else
      error=1
    EndIf  
  Wend
  
  ok=libBzip2bzCompressEnd(@strm)
  Debug ok
  Debug state
  ;ok= libBzip2FreeLibrary()
  ;Debug ok
  If error=1
    ProcedureReturn 0
  EndIf
  *compressedBuffer=AllocateMemory(strm\total_out)
  compressedBufferSize=strm\total_out
  *tempBuffer=*compressedBuffer
  ResetList(bufferList())
  While NextElement(bufferList())
    CopyMemory(bufferList()\buffer,*tempBuffer,bufferList()\bytesCount)
    *tempBuffer+bufferList()\bytesCount
    FreeMemory( bufferList()\buffer)
  Wend

  ProcedureReturn *compressedBuffer
EndProcedure

Code: Alles auswählen

;includeMemoryIO.pbi
;-----------------------------------------------------
Procedure LoadFileToMem(fname.s) 
  fileNo=ReadFile(#PB_Any,fname)
  If fileNo>0
    MemFileSize = Lof(fileNo)
    *FileBuffer = AllocateMemory(MemFileSize)
    If *FileBuffer : ReadData(fileNo,*FileBuffer,MemFileSize) : EndIf 
    CloseFile(fileNo)
  EndIf 
ProcedureReturn *FileBuffer
EndProcedure 
;-----------------------------------------------------
Procedure SaveMemToFile(fname.s,*FileBuffer) 
  fileNo=CreateFile(#PB_Any,fname)
  If fileNo>0
    MemFileSize = MemorySize(*fileBuffer)
    If *FileBuffer : WriteData(fileNo,*FileBuffer,MemFileSize) : EndIf 
    CloseFile(fileNo)
  EndIf 
EndProcedure 
;-----------------------------------------------------

Code: Alles auswählen

;memory-bzip.pb
IncludeFile "includeLibBzip2.pbi"
IncludeFile "includeMemoryIO.pbi"

OpenConsole()
ok=libBzip2Init()
If BZ2_DLL=0 : End : EndIf
;--------------------------
PrintN("Start Compressing")

fnameDecompressed.s="..\data\pb2.7z"
fnameCompressed.s= "..\data\pb2.bz2"

*decompressedBuffer=LoadFileToMem(fnameDecompressed.s)
*compressedBuffer=bzLibCompressMemory(*decompressedBuffer)

If *compressedBuffer<>0
  SaveMemToFile(fnameCompressed.s,*compressedBuffer) 
  PrintN("saved File")
  ok= FreeMemory(*compressedBuffer)
EndIf
ok= FreeMemory(*decompressedBuffer)

;--------------------------
PrintN("Start Decompressing")

fnameCompressed.s="..\data\pb2.bz2"
fnameDecompressed.s="..\data\pb2b.7z"

*compressedBuffer=LoadFileToMem(fnameCompressed.s)
If *compressedBuffer=0 : End : EndIf
*decompressedBuffer=bzLibDecompressMemory(*compressedBuffer)
;here you can check the first bytes for the file type and then put an extension to it

If *decompressedBuffer<>0
  SaveMemToFile(fnameDecompressed.s,*decompressedBuffer) 
  PrintN("saved File")
  ok= FreeMemory(*decompressedBuffer)
EndIf
ok= FreeMemory(*compressedBuffer)

;--------------------------

Input()
ok= libBzip2FreeLibrary()

End

Verfasst: 28.05.2006 01:47
von ts-soft
Sehr schön, aber ein kleiner Verbesserungsvorschlag, mit Prototypes sparste ein paar Proceduren und ist dann PB 4 mässiger :wink:

Code: Alles auswählen

Procedure libBzip2Init()
  BZ2_DLL = OpenLibrary(#PB_Any,"..\dlls\bzip2.dll")
  If BZ2_DLL
    BZ2_bzCompressInit = GetFunction(BZ2_DLL, "BZ2_bzCompressInit")
    BZ2_bzCompress = GetFunction(BZ2_DLL, "BZ2_bzCompress")
    BZ2_bzCompressEnd = GetFunction(BZ2_DLL, "BZ2_bzCompressEnd")
    BZ2_bzDecompressInit = GetFunction(BZ2_DLL, "BZ2_bzDecompressInit")
    BZ2_bzDecompress = GetFunction(BZ2_DLL, "BZ2_bzDecompress")
    BZ2_bzDecompressEnd = GetFunction(BZ2_DLL, "BZ2_bzDecompressEnd")
  Else
    MessageRequester("error!","Can't open library!",0)
  EndIf
EndProcedure
Procedure.l libBzip2bzCompressInit(*strm,blockSize100k.l,verbosity.l,workFactor.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzCompressInit,*strm,blockSize100k.l,verbosity.l,workFactor.l)
EndProcedure
Procedure.l libBzip2bzCompress(*strm,action.l)
  ProcedureReturn CallCFunctionFast(BZ2_bzCompress,*strm,action.l)
EndProcedure
Diesen Teil kannste so ersetzen (nicht vollständig, aber sollte zum verständnis reichen)

Code: Alles auswählen

PrototypeC.l libBzip2bzCompressInit(*strm,blockSize100k.l,verbosity.l,workFactor.l)
PrototypeC.l libBzip2bzCompress(*strm,action.l)
; usw.
Procedure libBzip2Init()
  BZ2_DLL = OpenLibrary(#PB_Any,"..\dlls\bzip2.dll")
  If BZ2_DLL
    Global libBzip2bzCompressInit.libBzip2bzCompressInit = GetFunction(BZ2_DLL, "BZ2_bzCompressInit")
    Global libBzip2bzCompress.libBzip2bzCompress = GetFunction(BZ2_DLL, "BZ2_bzCompress")
    ; usw.
  Else
    MessageRequester("error!","Can't open library!",0)
  EndIf
EndProcedure
Du sparst ein paar Proceduren und hast dieselbe Wirkung

Verfasst: 28.05.2006 07:43
von mar
Ja das kannte ich noch nicht und spart Platz.

mar :allright: