LZW compression methods in AS2
[Update: Some readers have come up with decompress solutions for C# and PHP in the comments below. Thanks cakeWho and billy]
In a recent project, one of the requirements was that a lot of text-based data be passed between client and server.. it would be handy if there was a way to compress this data to speed up transfers. One or two quick web searches later led me to the following URLs:
shoe-box.org weblog
and
lalex.com weblog.
Unfortunately the class didn’t want to play ball when exporting to flash player 6 because fp6 doesn’t handle case-sensitive variables. Also there appeared to be a bug where repeated characters didn’t decompress correctly. So I decided to modify the class to fix these issues, and also provide a compressed string that was safe to pass within an xml document (ie. it shouldn’t contain certain characters like < ,> etc.).
I have posted a link to the class below, please feel free to use it if you so wish, as long as you check out the blogs above.. credit lies with them!
If anyone has any suggestions for optimizing the class, please don’t hesitate to post. You could make a static copy of the base dictionary for example, so it isn’t rebuilt every time.

very good
All nice an dandy, mate… but how about a server-side solution (let’s say in PHP) to de-compress all that data… There is a kinda solution here, but it works on other algorythms, not on yours, unfortunately… Do you happen to have/know a working compressor/decompressor in php? (by any chance…
http://www.ensogroup.com.au/grant/pack64float.zip
i like this, but i need php decompression!
Also check out an article discussing the LZ77 algorithm for Java and ActionScript at the Flash Game Programming Wiki. The example compresses XML, but it could easily be applied to other types of data.
Thanks alot for the article!
Here’s a conversion of the decompress function that I made on the .NET 2.0 platform (C# )
take care!
private string decompress(string str)
{
string[] dico = new string[100000];
int skipnum = 0;
for (int i = 0; i < 256; i++)
{
string c = char.ConvertFromUtf32(i);
dico[i] = c;
}
string txt2encode = str;
string splitStr = txt2encode;
int length = splitStr.Length;
int nbChar = 256 + skipnum;
string buffer = “”;
string chaine = “”;
String result = “”;
string current = “”;
int code = 0;
string undefined = dico[nbChar];
code = char.ConvertToUtf32(txt2encode[0].ToString(), 0);
current = dico[code];
buffer = current.ToString();
result += current;
for (int i = 0; i < length; i++)
{
code = char.ConvertToUtf32(txt2encode[i].ToString(), 0);
current = dico[code];
if (code <= 255 + skipnum)
{
result += current;
chaine = buffer + current;
dico[nbChar] = chaine;
nbChar++;
buffer = current;
}
else
{
if (dico[code] == undefined)
{
chaine = buffer + buffer[0].ToString();
result += chaine;
dico[nbChar] = buffer + chaine[0].ToString();
}
else
{
chaine = dico[code];
result += chaine;
dico[nbChar] = buffer + chaine[0].ToString();
}
nbChar++;
buffer = chaine;
}
}
return result;
}
If LZW commpression die? What algo you can use?
I just did an ActionScript 3 port of this code, for those interested. It can be downloaded as part of the ASCrypt3 project at http://ascrypt3.riaforge.org/ .
Thanks for the code!
I want to point out there is a bug in the original code. It only happens when certain text is fed in and contains word pattern “sort”, such as resort. The root of the problem is the declaration of “new Array();” as the code hash table. If LZW calculates a string which happens to match one of Array’s internal property/method name , it will not return as “undefined”, thus generate wrong compression code. Declare it as Object instead.
I need a general work flow of LZW compression algo can any body help me in this regard…
No one replied yet have any body information regarding my problem:roll:
Man… I LOVE YOU.. Ahuahuhau…
TNKSSSS!!!!!!!! TNKS!!!!!!!!!!!!!!!!!
Easy to use and powerfull!!!!
Tnks!
Do you have decompress function on PHP?
Thx~
Hi,
I have a problem. I have compressed data in AS2 at client side and compressed in using LZW(Flash) and send it to server, but when we decompress over server using java decompression (mentioned at - Server-side (Java) decompression
http://www.geocities.com/yccheok/lzw/lzw.html), it doesnt decompress properly.
If i compress and decompress in same environment(Flash to Flash or Java to Java ) then it is going ok.
Any help is appreciated.
~Amit
Hi man,
We could really use a decompression algorithm for PHP, able to decompress a string compressed with your AS class…
This is pretty much a literal translation into php and works for me.
You may need some extra libraries (for mb_* calls)
Here are the tricky parts to porting to PHP:
1. ord/chr in php don’t handle unicode (I’ve included two functions thanks to the community on php.net)
2. after preg_splitting with //g (to split unicode), there is a blank item in the beginning and end of the array (which i pop and shift off)
3. I give this code without any warranty of its validity — check everything before you use in production
function encode_lzw($str)
{
$dico = array();
for ($i = 0; $i < 256; $i++)
{
$dico[unichr($i)] = $i;
}
$res = “”;
$len = strlen($str);
$nbChar = 256;
$buffer = “”;
for ($i = 0; $i <= $len; $i++)
{
$current = $str[$i];
if ($i < strlen($str) && $dico[$buffer . $current] !== null)
{
$buffer .= $current;
}
else
{
$res .= unichr($dico[$buffer]);
$dico[$buffer . $current] = $nbChar;
$nbChar++;
$buffer = $current;
}
}
return $res;
}
function decode_lzw($str)
{
$dico = array();
for ($i = 0; $i < 256; $i++)
{
$c = unichr($i);
$dico[$i] = $c;
}
$nbChar = 256;
$buffer = “”;
$chaine = “”;
$result = “”;
$strSplit = preg_split(’//u’, $str);
array_pop($strSplit);
array_shift($strSplit);
$length = count($strSplit);
for ($i = 0; $i < $length; $i++)
{
$code = uniord($strSplit[$i]);
$current = $dico[$code];
if ($buffer == “”)
{
$buffer = $current;
$result .= $current;
}
else
{
if ($code <= 255)
{
$result .= $current;
$chaine = $buffer . $current;
$dico[$nbChar] = $chaine;
$nbChar++;
$buffer = $current;
}
else
{
$chaine = $dico[$code];
if ($chaine == “”) $chaine = $buffer . $buffer[0];
$result .= $chaine;
$dico[$nbChar] = $buffer . $chaine[0];
$nbChar++;
$buffer = $chaine;
}
}
}
return $result;
}
function unichr($u)
{
$str = html_entity_decode(’&#’.$u.’;',ENT_NOQUOTES,’UTF-8′);
return $str;
}
function uniord($u) {
$k = mb_convert_encoding($u, ‘UCS-2LE’, ‘UTF-8′);
$k1 = ord(substr($k, 0, 1));
$k2 = ord(substr($k, 1, 1));
return $k2 * 256 + $k1;
}
Excellent! Thanks Billy.
Hi,
I have used the code you have modified on FP9 and I get the slow down error when tried to compress a bitmap image data.
I have the hexadecimal data of a bitmap image and I want to compress this data. Can you help me about this? Is there any thing to optimize the compressor?
thanks
using LZW algorithm iwant the C#.net implementation of the LZW algorithm so that i can compress in flex and un compress in c#
and again compress in c# an un compress in Flex
People PLEASE, I am suffering here, any of the above php code doesn’t decode correctly. is that relevant to code page or what that is different on the server than my client ? the character codes are the root of evil. the numbers i get for the same string on AS2 is different than Php. my solution has to be AS2 based.
Please email me back
yehia.shouman@gmail.com