Mastering Algorithms With C - Kyle Loudon [175]
* *
* Get the header information. *
* *
*****************************************************************************/
hsize = sizeof(int);
memcpy(&size, compressed, sizeof(int));
/*****************************************************************************
* *
* Initialize the sliding window and the look-ahead buffer. *
* *
*****************************************************************************/
memset(window, 0, LZ77_WINDOW_SIZE);
memset(buffer, 0, LZ77_BUFFER_SIZE);
/*****************************************************************************
* *
* Uncompress the data. *
* *
*****************************************************************************/
ipos = hsize * 8;
opos = 0;
remaining = size;
while (remaining > 0) {
/**************************************************************************
* *
* Get the next bit in the compressed data. *
* *
**************************************************************************/
state = bit_get(compressed, ipos);
ipos++;
if (state == 1) {
/***********************************************************************
* *
* Handle processing a phrase token. *
* *
***********************************************************************/
memset(&offset, 0, sizeof(int));
for (i = 0; i < LZ77_WINOFF_BITS; i++) {
tpos = (sizeof(int) * 8) - LZ77_WINOFF_BITS + i;
bit_set((unsigned char *)&offset, tpos, bit_get(compressed, ipos));
ipos++;
}
memset(&length, 0, sizeof(int));
for (i = 0; i < LZ77_BUFLEN_BITS; i++) {
tpos = (sizeof(int) * 8) - LZ77_BUFLEN_BITS + i;
bit_set((unsigned char *)&length, tpos, bit_get(compressed, ipos));
ipos++;
}
next = 0x00;
for (i = 0; i < LZ77_NEXT_BITS; i++) {
tpos = (sizeof(unsigned char) * 8) - LZ77_NEXT_BITS + i;
bit_set((unsigned char *)&next, tpos, bit_get(compressed, ipos));
ipos++;
}
/***********************************************************************
* *
* Ensure that the offset and length have the correct byte ordering *
* for the system. *
* *
***********************************************************************/
offset = ntohl(offset);
length = ntohl(length);
/***********************************************************************
* *
* Write the phrase from the window to the buffer of original data. *
* *
***********************************************************************/
i = 0;
if (opos > 0) {
if ((temp = (unsigned char *)realloc(orig, opos+length+1)) == NULL) {
free(orig);
return -1;
}
orig = temp;
}
else {
if ((orig = (unsigned char *)malloc(length + 1)) == NULL)
return -1;
}
while (i < length && remaining > 0) {
orig[opos] = window[offset + i];
opos++;
/********************************************************************
* *
* Record each symbol in the look-ahead buffer until ready to *
* update the sliding window. *
* *
********************************************************************/
buffer[i] = window[offset + i];
i++;
/********************************************************************
* *
* Adjust the total symbols remaining to account for each symbol *
* consumed. *
* *
********************************************************************/
remaining--;
}
/***********************************************************************
* *
* Write the unmatched symbol to the buffer of original data. *
* *
***********************************************************************/
if (remaining > 0) {
orig[opos] = next;
opos++;
/********************************************************************
* *
* Also record this symbol in the look-ahead buffer. *
* *
********************************************************************/
buffer[i] = next;
/********************************************************************
* *
* Adjust the total symbols remaining to account for the unmatched *
* symbol. *
* *
********************************************************************/
remaining--;
}
/***********************************************************************