summaryrefslogtreecommitdiff
path: root/xdelta3/xdelta3-fgk.h
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3/xdelta3-fgk.h')
-rw-r--r--xdelta3/xdelta3-fgk.h67
1 files changed, 38 insertions, 29 deletions
diff --git a/xdelta3/xdelta3-fgk.h b/xdelta3/xdelta3-fgk.h
index f5d8fc6..b2b8f09 100644
--- a/xdelta3/xdelta3-fgk.h
+++ b/xdelta3/xdelta3-fgk.h
@@ -22,11 +22,12 @@
22#ifndef _XDELTA3_FGK_h_ 22#ifndef _XDELTA3_FGK_h_
23#define _XDELTA3_FGK_h_ 23#define _XDELTA3_FGK_h_
24 24
25/* An implementation of the FGK algorithm described by D.E. Knuth in "Dynamic Huffman 25/* An implementation of the FGK algorithm described by D.E. Knuth in
26 * Coding" in Journal of Algorithms 6. */ 26 * "Dynamic Huffman Coding" in Journal of Algorithms 6. */
27 27
28/* A 32bit counter (fgk_weight) is used as the frequency counter for nodes in the huffman 28/* A 32bit counter (fgk_weight) is used as the frequency counter for
29 * tree. TODO: Need to test for overflow and/or reset stats. */ 29 * nodes in the huffman tree. TODO: Need oto test for overflow and/or
30 * reset stats. */
30 31
31typedef struct _fgk_stream fgk_stream; 32typedef struct _fgk_stream fgk_stream;
32typedef struct _fgk_node fgk_node; 33typedef struct _fgk_node fgk_node;
@@ -47,12 +48,14 @@ struct _fgk_block {
47/* The code can also support fixed huffman encoding/decoding. */ 48/* The code can also support fixed huffman encoding/decoding. */
48#define IS_ADAPTIVE 1 49#define IS_ADAPTIVE 1
49 50
50/* weight is a count of the number of times this element has been seen in the current 51/* weight is a count of the number of times this element has been seen
51 * encoding/decoding. parent, right_child, and left_child are pointers defining the tree 52 * in the current encoding/decoding. parent, right_child, and
52 * structure. right and left point to neighbors in an ordered sequence of 53 * left_child are pointers defining the tree structure. right and
53 * weights. The left child of a node is always guaranteed to have weight not greater than 54 * left point to neighbors in an ordered sequence of weights. The
54 * its sibling. fgk_blockLeader points to the element with the same weight as itself which is 55 * left child of a node is always guaranteed to have weight not
55 * closest to the next increasing weight block. */ 56 * greater than its sibling. fgk_blockLeader points to the element
57 * with the same weight as itself which is closest to the next
58 * increasing weight block. */
56struct _fgk_node 59struct _fgk_node
57{ 60{
58 fgk_weight weight; 61 fgk_weight weight;
@@ -64,14 +67,17 @@ struct _fgk_node
64 fgk_block *my_block; 67 fgk_block *my_block;
65}; 68};
66 69
67/* alphabet_size is the a count of the number of possible leaves in the huffman tree. The 70/* alphabet_size is the a count of the number of possible leaves in
68 * number of total nodes counting internal nodes is ((2 * alphabet_size) - 1). 71 * the huffman tree. The number of total nodes counting internal
69 * zero_freq_count is the number of elements remaining which have zero frequency. 72 * nodes is ((2 * alphabet_size) - 1). zero_freq_count is the number
70 * zero_freq_exp and zero_freq_rem satisfy the equation zero_freq_count = 2^zero_freq_exp + 73 * of elements remaining which have zero frequency. zero_freq_exp and
71 * zero_freq_rem. root_node is the root of the tree, which is initialized to a node with 74 * zero_freq_rem satisfy the equation zero_freq_count =
72 * zero frequency and contains the 0th such element. free_node contains a pointer to the 75 * 2^zero_freq_exp + zero_freq_rem. root_node is the root of the
73 * next available fgk_node space. alphabet contains all the elements and is indexed by N. 76 * tree, which is initialized to a node with zero frequency and
74 * remaining_zeros points to the head of the list of zeros. */ 77 * contains the 0th such element. free_node contains a pointer to the
78 * next available fgk_node space. alphabet contains all the elements
79 * and is indexed by N. remaining_zeros points to the head of the
80 * list of zeros. */
75struct _fgk_stream 81struct _fgk_stream
76{ 82{
77 int alphabet_size; 83 int alphabet_size;
@@ -533,9 +539,10 @@ static fgk_node* fgk_increase_zero_weight (fgk_stream *h, int n)
533 return this_zero; 539 return this_zero;
534} 540}
535 541
536/* When a zero frequency element is encoded, it is followed by the binary representation 542/* When a zero frequency element is encoded, it is followed by the
537 * of the index into the remaining elements. Sets a cache to the element before it so 543 * binary representation of the index into the remaining elements.
538 * that it can be removed without calling this procedure again. */ 544 * Sets a cache to the element before it so that it can be removed
545 * without calling this procedure again. */
539static unsigned int fgk_find_nth_zero (fgk_stream* h, int n) 546static unsigned int fgk_find_nth_zero (fgk_stream* h, int n)
540{ 547{
541 fgk_node *target_ptr = h->alphabet + n; 548 fgk_node *target_ptr = h->alphabet + n;
@@ -604,9 +611,10 @@ static void fgk_init_node (fgk_node *node, int i, int size)
604 node->my_block = NULL; 611 node->my_block = NULL;
605} 612}
606 613
607/* The data structure used is an array of blocks, which are unions of free pointers and 614/* The data structure used is an array of blocks, which are unions of
608 * huffnode pointers. free blocks are a linked list of free blocks, the front of which is 615 * free pointers and huffnode pointers. free blocks are a linked list
609 * h->free_block. The used blocks are pointers to the head of each block. */ 616 * of free blocks, the front of which is h->free_block. The used
617 * blocks are pointers to the head of each block. */
610static fgk_block* fgk_make_block (fgk_stream *h, fgk_node* lead) 618static fgk_block* fgk_make_block (fgk_stream *h, fgk_node* lead)
611{ 619{
612 fgk_block *ret = h->free_block; 620 fgk_block *ret = h->free_block;
@@ -627,8 +635,8 @@ static void fgk_free_block (fgk_stream *h, fgk_block *b)
627 h->free_block = b; 635 h->free_block = b;
628} 636}
629 637
630/* sets zero_freq_count, zero_freq_rem, and zero_freq_exp to satsity the equation given 638/* sets zero_freq_count, zero_freq_rem, and zero_freq_exp to satsity
631 * above. */ 639 * the equation given above. */
632static void fgk_factor_remaining (fgk_stream *h) 640static void fgk_factor_remaining (fgk_stream *h)
633{ 641{
634 unsigned int i; 642 unsigned int i;
@@ -705,9 +713,10 @@ static int fgk_nth_zero (fgk_stream* h, int n)
705{ 713{
706 fgk_node *ret = h->remaining_zeros; 714 fgk_node *ret = h->remaining_zeros;
707 715
708 /* ERROR: if during this loop (ret->right_child == NULL) then the encoder's zero count 716 /* ERROR: if during this loop (ret->right_child == NULL) then the
709 * is too high. Could return an error code now, but is probably unnecessary overhead, 717 * encoder's zero count is too high. Could return an error code
710 * since the caller should check integrity anyway. */ 718 * now, but is probably unnecessary overhead, since the caller
719 * should check integrity anyway. */
711 for (; n != 0 && ret->right_child != NULL; n -= 1) 720 for (; n != 0 && ret->right_child != NULL; n -= 1)
712 { 721 {
713 ret = ret->right_child; 722 ret = ret->right_child;