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)