473,473 Members | 1,491 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

LZW Compression Algorithm in VBScript

Rabbit
12,516 Recognized Expert Moderator MVP
Introduction
This article shows you how to implement the LZW lossless compression algorithm in VBScript. It can also be used in VBA as is or almost as is.

https://en.wikipedia.org/wiki/Lempel...%E2%80%93Welch

The LZW Algorithm
The LZW algorithm is a compression technique that results in no loss of data. It builds a dictionary of codes and values used in the compression on the fly. The dictionary is not stored with the compressed file and is discarded after compression. During decompression, the dictionary is rebuilt from the compressed data.

The LZW algorithm functions by:
  1. Initialize the dictionary to contain all strings of length one
  2. Find the longest string in the dictionary that matches the current input
  3. Output the dictionary code for that matching input
  4. Append the next character from the input to the matching input string and add it as a new dictionary value with a new code
  5. Go to step 2

The Code and How to Use It
The code below is an example implementation of the LZW Algorithm in VBScript and is easily portable to VBA. The functions are LZWCompress and LZWUncompress and take the file path as the parameter.

The dictionary is initialized to the full range of 8 bit values and uses 16 bits for each key. The dictionary reinitializes after reaching 65535 keys I did this for ease of implementation even though that also means it's not as compressed as it can be.

My tests on large Access databases have shown an 86% compression level compared to 93% compression using "ultra" level compression with the LZMA algorithm in 7zip.

My implementation of the algorithm is also slow due to the fact that I read the file 1 byte at a time. Again, this was due to ease of implementation. Would be more efficient to read a large amount of the file into memory rather than byte by byte.

Expand|Select|Wrap|Line Numbers
  1. Option Explicit
  2. Const ForReading = 1, ForWriting = 2, ForAppending = 8
  3.  
  4. Function LZWCompress(strPath)
  5.     Dim oFS, oFRead, oFWrite, oDict, strNext, strCurrent, intMaxCode, i
  6.  
  7.     Set oDict = CreateObject("Scripting.Dictionary")
  8.     Set oFS = CreateObject("Scripting.FileSystemObject")
  9.     Set oFRead = oFS.OpenTextFile(strPath, ForReading)
  10.     Set oFWrite = oFS.OpenTextFile(strPath & ".lzw", ForWriting, True)
  11.     Set oFS = Nothing
  12.     intMaxCode = 255
  13.     strCurrent = oFRead.Read(1)
  14.  
  15.     For i = 0 To 255
  16.         oDict.Add Chr(i), i
  17.     Next
  18.  
  19.     Do Until oFRead.AtEndOfStream
  20.         strNext = oFRead.Read(1)
  21.  
  22.         If oDict.Exists(strCurrent & strNext) Then
  23.             strCurrent = strCurrent & strNext
  24.         Else
  25.             oFWrite.Write(Chr(CByte(oDict.Item(strCurrent) \ 256)) & Chr(CByte(oDict.Item(strCurrent) Mod 256)))
  26.  
  27.             intMaxCode = intMaxCode + 1
  28.             oDict.Add strCurrent & strNext, intMaxCode
  29.             strCurrent = strNext
  30.  
  31.             If intMaxCode = 65535 Then
  32.                 intMaxCode = 255
  33.                 oDict.RemoveAll
  34.  
  35.                 For i = 0 To 255
  36.                     oDict.Add Chr(i), i
  37.                 Next
  38.             End If
  39.         End If
  40.     Loop
  41.  
  42.     oFWrite.Write(Chr(CByte(oDict.Item(strCurrent) \ 256)) & Chr(CByte(oDict.Item(strCurrent) Mod 256)))
  43.  
  44.     oFRead.Close
  45.     oFWrite.Close
  46.     Set oFRead = Nothing
  47.     Set oFWrite = Nothing
  48.     Set oDict = Nothing
  49. End Function
  50.  
  51. Function LZWUncompress(strPath)
  52.     Dim oFS, oFRead, oFWrite, oDict, intNext, intCurrent, intMaxCode, i, strNext
  53.  
  54.     Set oDict = CreateObject("Scripting.Dictionary")
  55.     Set oFS = CreateObject("Scripting.FileSystemObject")
  56.     Set oFRead = oFS.OpenTextFile(strPath, ForReading)
  57.     Set oFWrite = oFS.OpenTextFile(strPath & ".unc", ForWriting, True)
  58.     Set oFS = Nothing
  59.     intMaxCode = 255
  60.     strNext = oFRead.Read(2)
  61.     intCurrent = 0
  62.     For i = 1 To Len(strNext)
  63.         intCurrent = intCurrent + 256 ^ (Len(strNext) - i) * Asc(Mid(strNext, i, 1))
  64.     Next
  65.  
  66.     For i = 0 To 255
  67.         oDict.Add i, Chr(i)
  68.     Next
  69.  
  70.     Do Until oFRead.AtEndOfStream
  71.         oFWrite.Write(oDict.Item(intCurrent))
  72.         intMaxCode = intMaxCode + 1
  73.  
  74.         strNext = oFRead.Read(2)
  75.         intNext = 0
  76.         For i = 1 To Len(strNext)
  77.             intNext = intNext + 256 ^ (Len(strNext) - i) * Asc(Mid(strNext, i, 1))
  78.         Next
  79.  
  80.         If oDict.Exists(intNext) Then
  81.             oDict.Add intMaxCode, oDict.Item(intCurrent) & Left(oDict.Item(intNext), 1)
  82.         Else
  83.             oDict.Add intMaxCode, oDict.Item(intCurrent) & Left(oDict.Item(intCurrent), 1)
  84.         End If
  85.  
  86.         If intMaxCode = 65535 Then
  87.             intMaxCode = 255
  88.             oDict.RemoveAll
  89.  
  90.             For i = 0 To 255
  91.                 oDict.Add i, Chr(i)
  92.             Next
  93.         End If
  94.  
  95.         intCurrent = intNext
  96.     Loop
  97.     oFWrite.Write(oDict.Item(intCurrent))
  98.  
  99.     oFRead.Close
  100.     oFWrite.Close
  101.     Set oFRead = Nothing
  102.     Set oFWrite = Nothing
  103.     Set oDict = Nothing
  104. End Function
