1*13d37d77SDavid du Colombier /* Clzip - LZMA lossless data compressor
2*13d37d77SDavid du Colombier Copyright (C) 2010-2017 Antonio Diaz Diaz.
3*13d37d77SDavid du Colombier
4*13d37d77SDavid du Colombier This program is free software: you can redistribute it and/or modify
5*13d37d77SDavid du Colombier it under the terms of the GNU General Public License as published by
6*13d37d77SDavid du Colombier the Free Software Foundation, either version 2 of the License, or
7*13d37d77SDavid du Colombier (at your option) any later version.
8*13d37d77SDavid du Colombier
9*13d37d77SDavid du Colombier This program is distributed in the hope that it will be useful,
10*13d37d77SDavid du Colombier but WITHOUT ANY WARRANTY; without even the implied warranty of
11*13d37d77SDavid du Colombier MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*13d37d77SDavid du Colombier GNU General Public License for more details.
13*13d37d77SDavid du Colombier
14*13d37d77SDavid du Colombier You should have received a copy of the GNU General Public License
15*13d37d77SDavid du Colombier along with this program. If not, see <http://www.gnu.org/licenses/>. */
16*13d37d77SDavid du Colombier
17*13d37d77SDavid du Colombier enum { rd_buffer_size = 16384 };
18*13d37d77SDavid du Colombier
19*13d37d77SDavid du Colombier typedef struct LZ_decoder LZ_decoder;
20*13d37d77SDavid du Colombier typedef struct Range_decoder Range_decoder;
21*13d37d77SDavid du Colombier
22*13d37d77SDavid du Colombier struct Range_decoder {
23*13d37d77SDavid du Colombier uvlong partial_member_pos;
24*13d37d77SDavid du Colombier uchar * buffer; /* input buffer */
25*13d37d77SDavid du Colombier int pos; /* current pos in buffer */
26*13d37d77SDavid du Colombier int stream_pos; /* when reached, a new block must be read */
27*13d37d77SDavid du Colombier uint32_t code;
28*13d37d77SDavid du Colombier uint32_t range;
29*13d37d77SDavid du Colombier int infd; /* input file descriptor */
30*13d37d77SDavid du Colombier bool at_stream_end;
31*13d37d77SDavid du Colombier };
32*13d37d77SDavid du Colombier
33*13d37d77SDavid du Colombier bool Rd_read_block(Range_decoder *rdec);
34*13d37d77SDavid du Colombier
35*13d37d77SDavid du Colombier static bool
Rd_init(Range_decoder * rdec,int ifd)36*13d37d77SDavid du Colombier Rd_init(Range_decoder *rdec, int ifd)
37*13d37d77SDavid du Colombier {
38*13d37d77SDavid du Colombier rdec->partial_member_pos = 0;
39*13d37d77SDavid du Colombier rdec->buffer = (uchar *)malloc(rd_buffer_size);
40*13d37d77SDavid du Colombier if (!rdec->buffer)
41*13d37d77SDavid du Colombier return false;
42*13d37d77SDavid du Colombier rdec->pos = 0;
43*13d37d77SDavid du Colombier rdec->stream_pos = 0;
44*13d37d77SDavid du Colombier rdec->code = 0;
45*13d37d77SDavid du Colombier rdec->range = 0xFFFFFFFFU;
46*13d37d77SDavid du Colombier rdec->infd = ifd;
47*13d37d77SDavid du Colombier rdec->at_stream_end = false;
48*13d37d77SDavid du Colombier return true;
49*13d37d77SDavid du Colombier }
50*13d37d77SDavid du Colombier
51*13d37d77SDavid du Colombier static void
Rd_free(Range_decoder * rdec)52*13d37d77SDavid du Colombier Rd_free(Range_decoder *rdec)
53*13d37d77SDavid du Colombier {
54*13d37d77SDavid du Colombier free(rdec->buffer);
55*13d37d77SDavid du Colombier }
56*13d37d77SDavid du Colombier
57*13d37d77SDavid du Colombier static bool
Rd_finished(Range_decoder * rdec)58*13d37d77SDavid du Colombier Rd_finished(Range_decoder *rdec)
59*13d37d77SDavid du Colombier {
60*13d37d77SDavid du Colombier return rdec->pos >= rdec->stream_pos && !Rd_read_block(rdec);
61*13d37d77SDavid du Colombier }
62*13d37d77SDavid du Colombier
63*13d37d77SDavid du Colombier static uvlong
Rd_member_position(Range_decoder * rdec)64*13d37d77SDavid du Colombier Rd_member_position(Range_decoder *rdec)
65*13d37d77SDavid du Colombier {
66*13d37d77SDavid du Colombier return rdec->partial_member_pos + rdec->pos;
67*13d37d77SDavid du Colombier }
68*13d37d77SDavid du Colombier
69*13d37d77SDavid du Colombier static void
Rd_reset_member_position(Range_decoder * rdec)70*13d37d77SDavid du Colombier Rd_reset_member_position(Range_decoder *rdec)
71*13d37d77SDavid du Colombier {
72*13d37d77SDavid du Colombier rdec->partial_member_pos = 0;
73*13d37d77SDavid du Colombier rdec->partial_member_pos -= rdec->pos;
74*13d37d77SDavid du Colombier }
75*13d37d77SDavid du Colombier
76*13d37d77SDavid du Colombier static uchar
Rd_get_byte(Range_decoder * rdec)77*13d37d77SDavid du Colombier Rd_get_byte(Range_decoder *rdec)
78*13d37d77SDavid du Colombier {
79*13d37d77SDavid du Colombier /* 0xFF avoids decoder error if member is truncated at EOS marker */
80*13d37d77SDavid du Colombier if (Rd_finished(rdec))
81*13d37d77SDavid du Colombier return 0xFF;
82*13d37d77SDavid du Colombier return rdec->buffer[rdec->pos++];
83*13d37d77SDavid du Colombier }
84*13d37d77SDavid du Colombier
Rd_read_data(Range_decoder * rdec,uchar * outbuf,int size)85*13d37d77SDavid du Colombier static int Rd_read_data(Range_decoder *rdec, uchar *outbuf, int size)
86*13d37d77SDavid du Colombier {
87*13d37d77SDavid du Colombier int sz = 0;
88*13d37d77SDavid du Colombier
89*13d37d77SDavid du Colombier while (sz < size && !Rd_finished(rdec)) {
90*13d37d77SDavid du Colombier int rd, rsz = size - sz;
91*13d37d77SDavid du Colombier int rpos = rdec->stream_pos - rdec->pos;
92*13d37d77SDavid du Colombier
93*13d37d77SDavid du Colombier if (rsz < rpos)
94*13d37d77SDavid du Colombier rd = rsz;
95*13d37d77SDavid du Colombier else
96*13d37d77SDavid du Colombier rd = rpos;
97*13d37d77SDavid du Colombier memcpy(outbuf + sz, rdec->buffer + rdec->pos, rd);
98*13d37d77SDavid du Colombier rdec->pos += rd;
99*13d37d77SDavid du Colombier sz += rd;
100*13d37d77SDavid du Colombier }
101*13d37d77SDavid du Colombier return sz;
102*13d37d77SDavid du Colombier }
103*13d37d77SDavid du Colombier
104*13d37d77SDavid du Colombier static void
Rd_load(Range_decoder * rdec)105*13d37d77SDavid du Colombier Rd_load(Range_decoder *rdec)
106*13d37d77SDavid du Colombier {
107*13d37d77SDavid du Colombier int i;
108*13d37d77SDavid du Colombier rdec->code = 0;
109*13d37d77SDavid du Colombier for (i = 0; i < 5; ++i)
110*13d37d77SDavid du Colombier rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
111*13d37d77SDavid du Colombier rdec->range = 0xFFFFFFFFU;
112*13d37d77SDavid du Colombier rdec->code &= rdec->range; /* make sure that first byte is discarded */
113*13d37d77SDavid du Colombier }
114*13d37d77SDavid du Colombier
115*13d37d77SDavid du Colombier static void
Rd_normalize(Range_decoder * rdec)116*13d37d77SDavid du Colombier Rd_normalize(Range_decoder *rdec)
117*13d37d77SDavid du Colombier {
118*13d37d77SDavid du Colombier if (rdec->range <= 0x00FFFFFFU) {
119*13d37d77SDavid du Colombier rdec->range <<= 8;
120*13d37d77SDavid du Colombier rdec->code = (rdec->code << 8) | Rd_get_byte(rdec);
121*13d37d77SDavid du Colombier }
122*13d37d77SDavid du Colombier }
123*13d37d77SDavid du Colombier
124*13d37d77SDavid du Colombier static unsigned
Rd_decode(Range_decoder * rdec,int num_bits)125*13d37d77SDavid du Colombier Rd_decode(Range_decoder *rdec, int num_bits)
126*13d37d77SDavid du Colombier {
127*13d37d77SDavid du Colombier unsigned symbol = 0;
128*13d37d77SDavid du Colombier int i;
129*13d37d77SDavid du Colombier for (i = num_bits; i > 0; --i) {
130*13d37d77SDavid du Colombier bool bit;
131*13d37d77SDavid du Colombier Rd_normalize(rdec);
132*13d37d77SDavid du Colombier rdec->range >>= 1;
133*13d37d77SDavid du Colombier /* symbol <<= 1; */
134*13d37d77SDavid du Colombier /* if(rdec->code >= rdec->range) { rdec->code -= rdec->range; symbol |= 1; } */
135*13d37d77SDavid du Colombier bit = (rdec->code >= rdec->range);
136*13d37d77SDavid du Colombier symbol = (symbol << 1) + bit;
137*13d37d77SDavid du Colombier rdec->code -= rdec->range & (0U - bit);
138*13d37d77SDavid du Colombier }
139*13d37d77SDavid du Colombier return symbol;
140*13d37d77SDavid du Colombier }
141*13d37d77SDavid du Colombier
142*13d37d77SDavid du Colombier static unsigned
Rd_decode_bit(Range_decoder * rdec,Bit_model * probability)143*13d37d77SDavid du Colombier Rd_decode_bit(Range_decoder *rdec, Bit_model *probability)
144*13d37d77SDavid du Colombier {
145*13d37d77SDavid du Colombier uint32_t bound;
146*13d37d77SDavid du Colombier Rd_normalize(rdec);
147*13d37d77SDavid du Colombier bound = (rdec->range >> bit_model_total_bits) * *probability;
148*13d37d77SDavid du Colombier if (rdec->code < bound) {
149*13d37d77SDavid du Colombier rdec->range = bound;
150*13d37d77SDavid du Colombier *probability += (bit_model_total - *probability) >> bit_model_move_bits;
151*13d37d77SDavid du Colombier return 0;
152*13d37d77SDavid du Colombier } else {
153*13d37d77SDavid du Colombier rdec->range -= bound;
154*13d37d77SDavid du Colombier rdec->code -= bound;
155*13d37d77SDavid du Colombier *probability -= *probability >> bit_model_move_bits;
156*13d37d77SDavid du Colombier return 1;
157*13d37d77SDavid du Colombier }
158*13d37d77SDavid du Colombier }
159*13d37d77SDavid du Colombier
160*13d37d77SDavid du Colombier static unsigned
Rd_decode_tree3(Range_decoder * rdec,Bit_model bm[])161*13d37d77SDavid du Colombier Rd_decode_tree3(Range_decoder *rdec, Bit_model bm[])
162*13d37d77SDavid du Colombier {
163*13d37d77SDavid du Colombier unsigned symbol = 1;
164*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
165*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
166*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
167*13d37d77SDavid du Colombier return symbol & 7;
168*13d37d77SDavid du Colombier }
169*13d37d77SDavid du Colombier
170*13d37d77SDavid du Colombier static unsigned
Rd_decode_tree6(Range_decoder * rdec,Bit_model bm[])171*13d37d77SDavid du Colombier Rd_decode_tree6(Range_decoder *rdec, Bit_model bm[])
172*13d37d77SDavid du Colombier {
173*13d37d77SDavid du Colombier unsigned symbol = 1;
174*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
175*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
176*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
177*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
178*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
179*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
180*13d37d77SDavid du Colombier return symbol & 0x3F;
181*13d37d77SDavid du Colombier }
182*13d37d77SDavid du Colombier
183*13d37d77SDavid du Colombier static unsigned
Rd_decode_tree8(Range_decoder * rdec,Bit_model bm[])184*13d37d77SDavid du Colombier Rd_decode_tree8(Range_decoder *rdec, Bit_model bm[])
185*13d37d77SDavid du Colombier {
186*13d37d77SDavid du Colombier unsigned symbol = 1;
187*13d37d77SDavid du Colombier int i;
188*13d37d77SDavid du Colombier for (i = 0; i < 8; ++i)
189*13d37d77SDavid du Colombier symbol = (symbol << 1) | Rd_decode_bit(rdec, &bm[symbol]);
190*13d37d77SDavid du Colombier return symbol & 0xFF;
191*13d37d77SDavid du Colombier }
192*13d37d77SDavid du Colombier
193*13d37d77SDavid du Colombier static unsigned
Rd_decode_tree_reversed(Range_decoder * rdec,Bit_model bm[],int num_bits)194*13d37d77SDavid du Colombier Rd_decode_tree_reversed(Range_decoder *rdec, Bit_model bm[], int num_bits)
195*13d37d77SDavid du Colombier {
196*13d37d77SDavid du Colombier unsigned model = 1;
197*13d37d77SDavid du Colombier unsigned symbol = 0;
198*13d37d77SDavid du Colombier int i;
199*13d37d77SDavid du Colombier for (i = 0; i < num_bits; ++i) {
200*13d37d77SDavid du Colombier unsigned bit = Rd_decode_bit(rdec, &bm[model]);
201*13d37d77SDavid du Colombier model = (model << 1) + bit;
202*13d37d77SDavid du Colombier symbol |= (bit << i);
203*13d37d77SDavid du Colombier }
204*13d37d77SDavid du Colombier return symbol;
205*13d37d77SDavid du Colombier }
206*13d37d77SDavid du Colombier
207*13d37d77SDavid du Colombier static unsigned
Rd_decode_tree_reversed4(Range_decoder * rdec,Bit_model bm[])208*13d37d77SDavid du Colombier Rd_decode_tree_reversed4(Range_decoder *rdec, Bit_model bm[])
209*13d37d77SDavid du Colombier {
210*13d37d77SDavid du Colombier unsigned symbol = Rd_decode_bit(rdec, &bm[1]);
211*13d37d77SDavid du Colombier unsigned model = 2 + symbol;
212*13d37d77SDavid du Colombier unsigned bit = Rd_decode_bit(rdec, &bm[model]);
213*13d37d77SDavid du Colombier model = (model << 1) + bit;
214*13d37d77SDavid du Colombier symbol |= (bit << 1);
215*13d37d77SDavid du Colombier bit = Rd_decode_bit(rdec, &bm[model]);
216*13d37d77SDavid du Colombier model = (model << 1) + bit;
217*13d37d77SDavid du Colombier symbol |= (bit << 2);
218*13d37d77SDavid du Colombier symbol |= (Rd_decode_bit(rdec, &bm[model]) << 3);
219*13d37d77SDavid du Colombier return symbol;
220*13d37d77SDavid du Colombier }
221*13d37d77SDavid du Colombier
222*13d37d77SDavid du Colombier static unsigned
Rd_decode_matched(Range_decoder * rdec,Bit_model bm[],unsigned match_byte)223*13d37d77SDavid du Colombier Rd_decode_matched(Range_decoder *rdec, Bit_model bm[], unsigned match_byte)
224*13d37d77SDavid du Colombier {
225*13d37d77SDavid du Colombier unsigned symbol = 1;
226*13d37d77SDavid du Colombier unsigned mask = 0x100;
227*13d37d77SDavid du Colombier while (true) {
228*13d37d77SDavid du Colombier unsigned match_bit = (match_byte <<= 1) & mask;
229*13d37d77SDavid du Colombier unsigned bit = Rd_decode_bit(rdec, &bm[symbol+match_bit+mask]);
230*13d37d77SDavid du Colombier symbol = (symbol << 1) + bit;
231*13d37d77SDavid du Colombier if (symbol > 0xFF)
232*13d37d77SDavid du Colombier return symbol & 0xFF;
233*13d37d77SDavid du Colombier mask &= ~(match_bit ^ (bit << 8)); /* if(match_bit != bit) mask = 0; */
234*13d37d77SDavid du Colombier }
235*13d37d77SDavid du Colombier }
236*13d37d77SDavid du Colombier
237*13d37d77SDavid du Colombier static unsigned
Rd_decode_len(struct Range_decoder * rdec,Len_model * lm,int pos_state)238*13d37d77SDavid du Colombier Rd_decode_len(struct Range_decoder *rdec, Len_model *lm, int pos_state)
239*13d37d77SDavid du Colombier {
240*13d37d77SDavid du Colombier if (Rd_decode_bit(rdec, &lm->choice1) == 0)
241*13d37d77SDavid du Colombier return Rd_decode_tree3(rdec, lm->bm_low[pos_state]);
242*13d37d77SDavid du Colombier if (Rd_decode_bit(rdec, &lm->choice2) == 0)
243*13d37d77SDavid du Colombier return len_low_syms + Rd_decode_tree3(rdec, lm->bm_mid[pos_state]);
244*13d37d77SDavid du Colombier return len_low_syms + len_mid_syms + Rd_decode_tree8(rdec, lm->bm_high);
245*13d37d77SDavid du Colombier }
246*13d37d77SDavid du Colombier
247*13d37d77SDavid du Colombier struct LZ_decoder {
248*13d37d77SDavid du Colombier uvlong partial_data_pos;
249*13d37d77SDavid du Colombier struct Range_decoder *rdec;
250*13d37d77SDavid du Colombier unsigned dict_size;
251*13d37d77SDavid du Colombier uchar * buffer; /* output buffer */
252*13d37d77SDavid du Colombier unsigned pos; /* current pos in buffer */
253*13d37d77SDavid du Colombier unsigned stream_pos; /* first byte not yet written to file */
254*13d37d77SDavid du Colombier uint32_t crc;
255*13d37d77SDavid du Colombier int outfd; /* output file descriptor */
256*13d37d77SDavid du Colombier bool pos_wrapped;
257*13d37d77SDavid du Colombier };
258*13d37d77SDavid du Colombier
259*13d37d77SDavid du Colombier void LZd_flush_data(LZ_decoder *d);
260*13d37d77SDavid du Colombier
261*13d37d77SDavid du Colombier static uchar
LZd_peek_prev(LZ_decoder * d)262*13d37d77SDavid du Colombier LZd_peek_prev(LZ_decoder *d)
263*13d37d77SDavid du Colombier {
264*13d37d77SDavid du Colombier if (d->pos > 0)
265*13d37d77SDavid du Colombier return d->buffer[d->pos-1];
266*13d37d77SDavid du Colombier if (d->pos_wrapped)
267*13d37d77SDavid du Colombier return d->buffer[d->dict_size-1];
268*13d37d77SDavid du Colombier return 0; /* prev_byte of first byte */
269*13d37d77SDavid du Colombier }
270*13d37d77SDavid du Colombier
271*13d37d77SDavid du Colombier static uchar
LZd_peek(LZ_decoder * d,unsigned distance)272*13d37d77SDavid du Colombier LZd_peek(LZ_decoder *d,
273*13d37d77SDavid du Colombier unsigned distance)
274*13d37d77SDavid du Colombier {
275*13d37d77SDavid du Colombier unsigned i = ((d->pos > distance) ? 0 : d->dict_size) +
276*13d37d77SDavid du Colombier d->pos - distance - 1;
277*13d37d77SDavid du Colombier return d->buffer[i];
278*13d37d77SDavid du Colombier }
279*13d37d77SDavid du Colombier
280*13d37d77SDavid du Colombier static void
LZd_put_byte(LZ_decoder * d,uchar b)281*13d37d77SDavid du Colombier LZd_put_byte(LZ_decoder *d, uchar b)
282*13d37d77SDavid du Colombier {
283*13d37d77SDavid du Colombier d->buffer[d->pos] = b;
284*13d37d77SDavid du Colombier if (++d->pos >= d->dict_size)
285*13d37d77SDavid du Colombier LZd_flush_data(d);
286*13d37d77SDavid du Colombier }
287*13d37d77SDavid du Colombier
288*13d37d77SDavid du Colombier static void
LZd_copy_block(LZ_decoder * d,unsigned distance,unsigned len)289*13d37d77SDavid du Colombier LZd_copy_block(LZ_decoder *d, unsigned distance, unsigned len)
290*13d37d77SDavid du Colombier {
291*13d37d77SDavid du Colombier unsigned lpos = d->pos, i = lpos -distance -1;
292*13d37d77SDavid du Colombier bool fast, fast2;
293*13d37d77SDavid du Colombier
294*13d37d77SDavid du Colombier if (lpos > distance) {
295*13d37d77SDavid du Colombier fast = (len < d->dict_size - lpos);
296*13d37d77SDavid du Colombier fast2 = (fast && len <= lpos - i);
297*13d37d77SDavid du Colombier } else {
298*13d37d77SDavid du Colombier i += d->dict_size;
299*13d37d77SDavid du Colombier fast = (len < d->dict_size - i); /* (i == pos) may happen */
300*13d37d77SDavid du Colombier fast2 = (fast && len <= i - lpos);
301*13d37d77SDavid du Colombier }
302*13d37d77SDavid du Colombier if (fast) /* no wrap */ {
303*13d37d77SDavid du Colombier d->pos += len;
304*13d37d77SDavid du Colombier if (fast2) /* no wrap, no overlap */
305*13d37d77SDavid du Colombier memcpy(d->buffer + lpos, d->buffer + i, len);
306*13d37d77SDavid du Colombier else
307*13d37d77SDavid du Colombier for (; len > 0; --len)
308*13d37d77SDavid du Colombier d->buffer[lpos++] = d->buffer[i++];
309*13d37d77SDavid du Colombier } else
310*13d37d77SDavid du Colombier for (; len > 0; --len) {
311*13d37d77SDavid du Colombier d->buffer[d->pos] = d->buffer[i];
312*13d37d77SDavid du Colombier if (++d->pos >= d->dict_size)
313*13d37d77SDavid du Colombier LZd_flush_data(d);
314*13d37d77SDavid du Colombier if (++i >= d->dict_size)
315*13d37d77SDavid du Colombier i = 0;
316*13d37d77SDavid du Colombier }
317*13d37d77SDavid du Colombier }
318*13d37d77SDavid du Colombier
319*13d37d77SDavid du Colombier static bool
LZd_init(struct LZ_decoder * d,Range_decoder * rde,unsigned dict_size,int ofd)320*13d37d77SDavid du Colombier LZd_init(struct LZ_decoder *d, Range_decoder *rde, unsigned dict_size, int ofd)
321*13d37d77SDavid du Colombier {
322*13d37d77SDavid du Colombier d->partial_data_pos = 0;
323*13d37d77SDavid du Colombier d->rdec = rde;
324*13d37d77SDavid du Colombier d->dict_size = dict_size;
325*13d37d77SDavid du Colombier d->buffer = (uchar *)malloc(d->dict_size);
326*13d37d77SDavid du Colombier if (!d->buffer)
327*13d37d77SDavid du Colombier return false;
328*13d37d77SDavid du Colombier d->pos = 0;
329*13d37d77SDavid du Colombier d->stream_pos = 0;
330*13d37d77SDavid du Colombier d->crc = 0xFFFFFFFFU;
331*13d37d77SDavid du Colombier d->outfd = ofd;
332*13d37d77SDavid du Colombier d->pos_wrapped = false;
333*13d37d77SDavid du Colombier return true;
334*13d37d77SDavid du Colombier }
335*13d37d77SDavid du Colombier
336*13d37d77SDavid du Colombier static void
LZd_free(LZ_decoder * d)337*13d37d77SDavid du Colombier LZd_free(LZ_decoder *d)
338*13d37d77SDavid du Colombier {
339*13d37d77SDavid du Colombier free(d->buffer);
340*13d37d77SDavid du Colombier }
341*13d37d77SDavid du Colombier
342*13d37d77SDavid du Colombier static unsigned
LZd_crc(LZ_decoder * d)343*13d37d77SDavid du Colombier LZd_crc(LZ_decoder *d)
344*13d37d77SDavid du Colombier {
345*13d37d77SDavid du Colombier return d->crc ^ 0xFFFFFFFFU;
346*13d37d77SDavid du Colombier }
347*13d37d77SDavid du Colombier
348*13d37d77SDavid du Colombier static uvlong
LZd_data_position(LZ_decoder * d)349*13d37d77SDavid du Colombier LZd_data_position(LZ_decoder *d)
350*13d37d77SDavid du Colombier {
351*13d37d77SDavid du Colombier return d->partial_data_pos + d->pos;
352*13d37d77SDavid du Colombier }
353*13d37d77SDavid du Colombier
354*13d37d77SDavid du Colombier int LZd_decode_member(struct LZ_decoder *d, Pretty_print *pp);
355