GZIP und/oder Deflate Komprimierung gesucht

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

GZIP und/oder Deflate Komprimierung gesucht

Beitrag von AND51 »

Hallo!

Wie kann ich Daten mit GZIp und/oder Deflate komprimieren? Ich habe im deutschen und englischen Forum nichts dazu gefunden, bei Google such ich immr noch... :|
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
vonTurnundTaxis
Beiträge: 2130
Registriert: 06.10.2004 20:38
Wohnort: Bayreuth
Kontaktdaten:

Beitrag von vonTurnundTaxis »

Nicht durch Zorn, sondern durch Lachen tötet man
ClipGrab | Pastor - jetzt mit kurzen URLs!
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Hallo!

Danke für den Link! Leider weiß ich das nicht in mein Programm einzubinden. Ich möchte Speicherbereiche komprimieren (komprimieren reicht). Ich weiß nicht, ob es dazu gut ist, Daten, die nur versendet werden sollen, temporär zwischenzuspeichern. Gibt es noch andere Lösungen?

Wenn ihr meint, dass z. B. deflate einfacherer ist, als gzip, dann soll mir deflate vorerst reichen. Der Verwendungszweck soll sein für Daten, die ich browsern deflate/gzip-Komprimiert zusenden will.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

die ZUserLib http://www.purearea.net/pb/download/use ... serLIB.zip müsste für Deine Zwecke genau passen.

für deflate:

Code: Alles auswählen

