OSDN Git Service

should check the tree1 value
[lha/lha.git] / src / pm2.c
1 /***********************************************************
2         pm2.c -- extract pmext2 coding
3 ***********************************************************/
4 #include "lha.h"
5 #include "pm2hist.h"
6 #include "pm2tree.h"
7
8 static off_t nextcount;
9 static unsigned long lastupdate;
10
11 /* repeated from slide.c */
12 static unsigned int dicsiz1;
13 #define offset (0x100 - 2)
14
15 void
16 decode_start_pm2(void)
17 {
18     dicsiz1 = (1 << dicbit) - 1;
19     init_getbits();
20     hist_init();
21     nextcount = 0;
22     lastupdate = 0;
23     getbits(1);                 /* discard bit */
24 }
25
26
27 static unsigned char gettree1;
28
29 static int historyBits[8] = {   3,   3,   4,   5,   5,   5,   6,   6 };
30 static int historyBase[8] = {   0,   8,  16,  32,  64,  96, 128, 192 };
31 static int repeatBits[6]  = {   3,   3,   5,   6,   7,   0 };
32 static int repeatBase[6]  = {  17,  25,  33,  65, 129, 256 };
33
34 unsigned short
35 decode_c_pm2(void)
36 {
37     /* various admin: */
38     while (lastupdate != loc) {
39         hist_update(dtext[lastupdate]);
40         lastupdate = (lastupdate + 1) & dicsiz1;
41     }
42
43     while (decode_count >= nextcount) {
44         /* Actually it will never loop, because decode_count doesn't grow that fast.
45            However, this is the way LHA does it.
46            Probably other encoding methods can have repeats larger than 256 bytes.
47            Note: LHA puts this code in decode_p...
48         */
49
50         switch (nextcount) {
51         case 0x0000:
52             maketree1();
53             maketree2(5);
54             nextcount = 0x0400;
55             break;
56         case 0x0400:
57             maketree2(6);
58             nextcount = 0x0800;
59             break;
60         case 0x0800:
61             maketree2(7);
62             nextcount = 0x1000;
63             break;
64         case 0x1000:
65             if (getbits(1) != 0)
66                 maketree1();
67             maketree2(8);
68             nextcount = 0x2000;
69             break;
70         default:                /* 0x2000, 0x3000, 0x4000, ... */
71             if (getbits(1) != 0) {
72                 maketree1();
73                 maketree2(8);
74             }
75             nextcount += 0x1000;
76             break;
77         }
78     }
79     gettree1 = tree_get(&tree1);        /* value preserved for decode_p */
80     if (gettree1 >= 29) {
81         error("Bad table");
82         exit(1);
83     }
84
85     /* direct value (ret <= UCHAR_MAX) */
86     if (gettree1 < 8)
87         return hist_lookup(historyBase[gettree1] +
88                            getbits(historyBits[gettree1]));
89     /* repeats: (ret > UCHAR_MAX) */
90     if (gettree1 < 23)
91         return offset + 2 + (gettree1 - 8);
92
93     return offset + repeatBase[gettree1 - 23]
94         + getbits(repeatBits[gettree1 - 23]);
95 }
96
97 unsigned short
98 decode_p_pm2(void)
99 {
100     /* gettree1 value preserved from decode_c */
101     int nbits, delta, gettree2;
102     if (gettree1 == 8) {        /* 2-byte repeat with offset 0..63 */
103         nbits = 6;
104         delta = 0;
105     }
106     else if (gettree1 < 28) {   /* n-byte repeat with offset 0..8191 */
107         gettree2 = tree_get(&tree2);
108         if (gettree2 == 0) {
109             nbits = 6;
110             delta = 0;
111         }
112         else {                  /* 1..7 */
113             nbits = 5 + gettree2;
114             delta = 1 << nbits;
115         }
116     }
117     else {                      /* 256 bytes repeat with offset 0 */
118         nbits = 0;
119         delta = 0;
120     }
121
122     return delta + getbits(nbits);
123 }