#include <stdlib.h>#include <stdio.h>#include <string.h>#include <limits.h>#include "cbf.h"#include "cbf_alloc.h"#include "cbf_canonical.h"#include "cbf_compress.h"#include "cbf_file.h"
Go to the source code of this file.
| #define CBF_MAXBITS 15 |
Definition at line 136 of file cbf_canonical.c.
Referenced by cbf_initialise_compressdata().
| #define CBF_MAXCODEBITS 64 |
Definition at line 138 of file cbf_canonical.c.
Referenced by cbf_generate_canonicalcodes().
| #define CBF_MAXMAXBITS 65 |
Definition at line 137 of file cbf_canonical.c.
Referenced by cbf_initialise_compressdata().
| #define CBF_SHIFT63 (sizeof (int) * CHAR_BIT > 64 ? 63 : 0) |
Definition at line 140 of file cbf_canonical.c.
Referenced by cbf_compress_canonical(), cbf_count_values(), and cbf_decompress_canonical().
| #define CBF_TABLEENTRYBITS 8 |
Definition at line 135 of file cbf_canonical.c.
Referenced by cbf_count_bits(), cbf_get_table(), and cbf_put_table().
| typedef struct cbf_compress_nodestruct cbf_compress_node |
| cbf_compress_node* cbf_append_node | ( | cbf_compress_node * | list, |
| cbf_compress_node * | node | ||
| ) |
Definition at line 476 of file cbf_canonical.c.
References cbf_compress_nodestruct::next.
Referenced by cbf_order_node().
{
cbf_compress_node *next;
if (list)
{
next = list;
while (next->next)
next = next->next;
next->next = node;
return list;
}
return node;
}
| int cbf_compare_bitcodes | ( | const void * | void1, |
| const void * | void2 | ||
| ) |
Definition at line 743 of file cbf_canonical.c.
References bit, cbf_compress_nodestruct::bitcode, cbf_compress_nodestruct::bitcount, and bits().
Referenced by cbf_setup_decode().
{
const cbf_compress_node *node1, *node2;
const unsigned int *code1, *code2;
unsigned int bit, bits;
node1 = (const cbf_compress_node *) void1;
node2 = (const cbf_compress_node *) void2;
/* Get the codes */
code1 = node1->bitcode;
code2 = node2->bitcode;
bits = node1->bitcount;
if (bits > node2->bitcount)
bits = node2->bitcount;
/* Is either node not used? */
if (bits == 0)
{
if (node1->bitcount == node2->bitcount)
return 0;
return 1 - ((node1->bitcount != 0) << 1);
}
/* Compare the codes bit-by-bit */
for (bit = 0; bits > 0; bit++, bits--)
{
if (bit == sizeof (int) * CHAR_BIT)
{
bit = 0;
code1++;
code2++;
}
if (((*code1 ^ *code2) >> bit) & 1)
return ((*code1 >> bit) & 1) - ((*code2 >> bit) & 1);
}
/* Same code */
return 0;
}
| int cbf_compress_canonical | ( | void * | source, |
| size_t | elsize, | ||
| int | elsign, | ||
| size_t | nelem, | ||
| unsigned int | compression, | ||
| cbf_file * | file, | ||
| size_t * | binsize, | ||
| 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_construct_tree | ( | cbf_compress_data * | data, |
| cbf_compress_node ** | node, | ||
| int | bits, | ||
| cbf_compress_node ** | root | ||
| ) |
Definition at line 805 of file cbf_canonical.c.
References cbf_failnez, cbf_compress_nodestruct::child, cbf_compress_data::nextnode, and cbf_compress_data::node.
Referenced by cbf_setup_decode().
{
cbf_compress_node *nextnode;
if (node == NULL)
{
nextnode = data->node;
node = &nextnode;
}
/* Create the node */
*root = data->node + data->nextnode;
data->nextnode++;
/* Make the 0 branch then the 1 branch */
if ((*node)->bitcount == bits)
{
(*root)->child [0] = *node;
(*node)++;
}
else
cbf_failnez (cbf_construct_tree (data, node, bits + 1,
&(*root)->child [0]))
if ((*node)->bitcount == bits)
{
(*root)->child [1] = *node;
(*node)++;
}
else
cbf_failnez (cbf_construct_tree (data, node, bits + 1,
&(*root)->child [1]))
/* Success */
return 0;
}
| unsigned long cbf_count_bits | ( | cbf_compress_data * | data | ) |
Definition at line 879 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, CBF_TABLEENTRYBITS, cbf_compress_nodestruct::code, cbf_compress_nodestruct::count, cbf_compress_data::maxbits, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
unsigned int endcode, codes, code;
unsigned long bitcount;
cbf_compress_node *node;
endcode = 1 << data->bits;
node = data->node;
/* Basic entries */
bitcount = 4 * 64;
/* How many symbols do we actually use? */
for (codes = endcode + data->maxbits; node [codes].bitcount == 0; codes--);
codes++;
/* Compression table */
if (codes > endcode + data->bits)
bitcount += 2 * CBF_TABLEENTRYBITS +
(codes - data->bits) * CBF_TABLEENTRYBITS;
else
bitcount += 2 * CBF_TABLEENTRYBITS + (endcode + 1) * CBF_TABLEENTRYBITS;
/* Compressed data */
for (code = 0; code < endcode; code++, node++)
bitcount += node->count * node->bitcount;
for (; code < codes; code++, node++)
bitcount += node->count * (node->bitcount + code - endcode);
return bitcount;
}
| int cbf_count_values | ( | cbf_compress_data * | data, |
| void * | source, | ||
| size_t | elsize, | ||
| int | elsign, | ||
| size_t | nelem, | ||
| int * | minelem, | ||
| int * | maxelem | ||
| ) |
Definition at line 1090 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, CBF_ARGUMENT, CBF_SHIFT63, cbf_compress_nodestruct::code, cbf_compress_nodestruct::count, cbf_compress_data::maxbits, cbf_compress_data::nextnode, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
int code;
unsigned int count, element, lastelement, minelement, maxelement,
unsign, sign, bitcount, m, endcode, limit;
unsigned char *unsigned_char_data;
cbf_compress_node *node;
/* Is the element size valid? */
if (elsize != sizeof (int) &&
elsize != sizeof (short) &&
elsize != sizeof (char))
return CBF_ARGUMENT;
/* 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);
}
else
{
sign = 1 << (elsize * CHAR_BIT - 1);
limit = ~0;
}
/* Offset to make the value unsigned */
if (elsign)
unsign = sign;
else
unsign = 0;
/* Initialise the minimum and maximum elements */
minelement = ~0;
maxelement = 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;
/* Update the minimum and maximum values */
if (element < minelement)
minelement = element;
if (element > maxelement)
maxelement = element;
/* Calculate the offset to save */
code = element - lastelement;
/* Overflow? */
if ((element < lastelement) ^ (code < 0))
node [endcode + sizeof (int) * CHAR_BIT + 1].count++;
else
{
/* Encode the offset */
m = (code ^ (code << 1));
if ((m & -((int) endcode)) == 0)
/* Simple code */
node [code & (endcode - 1)].count++;
else
{
/* Count the number of bits */
bitcount = sizeof (int) * CHAR_BIT;
while (((m >> (bitcount - 1)) & 1) == 0)
bitcount--;
node [endcode + bitcount].count++;
}
}
/* Update the previous element */
lastelement = element;
}
/* Make the minimum and maxium signed? */
minelement -= unsign;
maxelement -= unsign;
/* Save the minimum and maximum */
if (nelem)
{
*minelem = (int) minelement;
*maxelem = (int) maxelement;
}
/* End code */
node [endcode].count = 1;
data->nextnode = endcode + data->maxbits + 1;
/* Success */
return 0;
}
| cbf_compress_node* cbf_create_list | ( | cbf_compress_data * | data | ) |
Definition at line 513 of file cbf_canonical.c.
References cbf_compress_data::bits, cbf_insert_node(), cbf_order_node(), cbf_compress_nodestruct::child, cbf_compress_nodestruct::count, cbf_compress_data::maxbits, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
unsigned int count, endcode, codes;
cbf_compress_node *tree, *list, *node;
/* Sort the nodes */
endcode = 1 << data->bits;
codes = endcode + data->maxbits + 1;
node = data->node;
tree = NULL;
for (count = 0; count < codes; count++)
if (node [count].count)
tree = cbf_insert_node (tree, node + count);
list = cbf_order_node (tree);
/* Dismantle the tree */
for (count = 0; count < codes; count++)
node [count].child [0] =
node [count].child [1] = NULL;
return list;
}
| 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;
}
| void cbf_free_compressdata | ( | cbf_compress_data * | data | ) |
Definition at line 217 of file cbf_canonical.c.
References cbf_free(), cbf_compress_data::node, and cbf_compress_data::nodes.
Referenced by cbf_compress_canonical(), and cbf_decompress_canonical().
| int cbf_generate_canonicalcodes | ( | cbf_compress_data * | data | ) |
Definition at line 675 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcode, cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, bits(), CBF_ARGUMENT, CBF_MAXCODEBITS, cbf_reverse_bitcodes(), cbf_compress_nodestruct::count, cbf_compress_data::maxbits, and cbf_compress_data::node.
Referenced by cbf_compress_canonical(), and cbf_setup_decode().
{
unsigned int count [2],
base [CBF_MAXCODEBITS],
node, codes, endcode, bits;
endcode = 1 << data->bits;
codes = endcode + data->maxbits + 1;
/* Count the number of symbols with the same number of bits */
memset (base, 0, sizeof (base));
for (node = 0; node < codes; node++)
{
bits = data->node [node].bitcount;
if (bits > CBF_MAXCODEBITS)
return CBF_ARGUMENT;
if (bits > 0)
{
memset (data->node [node].bitcode, 0, 4 * sizeof (unsigned int));
data->node [node].bitcode [0] = base [bits - 1];
base [bits - 1]++;
}
}
/* Generate the initial code values */
count [0] = 0;
for (bits = CBF_MAXCODEBITS - 1; bits > 0; bits--)
{
count [1] = base [bits - 1];
base [bits - 1] = (base [bits] + count [0]) / 2;
count [0] = count [1];
}
/* Add the initial code to the count */
for (node = 0; node < codes; node++)
{
bits = data->node [node].bitcount;
if (bits > 0)
data->node [node].bitcode [0] += base [bits - 1];
}
/* Reverse the order of the bits in the code */
return cbf_reverse_bitcodes (data);
}
| int cbf_generate_codelengths | ( | cbf_compress_node * | tree, |
| int | bitcount | ||
| ) |
Definition at line 611 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, and cbf_compress_nodestruct::child.
Referenced by cbf_compress_canonical().
{
if (tree)
{
tree->bitcount = bitcount;
cbf_generate_codelengths (tree->child [0], bitcount + 1);
cbf_generate_codelengths (tree->child [1], bitcount + 1);
}
/* Success */
return 0;
}
| int cbf_get_code | ( | cbf_compress_data * | data, |
| cbf_compress_node * | root, | ||
| unsigned int * | code, | ||
| unsigned int * | bitcount | ||
| ) |
Definition at line 932 of file cbf_canonical.c.
References cbf_compress_data::bits, cbf_file::bits, CBF_ENDOFDATA, CBF_FILEREAD, CBF_FORMAT, cbf_get_bits(), cbf_compress_nodestruct::child, cbf_compress_nodestruct::code, cbf_compress_data::endcode, cbf_compress_data::file, cbf_compress_data::maxbits, and cbf_file::stream.
Referenced by cbf_decompress_canonical().
{
int bits0, bits1;
/* Decode the bitstream */
bits0 = data->file->bits [0];
bits1 = data->file->bits [1];
while (*(root->child))
{
if (bits0 == 0)
{
bits1 = getc (data->file->stream);
if (bits1 == EOF)
{
data->file->bits [0] =
data->file->bits [1] = 0;
return CBF_FILEREAD;
}
bits0 = 8;
}
root = root->child [bits1 & 1];
bits1 >>= 1;
bits0--;
}
data->file->bits [0] = bits0;
data->file->bits [1] = bits1;
*code = root->code;
/* Simple coding? */
if ((int) *code < (int) data->endcode)
{
*bitcount = data->bits;
return 0;
}
/* Coded bit count? */
*code -= data->endcode;
if (*code)
if (*code > data->maxbits)
return CBF_FORMAT;
else
{
*bitcount = *code;
return cbf_get_bits (data->file, (int *) code, *code);
}
/* End code */
return CBF_ENDOFDATA;
}
| int cbf_get_table | ( | cbf_compress_data * | data | ) |
Definition at line 381 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, bits(), cbf_failnez, cbf_get_integer(), cbf_initialise_compressdata(), CBF_TABLEENTRYBITS, cbf_compress_nodestruct::count, cbf_compress_data::file, cbf_compress_data::maxbits, cbf_compress_data::nextnode, and cbf_compress_data::node.
Referenced by cbf_decompress_canonical().
{
unsigned int bits, maxbits, endcode, count;
/* Coded bits */
cbf_failnez (cbf_get_integer (data->file, (int *) &bits, 0,
CBF_TABLEENTRYBITS))
/* Maximum number of bits */
cbf_failnez (cbf_get_integer (data->file, (int *) &maxbits, 0,
CBF_TABLEENTRYBITS))
/* Initialise the data */
cbf_failnez (cbf_initialise_compressdata (data, bits, maxbits))
/* Reserve nodes */
endcode = 1 << data->bits;
data->nextnode = endcode + data->maxbits + 1;
/* Read the table */
for (count = 0; count <= endcode + maxbits; count++)
{
cbf_failnez (cbf_get_integer (data->file, (int *) &bits, 0,
CBF_TABLEENTRYBITS))
if (count == endcode + 1)
count = endcode + data->bits + 1;
data->node [count].bitcount = bits;
}
/* Success */
return 0;
}
| int cbf_initialise_compressdata | ( | cbf_compress_data * | data, |
| unsigned int | bits, | ||
| unsigned int | maxbits | ||
| ) |
Definition at line 232 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, bits(), cbf_compress_data::bits, cbf_failnez, CBF_FORMAT, CBF_MAXBITS, CBF_MAXMAXBITS, cbf_realloc(), cbf_compress_nodestruct::child, cbf_compress_nodestruct::code, cbf_compress_nodestruct::count, cbf_compress_data::endcode, cbf_compress_data::maxbits, cbf_compress_nodestruct::next, cbf_compress_data::nextnode, cbf_compress_data::node, and cbf_compress_data::nodes.
Referenced by cbf_compress_canonical(), and cbf_get_table().
{
size_t count;
cbf_compress_node *node;
/* Coded bits */
if (bits > CBF_MAXBITS)
return CBF_FORMAT;
/* Codes must fit int + 1 bit */
if (maxbits > CBF_MAXMAXBITS)
return CBF_FORMAT;
if (maxbits < sizeof (int) * CHAR_BIT + 1)
{
maxbits = sizeof (int) * CHAR_BIT + 1;
if (maxbits > CBF_MAXMAXBITS)
maxbits = CBF_MAXMAXBITS;
}
if (maxbits < bits)
return CBF_FORMAT;
/* Update the values */
data->bits = bits;
data->maxbits = maxbits;
/* end-of-code code */
data->endcode = 1 << bits;
/* Allocate memory for the nodes */
count = (data->endcode + maxbits) * 2 + 1;
cbf_failnez (cbf_realloc ((void **) &data->node, &data->nodes,
sizeof (cbf_compress_node), count))
/* Initialise the nodes */
node = data->node;
for (count = 0; count < data->nodes; count++, node++)
{
node->bitcount = 0;
node->count = 0;
node->next =
node->child [0] =
node->child [1] = NULL;
if (count < data->endcode)
node->code = count - ((count << 1) & data->endcode);
else
node->code = count;
}
data->nextnode = 0;
/* Success */
return 0;
}
| cbf_compress_node* cbf_insert_node | ( | cbf_compress_node * | tree, |
| cbf_compress_node * | node | ||
| ) |
Definition at line 454 of file cbf_canonical.c.
References cbf_compress_nodestruct::child, and cbf_compress_nodestruct::count.
Referenced by cbf_create_list().
{
if (tree)
{
if (node->count > tree->count)
tree->child [1] = cbf_insert_node (tree->child [1], node);
else
tree->child [0] = cbf_insert_node (tree->child [0], node);
return tree;
}
return node;
}
| int cbf_make_compressdata | ( | cbf_compress_data ** | data, |
| cbf_file * | file | ||
| ) |
Definition at line 178 of file cbf_canonical.c.
References cbf_file::bits, cbf_alloc(), CBF_ARGUMENT, cbf_failnez, and cbf_file::stream.
Referenced by cbf_compress_canonical(), and cbf_decompress_canonical().
{
/* Does the file exist? */
if (!file)
return CBF_ARGUMENT;
if (!file->stream)
return CBF_ARGUMENT;
/* Allocate memory */
cbf_failnez (cbf_alloc ((void **) data, NULL, sizeof (cbf_compress_data), 1))
/* Initialise */
(*data)->file = file;
(*data)->bits = 0;
(*data)->maxbits = 0;
(*data)->endcode = 0;
(*data)->nodes = 0;
(*data)->nextnode = 0;
(*data)->node = NULL;
/* Success */
return 0;
}
| cbf_compress_node* cbf_order_node | ( | cbf_compress_node * | tree | ) |
Definition at line 500 of file cbf_canonical.c.
References cbf_append_node(), and cbf_compress_nodestruct::child.
Referenced by cbf_create_list().
{
if (tree)
return cbf_append_node (cbf_append_node (cbf_order_node (tree->child [0]),
tree), cbf_order_node (tree->child [1]));
return NULL;
}
| int cbf_put_code | ( | cbf_compress_data * | data, |
| int | code, | ||
| unsigned int | overflow, | ||
| unsigned int * | bitcount | ||
| ) |
Definition at line 1009 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcode, cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, bits(), cbf_put_bits(), cbf_compress_nodestruct::code, cbf_compress_data::file, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
unsigned int bits, m, endcode;
int overcode [2], *usecode;
cbf_compress_node *node;
endcode = 1 << data->bits;
/* Does the number fit in an integer? */
if (!overflow)
{
/* Code direct? */
m = (code ^ (code << 1));
if ((m & -((int) endcode)) == 0)
{
/* Code the number */
node = data->node + (code & (endcode - 1));
bits = node->bitcount;
cbf_put_bits (data->file, (int *) node->bitcode, bits);
*bitcount = bits;
return 0;
}
/* Count the number of bits */
bits = sizeof (int) * CHAR_BIT;
while (((m >> (bits - 1)) & 1) == 0)
bits--;
usecode = &code;
}
else
{
/* Overflow */
overcode [0] = code;
overcode [1] = -(code < 0);
usecode = overcode;
bits = sizeof (int) * CHAR_BIT;
}
/* Code the number of bits */
node = data->node + endcode + bits;
cbf_put_bits (data->file, (int *) node->bitcode, node->bitcount);
/* Write the number */
cbf_put_bits (data->file, usecode, bits);
*bitcount = bits + node->bitcount;
/* Success */
return 0;
}
| int cbf_put_stopcode | ( | cbf_compress_data * | data, |
| unsigned int * | bitcount | ||
| ) |
Definition at line 433 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcode, cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, cbf_failnez, cbf_put_bits(), cbf_compress_data::file, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
unsigned int endcode;
endcode = 1 << data->bits;
cbf_failnez (cbf_put_bits (data->file,
(int *) data->node [endcode].bitcode,
data->node [endcode].bitcount))
*bitcount = data->node [endcode].bitcount;
/* Success */
return 0;
}
| int cbf_put_table | ( | cbf_compress_data * | data, |
| unsigned int * | bitcount | ||
| ) |
Definition at line 320 of file cbf_canonical.c.
References cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, cbf_failnez, cbf_put_integer(), CBF_TABLEENTRYBITS, cbf_compress_nodestruct::count, cbf_compress_data::file, cbf_compress_data::maxbits, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
unsigned int count, codes, endcode, maxbits;
/* Coded bits */
cbf_failnez (cbf_put_integer (data->file, data->bits, 0, CBF_TABLEENTRYBITS))
*bitcount = CBF_TABLEENTRYBITS;
/* How many symbols do we actually use? */
endcode = 1 << data->bits;
for (codes = endcode + data->maxbits; data->node [codes].bitcount == 0;
codes--);
codes++;
/* Maximum bits used */
if (codes > endcode + data->bits)
maxbits = codes - endcode - 1;
else
maxbits = data->bits;
cbf_failnez (cbf_put_integer (data->file, maxbits, 0, CBF_TABLEENTRYBITS))
*bitcount += CBF_TABLEENTRYBITS;
/* Minimum-redundancy code lengths */
for (count = 0; count < codes; count++)
{
if (count == endcode + 1)
count = endcode + data->bits + 1;
cbf_failnez (cbf_put_integer (data->file,
data->node [count].bitcount, 0,
CBF_TABLEENTRYBITS))
*bitcount += CBF_TABLEENTRYBITS;
}
/* Success */
return 0;
}
| cbf_compress_node* cbf_reduce_list | ( | cbf_compress_data * | data, |
| cbf_compress_node * | list | ||
| ) |
Definition at line 552 of file cbf_canonical.c.
References cbf_compress_nodestruct::child, cbf_compress_nodestruct::count, cbf_compress_nodestruct::next, cbf_compress_data::nextnode, and cbf_compress_data::node.
Referenced by cbf_compress_canonical().
{
cbf_compress_node *node, *next, *cnext;
/* Construct a node */
node = data->node + data->nextnode;
data->nextnode++;
/* Attach the top nodes */
node->child [0] = list;
node->child [1] = list->next;
node->count = list->count + list->next->count;
/* Put it at the top */
next = node->next = list->next->next;
/* Order correct? */
if (next == NULL)
return node;
if (node->count <= next->count)
return node;
/* Otherwise move the node down to the correct position */
cnext = next;
while (cnext->next)
if (node->count < cnext->count || node->count > cnext->next->count)
cnext = cnext->next;
else
break;
node->next = cnext->next;
cnext->next = node;
return next;
}
| int cbf_reverse_bitcodes | ( | cbf_compress_data * | data | ) |
Definition at line 630 of file cbf_canonical.c.
References bit, cbf_compress_nodestruct::bitcode, cbf_compress_nodestruct::bitcount, cbf_compress_data::bits, cbf_compress_nodestruct::count, cbf_compress_data::maxbits, and cbf_compress_data::node.
Referenced by cbf_generate_canonicalcodes().
{
unsigned int node, endcode, codes, count, index [2][2], bit [2];
endcode = 1 << data->bits;
codes = endcode + data->maxbits + 1;
/* Reverse the order of the bits in the code */
for (node = 0; node < codes; node++)
if (data->node [node].bitcount > 0)
for (count = 0; count < data->node [node].bitcount - count - 1; count++)
{
bit [0] = count;
bit [1] = data->node [node].bitcount - count - 1;
index [0][0] = bit [0] % (sizeof (unsigned int) * CHAR_BIT);
index [0][1] = bit [0] / (sizeof (unsigned int) * CHAR_BIT);
index [1][0] = bit [1] % (sizeof (unsigned int) * CHAR_BIT);
index [1][1] = bit [1] / (sizeof (unsigned int) * CHAR_BIT);
bit [0] = (data->node [node].bitcode [index [0][1]]
>> (index [0][0])) & 1;
bit [1] = (data->node [node].bitcode [index [1][1]]
>> (index [1][0])) & 1;
data->node [node].bitcode [index [0][1]] ^= (bit [0] ^ bit [1])
<< index [0][0];
data->node [node].bitcode [index [1][1]] ^= (bit [0] ^ bit [1])
<< index [1][0];
}
/* Success */
return 0;
}
| int cbf_setup_decode | ( | cbf_compress_data * | data, |
| cbf_compress_node ** | start | ||
| ) |
Definition at line 858 of file cbf_canonical.c.
References cbf_compare_bitcodes(), cbf_construct_tree(), cbf_failnez, cbf_generate_canonicalcodes(), cbf_compress_data::nextnode, and cbf_compress_data::node.
Referenced by cbf_decompress_canonical().
{
/* Generate the codes */
cbf_failnez (cbf_generate_canonicalcodes (data))
/* Sort the nodes in order of the codes */
qsort (data->node, data->nextnode, sizeof (cbf_compress_node),
cbf_compare_bitcodes);
/* Construct the tree */
return cbf_construct_tree (data, NULL, 1, start);
}
1.7.3