Click here to Skip to main content
15,861,366 members
Articles / Programming Languages / Visual Basic
Article

Implementation of LZW Compression and Decompression in VB.NET

Rate me:
Please Sign up or sign in to vote.
4.57/5 (10 votes)
24 Aug 20062 min read 95.2K   2.3K   46   14
Implementation of Mark Nelson's LZW algorithms in VB.NET.

Introduction

Why a VB.NET implementation of LZW compression?

I am working with a team of VB.NET developers on a large project, and it is best for us to have all of the components in native VB to simplify maintainence and upgrades. I also thought this might be a good introduction to LZW for people who don't know C.

Credit where Credit is Due

The source code is a nearly direct port of the LZW implementation by Mark Nelson on his web site on C. I even retained many of his comments. Be sure to look at his code here and view his C implementation here.

His original article was published in the October, 1989 issue of Dr. Dobb's Journal, which implies that Mark is very likely at least as ancient as I am.

Demo Code

Running the Code

Start a new Windows Forms project in VB.NET. Add clsLZW.vb to the project. Draw a button in the center of the main form, view the form's code, and paste the following code just above the form's End Class statement:

VB
Private Sub Button1_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) _
            Handles Button1.Click
    ' test the LZW program:
    ' Place a bunch of files in c:\testdir
    ' Create c:\testdir\lzw and c:\testdir\postlzw
    ' Run this program
    ' test it with a command file such as:
    ' c:
    ' cd \testdir
    ' for %%1 in (*.*) do fc /b %%1 
    '       postlzw\%%1 >> results.txt

    Button1.Enabled = False          
    Dim di As New IO.DirectoryInfo("c:\testdir")
    For Each fi As IO.FileInfo In di.GetFiles
        ' print filename
        Dim g As Graphics = Me.CreateGraphics
        g.FillRectangle(New SolidBrush(Me.BackColor), _
                        0, 0, Me.Width, 100)
        g.DrawString(fi.Name, Me.Font, Brushes.Black, 0, 0)
        g.Dispose()

        ' compress...
        Dim lzw1 As New clsLZW
        lzw1.brInput = _
          New IO.BinaryReader(IO.File.Open(fi.FullName, _
          IO.FileMode.Open))
        lzw1.bwOutput = _
             New IO.BinaryWriter(IO.File.Open("c:\testdir\lzw\" & _
             fi.Name & ".lzw14", _
             IO.FileMode.OpenOrCreate, IO.FileAccess.Write))
        lzw1.compress()
        lzw1.brInput.Close()
        lzw1.bwOutput.Close()

        ' decompress
        Dim lzw2 As New clsLZW
        lzw2.brInput = _
             New IO.BinaryReader(IO.File.Open("c:\testdir\lzw\" _
             & fi.Name & ".lzw14", IO.FileMode.Open))
        lzw2.bwOutput = _
             New IO.BinaryWriter(IO.File.Open("c:\testdir\postlzw\" _ 
             & fi.Name, IO.FileMode.OpenOrCreate, _
             IO.FileAccess.Write))
        lzw2.expand()
        lzw2.brInput.Close()
        lzw2.bwOutput.Close()
    Next
    Button1.Enabled = True
End Sub

Testing the Results

To test, create the file structure specified by the comments in the above Sub. You should choose a variety of files.

The batch command 'For %%1...' uses the FileCompare utility (fc) to verify that the uncompressed files match the originals.

If you choose to run it outside of the batch or command file, and at a command prompt, change the three %% to % so it will work.

For %1 in (*.*) do fc /b %1 postlzw\%1 >> results.txt        

Usage

Refer to the sample code for usage. I have not tested multiple compressions per instantiation of the class, so it is best to create a new instance for each compression or decompression that you wish to complete.

I had to use this to build a multi-file archive, so the calling program maintains control of the streams. Multiple files can be written to the same stream without closing it, however, the input stream is exausted until the end of the file is reached. This can be changed with minor modifications to prevent the need to write temporary files.

Best wishes and good luck with your VB coding!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Alan Budelier is a happy Catholic working for IT in Major Fraternal Life Insurnance Company in Rock Island, IL, who, like Christ, would someday like to compile and run without any need for exception handling.

Comments and Discussions

 
GeneralMy vote of 3 Pin
Member 1275639330-Nov-16 7:41
Member 1275639330-Nov-16 7:41 
GeneralMy vote of 5 Pin
revive1393-May-12 12:59
revive1393-May-12 12:59 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey28-Feb-12 19:22
professionalManoj Kumar Choubey28-Feb-12 19:22 
Generalnot excute LZW Pin
shanaou ncik14-Apr-11 17:20
shanaou ncik14-Apr-11 17:20 
GeneralLZW coding Pin
neelu.j9-Dec-08 23:26
neelu.j9-Dec-08 23:26 
GeneralRe: LZW coding Pin
prasannacse52826-Feb-09 21:16
prasannacse52826-Feb-09 21:16 
GeneralGreat Work Pin
TylerGall23-Mar-07 16:29
TylerGall23-Mar-07 16:29 
QuestionWhere download vb.net study document? Pin
xjf1511-Dec-06 21:38
xjf1511-Dec-06 21:38 
GeneralRE: Compressed file came out larger! Pin
Richard Vantrease14-Sep-06 15:19
Richard Vantrease14-Sep-06 15:19 
GeneralRe: RE: Compressed file came out larger! Pin
Ri Qen-Sin4-Jan-07 6:49
Ri Qen-Sin4-Jan-07 6:49 
GeneralGood work! Pin
Eric Engler28-Aug-06 5:36
Eric Engler28-Aug-06 5:36 
GeneralCompressed file came out larger! Pin
Dankarmy27-Aug-06 4:27
Dankarmy27-Aug-06 4:27 
GeneralRe: Compressed file came out larger! Pin
jmueller28-Aug-06 4:17
jmueller28-Aug-06 4:17 
GeneralRe: Compressed file came out larger! Pin
ChipLeader26-Jun-07 4:36
ChipLeader26-Jun-07 4:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.