Rice Decompress

Rice is data compression algorithm. This is most useful for compressing data like image and audio.

For Rice Compress algorithm click here.



									Private Const RICE_HISTORY As Integer = 16
Private Const RICE_THRESHOLD As Integer = 8

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

Private Shared Function numBits(x As UInteger) As Integer
	Dim n As Integer
	n = 32
	While Not Convert.ToBoolean(x And &H80000000UI) AndAlso (n > 0)
		x <<= 1
		n -= 1
	End While
	Return n
End Function

Private Shared Sub initBitStream(ByRef stream As BitStream, buffer As Byte(), bytes As UInteger)
	stream.BytePointer = buffer
	stream.BitPosition = 0
	stream.NumBytes = bytes
End Sub

Private Shared Function readBit(ByRef stream As BitStream) As Integer
	Dim x As UInteger
	Dim index As UInteger = stream.BitPosition >> 3

	If index < stream.NumBytes Then
		Dim bit As UInteger = 7 - (stream.BitPosition And 7)
		x = CUInt((stream.BytePointer(index) >> CInt(bit)) And 1)
		stream.BitPosition += 1
	Else
		x = 0
	End If

	Return CInt(x)
End Function

Private Shared Function decodeWord(k As Integer, ByRef stream As BitStream) As UInteger
	Dim x As UInteger
	Dim q As UInteger = 0
	Dim i As Integer

	While Convert.ToBoolean(readBit(stream))
		q += 1
	End While

	If q > RICE_THRESHOLD Then
		Dim o As Integer = CInt(q - RICE_THRESHOLD)
		x = 1

		For i = 0 To o - 2
			x = CUInt(CInt(x << 1) Or readBit(stream))
		Next

		x += RICE_THRESHOLD
	Else
		x = q
	End If

	For i = k - 1 To 0 Step -1
		x = CUInt(CInt(x << 1) Or readBit(stream))
	Next

	Return x
End Function

Public Shared Sub Decompress(input As Byte(), output As Byte(), inputSize As UInteger, outputSize As UInteger)
	Dim stream As New BitStream()
	Dim i As UInteger, x As UInteger, k As UInteger, wordSize As UInteger = 8
	Dim histogram As UInteger() = New UInteger(RICE_HISTORY - 1) {}
	Dim j As Integer

	Dim outputCount As UInteger = outputSize / (wordSize >> 3)

	If outputCount = 0 Then
		Return
	End If

	initBitStream(stream, input, inputSize)
	k = CUInt(input(0))
	stream.BitPosition = 8

	If k = 0 Then
		For i = 0 To outputCount - 1
			x = 0

			For j = CInt(wordSize) - 1 To 0 Step -1
				x = CUInt(CInt(x << 1) Or readBit(stream))
			Next

			output(i) = CByte(x)
		Next
	Else
		For i = 0 To outputCount - 1
			If i >= RICE_HISTORY Then
				k = 0

				For j = 0 To RICE_HISTORY - 1
					k += histogram(j)
				Next

				k = (k + (RICE_HISTORY >> 1)) / RICE_HISTORY
			End If

			x = decodeWord(CInt(k), stream)
			output(i) = CByte(x)
			histogram(i Mod RICE_HISTORY) = CUInt(numBits(x))
		Next
	End If
End Sub
								


Example

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

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