LZW compression methods in AS2

Actionscript

[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!

Download LZW.as here.

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.

This entry was posted on Sunday, August 22nd, 2004 at 10:07 pm and is filed under Actionscript. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

20 Responses to “LZW compression methods in AS2”

  1. JEAN Says:

    very good

  2. Eros Nicolau Says:

    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… ;)

  3. adadi091 Says:

    http://www.ensogroup.com.au/grant/pack64float.zip

  4. me Says:

    i like this, but i need php decompression!

  5. Rich Dougherty Says:

    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.

  6. cakeWho Says:

    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;
    }

  7. Ilya Burkaltsev Says:

    If LZW commpression die? What algo you can use?

  8. Jeffry Houser Says:

    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!

  9. Kent Xu Says:

    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.

  10. hassaan Says:

    I need a general work flow of LZW compression algo can any body help me in this regard…

  11. hassaan Says:

    No one replied yet have any body information regarding my problem:roll:

  12. CauĂȘ Says:

    Man… I LOVE YOU.. Ahuahuhau…
    TNKSSSS!!!!!!!! TNKS!!!!!!!!!!!!!!!!!
    Easy to use and powerfull!!!!
    Tnks!

  13. Element Says:

    Do you have decompress function on PHP?
    Thx~ :cry:

  14. Amit Says:

    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

  15. Eros Says:

    Hi man,
    We could really use a decompression algorithm for PHP, able to decompress a string compressed with your AS class…

  16. billy Says:

    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;
    }

  17. Ash Says:

    Excellent! Thanks Billy.

  18. axaq Says:

    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

  19. venkateshwarlu Says:

    :roll: yeh this is great example for compression and uncompress of data
    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

  20. Yehia Says:

    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

Leave a Reply