Structure z_stream
  next_in.l   ;pointer to next memoryblock for input
  avail_in.l  ;availaible bytes for input
  total_in.l  ;filled by zlib, stores the read bytes
  next_out.l  ;pointer to next memoryblock for output
  avail_out.l ;availaible bytes for output
  total_out.l ;filled by zlib, stores the written bytes
  msg.s       ;maybe good to free a few bytes for it, just for safety (\msg=space(255)
  zalloc.l    ;null at start
  zfree.l     ;null at start
  opaque.l    ;null at start
  data_type.l
  adler.l
  reserved.l
EndStructure

;-Const
#ZLIB_VERSION = "1.2.1"
#ZLIB_VERNUM = $1210

#Z_NO_FLUSH = 0
#Z_PARTIAL_FLUSH = 1
#Z_SYNC_FLUSH = 2
#Z_FULL_FLUSH = 3
#Z_FINISH = 4
#Z_BLOCK = 5

;return codes
#Z_OK = 0
#Z_STREAM_END = 1
#Z_NEED_DICT = 2

#Z_ERRNO = (-1)
#Z_STREAM_ERROR = (-2)
#Z_DATA_ERROR = (-3)
#Z_MEM_ERROR = (-4)
#Z_BUF_ERROR = (-5)
#Z_VERSION_ERROR = (-6)

;compression level
#Z_NO_COMPRESSION = 0
#Z_BEST_SPEED = 1
#Z_BEST_COMPRESSION = 9
#Z_DEFAULT_COMPRESSION = (-1)

;strategy
#Z_FILTERED = 1
#Z_HUFFMAN_ONLY = 2
#Z_RLE = 3
#Z_DEFAULT_STRATEGY = 0   

;method MUST be #Z_DEFLATED in this version
;#Z_BINARY = 0             
;#Z_ASCII = 1              
;#Z_UNKNOWN = 2            
#Z_DEFLATED = 8           
#Z_NULL = 0               

Global stream.z_stream
Global test$

;-procedures for feeding zlib piecemeal for compressing
Procedure initzlib()
  stream\msg       = "                  ";Space(255) 
  stream\zalloc    = #Z_NULL;(alloc_func)0;
  stream\zfree     = #Z_NULL;(free_func)0;
  stream\opaque    = #Z_NULL;(voidpf)0;
  a$=#ZLIB_VERSION
  zerr = ZdeflateInit_(@stream,#Z_BEST_SPEED,0,0)
  ProcedureReturn = zerr ;should be #Z_OK if no error occured
EndProcedure

Procedure add2Stream(txt$,DestMem,nums)
  ;Debug txt$
  ;Debug "1 out | in = " + Str(stream\total_out) + " | " + Str(stream\total_in)
  old_total_in = stream\total_in
  SrcLen=Len(txt$)
  ;Debug "srcLen= " +Str(srcLen)
  stream\next_in   = @txt$;(Bytef*)source
  stream\avail_in  = SrcLen;(uInt)SourceLen
  Repeat
    err = Zdeflate(@stream, #Z_NO_FLUSH)
    If err <> #Z_OK
      Debug "Zdeflate err= " + Str(err);should be #Z_OK if no error occured
    EndIf
    ;Debug "2 out | in = " + Str(stream\total_out) + " | " + Str(stream\total_in)
    ;Debug "stream\avail_in= " + Str(stream\avail_in)
  Until stream\total_in - old_total_in = SrcLen
  ProcedureReturn stream\total_out
EndProcedure

Procedure endcompress(DestMem, DestLen)
  stream\next_out = DestMem
  Repeat
    stream\avail_out = DestLen
    err = Zdeflate(@stream, #Z_FINISH)
    ;Debug "Zdeflate-#Z_FINISH err= " + Str(err)
  Until err = #Z_STREAM_END
  err = ZdeflateEnd(stream);should be #Z_OK if no error occured
  
  Debug "ZdeflateEnd err= " + Str(err)
  Debug "end out | in = " + Str(stream\total_out) + " | " + Str(stream\total_in)
EndProcedure

Procedure test_deflate()
  memLen=1000;32000
  Debug "# start feeding zlib piecemeal" 
  If initzlib() = #Z_OK
    MemComprStream=AllocateMemory(memLen)
    zeiger=MemComprStream
    stream\next_out  = zeiger
    stream\avail_out = memLen
    For i = 1 To 8288
      tmp$=test$ + " " + Str(i) + " "
      leng+Len(tmp$)
      MemComprStream=ReAllocateMemory(MemComprStream,leng + leng/1000 + 16)
      ;stream\avail_out=leng/1000 + 16
      zeiger = MemComprStream + add2Stream(tmp$,zeiger,i)
    Next
    endcompress(zeiger, memLen-(zeiger-MemComprStream))
    Debug "stream\total_out= " + Str(stream\total_out)
    CreateFile(1, "e:\test\kompri.txt"+".zlb")  ;- !! change path !!
    WriteData(1, MemComprStream, stream\total_out+1)
    CloseFile(1) 
    FreeMemory(MemComprStream)
  Else
    Debug "error initzlib"
  EndIf
  Debug ""
EndProcedure
und gzip:

Code: Alles auswählen

;-test gzio, read/write .gz files
Procedure test_gzio()
  Debug "# start gz input / output"
  txt$="another text for testing"
  TESTFILE$="e:\test\gztest.txt.gz" ;- !! change path !!
  Debug "- first output"
  ;-write gz
  fileHdl = Zgzopen(@TESTFILE$, @"wb9");Type of access permitted "wb" or "rb" + comressionlevel and strategy i.e. "wb9f"
  ;"r"
  ;Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
  ;"w"
  ;Opens an empty file for writing. If the given file exists, its contents are destroyed.
  ;this are the same parameters as for the fopen function in c++
  ;
  ;9 for max compression, 0 for no comression (0 can be good for controlling with an editor what happened).
  ;'f' for filtered data as in "wb6f", 'h' for
  ;Huffman only compression as in "wb1h", Or 'R' For run-length encoding ...
  ;See the description of deflateInit2 in zlib.h  for more information for these parameters
  Debug "fileHdl for write= " + Str(fileHdl)
  zerr=Zgzputc(fileHdl, Asc("H"))
  Debug "err gzputc " + Str(zerr) + " = " + "Asc('H')" + " = " + Str(Asc("H"))
  len=1
  zerr=Zgzputs(fileHdl, @"ello |");returns length of the uncompressed string
  Debug "err gzputs " + Str(zerr)
  len + zerr
  xtmp$=txt$ + Str(i) + " "
  zerr=Zgzwrite(fileHdl, @xtmp$,Len(txt$));returns length of the uncompressed 
  Debug "err gzwrite " + Str(zerr)                     ;string if successfull and a zerror if not
  len + zerr
  Debug "Bytes written: " + Str(len)
  zerr=Zgzclose(fileHdl) 
  Debug ""
  
  ;-read gz
  Debug "- then input"
  ;read the uncompressed length
  ;  must not be done, you can allocate a buffer (don´t even have to be much, in my test it worked 
  ;                                               with 1 Byte for 20 loops of obove gzwrite !?)
  ;  and do a loop until Zgzread(fileHdl,@Buf$,length-1) returns zero
  ;  look at the gz_uncompress function in minigzip.c from the zlib source this 
  ;  demonstrates reading compressed data without knowing the uncompressed length
  If OpenFile(0,TESTFILE$)
    length=Lof(0)
    FileSeek(0,length-4)
    length=ReadLong(0);the length of the uncompressed data is stored in the last 4 bytes
    Debug "length " + Str(length)
    CloseFile(0)
  EndIf
  
  fileHdl = Zgzopen(@TESTFILE$, @"rb");"rb" for read byte, returns the file handle
  Debug "fileHdl for read= " + Str(fileHdl)
  Buf$=Space(length)
  len=Zgzread(fileHdl,@Buf$,length)
  Debug PeekS(@Buf$)
  Debug "Bytes read: " + Str(len);if len < 0 then an error occured
  
  zerr=Zgzclose(fileHdl)
EndProcedure
Gruß
schic
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Hallo vielen Dank für deinen Beitrag.
Ich werde es mir später genauer ansehen, ich sitze zur Zeit ja an diesem Projekt, für das ich gern die Komprimierung hätte.

Für welche Version ist die Lib denn gebaut? Denn ich benutze PB 4.
In der ZIP-Datei sind außerdem 2 Dateien, die bei mir keine Dateiendung haben. Was sind das für welche?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
schic
Beiträge: 68
Registriert: 25.12.2004 19:04

Beitrag von schic »

die obigen Beispiele sind für PB4. Die Lib funktioniert unverändert auch für PB4.
Die Dateien ohne Endung sind die User-Libraies.
Zu kopieren nach PB-Programmpfad\PureLibraries\UserLibraries
m0
Beiträge: 150
Registriert: 12.10.2004 13:55
Wohnort: Immenstadt
Kontaktdaten:

Re: GZIP und/oder Deflate Komprimierung gesucht

Beitrag von m0 »

Hallo zusammen,

der Thread ist nun ja schon einige Tage alt, und ich frage mich, ob es mit der aktuellen Version noch eine Möglichkeit gibt, .gz Archive zu entpacken, ohne den Umweg über the gzip.exe nehmen zu müssen. Die UserLib scheint ja nicht mit x64 Systemen kompatibel zu sein.

Würde mich sehrt freuen, wenn jemand dafür eine Lösung hätte.

Schöne Grüße,
m0
Schaut euch doch http://www.momo-wagner.de mal an ;)

MfG
m0
Antworten