Huffman Decompress

Huffman coding is a data compression algorithm. It is based on the idea that frequently-appearing letters should have shorter bit representations and less common letters should have longer representations.

For Huffman Compress algorithm click here.



									Private Const MAX_TREE_NODES As Integer = 511

Public Class BitStream
	Public BytePointer As Byte()
	Public BitPosition As UInteger
	Public Index As UInteger
End Class

Public Structure Symbol
	Public Sym As Integer
	Public Count As UInteger
	Public Code As UInteger
	Public Bits As UInteger
End Structure

Public Class DecodeNode
	Public ChildA As DecodeNode
	Public ChildB As DecodeNode
	Public Symbol As Integer
End Class

Private Shared Sub initBitstream(ByRef stream As BitStream, buffer As Byte())
	stream.BytePointer = buffer
	stream.BitPosition = 0
End Sub

Private Shared Function readBit(ByRef stream As BitStream) As UInteger
	Dim buffer As Byte() = stream.BytePointer
	Dim bit As UInteger = stream.BitPosition

	Dim x As UInteger = CUInt(If(Convert.ToBoolean((buffer(stream.Index) And (1 << CInt(7 - bit)))), 1, 0))
	bit = (bit + 1) And 7

	If Not Convert.ToBoolean(bit) Then
		stream.Index += 1
	End If

	stream.BitPosition = bit

	Return x
End Function

Private Shared Function read8Bits(ByRef stream As BitStream) As UInteger
	Dim buffer As Byte() = stream.BytePointer
	Dim bit As UInteger = stream.BitPosition
	Dim x As UInteger = CUInt(CInt(buffer(stream.Index) << CInt(bit)) Or (CInt(buffer(stream.Index + 1)) >> CInt(8 - bit)))
	stream.Index += 1

	Return x
End Function

Private Shared Function recoverTree(nodes As DecodeNode(), ByRef stream As BitStream, ByRef nodenum As UInteger) As DecodeNode
	Dim thisNode As DecodeNode

	thisNode = nodes(nodenum)
	nodenum = nodenum + 1
	thisNode.Symbol = -1
	thisNode.ChildA = Nothing
	thisNode.ChildB = Nothing

	If Convert.ToBoolean(readBit(stream)) Then
		thisNode.Symbol = CInt(read8Bits(stream))
		Return thisNode
	End If

	thisNode.ChildA = recoverTree(nodes, stream, nodenum)
	thisNode.ChildB = recoverTree(nodes, stream, nodenum)

	Return thisNode
End Function

Public Shared Sub Decompress(input As Byte(), output As Byte(), inputSize As UInteger, outputSize As UInteger)
	Dim nodes As DecodeNode() = New DecodeNode(MAX_TREE_NODES - 1) {}

	For counter As Integer = 0 To nodes.Length - 1
		nodes(counter) = New DecodeNode()
	Next

	Dim root As DecodeNode, node As DecodeNode
	Dim stream As New BitStream()
	Dim i As UInteger, nodeCount As UInteger
	Dim buffer As Byte()

	If inputSize < 1 Then
		Return
	End If

	initBitstream(stream, input)
	nodeCount = 0
	root = recoverTree(nodes, stream, nodeCount)
	buffer = output

	For i = 0 To outputSize - 1
		node = root

		While node.Symbol < 0
			If Convert.ToBoolean(readBit(stream)) Then
				node = node.ChildB
			Else
				node = node.ChildA
			End If
		End While

		buffer(i) = node.Symbol And Byte.MaxValue
	Next
End Sub
								


Example

									Dim decompressedData As Byte() = New Byte(originalDataSize - 1) {}

Decompress(compressedData, decompressedData, CUInt(compressedDataSize), originalDataSize)