xref: /plan9-contrib/sys/src/cmd/lzip/lzip.h (revision 13d37d7716a3e781f408392d7869dff5927c6669)
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 
18*13d37d77SDavid du Colombier #ifndef _LZIP_H
19*13d37d77SDavid du Colombier #define _LZIP_H
20*13d37d77SDavid du Colombier 
21*13d37d77SDavid du Colombier #include <u.h>
22*13d37d77SDavid du Colombier #include <libc.h>
23*13d37d77SDavid du Colombier #include <stdio.h>
24*13d37d77SDavid du Colombier #include <ctype.h>
25*13d37d77SDavid du Colombier 
26*13d37d77SDavid du Colombier #define exit(n) exits((n) == 0? 0: "err")
27*13d37d77SDavid du Colombier #define isatty(fd) 0
28*13d37d77SDavid du Colombier #define lseek seek
29*13d37d77SDavid du Colombier 
30*13d37d77SDavid du Colombier #ifndef max
31*13d37d77SDavid du Colombier #define max(x,y) ((x) >= (y) ? (x) : (y))
32*13d37d77SDavid du Colombier #endif
33*13d37d77SDavid du Colombier #ifndef min
34*13d37d77SDavid du Colombier #define min(x,y) ((x) <= (y) ? (x) : (y))
35*13d37d77SDavid du Colombier #endif
36*13d37d77SDavid du Colombier 
37*13d37d77SDavid du Colombier typedef int	State;
38*13d37d77SDavid du Colombier typedef long int32_t;
39*13d37d77SDavid du Colombier typedef ulong uint32_t;
40*13d37d77SDavid du Colombier typedef int bool;
41*13d37d77SDavid du Colombier 
42*13d37d77SDavid du Colombier enum { false, true };
43*13d37d77SDavid du Colombier 
44*13d37d77SDavid du Colombier enum { states = 12 };
45*13d37d77SDavid du Colombier enum {
46*13d37d77SDavid du Colombier 	min_dict_bits = 12,
47*13d37d77SDavid du Colombier 	min_dict_size = 1 << min_dict_bits,	/* >= modeled_distances */
48*13d37d77SDavid du Colombier 	max_dict_bits = 29,
49*13d37d77SDavid du Colombier 	max_dict_size = 1 << max_dict_bits,
50*13d37d77SDavid du Colombier 	min_member_size = 36,
51*13d37d77SDavid du Colombier 	literal_context_bits = 3,
52*13d37d77SDavid du Colombier 	literal_pos_state_bits = 0, 			/* not used */
53*13d37d77SDavid du Colombier 	pos_state_bits = 2,
54*13d37d77SDavid du Colombier 	pos_states = 1 << pos_state_bits,
55*13d37d77SDavid du Colombier 	pos_state_mask = pos_states -1,
56*13d37d77SDavid du Colombier 
57*13d37d77SDavid du Colombier 	len_states = 4,
58*13d37d77SDavid du Colombier 	dis_slot_bits = 6,
59*13d37d77SDavid du Colombier 	start_dis_model = 4,
60*13d37d77SDavid du Colombier 	end_dis_model = 14,
61*13d37d77SDavid du Colombier 	modeled_distances = 1 << (end_dis_model / 2), 	/* 128 */
62*13d37d77SDavid du Colombier 	dis_align_bits = 4,
63*13d37d77SDavid du Colombier 	dis_align_size = 1 << dis_align_bits,
64*13d37d77SDavid du Colombier 
65*13d37d77SDavid du Colombier 	len_low_bits = 3,
66*13d37d77SDavid du Colombier 	len_mid_bits = 3,
67*13d37d77SDavid du Colombier 	len_high_bits = 8,
68*13d37d77SDavid du Colombier 	len_low_syms = 1 << len_low_bits,
69*13d37d77SDavid du Colombier 	len_mid_syms = 1 << len_mid_bits,
70*13d37d77SDavid du Colombier 	len_high_syms = 1 << len_high_bits,
71*13d37d77SDavid du Colombier 	max_len_syms = len_low_syms + len_mid_syms + len_high_syms,
72*13d37d77SDavid du Colombier 
73*13d37d77SDavid du Colombier 	min_match_len = 2, 					/* must be 2 */
74*13d37d77SDavid du Colombier 	max_match_len = min_match_len + max_len_syms - 1, 	/* 273 */
75*13d37d77SDavid du Colombier 	min_match_len_limit = 5,
76*13d37d77SDavid du Colombier 
77*13d37d77SDavid du Colombier 	bit_model_move_bits = 5,
78*13d37d77SDavid du Colombier 	bit_model_total_bits = 11,
79*13d37d77SDavid du Colombier 	bit_model_total = 1 << bit_model_total_bits,
80*13d37d77SDavid du Colombier };
81*13d37d77SDavid du Colombier 
82*13d37d77SDavid du Colombier typedef struct Len_model Len_model;
83*13d37d77SDavid du Colombier typedef struct Pretty_print Pretty_print;
84*13d37d77SDavid du Colombier typedef struct Matchfinder_base Matchfinder_base;
85*13d37d77SDavid du Colombier typedef int	Bit_model;
86*13d37d77SDavid du Colombier 
87*13d37d77SDavid du Colombier struct Len_model {
88*13d37d77SDavid du Colombier 	Bit_model choice1;
89*13d37d77SDavid du Colombier 	Bit_model choice2;
90*13d37d77SDavid du Colombier 	Bit_model bm_low[pos_states][len_low_syms];
91*13d37d77SDavid du Colombier 	Bit_model bm_mid[pos_states][len_mid_syms];
92*13d37d77SDavid du Colombier 	Bit_model bm_high[len_high_syms];
93*13d37d77SDavid du Colombier };
94*13d37d77SDavid du Colombier struct Pretty_print {
95*13d37d77SDavid du Colombier 	char	*name;
96*13d37d77SDavid du Colombier 	char	*stdin_name;
97*13d37d77SDavid du Colombier 	ulong	longest_name;
98*13d37d77SDavid du Colombier 	bool	first_post;
99*13d37d77SDavid du Colombier };
100*13d37d77SDavid du Colombier 
101*13d37d77SDavid du Colombier typedef ulong CRC32[256];	/* Table of CRCs of all 8-bit messages. */
102*13d37d77SDavid du Colombier 
103*13d37d77SDavid du Colombier extern CRC32 crc32;
104*13d37d77SDavid du Colombier 
105*13d37d77SDavid du Colombier #define errno 0
106*13d37d77SDavid du Colombier 
107*13d37d77SDavid du Colombier static uchar magic_string[4] = { "LZIP" };
108*13d37d77SDavid du Colombier 
109*13d37d77SDavid du Colombier typedef uchar File_header[6];		/* 0-3 magic bytes */
110*13d37d77SDavid du Colombier /*   4 version */
111*13d37d77SDavid du Colombier /*   5 coded_dict_size */
112*13d37d77SDavid du Colombier enum { Fh_size = 6 };
113*13d37d77SDavid du Colombier 
114*13d37d77SDavid du Colombier typedef uchar File_trailer[20];
115*13d37d77SDavid du Colombier /*  0-3  CRC32 of the uncompressed data */
116*13d37d77SDavid du Colombier /*  4-11 size of the uncompressed data */
117*13d37d77SDavid du Colombier /* 12-19 member size including header and trailer */
118*13d37d77SDavid du Colombier 
119*13d37d77SDavid du Colombier enum { Ft_size = 20 };
120*13d37d77SDavid du Colombier 
121*13d37d77SDavid du Colombier enum {
122*13d37d77SDavid du Colombier 	price_shift_bits = 6,
123*13d37d77SDavid du Colombier 	price_step_bits = 2,
124*13d37d77SDavid du Colombier 	price_step = 1 << price_step_bits,
125*13d37d77SDavid du Colombier };
126*13d37d77SDavid du Colombier 
127*13d37d77SDavid du Colombier typedef uchar Dis_slots[1<<10];
128*13d37d77SDavid du Colombier typedef short	Prob_prices[bit_model_total >> price_step_bits];
129*13d37d77SDavid du Colombier 
130*13d37d77SDavid du Colombier extern Dis_slots dis_slots;
131*13d37d77SDavid du Colombier extern Prob_prices prob_prices;
132*13d37d77SDavid du Colombier 
133*13d37d77SDavid du Colombier #define get_price(prob)		prob_prices[(prob) >> price_step_bits]
134*13d37d77SDavid du Colombier #define price0(prob)		get_price(prob)
135*13d37d77SDavid du Colombier #define price1(prob)		get_price(bit_model_total - (prob))
136*13d37d77SDavid du Colombier #define price_bit(bm, bit)	((bit)? price1(bm): price0(bm))
137*13d37d77SDavid du Colombier 
138*13d37d77SDavid du Colombier #define Mb_ptr_to_current_pos(mb) ((mb)->buffer + (mb)->pos)
139*13d37d77SDavid du Colombier #define Mb_peek(mb, distance) (mb)->buffer[(mb)->pos - (distance)]
140*13d37d77SDavid du Colombier 
141*13d37d77SDavid du Colombier #define Lp_price(lp, len, pos_state) \
142*13d37d77SDavid du Colombier 	(lp)->prices[pos_state][(len) - min_match_len]
143*13d37d77SDavid du Colombier 
144*13d37d77SDavid du Colombier #define Tr_update(trial, pr, distance4, p_i) \
145*13d37d77SDavid du Colombier { \
146*13d37d77SDavid du Colombier 	if ((pr) < (trial)->price) { \
147*13d37d77SDavid du Colombier 		(trial)->price = pr; \
148*13d37d77SDavid du Colombier 		(trial)->dis4 = distance4; \
149*13d37d77SDavid du Colombier 		(trial)->prev_index = p_i; \
150*13d37d77SDavid du Colombier 		(trial)->prev_index2 = single_step_trial; \
151*13d37d77SDavid du Colombier 	} else { \
152*13d37d77SDavid du Colombier 	} \
153*13d37d77SDavid du Colombier }
154*13d37d77SDavid du Colombier 
155*13d37d77SDavid du Colombier /* these functions are now extern and must be defined exactly once */
156*13d37d77SDavid du Colombier #ifdef	_DEFINE_INLINES
157*13d37d77SDavid du Colombier #define	_INLINES_DEFINED
158*13d37d77SDavid du Colombier 
159*13d37d77SDavid du Colombier int
get_len_state(int len)160*13d37d77SDavid du Colombier get_len_state(int len)
161*13d37d77SDavid du Colombier {
162*13d37d77SDavid du Colombier 	int lenstm1, lenmmm;
163*13d37d77SDavid du Colombier 
164*13d37d77SDavid du Colombier 	lenmmm = len - min_match_len;
165*13d37d77SDavid du Colombier 	lenstm1 = len_states - 1;
166*13d37d77SDavid du Colombier 	if (lenmmm < lenstm1)
167*13d37d77SDavid du Colombier 		return lenmmm;
168*13d37d77SDavid du Colombier 	else
169*13d37d77SDavid du Colombier 		return lenstm1;
170*13d37d77SDavid du Colombier }
171*13d37d77SDavid du Colombier 
172*13d37d77SDavid du Colombier State
St_set_char(State st)173*13d37d77SDavid du Colombier St_set_char(State st)
174*13d37d77SDavid du Colombier {
175*13d37d77SDavid du Colombier 	static State next[states] = { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
176*13d37d77SDavid du Colombier 
177*13d37d77SDavid du Colombier 	assert((unsigned)st < nelem(next));
178*13d37d77SDavid du Colombier 	return next[st];
179*13d37d77SDavid du Colombier }
180*13d37d77SDavid du Colombier 
181*13d37d77SDavid du Colombier int
get_lit_state(uchar prev_byte)182*13d37d77SDavid du Colombier get_lit_state(uchar prev_byte)
183*13d37d77SDavid du Colombier {
184*13d37d77SDavid du Colombier 	return prev_byte >> (8 - literal_context_bits);
185*13d37d77SDavid du Colombier }
186*13d37d77SDavid du Colombier 
187*13d37d77SDavid du Colombier void
Bm_init(Bit_model * probability)188*13d37d77SDavid du Colombier Bm_init(Bit_model *probability)
189*13d37d77SDavid du Colombier {
190*13d37d77SDavid du Colombier 	*probability = bit_model_total / 2;
191*13d37d77SDavid du Colombier }
192*13d37d77SDavid du Colombier 
193*13d37d77SDavid du Colombier void
Bm_array_init(Bit_model bm[],int size)194*13d37d77SDavid du Colombier Bm_array_init(Bit_model bm[], int size)
195*13d37d77SDavid du Colombier {
196*13d37d77SDavid du Colombier 	int i;
197*13d37d77SDavid du Colombier 
198*13d37d77SDavid du Colombier 	for (i = 0; i < size; ++i)
199*13d37d77SDavid du Colombier 		Bm_init(&bm[i]);
200*13d37d77SDavid du Colombier }
201*13d37d77SDavid du Colombier 
202*13d37d77SDavid du Colombier void
Lm_init(Len_model * lm)203*13d37d77SDavid du Colombier Lm_init(Len_model *lm)
204*13d37d77SDavid du Colombier {
205*13d37d77SDavid du Colombier 	Bm_init(&lm->choice1);
206*13d37d77SDavid du Colombier 	Bm_init(&lm->choice2);
207*13d37d77SDavid du Colombier 	Bm_array_init(lm->bm_low[0], pos_states * len_low_syms);
208*13d37d77SDavid du Colombier 	Bm_array_init(lm->bm_mid[0], pos_states * len_mid_syms);
209*13d37d77SDavid du Colombier 	Bm_array_init(lm->bm_high, len_high_syms);
210*13d37d77SDavid du Colombier }
211*13d37d77SDavid du Colombier 
212*13d37d77SDavid du Colombier void
Pp_init(Pretty_print * pp,char * filenames[],int num_filenames,int verbosity)213*13d37d77SDavid du Colombier Pp_init(Pretty_print *pp, char *filenames[], int num_filenames, int verbosity)
214*13d37d77SDavid du Colombier {
215*13d37d77SDavid du Colombier 	unsigned stdin_name_len;
216*13d37d77SDavid du Colombier 	int i;
217*13d37d77SDavid du Colombier 
218*13d37d77SDavid du Colombier 	pp->name = 0;
219*13d37d77SDavid du Colombier 	pp->stdin_name = "(stdin)";
220*13d37d77SDavid du Colombier 	pp->longest_name = 0;
221*13d37d77SDavid du Colombier 	pp->first_post = false;
222*13d37d77SDavid du Colombier 
223*13d37d77SDavid du Colombier 	if (verbosity <= 0)
224*13d37d77SDavid du Colombier 		return;
225*13d37d77SDavid du Colombier 	stdin_name_len = strlen(pp->stdin_name);
226*13d37d77SDavid du Colombier 	for (i = 0; i < num_filenames; ++i) {
227*13d37d77SDavid du Colombier 		char *s = filenames[i];
228*13d37d77SDavid du Colombier 		unsigned len = strcmp(s, "-") == 0? stdin_name_len: strlen(s);
229*13d37d77SDavid du Colombier 
230*13d37d77SDavid du Colombier 		if (len > pp->longest_name)
231*13d37d77SDavid du Colombier 			pp->longest_name = len;
232*13d37d77SDavid du Colombier 	}
233*13d37d77SDavid du Colombier 	if (pp->longest_name == 0)
234*13d37d77SDavid du Colombier 		pp->longest_name = stdin_name_len;
235*13d37d77SDavid du Colombier }
236*13d37d77SDavid du Colombier 
237*13d37d77SDavid du Colombier void
Pp_set_name(Pretty_print * pp,char * filename)238*13d37d77SDavid du Colombier Pp_set_name(Pretty_print *pp, char *filename)
239*13d37d77SDavid du Colombier {
240*13d37d77SDavid du Colombier 	if ( filename && filename[0] && strcmp( filename, "-" ) != 0 )
241*13d37d77SDavid du Colombier 		pp->name = filename;
242*13d37d77SDavid du Colombier 	else
243*13d37d77SDavid du Colombier 		pp->name = pp->stdin_name;
244*13d37d77SDavid du Colombier 	pp->first_post = true;
245*13d37d77SDavid du Colombier }
246*13d37d77SDavid du Colombier 
247*13d37d77SDavid du Colombier void
Pp_reset(Pretty_print * pp)248*13d37d77SDavid du Colombier Pp_reset(Pretty_print *pp)
249*13d37d77SDavid du Colombier {
250*13d37d77SDavid du Colombier 	if (pp->name && pp->name[0])
251*13d37d77SDavid du Colombier 		pp->first_post = true;
252*13d37d77SDavid du Colombier }
253*13d37d77SDavid du Colombier 
254*13d37d77SDavid du Colombier void
255*13d37d77SDavid du Colombier Pp_show_msg(Pretty_print *pp, char *msg);
256*13d37d77SDavid du Colombier 
257*13d37d77SDavid du Colombier void
CRC32_init(void)258*13d37d77SDavid du Colombier CRC32_init(void)
259*13d37d77SDavid du Colombier {
260*13d37d77SDavid du Colombier 	unsigned n;
261*13d37d77SDavid du Colombier 
262*13d37d77SDavid du Colombier 	for (n = 0; n < 256; ++n) {
263*13d37d77SDavid du Colombier 		unsigned	c = n;
264*13d37d77SDavid du Colombier 		int	k;
265*13d37d77SDavid du Colombier 		for (k = 0; k < 8; ++k) {
266*13d37d77SDavid du Colombier 			if (c & 1)
267*13d37d77SDavid du Colombier 				c = 0xEDB88320U ^ (c >> 1);
268*13d37d77SDavid du Colombier 			else
269*13d37d77SDavid du Colombier 				c >>= 1;
270*13d37d77SDavid du Colombier 		}
271*13d37d77SDavid du Colombier 		crc32[n] = c;
272*13d37d77SDavid du Colombier 	}
273*13d37d77SDavid du Colombier }
274*13d37d77SDavid du Colombier 
275*13d37d77SDavid du Colombier void
CRC32_update_byte(uint32_t * crc,uchar byte)276*13d37d77SDavid du Colombier CRC32_update_byte(uint32_t *crc, uchar byte)
277*13d37d77SDavid du Colombier {
278*13d37d77SDavid du Colombier 	*crc = crc32[(*crc^byte)&0xFF] ^ (*crc >> 8);
279*13d37d77SDavid du Colombier }
280*13d37d77SDavid du Colombier 
281*13d37d77SDavid du Colombier void
CRC32_update_buf(uint32_t * crc,uchar * buffer,int size)282*13d37d77SDavid du Colombier CRC32_update_buf(uint32_t *crc, uchar *buffer, int size)
283*13d37d77SDavid du Colombier {
284*13d37d77SDavid du Colombier 	int	i;
285*13d37d77SDavid du Colombier 	uint32_t c = *crc;
286*13d37d77SDavid du Colombier 	for (i = 0; i < size; ++i)
287*13d37d77SDavid du Colombier 		c = crc32[(c^buffer[i])&0xFF] ^ (c >> 8);
288*13d37d77SDavid du Colombier 	*crc = c;
289*13d37d77SDavid du Colombier }
290*13d37d77SDavid du Colombier 
291*13d37d77SDavid du Colombier bool
isvalid_ds(unsigned dict_size)292*13d37d77SDavid du Colombier isvalid_ds(unsigned dict_size)
293*13d37d77SDavid du Colombier {
294*13d37d77SDavid du Colombier 	return (dict_size >= min_dict_size &&
295*13d37d77SDavid du Colombier 	    dict_size <= max_dict_size);
296*13d37d77SDavid du Colombier }
297*13d37d77SDavid du Colombier 
298*13d37d77SDavid du Colombier int
real_bits(unsigned value)299*13d37d77SDavid du Colombier real_bits(unsigned value)
300*13d37d77SDavid du Colombier {
301*13d37d77SDavid du Colombier 	int	bits = 0;
302*13d37d77SDavid du Colombier 
303*13d37d77SDavid du Colombier 	while (value > 0) {
304*13d37d77SDavid du Colombier 		value >>= 1;
305*13d37d77SDavid du Colombier 		++bits;
306*13d37d77SDavid du Colombier 	}
307*13d37d77SDavid du Colombier 	return bits;
308*13d37d77SDavid du Colombier }
309*13d37d77SDavid du Colombier 
310*13d37d77SDavid du Colombier void
Fh_set_magic(File_header data)311*13d37d77SDavid du Colombier Fh_set_magic(File_header data)
312*13d37d77SDavid du Colombier {
313*13d37d77SDavid du Colombier 	memcpy(data, magic_string, 4);
314*13d37d77SDavid du Colombier 	data[4] = 1;
315*13d37d77SDavid du Colombier }
316*13d37d77SDavid du Colombier 
317*13d37d77SDavid du Colombier bool
Fh_verify_magic(File_header data)318*13d37d77SDavid du Colombier Fh_verify_magic(File_header data)
319*13d37d77SDavid du Colombier {
320*13d37d77SDavid du Colombier 	return (memcmp(data, magic_string, 4) == 0);
321*13d37d77SDavid du Colombier }
322*13d37d77SDavid du Colombier 
323*13d37d77SDavid du Colombier /* detect truncated header */
324*13d37d77SDavid du Colombier bool
Fh_verify_prefix(File_header data,int size)325*13d37d77SDavid du Colombier Fh_verify_prefix(File_header data, int size)
326*13d37d77SDavid du Colombier {
327*13d37d77SDavid du Colombier 	int	i;
328*13d37d77SDavid du Colombier 	for (i = 0; i < size && i < 4; ++i)
329*13d37d77SDavid du Colombier 		if (data[i] != magic_string[i])
330*13d37d77SDavid du Colombier 			return false;
331*13d37d77SDavid du Colombier 	return (size > 0);
332*13d37d77SDavid du Colombier }
333*13d37d77SDavid du Colombier 
334*13d37d77SDavid du Colombier uchar
Fh_version(File_header data)335*13d37d77SDavid du Colombier Fh_version(File_header data)
336*13d37d77SDavid du Colombier {
337*13d37d77SDavid du Colombier 	return data[4];
338*13d37d77SDavid du Colombier }
339*13d37d77SDavid du Colombier 
340*13d37d77SDavid du Colombier bool
Fh_verify_version(File_header data)341*13d37d77SDavid du Colombier Fh_verify_version(File_header data)
342*13d37d77SDavid du Colombier {
343*13d37d77SDavid du Colombier 	return (data[4] == 1);
344*13d37d77SDavid du Colombier }
345*13d37d77SDavid du Colombier 
346*13d37d77SDavid du Colombier unsigned
Fh_get_dict_size(File_header data)347*13d37d77SDavid du Colombier Fh_get_dict_size(File_header data)
348*13d37d77SDavid du Colombier {
349*13d37d77SDavid du Colombier 	unsigned	sz = (1 << (data[5] &0x1F));
350*13d37d77SDavid du Colombier 	if (sz > min_dict_size)
351*13d37d77SDavid du Colombier 		sz -= (sz / 16) * ((data[5] >> 5) & 7);
352*13d37d77SDavid du Colombier 	return sz;
353*13d37d77SDavid du Colombier }
354*13d37d77SDavid du Colombier 
355*13d37d77SDavid du Colombier bool
Fh_set_dict_size(File_header data,unsigned sz)356*13d37d77SDavid du Colombier Fh_set_dict_size(File_header data, unsigned sz)
357*13d37d77SDavid du Colombier {
358*13d37d77SDavid du Colombier 	if (!isvalid_ds(sz))
359*13d37d77SDavid du Colombier 		return false;
360*13d37d77SDavid du Colombier 	data[5] = real_bits(sz - 1);
361*13d37d77SDavid du Colombier 	if (sz > min_dict_size) {
362*13d37d77SDavid du Colombier 		unsigned base_size = 1 << data[5];
363*13d37d77SDavid du Colombier 		unsigned fraction = base_size / 16;
364*13d37d77SDavid du Colombier 		unsigned	i;
365*13d37d77SDavid du Colombier 		for (i = 7; i >= 1; --i)
366*13d37d77SDavid du Colombier 			if (base_size - (i * fraction) >= sz) {
367*13d37d77SDavid du Colombier 				data[5] |= (i << 5);
368*13d37d77SDavid du Colombier 				break;
369*13d37d77SDavid du Colombier 			}
370*13d37d77SDavid du Colombier 	}
371*13d37d77SDavid du Colombier 	return true;
372*13d37d77SDavid du Colombier }
373*13d37d77SDavid du Colombier 
374*13d37d77SDavid du Colombier unsigned
Ft_get_data_crc(File_trailer data)375*13d37d77SDavid du Colombier Ft_get_data_crc(File_trailer data)
376*13d37d77SDavid du Colombier {
377*13d37d77SDavid du Colombier 	unsigned	tmp = 0;
378*13d37d77SDavid du Colombier 	int	i;
379*13d37d77SDavid du Colombier 	for (i = 3; i >= 0; --i) {
380*13d37d77SDavid du Colombier 		tmp <<= 8;
381*13d37d77SDavid du Colombier 		tmp += data[i];
382*13d37d77SDavid du Colombier 	}
383*13d37d77SDavid du Colombier 	return tmp;
384*13d37d77SDavid du Colombier }
385*13d37d77SDavid du Colombier 
386*13d37d77SDavid du Colombier void
Ft_set_data_crc(File_trailer data,unsigned crc)387*13d37d77SDavid du Colombier Ft_set_data_crc(File_trailer data, unsigned crc)
388*13d37d77SDavid du Colombier {
389*13d37d77SDavid du Colombier 	int	i;
390*13d37d77SDavid du Colombier 	for (i = 0; i <= 3; ++i) {
391*13d37d77SDavid du Colombier 		data[i] = (uchar)crc;
392*13d37d77SDavid du Colombier 		crc >>= 8;
393*13d37d77SDavid du Colombier 	}
394*13d37d77SDavid du Colombier }
395*13d37d77SDavid du Colombier 
396*13d37d77SDavid du Colombier uvlong
Ft_get_data_size(File_trailer data)397*13d37d77SDavid du Colombier Ft_get_data_size(File_trailer data)
398*13d37d77SDavid du Colombier {
399*13d37d77SDavid du Colombier 	uvlong	tmp = 0;
400*13d37d77SDavid du Colombier 	int	i;
401*13d37d77SDavid du Colombier 	for (i = 11; i >= 4; --i) {
402*13d37d77SDavid du Colombier 		tmp <<= 8;
403*13d37d77SDavid du Colombier 		tmp += data[i];
404*13d37d77SDavid du Colombier 	}
405*13d37d77SDavid du Colombier 	return tmp;
406*13d37d77SDavid du Colombier }
407*13d37d77SDavid du Colombier 
408*13d37d77SDavid du Colombier void
Ft_set_data_size(File_trailer data,uvlong sz)409*13d37d77SDavid du Colombier Ft_set_data_size(File_trailer data, uvlong sz)
410*13d37d77SDavid du Colombier {
411*13d37d77SDavid du Colombier 	int	i;
412*13d37d77SDavid du Colombier 	for (i = 4; i <= 11; ++i) {
413*13d37d77SDavid du Colombier 		data[i] = (uchar)sz;
414*13d37d77SDavid du Colombier 		sz >>= 8;
415*13d37d77SDavid du Colombier 	}
416*13d37d77SDavid du Colombier }
417*13d37d77SDavid du Colombier 
418*13d37d77SDavid du Colombier uvlong
Ft_get_member_size(File_trailer data)419*13d37d77SDavid du Colombier Ft_get_member_size(File_trailer data)
420*13d37d77SDavid du Colombier {
421*13d37d77SDavid du Colombier 	uvlong	tmp = 0;
422*13d37d77SDavid du Colombier 	int	i;
423*13d37d77SDavid du Colombier 	for (i = 19; i >= 12; --i) {
424*13d37d77SDavid du Colombier 		tmp <<= 8;
425*13d37d77SDavid du Colombier 		tmp += data[i];
426*13d37d77SDavid du Colombier 	}
427*13d37d77SDavid du Colombier 	return tmp;
428*13d37d77SDavid du Colombier }
429*13d37d77SDavid du Colombier 
430*13d37d77SDavid du Colombier void
Ft_set_member_size(File_trailer data,uvlong sz)431*13d37d77SDavid du Colombier Ft_set_member_size(File_trailer data, uvlong sz)
432*13d37d77SDavid du Colombier {
433*13d37d77SDavid du Colombier 	int	i;
434*13d37d77SDavid du Colombier 	for (i = 12; i <= 19; ++i) {
435*13d37d77SDavid du Colombier 		data[i] = (uchar)sz;
436*13d37d77SDavid du Colombier 		sz >>= 8;
437*13d37d77SDavid du Colombier 	}
438*13d37d77SDavid du Colombier }
439*13d37d77SDavid du Colombier #else					/* _DEFINE_INLINES */
440*13d37d77SDavid du Colombier void	Bm_array_init(Bit_model bm[], int size);
441*13d37d77SDavid du Colombier void	Bm_init(Bit_model *probability);
442*13d37d77SDavid du Colombier void	CRC32_init(void);
443*13d37d77SDavid du Colombier void	CRC32_update_buf(uint32_t *crc, uchar *buffer, int size);
444*13d37d77SDavid du Colombier void	CRC32_update_byte(uint32_t *crc, uchar byte);
445*13d37d77SDavid du Colombier unsigned	Fh_get_dict_size(File_header data);
446*13d37d77SDavid du Colombier bool	Fh_set_dict_size(File_header data, unsigned sz);
447*13d37d77SDavid du Colombier void	Fh_set_magic(File_header data);
448*13d37d77SDavid du Colombier bool	Fh_verify_magic(File_header data);
449*13d37d77SDavid du Colombier bool	Fh_verify_prefix(File_header data, int size);
450*13d37d77SDavid du Colombier bool	Fh_verify_version(File_header data);
451*13d37d77SDavid du Colombier uchar	Fh_version(File_header data);
452*13d37d77SDavid du Colombier unsigned	Ft_get_data_crc(File_trailer data);
453*13d37d77SDavid du Colombier uvlong	Ft_get_data_size(File_trailer data);
454*13d37d77SDavid du Colombier uvlong	Ft_get_member_size(File_trailer data);
455*13d37d77SDavid du Colombier void	Ft_set_data_crc(File_trailer data, unsigned crc);
456*13d37d77SDavid du Colombier void	Ft_set_data_size(File_trailer data, uvlong sz);
457*13d37d77SDavid du Colombier void	Ft_set_member_size(File_trailer data, uvlong sz);
458*13d37d77SDavid du Colombier void	Lm_init(Len_model *lm);
459*13d37d77SDavid du Colombier void	Pp_init(Pretty_print *pp, char *filenames[], int num_filenames, int verbosity);
460*13d37d77SDavid du Colombier void	Pp_reset(Pretty_print *pp);
461*13d37d77SDavid du Colombier void	Pp_set_name(Pretty_print *pp, char *filename);
462*13d37d77SDavid du Colombier void	Pp_show_msg(Pretty_print *pp, char *msg);
463*13d37d77SDavid du Colombier State	St_set_char(State st);
464*13d37d77SDavid du Colombier int	get_lit_state(uchar prev_byte);
465*13d37d77SDavid du Colombier int	get_len_state(int len);
466*13d37d77SDavid du Colombier bool	isvalid_ds(unsigned dict_size);
467*13d37d77SDavid du Colombier int	real_bits(unsigned value);
468*13d37d77SDavid du Colombier #endif					/* _DEFINE_INLINES */
469*13d37d77SDavid du Colombier 
470*13d37d77SDavid du Colombier #define St_is_char(state)	((state) < 7)
471*13d37d77SDavid du Colombier #define St_set_match(state)	((state) < 7? 7: 10)
472*13d37d77SDavid du Colombier #define St_set_rep(state)	((state) < 7? 8: 11)
473*13d37d77SDavid du Colombier #define St_set_short_rep(state)	((state) < 7? 9: 11)
474*13d37d77SDavid du Colombier 
475*13d37d77SDavid du Colombier static char *bad_magic_msg = "Bad magic number (file not in lzip format).";
476*13d37d77SDavid du Colombier static char *bad_dict_msg = "Invalid dictionary size in member header.";
477*13d37d77SDavid du Colombier static char *trailing_msg = "Trailing data not allowed.";
478*13d37d77SDavid du Colombier 
479*13d37d77SDavid du Colombier /* defined in decoder.c */
480*13d37d77SDavid du Colombier int	readblock(int fd, uchar *buf, int size);
481*13d37d77SDavid du Colombier int	writeblock(int fd, uchar *buf, int size);
482*13d37d77SDavid du Colombier 
483*13d37d77SDavid du Colombier /* defined in main.c */
484*13d37d77SDavid du Colombier extern int verbosity;
485*13d37d77SDavid du Colombier Dir;
486*13d37d77SDavid du Colombier char	*bad_version(unsigned version);
487*13d37d77SDavid du Colombier char	*format_ds(unsigned dict_size);
488*13d37d77SDavid du Colombier int	open_instream(char *name, Dir *in_statsp, bool no_ofile, bool reg_only);
489*13d37d77SDavid du Colombier void	*resize_buffer(void *buf, unsigned min_size);
490*13d37d77SDavid du Colombier void	cleanup_and_fail(int retval);
491*13d37d77SDavid du Colombier void	show_error(char *msg, int errcode, bool help);
492*13d37d77SDavid du Colombier void	show_file_error(char *filename, char *msg, int errcode);
493*13d37d77SDavid du Colombier void	internal_error(char *msg);
494*13d37d77SDavid du Colombier struct Matchfinder_base;
495*13d37d77SDavid du Colombier void	show_progress(uvlong partial_size, Matchfinder_base *m, Pretty_print *p,
496*13d37d77SDavid du Colombier 	uvlong cfile_size);
497*13d37d77SDavid du Colombier #endif
498