1

I'm looking for a LZW compression algorithm in C# that takes a "string" and returns a string. I've googling for hours and all I've found use MemoryStream, BinaryWriters, etc.

I just want to be able to do something like:

string _data = "12345";

string _result = CompressToLZW(_data);

and then pass that string via Ajax to the browser. I already have the LZW decompression algorithm for javascript (http://rosettacode.org/wiki/LZW_compression#JavaScript)

Thanks.-

UPDATE:

This is the code I'm using right now with http://paste.lisp.org/display/12198

    string _data = "12345_12345_12345_12345";

    byte[] byteArray = Encoding.ASCII.GetBytes(_data);

    MemoryStream _st = new MemoryStream(byteArray);

    StreamReader _sr = new StreamReader(_st);

    MemoryStream streamoutput = new MemoryStream();

    BinaryWriter _output= new BinaryWriter(streamoutput);

    LZW.Compress(_sr, _output);

    string _res = (new StreamReader(_output.BaseStream)).ReadToEnd();

    return _res;

UPDATE 2 I found a source code in C# that does the work at http://code.google.com/p/sharp-lzw/source/browse/ Thanks.-

Nick
  • 727
  • 10
  • 20

3 Answers3

4

Use something like this:

private string CompressToLZW(string input)
{
    using (MemoryStream stream = new MemoryStream())
    {
        ComputeLZW(input, stream);
        stream.Seek(0, SeekOrigin.Begin);
        using (StreamReader reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }
}

where ComputeLZW() is the LZW method you have that uses a stream.

Philipp Schmid
  • 5,778
  • 5
  • 44
  • 66
  • Unfortunatelly "ComputeLZW" does not take a "string" as the first parameter. – Nick Jul 15 '11 at 17:12
  • 1
    The point of my code snippet was to show you how you can use a stream and return the string contained in that stream. In your question you mentioned that you had found some code that used a stream and that instead you wanted to return a string. The ComputeLZW() method in my code snippet is just a stand-in for your real method. – Philipp Schmid Jul 15 '11 at 17:46
2

Given that LZW codes needn't necessarily fall on byte boundaries, simply converting the binary output of LZW compression to a UTF8 string (as with the StreamReader approach) will most likely fail, producing illegal output.

It seems that the Javascript decompress function you refer to actually takes an array of numbers as its input. Probably the most efficient way to convey the binary output to the javascript decompress method would be to base64 encode the binary output, then to base64 decode at the JS end into a number array and to supply this to your method.

This might be of questionable efficiency. Worth testing before deploying.

spender
  • 117,338
  • 33
  • 229
  • 351
  • I have a 90KB string on server side that I need to send back to the browser. I tested this particular string and zipped it by hand, resulting in a 20KB string. Base64 wont give me that kind of compression I think. – Nick Jul 15 '11 at 17:16
0

You can "convert" a string into a MemoryStrem like this:

byte[] byteArray = Encoding.ASCII.GetBytes(youInputString);
MemoryStream stream = new MemoryStream(byteArray);

(make sure you understand which encoding you need).

The other way goes like this:

StreamReader reader = new StreamReader(methodOutputStream);
string text = reader.ReadToEnd();

To use the methods found on http://paste.lisp.org/display/12198, you can first convert your string to a Stream, feed it to the LZW compression methods, receive an output Stream, and convert that stream to a string. The only difference is that the code on the site uses FileStreams.

Olaf
  • 10,049
  • 8
  • 38
  • 54
  • Not working, I have: string _x = "12345"; byte[] byteArray = Encoding.ASCII.GetBytes(_x); MemoryStream _st = new MemoryStream(byteArray); StreamReader _sr = new StreamReader(_st); MemoryStream streamoutput = new MemoryStream(byteArray); BinaryWriter _output= new BinaryWriter(streamoutput); LZW.Compress(_sr, _output); string _res = _output.ToString(); return _res; cant believe is that difficult... need a StreamReader, a MemoryStream and a BinaryWriter, I must be doing something wrong. – Nick Jul 15 '11 at 17:12