About Monkey 2 › Forums › Monkey 2 Programming Help › Compress/Decompress data buffers
This topic contains 11 replies, has 5 voices, and was last updated by 
 Mark Sibly
 10 months, 3 weeks ago.
- 
		AuthorPosts
 - 
		
			
				
April 18, 2018 at 3:03 pm #14398
Is it possible to compress/decompress data from/into a data buffer?
I would like to do something like that:
Monkey123456789Local originalData := New DataBuffer(256)For Local i := 0 Until 256originalData.PokeUByte(i, i)NextLocal compressedData:DataBuffer = Compress(originalData)Local decompressedData:DataBuffer = Decompress(compressedData)April 19, 2018 at 3:55 pm #14417There is the miniz module.
And example of its usage here:
https://github.com/blitz-research/monkey2/blob/develop/modules/std/misc/zipfile.monkey2
April 20, 2018 at 6:03 am #14419It’s probably time I added a zlib module – will do this soon so stay tuned for compress/decompress data buffer methods.
April 21, 2018 at 12:17 am #14430New zlib module and data buffer compress/decompress methods have been pushed to develop branch.
April 22, 2018 at 3:32 pm #14465Wow – that was fast!
I already tried it and it works like a charm:
Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243#Import "<std>"#Import "<zlib>"Function Main:Void()' generate some random dataLocal originalData := New std.memory.DataBuffer(8000)For Local i:UInt = 0 Until originalData.LengthoriginalData.PokeUByte(i, std.random.Rnd(5))End' get max compressed length (this can be more than original data size)Local maxCompressedLen := zlib.compressBound(originalData.Length)' create buffer for compressed dataLocal compressedData:std.memory.DataBuffer = New std.memory.DataBuffer(maxCompressedLen)' compress dataLocal compressedLen:ULong = maxCompressedLenIf zlib.compress( compressedData.Data,Cast<zlib.z_uLong Ptr>(Varptr(compressedLen)),originalData.Data,originalData.Length ) <> zlib.Z_OK ThenPrint( "Compressing: Something went wrong!" )ReturnEndPrint("Compressed data length: "+compressedLen+" Byte")' create buffer for uncompressed dataLocal uncompressedData := New std.memory.DataBuffer(originalData.Length)' uncompress dataLocal uncompressedLen:ULong = originalData.LengthIf zlib.uncompress(uncompressedData.Data,Cast<zlib.z_uLong Ptr>(Varptr(uncompressedLen)),compressedData.Data,compressedData.Length) <> zlib.Z_OK ThenPrint("Uncompressing: Something went wrong")ReturnEnd' success!Print("Uncompressed all data successfully!")EndMay 28, 2018 at 4:03 pm #14713Is there anyway yet to load an image straight from a zip file without the need to extract it to disk first?
May 29, 2018 at 5:24 am #14714See below for one possible solution. It loads a jpg image directly from a zip file.
It’s not very nice though, a simple ‘zip::’ stream would be sexier, or even some way to pass a DataStream to Image.Load. Will look into this…
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253Namespace myapp#Import "<std>"#Import "<mojo>"#Import "yasuko.zip"Using std..Using mojo..Class MyWindow Extends WindowField image:ImageMethod New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )Super.New( title,width,height,flags )Local zip:=ZipFile.Open( "asset::yasuko.zip" )For Local file:=Eachin zip.FilesPrint fileNextLocal data:=zip.ExtractData( "yasuko.jpg" )Local path:="memory::("+ULong( data.Data )+","+data.Length+")"image=Image.Load( path )zip.Close()EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()canvas.DrawImage( image,0,0 )canvas.DrawText( "Hello World!",Width/2,Height/2,.5,.5 )EndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndMay 29, 2018 at 10:58 am #14718zip::stream sounds awesome if you can add that
Thanks for the example, didn’t know about memory:: looks like something I could use in the meantime.
It was really cool in Blitzmax the way you could pass either a string or object to the image loader and it would handle it, so would be a nice feature to have. I’m looking to update TimelineFX to be able to load .eff files (basically zip files) rather then the need to unpack them first.
May 30, 2018 at 12:19 am #14721Ok, haven’t done zip:: stream yet but you can now use Stream.SharedPath to get a unique path to an already open stream. This means the zipfile stuff is a lot nicer:
Monkey1234567Local zip:=ZipFile.Open( "asset::yasuko.zip" )Local data:=zip.ExtractData( "yasuko.jpg" )Local stream:=New DataStream( data )image=image.Load( stream.SharedPath )stream.Close()zip.Close()May 30, 2018 at 9:24 am #14723That’s great Mark, thanks.
So if I wanted to save a zip would I compress stuff to a data buffer as above and then save the databuffer to disk, would that work?
May 30, 2018 at 8:05 pm #14724I’m looking to update TimelineFX to be able to load .eff files (basically zip files) rather then the need to unpack them first.
That would be awesome, because the editor does not export unzipped, and it is a bit of a hazzle, when you are finetuning effects.
PS: When you update, please make it work with tinyxml2 out of the box, just a tlXmlElement will do it if you don’t wan’t to use tinyxml2.
May 30, 2018 at 8:56 pm #14725So if I wanted to save a zip
More functionality will need to be added to the ZipFile class before this can (easily) be done.
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.