#define NPT NP
#endif
-static uchar c_len[NC], pt_len[NPT];
-static ushort c_freq[2 * NC - 1], c_table[4096], c_code[NC],
- p_freq[2 * NP - 1], pt_table[256], pt_code[NPT], t_freq[2 * NT - 1];
-
static int np;
static int pbit;
+/* encoding/decoding */
+static uchar c_len[NC], pt_len[NPT];
+
+/* encoding */
+static ushort c_freq[2 * NC - 1], c_code[NC];
+static ushort p_freq[2 * NP - 1], pt_code[NPT];
+static ushort t_freq[2 * NT - 1];
+
+/*
+ size frequency bitlength Huffman coding
+ -----------------------------------------------------------
+ NC c_freq c_len c_code
+ NT t_freq pt_len pt_code
+ np p_freq pt_len pt_code
+ */
+
+/* decoding */
+static ushort c_table[4096], pt_table[256];
+
static void
init_parameter(struct lha_method *m)
{
p_freq[i] = 0;
}
-static uint output_pos, output_mask;
+/*
+ call with output(wp, c, 0)
+ or output(wp, len, off)
+
+ block
+
+output_mask 128 64 32 16 8 4 2 1
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+buf | 32 | c1 | c2 | len | off | c3 | c4 | c5 | c6 | c7 |
+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ cpos /
+ /
+ output_pos
+
+*/
void
output(struct lzh_ostream *wp, uint c, uint p)
{
- static uint cpos;
-
- if ((output_mask >>= 1) == 0) {
- output_mask = 1U << (CHAR_BIT - 1);
- if (output_pos >= wp->bufsiz - 3 * CHAR_BIT) {
+ if ((wp->output_mask >>= 1) == 0) {
+ wp->output_mask = 1U << (CHAR_BIT - 1);
+ if (wp->output_pos >= wp->bufsiz - 3 * CHAR_BIT) {
send_block(wp);
if (wp->unpackable)
return;
- output_pos = 0;
+ wp->output_pos = 0;
}
- cpos = output_pos++;
- wp->buf[cpos] = 0;
+ wp->cpos = wp->output_pos++;
+ wp->buf[wp->cpos] = 0;
}
- wp->buf[output_pos++] = (uchar) c;
+ wp->buf[wp->output_pos++] = (uchar) c;
c_freq[c]++;
+
if (c >= (1U << CHAR_BIT)) {
- wp->buf[cpos] |= output_mask;
- wp->buf[output_pos++] = (uchar) (p >> CHAR_BIT);
- wp->buf[output_pos++] = (uchar) p;
- c = 0;
- while (p) {
- p >>= 1;
- c++;
+ /* c is length, p is offset */
+ wp->buf[wp->cpos] |= wp->output_mask;
+ wp->buf[wp->output_pos++] = (uchar) (p >> CHAR_BIT);
+ wp->buf[wp->output_pos++] = (uchar) p;
+
+ {
+ /* count frequency of p's bit length */
+ int n = 0; /* max of n is np-1 */
+ while (p) {
+ p >>= 1;
+ n++;
+ }
+ p_freq[n]++;
}
- p_freq[c]++;
}
}
int i;
init_parameter(m);
+ wp->output_pos = wp->output_mask = wp->cpos = 0;
if (wp->buf == 0) {
wp->bufsiz = 16 * 1024U;
c_freq[i] = 0;
for (i = 0; i < np; i++)
p_freq[i] = 0;
- output_pos = output_mask = 0;
+
init_putbits(wp);
}