

Go to the source code of this file.
Functions | |
| int | cbf_compress_canonical (void *source, size_t elsize, int elsign, size_t nelem, unsigned int compression, cbf_file *file, size_t *compressedsize, int *storedbits) |
| int | cbf_decompress_canonical (void *destination, size_t elsize, int elsign, size_t nelem, size_t *nelem_read, unsigned int compression, cbf_file *file) |
| int cbf_compress_canonical | ( | void * | source, |
| size_t | elsize, | ||
| int | elsign, | ||
| size_t | nelem, | ||
| unsigned int | compression, | ||
| cbf_file * | file, | ||
| size_t * | compressedsize, | ||
| int * | storedbits | ||
| ) |
Definition at line 1284 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, bits(), CBF_ARGUMENT, CBF_BITCOUNT, cbf_count_bits(), cbf_count_values(), cbf_create_list(), cbf_failnez, cbf_free_compressdata(), cbf_generate_canonicalcodes(), cbf_generate_codelengths(), cbf_initialise_compressdata(), cbf_make_compressdata(), cbf_onfailnez, cbf_put_code(), cbf_put_integer(), cbf_put_stopcode(), cbf_put_table(), cbf_reduce_list(), CBF_SHIFT63, cbf_compress_nodestruct::code, cbf_compress_nodestruct::count, cbf_compress_nodestruct::next, and cbf_compress_data::node.
Referenced by cbf_compress().
{
int code, minelement, maxelement;
unsigned int count, element, lastelement, bits, unsign, sign, limit, endcode;
unsigned long bitcount, expected_bitcount;
unsigned char *unsigned_char_data;
cbf_compress_node *node, *start;
cbf_compress_data *data;
/* Is the element size valid? */
if (elsize != sizeof (int) &&
elsize != sizeof (short) &&
elsize != sizeof (char))
return CBF_ARGUMENT;
/* Create and initialise the compression data */
cbf_failnez (cbf_make_compressdata (&data, file))
cbf_onfailnez (cbf_initialise_compressdata (data, 8, 0),
cbf_free_compressdata (data))
/* Count the symbols */
cbf_onfailnez (cbf_count_values (data, source, elsize, elsign, nelem,
&minelement, &maxelement),
cbf_free_compressdata (data))
/* Generate the code lengths */
start = cbf_create_list (data);
while (start->next)
start = cbf_reduce_list (data, start);
cbf_generate_codelengths (start, 0);
/* Count the expected number of bits */
expected_bitcount = cbf_count_bits (data);
/* Write the number of elements (64 bits) */
cbf_onfailnez (cbf_put_integer (file, nelem, 0, 64),
cbf_free_compressdata (data))
/* Write the minimum element (64 bits) */
cbf_onfailnez (cbf_put_integer (file, minelement, elsign, 64),
cbf_free_compressdata (data))
/* Write the maximum element (64 bits) */
cbf_onfailnez (cbf_put_integer (file, maxelement, elsign, 64),
cbf_free_compressdata (data))
/* Write the reserved entry (64 bits) */
cbf_onfailnez (cbf_put_integer (file, 0, 0, 64),
cbf_free_compressdata (data))
bitcount = 4 * 64;
/* Write the table */
cbf_onfailnez (cbf_put_table (data, &bits), cbf_free_compressdata (data))
bitcount += bits;
/* Generate the canonical bitcodes */
cbf_onfailnez (cbf_generate_canonicalcodes (data), \
cbf_free_compressdata (data))
/* Initialise the pointers */
unsigned_char_data = (unsigned char *) source;
node = data->node;
/* Maximum limit (unsigned) is 64 bits */
if (elsize * CHAR_BIT > 64)
{
sign = 1 << CBF_SHIFT63;
limit = ~-(sign << 1);
if (storedbits)
*storedbits = 64;
}
else
{
sign = 1 << (elsize * CHAR_BIT - 1);
limit = ~0;
if (storedbits)
*storedbits = elsize * CHAR_BIT;
}
/* Offset to make the value unsigned */
if (elsign)
unsign = sign;
else
unsign = 0;
/* Start from 0 */
lastelement = unsign;
endcode = 1 << data->bits;
for (count = 0; count < nelem; count++)
{
/* Get the next element */
if (elsize == sizeof (int))
element = *((unsigned int *) unsigned_char_data);
else
if (elsize == sizeof (short))
element = *((unsigned short *) unsigned_char_data);
else
element = *unsigned_char_data;
unsigned_char_data += elsize;
/* Make the element unsigned */
element += unsign;
/* Limit the value to 64 bits */
if (element > limit)
if (elsign && (int) (element - unsign) < 0)
element = 0;
else
element = limit;
/* Calculate the offset to save */
code = element - lastelement;
/* Write the (overflowed?) code */
cbf_onfailnez (cbf_put_code (data, code,
(element < lastelement) ^ (code < 0), &bits),
cbf_free_compressdata (data))
bitcount += bits;
/* Update the previous element */
lastelement = element;
}
/* End code */
cbf_onfailnez (cbf_put_stopcode (data, &bits), cbf_free_compressdata (data))
bitcount += bits;
/* Free memory */
cbf_free_compressdata (data);
/* Does the actual bit count match the expected bit count? */
if (bitcount != expected_bitcount)
return CBF_BITCOUNT;
/* Calculate the number of characters written */
if (binsize)
*binsize = (bitcount + 7) / 8;
/* Success */
return 0;
}
| int cbf_decompress_canonical | ( | void * | destination, |
| size_t | elsize, | ||
| int | elsign, | ||
| size_t | nelem, | ||
| size_t * | nelem_read, | ||
| unsigned int | compression, | ||
| cbf_file * | file | ||
| ) |
Definition at line 1530 of file cbf_canonical.c.
References bits(), CBF_ARGUMENT, cbf_failnez, cbf_free_compressdata(), cbf_get_code(), cbf_get_integer(), cbf_get_table(), cbf_make_compressdata(), cbf_onfailnez, cbf_setup_decode(), CBF_SHIFT63, and cbf_compress_nodestruct::count.
Referenced by cbf_decompress().
{
unsigned int bits, element, sign, unsign, limit, count64, count;
unsigned char *unsigned_char_data;
cbf_compress_data *data;
cbf_compress_node *start;
unsigned int offset [4], last_element [4];
int errorcode;
/* Is the element size valid? */
if (elsize != sizeof (int) &&
elsize != sizeof (short) &&
elsize != sizeof (char))
return CBF_ARGUMENT;
/* Discard the reserved entry (64 bits) */
cbf_failnez (cbf_get_integer (file, NULL, 0, 64))
/* Create and initialise the compression data */
cbf_failnez (cbf_make_compressdata (&data, file))
/* Read the compression table */
cbf_onfailnez (cbf_get_table (data), cbf_free_compressdata (data))
/* Set up the decode data */
cbf_onfailnez (cbf_setup_decode (data, &start), cbf_free_compressdata (data))
/* Initialise the pointer */
unsigned_char_data = (unsigned char *) destination;
/* Maximum limit (unsigned) is 64 bits */
if (elsize * CHAR_BIT > 64)
{
sign = 1 << CBF_SHIFT63;
limit = ~-(sign << 1);
}
else
{
sign = 1 << (elsize * CHAR_BIT - 1);
if (elsize == sizeof (int))
limit = ~0;
else
limit = ~-(1 << (elsize * CHAR_BIT));
}
/* Offset to make the value unsigned */
if (elsign)
unsign = sign;
else
unsign = 0;
/* How many ints do we need to hold 64 bits? */
count64 = (64 + sizeof (int) * CHAR_BIT - 1) / (sizeof (int) * CHAR_BIT);
/* Initialise the first element */
last_element [0] = unsign;
for (count = 1; count < count64; count++)
last_element [count] = 0;
/* Read the elements */
for (count = 0; count < nelem; count++)
{
/* Read the offset */
errorcode = cbf_get_code (data, start, offset, &bits);
if (errorcode)
{
if (nelem_read)
*nelem_read = count;
cbf_free_compressdata (data);
return errorcode;
}
/* Update the current element */
last_element [0] += offset [0];
element = last_element [0];
/* Limit the value to fit the element size */
if (element > limit)
if (elsign && (int) (element - unsign) < 0)
element = 0;
else
element = limit;
/* Make the element signed? */
element -= unsign;
/* Save the element */
if (elsize == sizeof (int))
*((unsigned int *) unsigned_char_data) = element;
else
if (elsize == sizeof (short))
*((unsigned short *) unsigned_char_data) = element;
else
*unsigned_char_data = element;
unsigned_char_data += elsize;
}
/* Number read */
if (nelem_read)
*nelem_read = count;
/* Free memory */
cbf_free_compressdata (data);
/* Success */
return 0;
}
1.7.3