AS3 port of JZLib

Monday, June 8th, 2009

Last month I was working on a project that used FZip to decompress some zip files in flash.

One tricky thing about FZip is that when running in Flash Player it requires your zip files to have an adler32 checksum for each file in order to work. This is normally fixed with a work around python script provided with FZip.

The python script is easy and all, but why not figure out how to do it in pure AS3 with more standard zip files?

The checksum is needed because AS3’s ByteArray only supports ZLib when running in Flash Player. In AIR it supports deflate which is what zip files use by default. I would be really curious to hear from Adobe why they chose not to support deflate since you need deflate for Zlib to work anyway.

I decided to implement inflate in as3 but I didn’t want to do it with new code so I looked for FOSS projects to port. JZlib was a good choice because Java is similar to AS3 and it didn’t rely on any external system calls.

This port supports everything in JZlib so you can use it for any inflate or deflate operations you might need.

To use with FZip

I used this library in FZip so it no longer requires that zip files be converted before use. It is tested to be working with the OSX cli zip command. It doesn’t work with OSX finder zip compression because of another issue.

In FZipFile.as:

span style="color: #808080; font-style: italic;">// Adobe Air supports inflate decompression.
			// If we got here, this is an Air application
			// and we can decompress without using the Adler32 hack
			// so we just write out the raw deflate compressed file
// Add zlib header
			// CMF (compression method and info)
// FLG (compression level, preset dict, checkbits)
// Add raw deflate-compressed file
// Add adler32 checksum
//throw new Error("Adler32 checksum not found.");
"Compression method "" is not supported.""deflate""decompress success:""stream error:"" ""data error:"" "//} else {
				//	System.println("status:" + this.filename + " " + err);
 

*** UPDATE 2/9/2010: Thanks to Kathrin Furtlehner for sending me a test case for a bug where it wasn’t extracting the full file when dealing with longer strings. I updated the patched FZip archive to reflect the fix.

Converting binary to signed decimal in Actionscript

Wednesday, April 8th, 2009

If you’re like me, you may have been living these past few years taking advantage of the luxury of new sleek programming languages that rarely require you to do low level operations. One of the old skills I seem to always let get rusty enough is bitwise operation. Most code written with the help of frameworks doesn’t require this type of code and most programmers probably don’t even bother to learn it anymore.

I came into an instance yesterday where I needed to do some bitwise work in actionscript. The code was reading a bytestream from a binary file and converting to an array of numbers. Since this project was ported from Java (by someone else), a simple operation was overlooked. It was taking the binary number and converting it to a signed short. Since actionscript doesn’t have the same casting mechanisms conversion isn’t as straight forward in java.

In java the operation looked like this:

//  binary: 1111 1111 1111 0001
// value = -15 

Since short in java is always stored with a signed bit, the cast appropriately set the value at -15.

The way this was translated into Actionscript looked liked this:

//  binary: 1111 1111 1111 0001
// value = 65521  // Wrong! 

Actionscript has no concept of casting for primitives so the int(hexValue) doesn’t do anything at all.

Here is the workaround I came up with, I suspect there is a shorter way to get the same result but I can’t think of one right now.

//  binary: 1111 1111 1111 0001
// get everything except the signed bit "111 1111 1111 0001"
// unsignedValue now equals 32,753
// if the signed flag is set, flip the value
// 0x800 =  32,768 (maximum 15 bit number)
}
 
// signedValue = -15