ref: 7c76dac1b268038f567939a70a18228e790a5cbc
dir: /lzuncompress.c/
#include <stdlib.h> #include <string.h> #include "ficl.h" int ficlLzDecodeHeaderField(const unsigned char *data, int *byteOffset) { unsigned char id; int networkOrder; int length; id = data[(*byteOffset)++]; if (id < 252) return id; networkOrder = 0; length = (id == 253) ? 2: 4; ficlBitGetString(((unsigned char *)&networkOrder), data, (*byteOffset) * 8, length * 8, sizeof(networkOrder) * 8); (*byteOffset) += length; return ficlNetworkUnsigned32(networkOrder); } int ficlLzUncompress(const unsigned char *compressed, char **uncompressed_p, size_t *uncompressedSize_p) { unsigned char *window; unsigned char *buffer; unsigned char *uncompressed; unsigned char *initialWindow; int bitstreamLength; int inputPosition; int uncompressedSize; *uncompressed_p = NULL; inputPosition = 0; bitstreamLength = ficlLzDecodeHeaderField(compressed, &inputPosition); uncompressedSize = ficlLzDecodeHeaderField(compressed, &inputPosition); inputPosition <<= 3; /* same as * 8 */ bitstreamLength += inputPosition; uncompressed = (unsigned char *)calloc(uncompressedSize + 1, 1); if (uncompressed == NULL) return -1; window = buffer = uncompressed; initialWindow = buffer + FICL_LZ_WINDOW_SIZE; while (inputPosition != bitstreamLength) { int length; int token = ficlBitGet(compressed, inputPosition); inputPosition++; if (token) { /* phrase token */ int offset = 0; ficlBitGetString((unsigned char *)&offset, compressed, inputPosition, FICL_LZ_PHRASE_BITS - (1 + FICL_LZ_NEXT_BITS), sizeof(offset) * 8); offset = ficlNetworkUnsigned32(offset); inputPosition += FICL_LZ_PHRASE_BITS - (1 + FICL_LZ_NEXT_BITS); length = (offset & ((1 << FICL_LZ_LENGTH_BITS) - 1)) + FICL_LZ_MINIMUM_USEFUL_MATCH; offset >>= FICL_LZ_LENGTH_BITS; memmove(buffer, window + offset, length); buffer += length; length++; } else length = 1; /* symbol token */ *buffer = 0; ficlBitGetString(buffer++, compressed, inputPosition, FICL_LZ_NEXT_BITS, sizeof(*buffer) * 8); inputPosition += FICL_LZ_NEXT_BITS; if (buffer > initialWindow) window = buffer - FICL_LZ_WINDOW_SIZE; } *uncompressed_p = (char *)uncompressed; *uncompressedSize_p = uncompressedSize; return 0; }