OSDN Git Service

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