diff options
Diffstat (limited to 'xdelta3/xdelta3-fgk.h')
-rw-r--r-- | xdelta3/xdelta3-fgk.h | 67 |
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 | ||
31 | typedef struct _fgk_stream fgk_stream; | 32 | typedef struct _fgk_stream fgk_stream; |
32 | typedef struct _fgk_node fgk_node; | 33 | typedef 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. */ | ||
56 | struct _fgk_node | 59 | struct _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. */ | ||
75 | struct _fgk_stream | 81 | struct _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. */ | ||
539 | static unsigned int fgk_find_nth_zero (fgk_stream* h, int n) | 546 | static 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. */ | ||
610 | static fgk_block* fgk_make_block (fgk_stream *h, fgk_node* lead) | 618 | static 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. */ |
632 | static void fgk_factor_remaining (fgk_stream *h) | 640 | static 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; |