-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDecompress LZW.vb
More file actions
120 lines (105 loc) · 4.47 KB
/
Copy pathDecompress LZW.vb
File metadata and controls
120 lines (105 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'This class's imports and settings.
Option Compare Binary
Option Explicit On
Option Infer Off
Option Strict On
Imports System
Imports System.Collections.Generic
Imports System.Convert
Imports System.Linq
'This module contains the LZW decompression related procedures.
Public Module DecompressLZWModule
'This procedure adds the specified entry to the specified LZW dictionary.
Private Sub AddDictionaryEntry(Prefix As Integer, Suffix As Integer, ByRef DictionaryIndex As Integer, DictionaryO As List(Of LZWEntryStr))
Try
DictionaryO(DictionaryIndex) = New LZWEntryStr With {.Prefix = Prefix, .Suffix = Suffix}
DictionaryIndex += &H1%
Catch ExceptionO As Exception
DisplayException(ExceptionO)
End Try
End Sub
'This procedure returns the specified data decompressed using LZW decompression.
Public Function DecompressLZW(Compressed() As Byte) As List(Of Byte)
Try
Dim BitsPerValue As Integer = &H9%
Dim BitsUsed As Integer = &H0%
Dim Buffer As New List(Of Byte)
Dim Decompressed As New List(Of Byte)
Dim DictionaryIndex As Integer = LZW_SYMBOL_BASE
Dim DictionaryO As List(Of LZWEntryStr) = InitializeDictionary()
Dim Literal As New Integer
Dim Parent As New Integer?
Dim Value As Integer = &H0%
For Each ByteO As Byte In Compressed
For Bit As Integer = &H0% To &H7%
Value = Value Or ((ByteO >> Bit) And &H1%) << BitsUsed
BitsUsed += &H1%
If BitsUsed >= BitsPerValue Then
If Value = LZW_END Then
Exit For
ElseIf Value = LZW_START Then
DictionaryO = InitializeDictionary()
BitsPerValue = &H9%
DictionaryIndex = LZW_SYMBOL_BASE
Parent = New Integer?
Else
If Value < DictionaryIndex Then
If Parent Is Nothing Then
Decompressed.Add(ToByte(Value))
Else
Buffer = GetBuffer(Value, DictionaryO)
Literal = Buffer.First
Decompressed.AddRange(Buffer)
AddDictionaryEntry(Parent.Value, Literal, DictionaryIndex, DictionaryO)
End If
Else
Buffer = GetBuffer(Parent.Value, DictionaryO)
Literal = Buffer.First
Decompressed.AddRange(Buffer)
Decompressed.Add(ToByte(Literal))
AddDictionaryEntry(Parent.Value, Literal, DictionaryIndex, DictionaryO)
End If
Parent = Value
End If
BitsUsed = &H0%
Value = &H0%
If (&H1% << BitsPerValue) = DictionaryIndex AndAlso DictionaryIndex < LZW_MAXIMUM_ENTRIES Then BitsPerValue += &H1%
End If
Next Bit
Next ByteO
Return Decompressed
Catch ExceptionO As Exception
DisplayException(ExceptionO)
End Try
Return Nothing
End Function
'This procedure returns the specified LZW literals decompressed using LZW decompression.
Private Function GetBuffer(Value As Integer, DictionaryO As List(Of LZWEntryStr)) As List(Of Byte)
Try
Dim Buffer As New List(Of Byte)
Do While Value > LZW_START
Buffer.Add(ToByte(DictionaryO(Value).Suffix And &HFF%))
Value = DictionaryO(Value).Prefix
Loop
Buffer.Add(ToByte(Value And &HFF%))
Buffer.Reverse()
Return Buffer
Catch ExceptionO As Exception
DisplayException(ExceptionO)
End Try
Return Nothing
End Function
'This procedure returns a LZW dictionary.
Private Function InitializeDictionary() As List(Of LZWEntryStr)
Try
Dim DictionaryO As New List(Of LZWEntryStr)
For Index As Integer = &H0% To LZW_MAXIMUM_ENTRIES - &H1%
DictionaryO.Add(New LZWEntryStr With {.Prefix = -1, .Suffix = If(Index < LZW_START, Index, -1)})
Next Index
Return DictionaryO
Catch ExceptionO As Exception
DisplayException(ExceptionO)
End Try
Return Nothing
End Function
End Module