|
|
1.1 root 1: /*---------------------------------------------------------------------------
2:
3: unreduce.c
4:
5: The Reducing algorithm is actually a combination of two distinct algorithms.
6: The first algorithm compresses repeated byte sequences, and the second al-
7: gorithm takes the compressed stream from the first algorithm and applies a
8: probabilistic compression method.
9:
10: ---------------------------------------------------------------------------*/
11:
12:
13: #include "unzip.h"
14:
15:
16: /**************************************/
17: /* UnReduce Defines, Typedefs, etc. */
18: /**************************************/
19:
20: #define DLE 144
21:
22: typedef byte f_array[64]; /* for followers[256][64] */
23:
24: static void LoadFollowers __((void));
25: void flush OF((unsigned)); /* routine from inflate.c */
26:
27:
28:
29: /*******************************/
30: /* UnReduce Global Variables */
31: /*******************************/
32:
33: #if (defined(MACOS) || defined(MTS))
34: f_array *followers; /* shared work space */
35: #else
36: f_array *followers = (f_array *) (slide + 0x4000);
37: #endif
38:
39: byte Slen[256];
40: int factor;
41:
42: int L_table[] =
43: {0, 0x7f, 0x3f, 0x1f, 0x0f};
44:
45: int D_shift[] =
46: {0, 0x07, 0x06, 0x05, 0x04};
47: int D_mask[] =
48: {0, 0x01, 0x03, 0x07, 0x0f};
49:
50: int B_table[] =
51: {8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
52: 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
53: 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
54: 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
55: 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
56: 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
57: 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
58: 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
59: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
60: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
61: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
62: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
63: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
64: 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
65: 8, 8, 8, 8};
66:
67:
68:
69:
70:
71: /*************************/
72: /* Function unReduce() */
73: /*************************/
74:
75: void unReduce() /* expand probabilistically reduced data */
76: {
77: register int lchar = 0;
78: int nchar;
79: int ExState = 0;
80: int V = 0;
81: int Len = 0;
82: longint s = ucsize; /* number of bytes left to decompress */
83: unsigned w = 0; /* position in output window slide[] */
84: unsigned u = 1; /* true if slide[] unflushed */
85:
86:
87: #if (defined(MACOS) || defined(MTS))
88: followers = (f_array *) (slide + 0x4000);
89: #endif
90:
91: factor = lrec.compression_method - 1;
92: LoadFollowers();
93:
94: while (s > 0 /* && (!zipeof) */) {
95: if (Slen[lchar] == 0)
96: READBIT(8, nchar) /* ; */
97: else {
98: READBIT(1, nchar);
99: if (nchar != 0)
100: READBIT(8, nchar) /* ; */
101: else {
102: int follower;
103: int bitsneeded = B_table[Slen[lchar]];
104: READBIT(bitsneeded, follower);
105: nchar = followers[lchar][follower];
106: }
107: }
108: /* expand the resulting byte */
109: switch (ExState) {
110:
111: case 0:
112: if (nchar != DLE) {
113: s--;
114: slide[w++] = (byte) nchar;
115: if (w == 0x4000) {
116: flush(w);
117: w = u = 0;
118: }
119: }
120: else
121: ExState = 1;
122: break;
123:
124: case 1:
125: if (nchar != 0) {
126: V = nchar;
127: Len = V & L_table[factor];
128: if (Len == L_table[factor])
129: ExState = 2;
130: else
131: ExState = 3;
132: } else {
133: s--;
134: slide[w++] = DLE;
135: if (w == 0x4000)
136: {
137: flush(w);
138: w = u = 0;
139: }
140: ExState = 0;
141: }
142: break;
143:
144: case 2:{
145: Len += nchar;
146: ExState = 3;
147: }
148: break;
149:
150: case 3:{
151: register unsigned e;
152: register unsigned n = Len + 3;
153: register unsigned d = w - ((((V >> D_shift[factor]) &
154: D_mask[factor]) << 8) + nchar + 1);
155:
156: s -= n;
157: do {
158: n -= (e = (e = 0x4000 - ((d &= 0x3fff) > w ? d : w)) > n ?
159: n : e);
160: if (u && w <= d)
161: {
162: memset(slide + w, 0, e);
163: w += e;
164: d += e;
165: }
166: else
167: if (w - d < e) /* (assume unsigned comparison) */
168: do { /* slow to avoid memcpy() overlap */
169: slide[w++] = slide[d++];
170: } while (--e);
171: else
172: {
173: memcpy(slide + w, slide + d, e);
174: w += e;
175: d += e;
176: }
177: if (w == 0x4000)
178: {
179: flush(w);
180: w = u = 0;
181: }
182: } while (n);
183:
184: ExState = 0;
185: }
186: break;
187: }
188:
189: /* store character for next iteration */
190: lchar = nchar;
191: }
192:
193: /* flush out slide */
194: flush(w);
195: }
196:
197:
198:
199:
200:
201: /******************************/
202: /* Function LoadFollowers() */
203: /******************************/
204:
205: static void LoadFollowers()
206: {
207: register int x;
208: register int i;
209:
210: for (x = 255; x >= 0; x--) {
211: READBIT(6, Slen[x]);
212: for (i = 0; (byte) i < Slen[x]; i++) {
213: READBIT(8, followers[x][i]);
214: }
215: }
216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.