Saturday, January 1, 2011

Inflate in JavaScript

Here's a little something I've been working with for the last few weeks...the Inflate algorithm implemented in JavaScript.

Just what is Inflate? Well, it's the opposite of Deflate. Obviously. In addition, it's also the algorithm used by gzip, WinZip, zlib, etc. to uncompress data. You can read all about it here or read the full RFC. It's been around a long time and has been implemented in lots of different languages, but I really wanted a pure JavaScript version. I'm that crazy.

I needed this because I've been working with the new HTML5 File API. With it, you can process file data in the client browser before uploading it to the server. This is great, until you try to work with a type of file (PNG, for example) that uses the Deflate algorithm to compress its data. I basically converted the simplest possible implementation of the process, Mark Adler's puff.c, to JavaScript and it works pretty well.

I'll have more to say on the HTML5 File API later, but now I release the JavaScript Inflate to the world! Typically, the algorithm works by processing streams of bytes. JavaScript, however, does not have such a data structure. Instead we just use arrays of numbers between 0 and 255 as input and output.

And a word of caution, I wouldn't try running this on a 3-years-out-of-date web browser or some old version of Netscape Navigator you've got running somewhere. It works great in the latest version of Chrome.


UPDATE! Here's a link to a page that you can use to see this thing in action. It uses a little HTML5 File API, which I'll discuss in a later post. I didn't explain much how to use the inflater in my original post so I hope this helps. It is really simple. Once you have your array of "bytes" representing deflated data, just pass it to the puff function along with an empty array you want to get filled up with the inflated "bytes". It will look like this:
var deflated = new Array();
// fill deflated with "bytes"
var inflated = new Array();
puff(inflated, deflated);
Your inflated array will contain the inflated data. It's that easy.