Blame


1 7a4ee46d 2003-11-23 devnull #include "stdinc.h"
2 7a4ee46d 2003-11-23 devnull #include "whack.h"
3 7a4ee46d 2003-11-23 devnull
4 7a4ee46d 2003-11-23 devnull enum
5 7a4ee46d 2003-11-23 devnull {
6 7a4ee46d 2003-11-23 devnull DMaxFastLen = 7,
7 7a4ee46d 2003-11-23 devnull DBigLenCode = 0x3c, /* minimum code for large lenth encoding */
8 7a4ee46d 2003-11-23 devnull DBigLenBits = 6,
9 7a4ee46d 2003-11-23 devnull DBigLenBase = 1 /* starting items to encode for big lens */
10 7a4ee46d 2003-11-23 devnull };
11 7a4ee46d 2003-11-23 devnull
12 7a4ee46d 2003-11-23 devnull static uchar lenval[1 << (DBigLenBits - 1)] =
13 7a4ee46d 2003-11-23 devnull {
14 7a4ee46d 2003-11-23 devnull 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15 7a4ee46d 2003-11-23 devnull 3, 3, 3, 3, 3, 3, 3, 3,
16 7a4ee46d 2003-11-23 devnull 4, 4, 4, 4,
17 7a4ee46d 2003-11-23 devnull 5,
18 7a4ee46d 2003-11-23 devnull 6,
19 7a4ee46d 2003-11-23 devnull 255,
20 7a4ee46d 2003-11-23 devnull 255
21 7a4ee46d 2003-11-23 devnull };
22 7a4ee46d 2003-11-23 devnull
23 7a4ee46d 2003-11-23 devnull static uchar lenbits[] =
24 7a4ee46d 2003-11-23 devnull {
25 7a4ee46d 2003-11-23 devnull 0, 0, 0,
26 7a4ee46d 2003-11-23 devnull 2, 3, 5, 5,
27 7a4ee46d 2003-11-23 devnull };
28 7a4ee46d 2003-11-23 devnull
29 7a4ee46d 2003-11-23 devnull static uchar offbits[16] =
30 7a4ee46d 2003-11-23 devnull {
31 7a4ee46d 2003-11-23 devnull 5, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 12, 13
32 7a4ee46d 2003-11-23 devnull };
33 7a4ee46d 2003-11-23 devnull
34 7a4ee46d 2003-11-23 devnull static ushort offbase[16] =
35 7a4ee46d 2003-11-23 devnull {
36 7a4ee46d 2003-11-23 devnull 0, 0x20,
37 7a4ee46d 2003-11-23 devnull 0x40, 0x60,
38 7a4ee46d 2003-11-23 devnull 0x80, 0xc0,
39 7a4ee46d 2003-11-23 devnull 0x100, 0x180,
40 7a4ee46d 2003-11-23 devnull 0x200, 0x300,
41 7a4ee46d 2003-11-23 devnull 0x400, 0x600,
42 7a4ee46d 2003-11-23 devnull 0x800, 0xc00,
43 7a4ee46d 2003-11-23 devnull 0x1000,
44 7a4ee46d 2003-11-23 devnull 0x2000
45 7a4ee46d 2003-11-23 devnull };
46 7a4ee46d 2003-11-23 devnull
47 7a4ee46d 2003-11-23 devnull void
48 7a4ee46d 2003-11-23 devnull unwhackinit(Unwhack *uw)
49 7a4ee46d 2003-11-23 devnull {
50 7a4ee46d 2003-11-23 devnull uw->err[0] = '\0';
51 7a4ee46d 2003-11-23 devnull }
52 7a4ee46d 2003-11-23 devnull
53 7a4ee46d 2003-11-23 devnull int
54 7a4ee46d 2003-11-23 devnull unwhack(Unwhack *uw, uchar *dst, int ndst, uchar *src, int nsrc)
55 7a4ee46d 2003-11-23 devnull {
56 7a4ee46d 2003-11-23 devnull uchar *s, *d, *dmax, *smax, lit;
57 7a4ee46d 2003-11-23 devnull ulong uwbits, lithist;
58 7a4ee46d 2003-11-23 devnull int i, off, len, bits, use, code, uwnbits, overbits;
59 7a4ee46d 2003-11-23 devnull
60 7a4ee46d 2003-11-23 devnull d = dst;
61 7a4ee46d 2003-11-23 devnull dmax = d + ndst;
62 7a4ee46d 2003-11-23 devnull
63 7a4ee46d 2003-11-23 devnull smax = src + nsrc;
64 7a4ee46d 2003-11-23 devnull uwnbits = 0;
65 7a4ee46d 2003-11-23 devnull uwbits = 0;
66 7a4ee46d 2003-11-23 devnull overbits = 0;
67 7a4ee46d 2003-11-23 devnull lithist = ~0;
68 7a4ee46d 2003-11-23 devnull while(src < smax || uwnbits - overbits >= MinDecode){
69 7a4ee46d 2003-11-23 devnull while(uwnbits <= 24){
70 7a4ee46d 2003-11-23 devnull uwbits <<= 8;
71 7a4ee46d 2003-11-23 devnull if(src < smax)
72 7a4ee46d 2003-11-23 devnull uwbits |= *src++;
73 7a4ee46d 2003-11-23 devnull else
74 7a4ee46d 2003-11-23 devnull overbits += 8;
75 7a4ee46d 2003-11-23 devnull uwnbits += 8;
76 7a4ee46d 2003-11-23 devnull }
77 7a4ee46d 2003-11-23 devnull
78 7a4ee46d 2003-11-23 devnull /*
79 7a4ee46d 2003-11-23 devnull * literal
80 7a4ee46d 2003-11-23 devnull */
81 7a4ee46d 2003-11-23 devnull len = lenval[(uwbits >> (uwnbits - 5)) & 0x1f];
82 7a4ee46d 2003-11-23 devnull if(len == 0){
83 7a4ee46d 2003-11-23 devnull if(lithist & 0xf){
84 7a4ee46d 2003-11-23 devnull uwnbits -= 9;
85 7a4ee46d 2003-11-23 devnull lit = (uwbits >> uwnbits) & 0xff;
86 7a4ee46d 2003-11-23 devnull lit &= 255;
87 7a4ee46d 2003-11-23 devnull }else{
88 7a4ee46d 2003-11-23 devnull uwnbits -= 8;
89 7a4ee46d 2003-11-23 devnull lit = (uwbits >> uwnbits) & 0x7f;
90 7a4ee46d 2003-11-23 devnull if(lit < 32){
91 7a4ee46d 2003-11-23 devnull if(lit < 24){
92 7a4ee46d 2003-11-23 devnull uwnbits -= 2;
93 7a4ee46d 2003-11-23 devnull lit = (lit << 2) | ((uwbits >> uwnbits) & 3);
94 7a4ee46d 2003-11-23 devnull }else{
95 7a4ee46d 2003-11-23 devnull uwnbits -= 3;
96 7a4ee46d 2003-11-23 devnull lit = (lit << 3) | ((uwbits >> uwnbits) & 7);
97 7a4ee46d 2003-11-23 devnull }
98 7a4ee46d 2003-11-23 devnull lit = (lit - 64) & 0xff;
99 7a4ee46d 2003-11-23 devnull }
100 7a4ee46d 2003-11-23 devnull }
101 7a4ee46d 2003-11-23 devnull if(d >= dmax){
102 7a4ee46d 2003-11-23 devnull snprint(uw->err, WhackErrLen, "too much output");
103 7a4ee46d 2003-11-23 devnull return -1;
104 7a4ee46d 2003-11-23 devnull }
105 7a4ee46d 2003-11-23 devnull *d++ = lit;
106 7a4ee46d 2003-11-23 devnull lithist = (lithist << 1) | (lit < 32) | (lit > 127);
107 7a4ee46d 2003-11-23 devnull continue;
108 7a4ee46d 2003-11-23 devnull }
109 7a4ee46d 2003-11-23 devnull
110 7a4ee46d 2003-11-23 devnull /*
111 7a4ee46d 2003-11-23 devnull * length
112 7a4ee46d 2003-11-23 devnull */
113 7a4ee46d 2003-11-23 devnull if(len < 255)
114 7a4ee46d 2003-11-23 devnull uwnbits -= lenbits[len];
115 7a4ee46d 2003-11-23 devnull else{
116 7a4ee46d 2003-11-23 devnull uwnbits -= DBigLenBits;
117 7a4ee46d 2003-11-23 devnull code = ((uwbits >> uwnbits) & ((1 << DBigLenBits) - 1)) - DBigLenCode;
118 7a4ee46d 2003-11-23 devnull len = DMaxFastLen;
119 7a4ee46d 2003-11-23 devnull use = DBigLenBase;
120 7a4ee46d 2003-11-23 devnull bits = (DBigLenBits & 1) ^ 1;
121 7a4ee46d 2003-11-23 devnull while(code >= use){
122 7a4ee46d 2003-11-23 devnull len += use;
123 7a4ee46d 2003-11-23 devnull code -= use;
124 7a4ee46d 2003-11-23 devnull code <<= 1;
125 7a4ee46d 2003-11-23 devnull uwnbits--;
126 7a4ee46d 2003-11-23 devnull if(uwnbits < 0){
127 7a4ee46d 2003-11-23 devnull snprint(uw->err, WhackErrLen, "len out of range");
128 7a4ee46d 2003-11-23 devnull return -1;
129 7a4ee46d 2003-11-23 devnull }
130 7a4ee46d 2003-11-23 devnull code |= (uwbits >> uwnbits) & 1;
131 7a4ee46d 2003-11-23 devnull use <<= bits;
132 7a4ee46d 2003-11-23 devnull bits ^= 1;
133 7a4ee46d 2003-11-23 devnull }
134 7a4ee46d 2003-11-23 devnull len += code;
135 7a4ee46d 2003-11-23 devnull
136 7a4ee46d 2003-11-23 devnull while(uwnbits <= 24){
137 7a4ee46d 2003-11-23 devnull uwbits <<= 8;
138 7a4ee46d 2003-11-23 devnull if(src < smax)
139 7a4ee46d 2003-11-23 devnull uwbits |= *src++;
140 7a4ee46d 2003-11-23 devnull else
141 7a4ee46d 2003-11-23 devnull overbits += 8;
142 7a4ee46d 2003-11-23 devnull uwnbits += 8;
143 7a4ee46d 2003-11-23 devnull }
144 7a4ee46d 2003-11-23 devnull }
145 7a4ee46d 2003-11-23 devnull
146 7a4ee46d 2003-11-23 devnull /*
147 7a4ee46d 2003-11-23 devnull * offset
148 7a4ee46d 2003-11-23 devnull */
149 7a4ee46d 2003-11-23 devnull uwnbits -= 4;
150 7a4ee46d 2003-11-23 devnull bits = (uwbits >> uwnbits) & 0xf;
151 7a4ee46d 2003-11-23 devnull off = offbase[bits];
152 7a4ee46d 2003-11-23 devnull bits = offbits[bits];
153 7a4ee46d 2003-11-23 devnull
154 7a4ee46d 2003-11-23 devnull uwnbits -= bits;
155 7a4ee46d 2003-11-23 devnull off |= (uwbits >> uwnbits) & ((1 << bits) - 1);
156 7a4ee46d 2003-11-23 devnull off++;
157 7a4ee46d 2003-11-23 devnull
158 7a4ee46d 2003-11-23 devnull if(off > d - dst){
159 7a4ee46d 2003-11-23 devnull snprint(uw->err, WhackErrLen, "offset out of range: off=%d d=%ld len=%d nbits=%d", off, d - dst, len, uwnbits);
160 7a4ee46d 2003-11-23 devnull return -1;
161 7a4ee46d 2003-11-23 devnull }
162 7a4ee46d 2003-11-23 devnull if(d + len > dmax){
163 7a4ee46d 2003-11-23 devnull snprint(uw->err, WhackErrLen, "len out of range");
164 7a4ee46d 2003-11-23 devnull return -1;
165 7a4ee46d 2003-11-23 devnull }
166 7a4ee46d 2003-11-23 devnull s = d - off;
167 7a4ee46d 2003-11-23 devnull for(i = 0; i < len; i++)
168 7a4ee46d 2003-11-23 devnull d[i] = s[i];
169 7a4ee46d 2003-11-23 devnull d += len;
170 7a4ee46d 2003-11-23 devnull }
171 7a4ee46d 2003-11-23 devnull if(uwnbits < overbits){
172 7a4ee46d 2003-11-23 devnull snprint(uw->err, WhackErrLen, "compressed data overrun");
173 7a4ee46d 2003-11-23 devnull return -1;
174 7a4ee46d 2003-11-23 devnull }
175 7a4ee46d 2003-11-23 devnull
176 7a4ee46d 2003-11-23 devnull len = d - dst;
177 7a4ee46d 2003-11-23 devnull
178 7a4ee46d 2003-11-23 devnull return len;
179 7a4ee46d 2003-11-23 devnull }