Rice Decompress
Rice is data compression algorithm. This is most useful for compressing data like image and audio.
For Rice Compress algorithm click here.
/*****Please include following header files*****/
// cstdint
/***********************************************/
#define RICE_HISTORY 16
#define RICE_THRESHOLD 8
typedef struct {
uint8_t* BytePointer;
uint32_t BitPosition;
uint32_t NumBytes;
} BitStream;
static int numBits(uint32_t x)
{
int n;
for (n = 32; !(x & 0x80000000) && (n > 0); --n) x <<= 1;
return n;
}
static void initBitStream(BitStream* stream, uint8_t* buffer, uint32_t bytes)
{
stream->BytePointer = buffer;
stream->BitPosition = 0;
stream->NumBytes = bytes;
}
static int readBit(BitStream* stream)
{
uint32_t x;
uint32_t index = stream->BitPosition >> 3;
if (index < stream->NumBytes)
{
uint32_t bit = 7 - (stream->BitPosition & 7);
x = (stream->BytePointer[index] >> bit) & 1;
++stream->BitPosition;
}
else
{
x = 0;
}
return x;
}
static uint32_t decodeWord(int k, BitStream* stream)
{
uint32_t x;
uint32_t q = 0;
int i;
while (readBit(stream))
{
++q;
}
if (q > RICE_THRESHOLD)
{
int o = q - RICE_THRESHOLD;
x = 1;
for (i = 0; i < o - 1; ++i)
{
x = (x << 1) | readBit(stream);
}
x += RICE_THRESHOLD;
}
else
{
x = q;
}
for (i = k - 1; i >= 0; --i)
{
x = (x << 1) | readBit(stream);
}
return x;
}
static void Decompress(uint8_t* input, uint8_t* output, uint32_t inputSize, uint32_t outputSize)
{
BitStream stream;
uint32_t i, x, k, wordSize = 8;
uint32_t histogram[RICE_HISTORY];
int j;
uint32_t outputCount = outputSize / (wordSize >> 3);
if (outputCount == 0)
{
return;
}
initBitStream(&stream, input, inputSize);
k = input[0];
stream.BitPosition = 8;
if (k == 0)
{
for (i = 0; i < outputCount; ++i)
{
x = 0;
for (j = wordSize - 1; j >= 0; --j)
{
x = (x << 1) | readBit(&stream);
}
output[i] = x;
}
}
else
{
for (i = 0; i < outputCount; ++i)
{
if (i >= RICE_HISTORY)
{
k = 0;
for (j = 0; j < RICE_HISTORY; ++j)
{
k += histogram[j];
}
k = (k + (RICE_HISTORY >> 1)) / RICE_HISTORY;
}
x = decodeWord(k, &stream);
output[i] = x;
histogram[i % RICE_HISTORY] = numBits(x);
}
}
}
Example
uint8_t* decompressedData = new uint8_t[originalDataSize];
Decompress(compressedData, decompressedData, compressedDataSize, originalDataSize);