AutoHotkey Community

It is currently May 27th, 2012, 6:27 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: zlib
PostPosted: February 5th, 2011, 8:35 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
Wrapper for zlib1.dll available from http://www.zlib.net (100K), inspired by this ask for help question.
Quote:
zlib is designed to be a free, general-purpose, legally unencumbered -- that is, not covered by any patents -- lossless data-compression library for use on virtually any computer hardware and operating system. The zlib data format is itself portable across platforms.
zlib was written by Jean-loup Gailly (compression) and Mark Adler (decompression). Jean-loup is also the primary author/maintainer of gzip(1), the author of the comp.compression FAQ list and the former maintainer of Info-ZIP's Zip; Mark is also the author of gzip's and UnZip's main decompression routines and was the original author of Zip. Not surprisingly, the compression algorithm used in zlib is essentially the same as that in gzip and Zip, namely, the `deflate' method that originated in PKWARE's PKZIP 2.x.


Requirements: AHK_L Unicode (Ansi will require minor modifications)

I have wrapped only the Utility and GZip compress/decompress functions.

Functions:
Code:
zlib_Compress(Byref Compressed, Byref Data, DataLen, level = -1) {
nSize := DllCall("zlib1\compressBound", "UInt", DataLen, "Cdecl")
VarSetCapacity(Compressed,nSize)
ErrorLevel := DllCall("zlib1\compress2", "ptr", &Compressed, "UIntP", nSize, "ptr", &Data, "UInt", DataLen, "Int"
               , level    ;level 0 (no compression), 1 (best speed) - 9 (best compression)
               , "Cdecl") ;0 means Z_OK
return ErrorLevel ? 0 : nSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

zlib_Decompress(Byref Decompressed, Byref CompressedData, DataLen, OriginalSize = -1) {
OriginalSize := (OriginalSize > 0) ? OriginalSize : DataLen*10 ;should be large enough for most cases
VarSetCapacity(Decompressed,OriginalSize)
ErrorLevel := DllCall("zlib1\uncompress", "Ptr", &Decompressed, "UIntP", OriginalSize, "Ptr", &CompressedData, "UInt", DataLen)
return ErrorLevel ? 0 : OriginalSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

gz_compress(infilename, outfilename)
{
VarSetCapacity(sOutFileName, 260)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", outfilename, "int", -1, "str", sOutFileName, "int", 260, "Uint", 0, "Uint", 0)
infile := FileOpen(infilename, "r"), outfile := DllCall("zlib1\gzopen", "Str" , sOutFileName , "Str", "wb", "Cdecl")
if (!infile || !outfile)
   return 0
nBufferLen := 8192 ; can be increased if gzbuffer function is called beforehand
VarSetCapacity(inbuffer,nBufferLen)
while ((num_read := infile.RawRead(inbuffer, nBufferLen)) > 0)
   DllCall("zlib1\gzwrite", "UPtr", outfile, "UPtr", &inbuffer, "UInt", num_read, "Cdecl")
infile.Close()
DllCall("zlib1\gzclose", "UPtr", outfile, "Cdecl")
return 1
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

gz_decompress(infilename, outfilename)
{
VarSetCapacity(sInFileName, 260)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", infilename, "int", -1, "str", sInFileName, "int", 260, "Uint", 0, "Uint", 0)
infile := DllCall("zlib1\gzopen", "Str" , sInFileName , "Str", "rb", "Cdecl"), outfile := FileOpen(outfilename, "w")
if (!infile || !outfile)
   return 0
VarSetCapacity(buffer,8192) ;can be increased after calling gzbuffer beforehand
num_read = 0
while ((num_read := DllCall("zlib1\gzread", "UPtr", infile, "UPtr", &buffer, "UInt", 8192, "Cdecl")) > 0)
   outfile.RawWrite(buffer, num_read)
DllCall("zlib1\gzclose", "UPtr", infile, "Cdecl")
infile.Close()
return 1
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

/*
Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events.
#define Z_OK            0
#define Z_STREAM_END    1
#define Z_NEED_DICT     2
#define Z_ERRNO        (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR   (-3)
#define Z_MEM_ERROR    (-4)
#define Z_BUF_ERROR    (-5)
#define Z_VERSION_ERROR (-6)

Compression levels.
#define Z_NO_COMPRESSION         0
#define Z_BEST_SPEED             1
#define Z_BEST_COMPRESSION       9
#define Z_DEFAULT_COMPRESSION  (-1)
*/


Example:
Code:
; DATA COMPRESSION
infile := FileOpen(A_ScriptFullPath, "r")
len := infile.length
infile.RawRead(MyData,len)
if (r := zlib_Compress(CompressedData , MyData, len))
 MsgBox % "Data compressed " . round((r/len)*100) . "%"
else MsgBox Error Errorlevel %Errorlevel%
infile.Close()

; DATA DECOMPRESSION
if (t := zlib_Decompress(Inflated,CompressedData,r,len))
 MsgBox % StrGet(&Inflated,len,"")
else MsgBox Error Errorlevel %Errorlevel%

;COMPRESS TO GZIP FILE
gz_compress(A_AhkPath,A_ScriptDir . "\test.gz")
;DECOMPRESS GZIP FILE
gz_decompress(A_ScriptDir . "\test.gz", A_ScriptDir . "\extracted.exe")




zlib_Compress(Byref Compressed, Byref Data, DataLen, level = -1) {
nSize := DllCall("zlib1\compressBound", "UInt", DataLen, "Cdecl")
VarSetCapacity(Compressed,nSize)
ErrorLevel := DllCall("zlib1\compress2", "ptr", &Compressed, "UIntP", nSize, "ptr", &Data, "UInt", DataLen, "Int"
               , level    ;level 0 (no compression), 1 (best speed) - 9 (best compression)
               , "Cdecl") ;0 means Z_OK
return ErrorLevel ? 0 : nSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

zlib_Decompress(Byref Decompressed, Byref CompressedData, DataLen, OriginalSize = -1) {
OriginalSize := (OriginalSize > 0) ? OriginalSize : DataLen*10 ;should be large enough for most cases
VarSetCapacity(Decompressed,OriginalSize)
ErrorLevel := DllCall("zlib1\uncompress", "Ptr", &Decompressed, "UIntP", OriginalSize, "Ptr", &CompressedData, "UInt", DataLen)
return ErrorLevel ? 0 : OriginalSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

gz_compress(infilename, outfilename)
{
VarSetCapacity(sOutFileName, 260)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", outfilename, "int", -1, "str", sOutFileName, "int", 260, "Uint", 0, "Uint", 0)
infile := FileOpen(infilename, "r"), outfile := DllCall("zlib1\gzopen", "Str" , sOutFileName , "Str", "wb", "Cdecl")
if (!infile || !outfile)
   return 0
nBufferLen := 8192 ; can be increased if gzbuffer function is called beforehand
VarSetCapacity(inbuffer,nBufferLen)
while ((num_read := infile.RawRead(inbuffer, nBufferLen)) > 0)
   DllCall("zlib1\gzwrite", "UPtr", outfile, "UPtr", &inbuffer, "UInt", num_read, "Cdecl")
infile.Close()
DllCall("zlib1\gzclose", "UPtr", outfile, "Cdecl")
return 1
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

gz_decompress(infilename, outfilename)
{
VarSetCapacity(sInFileName, 260)
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", infilename, "int", -1, "str", sInFileName, "int", 260, "Uint", 0, "Uint", 0)
infile := DllCall("zlib1\gzopen", "Str" , sInFileName , "Str", "rb", "Cdecl"), outfile := FileOpen(outfilename, "w")
if (!infile || !outfile)
   return 0
VarSetCapacity(buffer,8192) ;can be increased after calling gzbuffer beforehand
num_read = 0
while ((num_read := DllCall("zlib1\gzread", "UPtr", infile, "UPtr", &buffer, "UInt", 8192, "Cdecl")) > 0)
   outfile.RawWrite(buffer, num_read)
DllCall("zlib1\gzclose", "UPtr", infile, "Cdecl")
infile.Close()
return 1
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

/*
Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events.
#define Z_OK            0
#define Z_STREAM_END    1
#define Z_NEED_DICT     2
#define Z_ERRNO        (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR   (-3)
#define Z_MEM_ERROR    (-4)
#define Z_BUF_ERROR    (-5)
#define Z_VERSION_ERROR (-6)

Compression levels.
#define Z_NO_COMPRESSION         0
#define Z_BEST_SPEED             1
#define Z_BEST_COMPRESSION       9
#define Z_DEFAULT_COMPRESSION  (-1)
*/


Reference: http://www.zlib.net/manual.html

_________________
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 7th, 2011, 12:36 pm 
Offline

Joined: July 15th, 2005, 3:19 pm
Posts: 140
Location: Denmark
Hi,

Thank you for creating sharing. I am trying to test this on Autohotkey (not Autohotkey_L). I am, however, not getting any sensible results out of the following code:
Code:
zlib_Compress(Byref Compressed, Byref Data, DataLen, level = -1) {
nSize := DllCall("zlib1\compressBound", "UInt", DataLen, "Cdecl")
VarSetCapacity(Compressed,nSize)
ErrorLevel := DllCall("zlib1\compress2", "ptr", &Compressed, "UIntP", nSize, "ptr", &Data, "UInt", DataLen, "Int"
               , level    ;level 0 (no compression), 1 (best speed) - 9 (best compression)
               , "Cdecl") ;0 means Z_OK

return ErrorLevel ? 0 : nSize
} ;http://www.autohotkey.com/forum/viewtopic.php?t=68170

egg := "Eggers"
output := ""
error := zlib_Compress(output, egg, 100, 9)
msgbox, -%output%- -%error%-


The output is:
-- -113-

I just have nothing to work with, as the output is simply empty, but there is no error. zlib1.dll is placed in the same directory.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 7th, 2011, 1:00 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
David Andersen wrote:
I am trying to test this on Autohotkey (not Autohotkey_L)


The "Ptr" type is not supported in Autohotkey basic, use "UInt" instead in the DllCall

Also note that the output is binary data. You cannot show binary data with MsgBox (as it is not a string).
You can save it to a file or a variable, and read it from file or variable and decompress the data. File standard library may be useful to you.

If you just want to deal with files, use any of my other archiving functions on this forum.

_________________
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 7th, 2011, 2:01 pm 
Offline

Joined: July 15th, 2005, 3:19 pm
Posts: 140
Location: Denmark
Hi shajul,

Thank you for your fast reply. I am too stupid to make it work with UInt, just replacing the Ptr with UInt did not do the trick. Since the output is binary data, I am also not sure whether this would be the right way to achieve what I want, which is to compress text and store it into a text file. I have found some code, which seems to be able to convert binary data into text data, but then the whole purpose might be lost, as it then might become longer than it was in the first place. What I want to store is XML data, which should have nice compression rates.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 7th, 2011, 4:58 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
If you want to compress xml files, then you can use 7zip library, which is the best compression and relatively good speed.

If you want to store data, you may use this library, but it'll be best if saved in a binary data file.

_________________
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 17th, 2011, 8:58 am 
Offline

Joined: November 14th, 2008, 1:45 am
Posts: 80
Location: USA
Thank you very much for these functions shajul :) . The zlib_Compress, zlib_Compress2, and zlib_Decompress functions were no problem to convert to AHK Basic (non-unicode), and I have been using them over the past year. Because I am completely unfamiliar with AHK_L syntax or the differences between using Unicode strings, I am having trouble converting your gz_compress and gz_decompress to AHK Basic w/ Ansi. Would you (or anyone else who is more familiar with porting AHK_L to AHK Basic) mind doing it for me?

Thank you very much,
-Sam.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 17th, 2011, 11:52 am 
this conversion is not required
Code:
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", outfilename, "int", -1, "str", sOutFileName, "int", 260, "Uint", 0, "Uint", 0)

also some changes to the types in dllcall and you should be good!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: December 17th, 2011, 6:08 pm 
Offline

Joined: November 14th, 2008, 1:45 am
Posts: 80
Location: USA
Anonymous wrote:
this conversion is not required
Code:
DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", outfilename, "int", -1, "str", sOutFileName, "int", 260, "Uint", 0, "Uint", 0)

also some changes to the types in dllcall and you should be good!

I don't recognize the "." syntax in:
Code:
infile.RawRead(inbuffer, nBufferLen)
outfile.RawWrite(buffer, num_read)

I think it was added in AHK_L. I think these could be replaced by Laszlo's BinRead() and BinWrite() functions, but I think if you use them you no longer need to open and close the handle to the file with:
Code:
infile := FileOpen(infilename, "r")
infile.Close()

but then you no longer have infile to compare here:
Code:
if (!infile || !outfile)
   return 0

But I haven't been able to get them to work. So... My confusion is apparent :( .

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Apollo, Bing [Bot], rbrtryn, Stigg, Yahoo [Bot] and 25 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group