memory packen mit bzip2.dll

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
mar
Beiträge: 107
Registriert: 06.08.2005 14:49

memory packen mit bzip2.dll

Beitrag 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
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag 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
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
mar
Beiträge: 107
Registriert: 06.08.2005 14:49

Beitrag von mar »

Ja das kannte ich noch nicht und spart Platz.

mar :allright:
Antworten