UncompressZLib for PDB (C language)
/* uncompress ZLib compressed document/image */
static unsigned int UncompressZLib
(
unsigned char* src, /* in: compressed document */
unsigned int src_len, /* in: size of compressed document */
unsigned char* dest, /* out: buffer to put uncompressed
document in */
unsigned int dest_len, /* out: size of buffer to put uncompressed
document in */
unsigned char* owner_id /* in: owner-id key */
)
{
z_stream z;
unsigned int err;
unsigned int keylen;
unsigned int i;
unsigned char keybuf[OWNER_ID_HASH_LEN];
unsigned char owner_id_key[OWNER_ID_HASH_LEN];
ASSERT (src != NULL && src_len != 0 && dest != NULL && dest_len != 0);
keylen = 0;
if (owner_id != NULL) {
unsigned long crc;
int owner_id_len = strlen (owner_id);
crc = crc32 (0L, owner_id, owner_id_len);
for (i = 0; i < 10; i++) {
crc = crc32 (crc, owner_id, owner_id_len);
owner_id_key[(i * 4) + 0] = (crc >> 24) & 0xFF;
owner_id_key[(i * 4) + 1] = (crc >> 16) & 0xFF;
owner_id_key[(i * 4) + 2] = (crc >> 8) & 0xFF;
owner_id_key[(i * 4) + 3] = crc & 0xFF;
//*( (unsigned long *)( owner_id_key + ( 4 * i ) ) ) = crc;
}
keylen = min(src_len, OWNER_ID_HASH_LEN);
}
memset (&z, 0, sizeof z);
if (owner_id != NULL) {
for (i = 0; i < keylen; i++)
keybuf[i] = src[i] ^ owner_id_key[i];
z.next_in = keybuf;
z.avail_in = keylen;
}
else {
z.next_in = src;
z.avail_in = src_len;
}
z.next_out = dest;
z.avail_out = dest_len;
err = inflateInit (&z);
if (err != Z_OK) {
return err;
}
do {
if (z.avail_in == 0 && keylen > 0) {
z.next_in = src + keylen;
z.avail_in = src_len - keylen;
keylen = 0;
}
err = inflate (&z, Z_SYNC_FLUSH);
if( err == Z_MEM_ERROR )
{
fprintf( stderr, "[out of memory doing uncompress]\n" );
}
else if( err == Z_BUF_ERROR )
{
fprintf( stderr, "[output buffer too small doing uncompress]\n" );
}
else if( err == Z_DATA_ERROR )
{
fprintf( stderr, "[input data corrupted doing uncompress]\n" );
}
else if( err != Z_OK )
{
fprintf( stderr, "[error while uncompressing (%d)]\n", err );
}
} while (err == Z_OK);
if (err != Z_STREAM_END)
return err;
ASSERT (z.total_out == dest_len);
return inflateEnd (&z);
}
|