OSDN Git Service

huf.c was refined.
authorKoji Arai <jca02266@gmail.com>
Thu, 19 Jun 2008 14:51:33 +0000 (23:51 +0900)
committerKoji Arai <jca02266@gmail.com>
Thu, 19 Jun 2008 14:51:33 +0000 (23:51 +0900)
huf.c

diff --git a/huf.c b/huf.c
index 14c13e6..db46448 100644 (file)
--- a/huf.c
+++ b/huf.c
@@ -166,32 +166,99 @@ encode_p(struct lzh_ostream *wp, uint p)
         putbits(wp, c - 1, p & (0xFFFFU >> (17 - c)));
 }
 
+/*
+  output format for a block.
+
+    +-----------+
+    | blocksize |
+    +-----------+
+     16bit
+
+    +-----+--------------------+
+    | len |      pt_len        | Huffman tree for c_len[]
+    +-----+--------------------+
+      5bit        ?? bit
+      TBIT
+
+    +-------+------------------+
+    |  len  |     c_len        | Huffman tree for characters and length
+    +-------+------------------+
+      9bit        ?? bit
+      CBIT
+
+    +---------+--------------------+
+    |   len   |   pt_len           | Huffman tree for offset
+    +---------+--------------------+
+     pbit         ?? bit
+                               (pbit=4bit(lh4,5) or 5bit(lh6,7))
+
+    +---------------------+
+    |  encoding text      |
+    +---------------------+
+
+
+  In special case, only one kind characters in a block.
+
+                  TBIT: 5 bits
+                  CBIT: 9 bits
+
+    +-----------+
+    | blocksize |
+    +-----------+
+     16bit
+
+    +-----+-----+
+    |  0  |  0  | Huffman tree for c_len[]
+    +-----+-----+
+      TBIT  TBIT
+
+    +-------+-------+
+    |  0    |  0    | Huffman tree for characters and length
+    +-------+-------+
+      CBIT    CBIT
+
+    +---------+--------------+
+    |  0      | offset value | Huffman tree for offset
+    +---------+--------------+
+     pbit         pbit
+                               (pbit=4bit(lh4,5) or 5bit(lh6,7))
+
+    +---------------------+
+    |  encoding text      |
+    +---------------------+
+ */
 static void
 send_block(struct lzh_ostream *wp)
 {
     uint i, k, flags, root, pos, size;
 
+    /* make Huffman tree for characters and length */
     root = make_tree(NC, c_freq, c_len, c_code);
     size = c_freq[root];
     putbits(wp, 16, size);
     if (root >= NC) {
+        /* make Huffman tree for c_len */
         count_t_freq();
         root = make_tree(NT, t_freq, pt_len, pt_code);
         if (root >= NT) {
             write_pt_len(wp, NT, TBIT, 3);
         }
         else {
+            /* only one kind */
             putbits(wp, TBIT, 0);
             putbits(wp, TBIT, root);
         }
         write_c_len(wp);
     }
     else {
+        /* only one kind */
         putbits(wp, TBIT, 0);
         putbits(wp, TBIT, 0);
         putbits(wp, CBIT, 0);
         putbits(wp, CBIT, root);
     }
+
+    /* make Huffman tree for offset */
     root = make_tree(np, p_freq, pt_len, pt_code);
     if (root >= np) {
         write_pt_len(wp, np, pbit, -1);
@@ -200,6 +267,8 @@ send_block(struct lzh_ostream *wp)
         putbits(wp, pbit, 0);
         putbits(wp, pbit, root);
     }
+
+    /* write Huffman encoding */
     pos = 0;
     for (i = 0; i < size; i++) {
         if (i % CHAR_BIT == 0)
@@ -207,16 +276,22 @@ send_block(struct lzh_ostream *wp)
         else
             flags <<= 1;
         if (flags & (1U << (CHAR_BIT - 1))) {
+            /* write length */
             encode_c(wp, wp->buf[pos++] + (1U << CHAR_BIT));
+            /* write offset */
             k = wp->buf[pos++] << CHAR_BIT;
             k += wp->buf[pos++];
             encode_p(wp, k);
         }
-        else
+        else {
+            /* write character */
             encode_c(wp, wp->buf[pos++]);
+        }
         if (wp->unpackable)
             return;
     }
+
+    /* clear frequency table */
     for (i = 0; i < NC; i++)
         c_freq[i] = 0;
     for (i = 0; i < np; i++)
@@ -237,7 +312,8 @@ buf     |  32 | c1  | c2  | len |    off    |  c3 |  c4 |  c5 |  c6 |  c7 |
         cpos                                                             /
                                                                         /
                                                                output_pos
-
+c_freq[] has frequency of cN and len.
+p_freq[] has frequency of length of off bits.
 */
 void
 output(struct lzh_ostream *wp, uint c, uint p)