Jun 17 '15 #1
0 11533

Sign in to post your reply or Sign up for a free account.

Similar topics

24
by: c3poptuse | last post by:
Supercomputer and encryption and compression @ rate of 96% Take a document then or a 3D matrix document change it two random or binary code or just a program for 0's and 1's and fold it over and...
2
by: Jim Hubbard | last post by:
I went to the compression newsgroups, but all I saw was spam. So, I thought I'd post his question here to get the best info I could from other programmers. Which compression algorithm offers...
1
by: Howie | last post by:
Hi, does someone know a simple algorithm (Huffman, LZW etc.) for compression in memory with ANSI - C++ or STL-strings ? An implemention with zlib seems a little bit heavy for me. Thanks,...
0
by: Lenn | last post by:
Hello, I am looking for the algorithm to "de-compress" array of bytes compress with wavelet algorithm. Any links? Suggestions? Thank you.
17
by: dunric | last post by:
After writing the computing urban legend "The Helsinki Code", I spent several nights thinking up how in the world Gustav Larsson, the Finnish PDP-8 computer programmer, could have managed to...
1
by: Z.K. | last post by:
I not really sure this is the right newsgroup so please excuse me if it is not. I am trying to create a simple compression algorithm using the LZW system and I can find a lot of information on...
4
by: muralikc | last post by:
assume there r two float no. lat1=1300.1252; lat2=1302.2546; After subtracting, the result obtained must be converted to int, which is easily possible by multiplying with pow(10,4),if I get...
21
by: =?Utf-8?B?VkJB?= | last post by:
I compressed a file with GZipStream class and is larger than the original file.... how can this be?, the original file is 737 KB and the "compressed" file is 1.1 MB. Did i miss something or is...
9
by: csharpula csharp | last post by:
Hello, I would like to know which one of the following compressiom methods are the easiest to implement in c# and the most effective one in compression of files? (text or code files) Which...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.