trancexx Posted January 10, 2009 Share Posted January 10, 2009 Appears that memory compression is in these days. So, to be in, here is another method. This one is called "Native API Compression".Apparently it's LZ1(LZ77) compression algorithm or something very similar and it's available through one or two dll calls. Of course that files can be compressed too by this method.Functions with small example:expandcollapse popup#NoTrayIcon $sString = "lzwlzwlzwlzwlzwlzwlzwlzwlzwlzwlzwlzw" ConsoleWrite("Before compression: " & Binary($sString) & @CRLF) $BC = _LZNTCompress($sString) ConsoleWrite("Compressed: " & $BC & @CRLF) $CB = _LZNTDecompress($BC) ConsoleWrite("Decompressed: " & $CB & @CRLF) ; #FUNCTION# ;=============================================================================== ; ; Name...........: _LZNTDecompress ; Description ...: Decompresses input data. ; Syntax.........: _LZNTDecompress ($bBinary) ; Parameters ....: $vInput - Binary data to decompress. ; Return values .: Success - Returns decompressed binary data. ; - Sets @error to 0 ; Failure - Returns empty string and sets @error: ; |1 - Error decompressing. ; Author ........: trancexx ; Related .......: _LZNTCompress ; Link ..........; http://msdn.microsoft.com/en-us/library/bb981784.aspx ; ;========================================================================================== Func _LZNTDecompress($bBinary) $bBinary = Binary($bBinary) Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinary) & "]") DllStructSetData($tInput, 1, $bBinary) Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") ; initially oversizing buffer Local $a_Call = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _ "ushort", 2, _ "ptr", DllStructGetPtr($tBuffer), _ "dword", DllStructGetSize($tBuffer), _ "ptr", DllStructGetPtr($tInput), _ "dword", DllStructGetSize($tInput), _ "dword*", 0) If @error Or $a_Call[0] Then Return SetError(1, 0, "") ; error decompressing EndIf Local $tOutput = DllStructCreate("byte[" & $a_Call[6] & "]", DllStructGetPtr($tBuffer)) Return SetError(0, 0, DllStructGetData($tOutput, 1)) EndFunc ;==>_LZNTDecompress ; #FUNCTION# ;=============================================================================== ; ; Name...........: _LZNTCompress ; Description ...: Compresses input data. ; Syntax.........: _LZNTCompress ($vInput [, $iCompressionFormatAndEngine]) ; Parameters ....: $vInput - Data to compress. ; $iCompressionFormatAndEngine - Compression format and engine type. Default is 2 (standard compression). Can be: ; |2 - COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD ; |258 - COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM ; Return values .: Success - Returns compressed binary data. ; - Sets @error to 0 ; Failure - Returns empty string and sets @error: ; |1 - Error determining workspace buffer size. ; |2 - Error compressing. ; Author ........: trancexx ; Related .......: _LZNTDecompress ; Link ..........; http://msdn.microsoft.com/en-us/library/bb981783.aspx ; ;========================================================================================== Func _LZNTCompress($vInput, $iCompressionFormatAndEngine = 2) If Not ($iCompressionFormatAndEngine = 258) Then $iCompressionFormatAndEngine = 2 EndIf Local $bBinary = Binary($vInput) Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinary) & "]") DllStructSetData($tInput, 1, $bBinary) Local $a_Call = DllCall("ntdll.dll", "int", "RtlGetCompressionWorkSpaceSize", _ "ushort", $iCompressionFormatAndEngine, _ "dword*", 0, _ "dword*", 0) If @error Or $a_Call[0] Then Return SetError(1, 0, "") ; error determining workspace buffer size EndIf Local $tWorkSpace = DllStructCreate("byte[" & $a_Call[2] & "]") ; workspace is needed for compression Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") ; initially oversizing buffer Local $a_Call = DllCall("ntdll.dll", "int", "RtlCompressBuffer", _ "ushort", $iCompressionFormatAndEngine, _ "ptr", DllStructGetPtr($tInput), _ "dword", DllStructGetSize($tInput), _ "ptr", DllStructGetPtr($tBuffer), _ "dword", DllStructGetSize($tBuffer), _ "dword", 4096, _ "dword*", 0, _ "ptr", DllStructGetPtr($tWorkSpace)) If @error Or $a_Call[0] Then Return SetError(2, 0, "") ; error compressing EndIf Local $tOutput = DllStructCreate("byte[" & $a_Call[7] & "]", DllStructGetPtr($tBuffer)) Return SetError(0, 0, DllStructGetData($tOutput, 1)) EndFunc ;==>_LZNTCompressAvailable in Microsoft Windows XP and later versions of all Windows operating systems.There is $tBuffer there if you look. I'm oversizing it plenty initially (saw this bad example in c++). Probably should be some better way to do that but documentation for this functions on MSDN is not over yet apparently Two compression rates are available. Default COMPRESSION_ENGINE_STANDARD is lightening speedy. Better compression is gained by COMPRESSION_ENGINE_MAXIMUM which is slower. mLipok, Colduction and Celtic88 2 1 ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
smashly Posted January 10, 2009 Share Posted January 10, 2009 (edited) Thank You for sharing and nice work trancexx, I just tried it on a 12KB script as standard and the output file is 6KB.. 50% compression of my script... nice Set compression as max and I get 5KB filesize. The compression isn't as high as 3rd party programs, but since it's using the native windows to do it's thing I love the idea. I'm off to play with it bit more Cheers Edited January 10, 2009 by smashly Link to comment Share on other sites More sharing options...
trancexx Posted April 30, 2009 Author Share Posted April 30, 2009 Thank You for sharing and nice work trancexx,I just tried it on a 12KB script as standard and the output file is 6KB..50% compression of my script... niceSet compression as max and I get 5KB filesize.The compression isn't as high as 3rd party programs, but since it's using the native windows to do it's thing I love the idea.I'm off to play with it bit more CheersOk, enough playing with it! You're gonna break something. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
Splash Posted June 9, 2009 Share Posted June 9, 2009 Thanks! =D Automatic Update UDF - IP Address UDF - WinPcap AutoIt _FindDevice()[font="Verdana"][size="2"]AutoIt Spanish/Brasil/World community!!![/size][/font]Use you wanna a dot.tk domain please use my link: Link to comment Share on other sites More sharing options...
knightz Posted April 2, 2010 Share Posted April 2, 2010 thank you this script is very useful Link to comment Share on other sites More sharing options...
netegg Posted March 8, 2011 Share Posted March 8, 2011 so sad, would you like to explain how to use it? Why i can't get the result as above? Link to comment Share on other sites More sharing options...
trancexx Posted March 9, 2011 Author Share Posted March 9, 2011 (edited) It's very hard to explain.You just do. Understanding internal workings might help; 150 sentences about the working. Edited March 9, 2011 by trancexx ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
AdmiralAlkex Posted March 10, 2011 Share Posted March 10, 2011 This UDF is great. I use it for the "CompressPlaylist"-option in ShiftER, end result is around a third/sixth that of the non-compressed file. Thank you trancexx .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now