xref: /aosp_15_r20/external/erofs-utils/lib/kite_deflate.c (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1*33b1fccfSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
2*33b1fccfSAndroid Build Coastguard Worker /*
3*33b1fccfSAndroid Build Coastguard Worker  * erofs-utils/lib/kite_deflate.c
4*33b1fccfSAndroid Build Coastguard Worker  *
5*33b1fccfSAndroid Build Coastguard Worker  * Copyright (C) 2023, Alibaba Cloud
6*33b1fccfSAndroid Build Coastguard Worker  * Copyright (C) 2023, Gao Xiang <[email protected]>
7*33b1fccfSAndroid Build Coastguard Worker  */
8*33b1fccfSAndroid Build Coastguard Worker #include "erofs/defs.h"
9*33b1fccfSAndroid Build Coastguard Worker #include "erofs/print.h"
10*33b1fccfSAndroid Build Coastguard Worker #include <errno.h>
11*33b1fccfSAndroid Build Coastguard Worker #include <stdlib.h>
12*33b1fccfSAndroid Build Coastguard Worker #include <string.h>
13*33b1fccfSAndroid Build Coastguard Worker #include <ctype.h>
14*33b1fccfSAndroid Build Coastguard Worker #include <stdio.h>
15*33b1fccfSAndroid Build Coastguard Worker 
16*33b1fccfSAndroid Build Coastguard Worker unsigned long erofs_memcmp2(const u8 *s1, const u8 *s2,
17*33b1fccfSAndroid Build Coastguard Worker 			    unsigned long sz);
18*33b1fccfSAndroid Build Coastguard Worker 
19*33b1fccfSAndroid Build Coastguard Worker #ifdef TEST
20*33b1fccfSAndroid Build Coastguard Worker #define kite_dbg(x, ...)	fprintf(stderr, x "\n", ##__VA_ARGS__)
21*33b1fccfSAndroid Build Coastguard Worker #else
22*33b1fccfSAndroid Build Coastguard Worker #define kite_dbg(x, ...)
23*33b1fccfSAndroid Build Coastguard Worker #endif
24*33b1fccfSAndroid Build Coastguard Worker 
25*33b1fccfSAndroid Build Coastguard Worker #define kHistorySize32		(1U << 15)
26*33b1fccfSAndroid Build Coastguard Worker 
27*33b1fccfSAndroid Build Coastguard Worker #define kNumLenSymbols32	256
28*33b1fccfSAndroid Build Coastguard Worker #define kNumLenSymbolsMax	kNumLenSymbols32
29*33b1fccfSAndroid Build Coastguard Worker 
30*33b1fccfSAndroid Build Coastguard Worker #define kSymbolEndOfBlock	256
31*33b1fccfSAndroid Build Coastguard Worker #define kSymbolMatch		(kSymbolEndOfBlock + 1)
32*33b1fccfSAndroid Build Coastguard Worker #define kNumLenSlots		29
33*33b1fccfSAndroid Build Coastguard Worker #define kMainTableSize		(kSymbolMatch + kNumLenSlots)
34*33b1fccfSAndroid Build Coastguard Worker 
35*33b1fccfSAndroid Build Coastguard Worker #define kFixedLenTableSize	(kSymbolMatch + 31)
36*33b1fccfSAndroid Build Coastguard Worker #define FixedDistTableSize	32
37*33b1fccfSAndroid Build Coastguard Worker 
38*33b1fccfSAndroid Build Coastguard Worker #define kMainTableSize		(kSymbolMatch + kNumLenSlots)
39*33b1fccfSAndroid Build Coastguard Worker #define kDistTableSize32	30
40*33b1fccfSAndroid Build Coastguard Worker 
41*33b1fccfSAndroid Build Coastguard Worker #define kNumLitLenCodesMin	257
42*33b1fccfSAndroid Build Coastguard Worker #define kNumDistCodesMin	1
43*33b1fccfSAndroid Build Coastguard Worker 
44*33b1fccfSAndroid Build Coastguard Worker #define kNumLensCodesMin	4
45*33b1fccfSAndroid Build Coastguard Worker #define kLensTableSize		19
46*33b1fccfSAndroid Build Coastguard Worker 
47*33b1fccfSAndroid Build Coastguard Worker #define kMatchMinLen		3
48*33b1fccfSAndroid Build Coastguard Worker #define kMatchMaxLen32		kNumLenSymbols32 + kMatchMinLen - 1
49*33b1fccfSAndroid Build Coastguard Worker 
50*33b1fccfSAndroid Build Coastguard Worker #define kTableDirectLevels      16
51*33b1fccfSAndroid Build Coastguard Worker #define kBitLensRepNumber_3_6   kTableDirectLevels
52*33b1fccfSAndroid Build Coastguard Worker #define kBitLens0Number_3_10    (kBitLensRepNumber_3_6 + 1)
53*33b1fccfSAndroid Build Coastguard Worker #define kBitLens0Number_11_138  (kBitLens0Number_3_10 + 1)
54*33b1fccfSAndroid Build Coastguard Worker 
55*33b1fccfSAndroid Build Coastguard Worker static u32 kstaticHuff_mainCodes[kFixedLenTableSize];
56*33b1fccfSAndroid Build Coastguard Worker static const u8 kstaticHuff_litLenLevels[kFixedLenTableSize] = {
57*33b1fccfSAndroid Build Coastguard Worker 	[0   ... 143] = 8, [144 ... 255] = 9,
58*33b1fccfSAndroid Build Coastguard Worker 	[256 ... 279] = 7, [280 ... 287] = 8,
59*33b1fccfSAndroid Build Coastguard Worker };
60*33b1fccfSAndroid Build Coastguard Worker static u32 kstaticHuff_distCodes[kFixedLenTableSize];
61*33b1fccfSAndroid Build Coastguard Worker 
62*33b1fccfSAndroid Build Coastguard Worker const u8 kLenStart32[kNumLenSlots] =
63*33b1fccfSAndroid Build Coastguard Worker 	{0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224, 255};
64*33b1fccfSAndroid Build Coastguard Worker 
65*33b1fccfSAndroid Build Coastguard Worker const u8 kLenExtraBits32[kNumLenSlots] =
66*33b1fccfSAndroid Build Coastguard Worker 	{0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,
67*33b1fccfSAndroid Build Coastguard Worker 	 5,  5,  5, 0};
68*33b1fccfSAndroid Build Coastguard Worker 
69*33b1fccfSAndroid Build Coastguard Worker /* First normalized distance for each code (0 = distance of 1) */
70*33b1fccfSAndroid Build Coastguard Worker const u32 kDistStart[kDistTableSize32] =
71*33b1fccfSAndroid Build Coastguard Worker 	{0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,
72*33b1fccfSAndroid Build Coastguard Worker 	 1024,1536,2048,3072,4096,6144,8192,12288,16384,24576};
73*33b1fccfSAndroid Build Coastguard Worker 
74*33b1fccfSAndroid Build Coastguard Worker /* extra bits for each distance code */
75*33b1fccfSAndroid Build Coastguard Worker const u8 kDistExtraBits[kDistTableSize32] =
76*33b1fccfSAndroid Build Coastguard Worker 	{0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
77*33b1fccfSAndroid Build Coastguard Worker 
78*33b1fccfSAndroid Build Coastguard Worker const u8 kCodeLengthAlphabetOrder[kLensTableSize] =
79*33b1fccfSAndroid Build Coastguard Worker 	{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
80*33b1fccfSAndroid Build Coastguard Worker 
81*33b1fccfSAndroid Build Coastguard Worker const u8 kLevelExtraBits[3] = {2, 3, 7};
82*33b1fccfSAndroid Build Coastguard Worker 
83*33b1fccfSAndroid Build Coastguard Worker #define kStored			0
84*33b1fccfSAndroid Build Coastguard Worker #define kFixedHuffman		1
85*33b1fccfSAndroid Build Coastguard Worker #define kDynamicHuffman		2
86*33b1fccfSAndroid Build Coastguard Worker 
87*33b1fccfSAndroid Build Coastguard Worker struct kite_deflate_symbol {
88*33b1fccfSAndroid Build Coastguard Worker 	u16 len, dist;
89*33b1fccfSAndroid Build Coastguard Worker };
90*33b1fccfSAndroid Build Coastguard Worker 
91*33b1fccfSAndroid Build Coastguard Worker struct kite_deflate_table {
92*33b1fccfSAndroid Build Coastguard Worker 	u32  mainCodes[kMainTableSize];
93*33b1fccfSAndroid Build Coastguard Worker 	u8   litLenLevels[kMainTableSize];
94*33b1fccfSAndroid Build Coastguard Worker 	u32  distCodes[kDistTableSize32];
95*33b1fccfSAndroid Build Coastguard Worker 	u8   distLevels[kDistTableSize32];
96*33b1fccfSAndroid Build Coastguard Worker 	u32  levelCodes[kLensTableSize];
97*33b1fccfSAndroid Build Coastguard Worker 	u8   levelLens[kLensTableSize];
98*33b1fccfSAndroid Build Coastguard Worker 
99*33b1fccfSAndroid Build Coastguard Worker 	u8   numdistlens, numblcodes;
100*33b1fccfSAndroid Build Coastguard Worker 	u16  numlitlens;
101*33b1fccfSAndroid Build Coastguard Worker };
102*33b1fccfSAndroid Build Coastguard Worker 
103*33b1fccfSAndroid Build Coastguard Worker struct kite_deflate {
104*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_table  *tab;
105*33b1fccfSAndroid Build Coastguard Worker 	const u8   *in;
106*33b1fccfSAndroid Build Coastguard Worker 	u8         *out;
107*33b1fccfSAndroid Build Coastguard Worker 
108*33b1fccfSAndroid Build Coastguard Worker 	u32  inlen, outlen;
109*33b1fccfSAndroid Build Coastguard Worker 	u32  pos_in, pos_out;
110*33b1fccfSAndroid Build Coastguard Worker 	u32  inflightbits;
111*33b1fccfSAndroid Build Coastguard Worker 	u8   bitpos;
112*33b1fccfSAndroid Build Coastguard Worker 	u8   numHuffBits;
113*33b1fccfSAndroid Build Coastguard Worker 	u32  symbols;
114*33b1fccfSAndroid Build Coastguard Worker 
115*33b1fccfSAndroid Build Coastguard Worker 	u32  costbits, startpos;
116*33b1fccfSAndroid Build Coastguard Worker 	u8   encode_mode;
117*33b1fccfSAndroid Build Coastguard Worker 	bool freq_changed, lastblock;
118*33b1fccfSAndroid Build Coastguard Worker 
119*33b1fccfSAndroid Build Coastguard Worker 	/* Previous match for lazy matching */
120*33b1fccfSAndroid Build Coastguard Worker 	bool prev_valid;
121*33b1fccfSAndroid Build Coastguard Worker 	u16 prev_longest;
122*33b1fccfSAndroid Build Coastguard Worker 
123*33b1fccfSAndroid Build Coastguard Worker 	u32  mainFreqs[kMainTableSize];
124*33b1fccfSAndroid Build Coastguard Worker 	u32  distFreqs[kDistTableSize32];
125*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_table tables[2];
126*33b1fccfSAndroid Build Coastguard Worker 
127*33b1fccfSAndroid Build Coastguard Worker 	/* don't reset the following fields */
128*33b1fccfSAndroid Build Coastguard Worker 	struct kite_matchfinder *mf;
129*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_symbol *sym;
130*33b1fccfSAndroid Build Coastguard Worker 	u32 max_symbols;
131*33b1fccfSAndroid Build Coastguard Worker 	bool lazy_search;
132*33b1fccfSAndroid Build Coastguard Worker };
133*33b1fccfSAndroid Build Coastguard Worker 
134*33b1fccfSAndroid Build Coastguard Worker #define ZLIB_DISTANCE_TOO_FAR	4096
135*33b1fccfSAndroid Build Coastguard Worker 
136*33b1fccfSAndroid Build Coastguard Worker static u8 g_LenSlots[kNumLenSymbolsMax];
137*33b1fccfSAndroid Build Coastguard Worker 
138*33b1fccfSAndroid Build Coastguard Worker #define kNumLogBits 9		// do not change it
139*33b1fccfSAndroid Build Coastguard Worker static u8 g_FastPos[1 << kNumLogBits];
140*33b1fccfSAndroid Build Coastguard Worker 
writebits(struct kite_deflate * s,unsigned int v,u8 bits)141*33b1fccfSAndroid Build Coastguard Worker static void writebits(struct kite_deflate *s, unsigned int v, u8 bits)
142*33b1fccfSAndroid Build Coastguard Worker {
143*33b1fccfSAndroid Build Coastguard Worker 	unsigned int rem = sizeof(s->inflightbits) * 8 - s->bitpos;
144*33b1fccfSAndroid Build Coastguard Worker 
145*33b1fccfSAndroid Build Coastguard Worker 	s->inflightbits |= (v << s->bitpos) & (!rem - 1);
146*33b1fccfSAndroid Build Coastguard Worker 	if (bits > rem) {
147*33b1fccfSAndroid Build Coastguard Worker 		u8 *out = s->out + s->pos_out;
148*33b1fccfSAndroid Build Coastguard Worker 
149*33b1fccfSAndroid Build Coastguard Worker 		out[0] = s->inflightbits & 0xff;
150*33b1fccfSAndroid Build Coastguard Worker 		out[1] = (s->inflightbits >> 8) & 0xff;
151*33b1fccfSAndroid Build Coastguard Worker 		out[2] = (s->inflightbits >> 16) & 0xff;
152*33b1fccfSAndroid Build Coastguard Worker 		out[3] = (s->inflightbits >> 24) & 0xff;
153*33b1fccfSAndroid Build Coastguard Worker 		s->pos_out += 4;
154*33b1fccfSAndroid Build Coastguard Worker 		DBG_BUGON(s->pos_out > s->outlen);
155*33b1fccfSAndroid Build Coastguard Worker 		s->inflightbits = v >> rem;
156*33b1fccfSAndroid Build Coastguard Worker 		s->bitpos = bits - rem;
157*33b1fccfSAndroid Build Coastguard Worker 		return;
158*33b1fccfSAndroid Build Coastguard Worker 	}
159*33b1fccfSAndroid Build Coastguard Worker 	s->bitpos += bits;
160*33b1fccfSAndroid Build Coastguard Worker }
161*33b1fccfSAndroid Build Coastguard Worker 
flushbits(struct kite_deflate * s)162*33b1fccfSAndroid Build Coastguard Worker static void flushbits(struct kite_deflate *s)
163*33b1fccfSAndroid Build Coastguard Worker {
164*33b1fccfSAndroid Build Coastguard Worker 	u8 *out = s->out + s->pos_out;
165*33b1fccfSAndroid Build Coastguard Worker 
166*33b1fccfSAndroid Build Coastguard Worker 	if (!s->bitpos)
167*33b1fccfSAndroid Build Coastguard Worker 		return;
168*33b1fccfSAndroid Build Coastguard Worker 	out[0] = s->inflightbits & 0xff;
169*33b1fccfSAndroid Build Coastguard Worker 	if (s->bitpos >= 8) {
170*33b1fccfSAndroid Build Coastguard Worker 		out[1] = (s->inflightbits >> 8) & 0xff;
171*33b1fccfSAndroid Build Coastguard Worker 		if (s->bitpos >= 16) {
172*33b1fccfSAndroid Build Coastguard Worker 			out[2] = (s->inflightbits >> 16) & 0xff;
173*33b1fccfSAndroid Build Coastguard Worker 			if (s->bitpos >= 24)
174*33b1fccfSAndroid Build Coastguard Worker 				out[3] = (s->inflightbits >> 24) & 0xff;
175*33b1fccfSAndroid Build Coastguard Worker 		}
176*33b1fccfSAndroid Build Coastguard Worker 	}
177*33b1fccfSAndroid Build Coastguard Worker 	s->pos_out += round_up(s->bitpos, 8) >> 3;
178*33b1fccfSAndroid Build Coastguard Worker 	DBG_BUGON(s->pos_out > s->outlen);
179*33b1fccfSAndroid Build Coastguard Worker 	s->bitpos = 0;
180*33b1fccfSAndroid Build Coastguard Worker 	s->inflightbits = 0;
181*33b1fccfSAndroid Build Coastguard Worker }
182*33b1fccfSAndroid Build Coastguard Worker 
183*33b1fccfSAndroid Build Coastguard Worker #define kMaxLen 16
184*33b1fccfSAndroid Build Coastguard Worker 
deflate_genhuffcodes(const u8 * lens,u32 * p,unsigned int nr_codes,const u32 * bl_count)185*33b1fccfSAndroid Build Coastguard Worker static void deflate_genhuffcodes(const u8 *lens, u32 *p, unsigned int nr_codes,
186*33b1fccfSAndroid Build Coastguard Worker 				 const u32 *bl_count)
187*33b1fccfSAndroid Build Coastguard Worker {
188*33b1fccfSAndroid Build Coastguard Worker 	u32 nextCodes[kMaxLen + 1];	/* next code value for each bit length */
189*33b1fccfSAndroid Build Coastguard Worker 	unsigned int code = 0;		/* running code value */
190*33b1fccfSAndroid Build Coastguard Worker 	unsigned int bits, k;
191*33b1fccfSAndroid Build Coastguard Worker 
192*33b1fccfSAndroid Build Coastguard Worker 	for (bits = 1; bits <= kMaxLen; ++bits) {
193*33b1fccfSAndroid Build Coastguard Worker 		code = (code + bl_count[bits - 1]) << 1;
194*33b1fccfSAndroid Build Coastguard Worker 		nextCodes[bits] = code;
195*33b1fccfSAndroid Build Coastguard Worker 	}
196*33b1fccfSAndroid Build Coastguard Worker 
197*33b1fccfSAndroid Build Coastguard Worker 	DBG_BUGON(code + bl_count[kMaxLen] != 1 << kMaxLen);
198*33b1fccfSAndroid Build Coastguard Worker 
199*33b1fccfSAndroid Build Coastguard Worker 	for (k = 0; k < nr_codes; ++k)
200*33b1fccfSAndroid Build Coastguard Worker 		p[k] = nextCodes[lens[k]]++;
201*33b1fccfSAndroid Build Coastguard Worker }
202*33b1fccfSAndroid Build Coastguard Worker 
deflate_reversebits_one(u32 code,u8 bits)203*33b1fccfSAndroid Build Coastguard Worker static u32 deflate_reversebits_one(u32 code, u8 bits)
204*33b1fccfSAndroid Build Coastguard Worker {
205*33b1fccfSAndroid Build Coastguard Worker 	unsigned int x = code;
206*33b1fccfSAndroid Build Coastguard Worker 
207*33b1fccfSAndroid Build Coastguard Worker 	x = ((x & 0x5555) << 1) | ((x & 0xAAAA) >> 1);
208*33b1fccfSAndroid Build Coastguard Worker 	x = ((x & 0x3333) << 2) | ((x & 0xCCCC) >> 2);
209*33b1fccfSAndroid Build Coastguard Worker 	x = ((x & 0x0F0F) << 4) | ((x & 0xF0F0) >> 4);
210*33b1fccfSAndroid Build Coastguard Worker 
211*33b1fccfSAndroid Build Coastguard Worker 	return (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)) >> (16 - bits);
212*33b1fccfSAndroid Build Coastguard Worker }
213*33b1fccfSAndroid Build Coastguard Worker 
Huffman_ReverseBits(u32 * codes,const u8 * lens,unsigned int n)214*33b1fccfSAndroid Build Coastguard Worker static void Huffman_ReverseBits(u32 *codes, const u8 *lens, unsigned int n)
215*33b1fccfSAndroid Build Coastguard Worker {
216*33b1fccfSAndroid Build Coastguard Worker 	while (n) {
217*33b1fccfSAndroid Build Coastguard Worker 		u32 code = *codes;
218*33b1fccfSAndroid Build Coastguard Worker 
219*33b1fccfSAndroid Build Coastguard Worker 		*codes++ = deflate_reversebits_one(code, *lens++);
220*33b1fccfSAndroid Build Coastguard Worker 		--n;
221*33b1fccfSAndroid Build Coastguard Worker 	}
222*33b1fccfSAndroid Build Coastguard Worker }
223*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_init_once(void)224*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_init_once(void)
225*33b1fccfSAndroid Build Coastguard Worker {
226*33b1fccfSAndroid Build Coastguard Worker 	static const u32 static_bl_count[kMaxLen + 1] = {
227*33b1fccfSAndroid Build Coastguard Worker 		[7] = 279 - 256 + 1,
228*33b1fccfSAndroid Build Coastguard Worker 		[8] = (143 + 1) + (287 - 280 + 1),
229*33b1fccfSAndroid Build Coastguard Worker 		[9] = 255 - 144 + 1,
230*33b1fccfSAndroid Build Coastguard Worker 	};
231*33b1fccfSAndroid Build Coastguard Worker 	unsigned int i, c, j, k;
232*33b1fccfSAndroid Build Coastguard Worker 
233*33b1fccfSAndroid Build Coastguard Worker 	if (kstaticHuff_distCodes[31])
234*33b1fccfSAndroid Build Coastguard Worker 		return;
235*33b1fccfSAndroid Build Coastguard Worker 	deflate_genhuffcodes(kstaticHuff_litLenLevels, kstaticHuff_mainCodes,
236*33b1fccfSAndroid Build Coastguard Worker 			     kFixedLenTableSize, static_bl_count);
237*33b1fccfSAndroid Build Coastguard Worker 	Huffman_ReverseBits(kstaticHuff_mainCodes, kstaticHuff_litLenLevels,
238*33b1fccfSAndroid Build Coastguard Worker 			    kFixedLenTableSize);
239*33b1fccfSAndroid Build Coastguard Worker 
240*33b1fccfSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(kstaticHuff_distCodes); ++i)
241*33b1fccfSAndroid Build Coastguard Worker 		kstaticHuff_distCodes[i] = deflate_reversebits_one(i, 5);
242*33b1fccfSAndroid Build Coastguard Worker 
243*33b1fccfSAndroid Build Coastguard Worker 	for (i = 0; i < kNumLenSlots; i++) {
244*33b1fccfSAndroid Build Coastguard Worker 		c = kLenStart32[i];
245*33b1fccfSAndroid Build Coastguard Worker 		j = 1 << kLenExtraBits32[i];
246*33b1fccfSAndroid Build Coastguard Worker 
247*33b1fccfSAndroid Build Coastguard Worker 		for (k = 0; k < j; k++, c++)
248*33b1fccfSAndroid Build Coastguard Worker 			g_LenSlots[c] = (u8)i;
249*33b1fccfSAndroid Build Coastguard Worker 	}
250*33b1fccfSAndroid Build Coastguard Worker 
251*33b1fccfSAndroid Build Coastguard Worker 	c = 0;
252*33b1fccfSAndroid Build Coastguard Worker 	for (i = 0; i < /*kFastSlots*/ kNumLogBits * 2; i++) {
253*33b1fccfSAndroid Build Coastguard Worker 		k = 1 << kDistExtraBits[i];
254*33b1fccfSAndroid Build Coastguard Worker 		for (j = 0; j < k; j++)
255*33b1fccfSAndroid Build Coastguard Worker 			g_FastPos[c++] = i;
256*33b1fccfSAndroid Build Coastguard Worker 	}
257*33b1fccfSAndroid Build Coastguard Worker }
258*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_scanlens(unsigned int numlens,u8 * lens,u32 * freqs)259*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_scanlens(unsigned int numlens, u8 *lens, u32 *freqs)
260*33b1fccfSAndroid Build Coastguard Worker {
261*33b1fccfSAndroid Build Coastguard Worker 	int n;				/* iterates over all tree elements */
262*33b1fccfSAndroid Build Coastguard Worker 	int prevlen = -1;		/* last emitted length */
263*33b1fccfSAndroid Build Coastguard Worker 	int curlen;			/* length of current code */
264*33b1fccfSAndroid Build Coastguard Worker 	int nextlen = lens[0];		/* length of next code */
265*33b1fccfSAndroid Build Coastguard Worker 	int count = 0;			/* repeat count of the current code */
266*33b1fccfSAndroid Build Coastguard Worker 	int max_count = 7;		/* max repeat count */
267*33b1fccfSAndroid Build Coastguard Worker 	int min_count = 4;		/* min repeat count */
268*33b1fccfSAndroid Build Coastguard Worker 
269*33b1fccfSAndroid Build Coastguard Worker 	if (!nextlen)
270*33b1fccfSAndroid Build Coastguard Worker 		max_count = 138, min_count = 3;
271*33b1fccfSAndroid Build Coastguard Worker 
272*33b1fccfSAndroid Build Coastguard Worker 	for (n = 0; n < numlens; n++) {
273*33b1fccfSAndroid Build Coastguard Worker 		curlen = nextlen;
274*33b1fccfSAndroid Build Coastguard Worker 		nextlen = n + 1 < numlens ? lens[n + 1] : -1;
275*33b1fccfSAndroid Build Coastguard Worker 		++count;
276*33b1fccfSAndroid Build Coastguard Worker 
277*33b1fccfSAndroid Build Coastguard Worker 		if (count < max_count && curlen == nextlen)
278*33b1fccfSAndroid Build Coastguard Worker 			continue;
279*33b1fccfSAndroid Build Coastguard Worker 		if (count < min_count) {
280*33b1fccfSAndroid Build Coastguard Worker 			freqs[curlen] += count;
281*33b1fccfSAndroid Build Coastguard Worker 		} else if (curlen != 0) {
282*33b1fccfSAndroid Build Coastguard Worker 			if (curlen != prevlen)
283*33b1fccfSAndroid Build Coastguard Worker 				freqs[curlen]++;
284*33b1fccfSAndroid Build Coastguard Worker 			freqs[kBitLensRepNumber_3_6]++;
285*33b1fccfSAndroid Build Coastguard Worker 		} else if (count <= 10) {
286*33b1fccfSAndroid Build Coastguard Worker 			freqs[kBitLens0Number_3_10]++;
287*33b1fccfSAndroid Build Coastguard Worker 		} else {
288*33b1fccfSAndroid Build Coastguard Worker 			freqs[kBitLens0Number_11_138]++;
289*33b1fccfSAndroid Build Coastguard Worker 		}
290*33b1fccfSAndroid Build Coastguard Worker 
291*33b1fccfSAndroid Build Coastguard Worker 		count = 0;
292*33b1fccfSAndroid Build Coastguard Worker 		prevlen = curlen;
293*33b1fccfSAndroid Build Coastguard Worker 		if (!nextlen)
294*33b1fccfSAndroid Build Coastguard Worker 			max_count = 138, min_count = 3;
295*33b1fccfSAndroid Build Coastguard Worker 		else if (curlen == nextlen)
296*33b1fccfSAndroid Build Coastguard Worker 			max_count = 6, min_count = 3;
297*33b1fccfSAndroid Build Coastguard Worker 		else
298*33b1fccfSAndroid Build Coastguard Worker 			max_count = 7, min_count = 4;
299*33b1fccfSAndroid Build Coastguard Worker 	}
300*33b1fccfSAndroid Build Coastguard Worker }
301*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_sendtree(struct kite_deflate * s,const u8 * lens,unsigned int numlens)302*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_sendtree(struct kite_deflate *s, const u8 *lens,
303*33b1fccfSAndroid Build Coastguard Worker 				  unsigned int numlens)
304*33b1fccfSAndroid Build Coastguard Worker {
305*33b1fccfSAndroid Build Coastguard Worker 	int n;				/* iterates over all tree elements */
306*33b1fccfSAndroid Build Coastguard Worker 	int prevlen = -1;		/* last emitted length */
307*33b1fccfSAndroid Build Coastguard Worker 	int curlen;			/* length of current code */
308*33b1fccfSAndroid Build Coastguard Worker 	int nextlen = lens[0];		/* length of next code */
309*33b1fccfSAndroid Build Coastguard Worker 	int count = 0;			/* repeat count of the current code */
310*33b1fccfSAndroid Build Coastguard Worker 	int max_count = 7;		/* max repeat count */
311*33b1fccfSAndroid Build Coastguard Worker 	int min_count = 4;		/* min repeat count */
312*33b1fccfSAndroid Build Coastguard Worker 	const u8 *bl_lens = s->tab->levelLens;
313*33b1fccfSAndroid Build Coastguard Worker 	const u32 *bl_codes = s->tab->levelCodes;
314*33b1fccfSAndroid Build Coastguard Worker 
315*33b1fccfSAndroid Build Coastguard Worker 	if (!nextlen)
316*33b1fccfSAndroid Build Coastguard Worker 		max_count = 138, min_count = 3;
317*33b1fccfSAndroid Build Coastguard Worker 
318*33b1fccfSAndroid Build Coastguard Worker 	for (n = 0; n < numlens; n++) {
319*33b1fccfSAndroid Build Coastguard Worker 		curlen = nextlen;
320*33b1fccfSAndroid Build Coastguard Worker 		nextlen = n + 1 < numlens ? lens[n + 1] : -1;
321*33b1fccfSAndroid Build Coastguard Worker 		++count;
322*33b1fccfSAndroid Build Coastguard Worker 
323*33b1fccfSAndroid Build Coastguard Worker 		if (count < max_count && curlen == nextlen)
324*33b1fccfSAndroid Build Coastguard Worker 			continue;
325*33b1fccfSAndroid Build Coastguard Worker 		if (count < min_count) {
326*33b1fccfSAndroid Build Coastguard Worker 			do {
327*33b1fccfSAndroid Build Coastguard Worker 				writebits(s, bl_codes[curlen], bl_lens[curlen]);
328*33b1fccfSAndroid Build Coastguard Worker 			} while (--count);
329*33b1fccfSAndroid Build Coastguard Worker 		} else if (curlen) {
330*33b1fccfSAndroid Build Coastguard Worker 			if (curlen != prevlen) {
331*33b1fccfSAndroid Build Coastguard Worker 				writebits(s, bl_codes[curlen], bl_lens[curlen]);
332*33b1fccfSAndroid Build Coastguard Worker 				count--;
333*33b1fccfSAndroid Build Coastguard Worker 			}
334*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, bl_codes[kBitLensRepNumber_3_6],
335*33b1fccfSAndroid Build Coastguard Worker 				  bl_lens[kBitLensRepNumber_3_6]);
336*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, count - 3, 2);
337*33b1fccfSAndroid Build Coastguard Worker 		} else if (count <= 10) {
338*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, bl_codes[kBitLens0Number_3_10],
339*33b1fccfSAndroid Build Coastguard Worker 				  bl_lens[kBitLens0Number_3_10]);
340*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, count - 3, 3);
341*33b1fccfSAndroid Build Coastguard Worker 		} else {
342*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, bl_codes[kBitLens0Number_11_138],
343*33b1fccfSAndroid Build Coastguard Worker 				  bl_lens[kBitLens0Number_11_138]);
344*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, count - 11, 7);
345*33b1fccfSAndroid Build Coastguard Worker 		}
346*33b1fccfSAndroid Build Coastguard Worker 
347*33b1fccfSAndroid Build Coastguard Worker 		count = 0;
348*33b1fccfSAndroid Build Coastguard Worker 		prevlen = curlen;
349*33b1fccfSAndroid Build Coastguard Worker 		if (!nextlen)
350*33b1fccfSAndroid Build Coastguard Worker 			max_count = 138, min_count = 3;
351*33b1fccfSAndroid Build Coastguard Worker 		else if (curlen == nextlen)
352*33b1fccfSAndroid Build Coastguard Worker 			max_count = 6, min_count = 3;
353*33b1fccfSAndroid Build Coastguard Worker 		else
354*33b1fccfSAndroid Build Coastguard Worker 			max_count = 7, min_count = 4;
355*33b1fccfSAndroid Build Coastguard Worker 	}
356*33b1fccfSAndroid Build Coastguard Worker }
357*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_setfixedtrees(struct kite_deflate * s)358*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_setfixedtrees(struct kite_deflate *s)
359*33b1fccfSAndroid Build Coastguard Worker {
360*33b1fccfSAndroid Build Coastguard Worker 	writebits(s, (kFixedHuffman << 1) + s->lastblock, 3);
361*33b1fccfSAndroid Build Coastguard Worker }
362*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_sendtrees(struct kite_deflate * s)363*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_sendtrees(struct kite_deflate *s)
364*33b1fccfSAndroid Build Coastguard Worker {
365*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_table *t = s->tab;
366*33b1fccfSAndroid Build Coastguard Worker 	unsigned int i;
367*33b1fccfSAndroid Build Coastguard Worker 
368*33b1fccfSAndroid Build Coastguard Worker 	writebits(s, (kDynamicHuffman << 1) + s->lastblock, 3);
369*33b1fccfSAndroid Build Coastguard Worker 	writebits(s, t->numlitlens - kNumLitLenCodesMin, 5);
370*33b1fccfSAndroid Build Coastguard Worker 	writebits(s, t->numdistlens - kNumDistCodesMin,  5);
371*33b1fccfSAndroid Build Coastguard Worker 	writebits(s, t->numblcodes - kNumLensCodesMin,   4);
372*33b1fccfSAndroid Build Coastguard Worker 
373*33b1fccfSAndroid Build Coastguard Worker 	for (i = 0; i < t->numblcodes; i++)
374*33b1fccfSAndroid Build Coastguard Worker 		writebits(s, t->levelLens[kCodeLengthAlphabetOrder[i]], 3);
375*33b1fccfSAndroid Build Coastguard Worker 
376*33b1fccfSAndroid Build Coastguard Worker 	Huffman_ReverseBits(t->levelCodes, t->levelLens, kLensTableSize);
377*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_sendtree(s, t->litLenLevels, t->numlitlens);
378*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_sendtree(s, t->distLevels, t->numdistlens);
379*33b1fccfSAndroid Build Coastguard Worker }
380*33b1fccfSAndroid Build Coastguard Worker 
deflateDistSlot(unsigned int pos)381*33b1fccfSAndroid Build Coastguard Worker static inline unsigned int deflateDistSlot(unsigned int pos)
382*33b1fccfSAndroid Build Coastguard Worker {
383*33b1fccfSAndroid Build Coastguard Worker 	const unsigned int zz = (kNumLogBits - 1) &
384*33b1fccfSAndroid Build Coastguard Worker 		((((1U << kNumLogBits) - 1) - pos) >> (31 - 3));
385*33b1fccfSAndroid Build Coastguard Worker 
386*33b1fccfSAndroid Build Coastguard Worker 	return g_FastPos[pos >> zz] + (zz * 2);
387*33b1fccfSAndroid Build Coastguard Worker }
388*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_writeblock(struct kite_deflate * s,bool fixed)389*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_writeblock(struct kite_deflate *s, bool fixed)
390*33b1fccfSAndroid Build Coastguard Worker {
391*33b1fccfSAndroid Build Coastguard Worker 	int i;
392*33b1fccfSAndroid Build Coastguard Worker 	u32 *mainCodes, *distCodes;
393*33b1fccfSAndroid Build Coastguard Worker 	const u8 *litLenLevels, *distLevels;
394*33b1fccfSAndroid Build Coastguard Worker 
395*33b1fccfSAndroid Build Coastguard Worker 	if (!fixed) {
396*33b1fccfSAndroid Build Coastguard Worker 		struct kite_deflate_table *t = s->tab;
397*33b1fccfSAndroid Build Coastguard Worker 
398*33b1fccfSAndroid Build Coastguard Worker 		mainCodes = t->mainCodes; distCodes = t->distCodes;
399*33b1fccfSAndroid Build Coastguard Worker 		litLenLevels = t->litLenLevels;	distLevels = t->distLevels;
400*33b1fccfSAndroid Build Coastguard Worker 
401*33b1fccfSAndroid Build Coastguard Worker 		Huffman_ReverseBits(mainCodes, litLenLevels, kMainTableSize);
402*33b1fccfSAndroid Build Coastguard Worker 		Huffman_ReverseBits(distCodes, distLevels, kDistTableSize32);
403*33b1fccfSAndroid Build Coastguard Worker 	} else {
404*33b1fccfSAndroid Build Coastguard Worker 		mainCodes = kstaticHuff_mainCodes;
405*33b1fccfSAndroid Build Coastguard Worker 		distCodes = kstaticHuff_distCodes;
406*33b1fccfSAndroid Build Coastguard Worker 
407*33b1fccfSAndroid Build Coastguard Worker 		litLenLevels = kstaticHuff_litLenLevels;
408*33b1fccfSAndroid Build Coastguard Worker 		distLevels = NULL;
409*33b1fccfSAndroid Build Coastguard Worker 	}
410*33b1fccfSAndroid Build Coastguard Worker 
411*33b1fccfSAndroid Build Coastguard Worker 	for (i = 0; i < s->symbols; ++i) {
412*33b1fccfSAndroid Build Coastguard Worker 		struct kite_deflate_symbol *sym = &s->sym[i];
413*33b1fccfSAndroid Build Coastguard Worker 
414*33b1fccfSAndroid Build Coastguard Worker 		if (sym->len < kMatchMinLen) {		/* literal */
415*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, mainCodes[sym->dist],
416*33b1fccfSAndroid Build Coastguard Worker 				  litLenLevels[sym->dist]);
417*33b1fccfSAndroid Build Coastguard Worker 		} else {
418*33b1fccfSAndroid Build Coastguard Worker 			unsigned int lenSlot, distSlot;
419*33b1fccfSAndroid Build Coastguard Worker 			unsigned int lc = sym->len - kMatchMinLen;
420*33b1fccfSAndroid Build Coastguard Worker 
421*33b1fccfSAndroid Build Coastguard Worker 			lenSlot = g_LenSlots[lc];
422*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, mainCodes[kSymbolMatch + lenSlot],
423*33b1fccfSAndroid Build Coastguard Worker 				  litLenLevels[kSymbolMatch + lenSlot]);
424*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, lc - kLenStart32[lenSlot],
425*33b1fccfSAndroid Build Coastguard Worker 				  kLenExtraBits32[lenSlot]);
426*33b1fccfSAndroid Build Coastguard Worker 
427*33b1fccfSAndroid Build Coastguard Worker 			distSlot = deflateDistSlot(sym->dist - 1);
428*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, distCodes[distSlot],
429*33b1fccfSAndroid Build Coastguard Worker 				  fixed ? 5 : distLevels[distSlot]);
430*33b1fccfSAndroid Build Coastguard Worker 			writebits(s, sym->dist - 1 - kDistStart[distSlot],
431*33b1fccfSAndroid Build Coastguard Worker 				  kDistExtraBits[distSlot]);
432*33b1fccfSAndroid Build Coastguard Worker 		}
433*33b1fccfSAndroid Build Coastguard Worker 	}
434*33b1fccfSAndroid Build Coastguard Worker 	writebits(s, mainCodes[kSymbolEndOfBlock],
435*33b1fccfSAndroid Build Coastguard Worker 		  litLenLevels[kSymbolEndOfBlock]);
436*33b1fccfSAndroid Build Coastguard Worker }
437*33b1fccfSAndroid Build Coastguard Worker 
Huffman_GetPrice(const u32 * freqs,const u8 * lens,u32 num)438*33b1fccfSAndroid Build Coastguard Worker static u32 Huffman_GetPrice(const u32 *freqs, const u8 *lens, u32 num)
439*33b1fccfSAndroid Build Coastguard Worker {
440*33b1fccfSAndroid Build Coastguard Worker 	u32 price = 0;
441*33b1fccfSAndroid Build Coastguard Worker 
442*33b1fccfSAndroid Build Coastguard Worker 	while (num) {
443*33b1fccfSAndroid Build Coastguard Worker 		price += (*lens++) * (*freqs++);
444*33b1fccfSAndroid Build Coastguard Worker 		--num;
445*33b1fccfSAndroid Build Coastguard Worker 	}
446*33b1fccfSAndroid Build Coastguard Worker 	return price;
447*33b1fccfSAndroid Build Coastguard Worker }
448*33b1fccfSAndroid Build Coastguard Worker 
Huffman_GetPriceEx(const u32 * freqs,const u8 * lens,u32 num,const u8 * extraBits,u32 extraBase)449*33b1fccfSAndroid Build Coastguard Worker static u32 Huffman_GetPriceEx(const u32 *freqs, const u8 *lens, u32 num,
450*33b1fccfSAndroid Build Coastguard Worker 			      const u8 *extraBits, u32 extraBase)
451*33b1fccfSAndroid Build Coastguard Worker {
452*33b1fccfSAndroid Build Coastguard Worker 	return Huffman_GetPrice(freqs, lens, num) +
453*33b1fccfSAndroid Build Coastguard Worker 		Huffman_GetPrice(freqs + extraBase, extraBits, num - extraBase);
454*33b1fccfSAndroid Build Coastguard Worker }
455*33b1fccfSAndroid Build Coastguard Worker 
456*33b1fccfSAndroid Build Coastguard Worker /* Adapted from C/HuffEnc.c (7zip) for now */
457*33b1fccfSAndroid Build Coastguard Worker #define HeapSortDown(p, k, size, temp) \
458*33b1fccfSAndroid Build Coastguard Worker   { for (;;) { \
459*33b1fccfSAndroid Build Coastguard Worker     size_t s = (k << 1); \
460*33b1fccfSAndroid Build Coastguard Worker     if (s > size) break; \
461*33b1fccfSAndroid Build Coastguard Worker     if (s < size && p[s + 1] > p[s]) s++; \
462*33b1fccfSAndroid Build Coastguard Worker     if (temp >= p[s]) break; \
463*33b1fccfSAndroid Build Coastguard Worker     p[k] = p[s]; k = s; \
464*33b1fccfSAndroid Build Coastguard Worker   } p[k] = temp; }
465*33b1fccfSAndroid Build Coastguard Worker 
HeapSort(u32 * p,size_t size)466*33b1fccfSAndroid Build Coastguard Worker static void HeapSort(u32 *p, size_t size)
467*33b1fccfSAndroid Build Coastguard Worker {
468*33b1fccfSAndroid Build Coastguard Worker   if (size <= 1)
469*33b1fccfSAndroid Build Coastguard Worker     return;
470*33b1fccfSAndroid Build Coastguard Worker   p--;
471*33b1fccfSAndroid Build Coastguard Worker   {
472*33b1fccfSAndroid Build Coastguard Worker     size_t i = size / 2;
473*33b1fccfSAndroid Build Coastguard Worker     do
474*33b1fccfSAndroid Build Coastguard Worker     {
475*33b1fccfSAndroid Build Coastguard Worker       u32 temp = p[i];
476*33b1fccfSAndroid Build Coastguard Worker       size_t k = i;
477*33b1fccfSAndroid Build Coastguard Worker       HeapSortDown(p, k, size, temp)
478*33b1fccfSAndroid Build Coastguard Worker     }
479*33b1fccfSAndroid Build Coastguard Worker     while (--i != 0);
480*33b1fccfSAndroid Build Coastguard Worker   }
481*33b1fccfSAndroid Build Coastguard Worker   /*
482*33b1fccfSAndroid Build Coastguard Worker   do
483*33b1fccfSAndroid Build Coastguard Worker   {
484*33b1fccfSAndroid Build Coastguard Worker     size_t k = 1;
485*33b1fccfSAndroid Build Coastguard Worker     UInt32 temp = p[size];
486*33b1fccfSAndroid Build Coastguard Worker     p[size--] = p[1];
487*33b1fccfSAndroid Build Coastguard Worker     HeapSortDown(p, k, size, temp)
488*33b1fccfSAndroid Build Coastguard Worker   }
489*33b1fccfSAndroid Build Coastguard Worker   while (size > 1);
490*33b1fccfSAndroid Build Coastguard Worker   */
491*33b1fccfSAndroid Build Coastguard Worker   while (size > 3)
492*33b1fccfSAndroid Build Coastguard Worker   {
493*33b1fccfSAndroid Build Coastguard Worker     u32 temp = p[size];
494*33b1fccfSAndroid Build Coastguard Worker     size_t k = (p[3] > p[2]) ? 3 : 2;
495*33b1fccfSAndroid Build Coastguard Worker     p[size--] = p[1];
496*33b1fccfSAndroid Build Coastguard Worker     p[1] = p[k];
497*33b1fccfSAndroid Build Coastguard Worker     HeapSortDown(p, k, size, temp)
498*33b1fccfSAndroid Build Coastguard Worker   }
499*33b1fccfSAndroid Build Coastguard Worker   {
500*33b1fccfSAndroid Build Coastguard Worker     u32 temp = p[size];
501*33b1fccfSAndroid Build Coastguard Worker     p[size] = p[1];
502*33b1fccfSAndroid Build Coastguard Worker     if (size > 2 && p[2] < temp)
503*33b1fccfSAndroid Build Coastguard Worker     {
504*33b1fccfSAndroid Build Coastguard Worker       p[1] = p[2];
505*33b1fccfSAndroid Build Coastguard Worker       p[2] = temp;
506*33b1fccfSAndroid Build Coastguard Worker     }
507*33b1fccfSAndroid Build Coastguard Worker     else
508*33b1fccfSAndroid Build Coastguard Worker       p[1] = temp;
509*33b1fccfSAndroid Build Coastguard Worker   }
510*33b1fccfSAndroid Build Coastguard Worker }
511*33b1fccfSAndroid Build Coastguard Worker 
512*33b1fccfSAndroid Build Coastguard Worker #define NUM_BITS 10
513*33b1fccfSAndroid Build Coastguard Worker #define MASK (((unsigned)1 << NUM_BITS) - 1)
514*33b1fccfSAndroid Build Coastguard Worker 
Huffman_Generate(const u32 * freqs,u32 * p,u8 * lens,unsigned int numSymbols,unsigned int maxLen)515*33b1fccfSAndroid Build Coastguard Worker static void Huffman_Generate(const u32 *freqs, u32 *p, u8 *lens,
516*33b1fccfSAndroid Build Coastguard Worker 			     unsigned int numSymbols, unsigned int maxLen)
517*33b1fccfSAndroid Build Coastguard Worker {
518*33b1fccfSAndroid Build Coastguard Worker 	u32 num, i;
519*33b1fccfSAndroid Build Coastguard Worker 
520*33b1fccfSAndroid Build Coastguard Worker 	num = 0;
521*33b1fccfSAndroid Build Coastguard Worker 	/* if (maxLen > 10) maxLen = 10; */
522*33b1fccfSAndroid Build Coastguard Worker 
523*33b1fccfSAndroid Build Coastguard Worker 	for (i = 0; i < numSymbols; i++) {
524*33b1fccfSAndroid Build Coastguard Worker 		u32 freq = freqs[i];
525*33b1fccfSAndroid Build Coastguard Worker 
526*33b1fccfSAndroid Build Coastguard Worker 		if (!freq)
527*33b1fccfSAndroid Build Coastguard Worker 			lens[i] = 0;
528*33b1fccfSAndroid Build Coastguard Worker 		else
529*33b1fccfSAndroid Build Coastguard Worker 			p[num++] = i | (freq << NUM_BITS);
530*33b1fccfSAndroid Build Coastguard Worker 	}
531*33b1fccfSAndroid Build Coastguard Worker 	HeapSort(p, num);
532*33b1fccfSAndroid Build Coastguard Worker 
533*33b1fccfSAndroid Build Coastguard Worker 	if (num < 2) {
534*33b1fccfSAndroid Build Coastguard Worker 		unsigned int minCode = 0, maxCode = 1;
535*33b1fccfSAndroid Build Coastguard Worker 
536*33b1fccfSAndroid Build Coastguard Worker 		if (num == 1) {
537*33b1fccfSAndroid Build Coastguard Worker 			maxCode = (unsigned int)p[0] & MASK;
538*33b1fccfSAndroid Build Coastguard Worker 			if (!maxCode)
539*33b1fccfSAndroid Build Coastguard Worker 				maxCode++;
540*33b1fccfSAndroid Build Coastguard Worker 		}
541*33b1fccfSAndroid Build Coastguard Worker 		p[minCode] = 0;
542*33b1fccfSAndroid Build Coastguard Worker 		p[maxCode] = 1;
543*33b1fccfSAndroid Build Coastguard Worker 		lens[minCode] = lens[maxCode] = 1;
544*33b1fccfSAndroid Build Coastguard Worker 		return;
545*33b1fccfSAndroid Build Coastguard Worker 	}
546*33b1fccfSAndroid Build Coastguard Worker 
547*33b1fccfSAndroid Build Coastguard Worker 	{
548*33b1fccfSAndroid Build Coastguard Worker 		u32 b, e, i;
549*33b1fccfSAndroid Build Coastguard Worker 
550*33b1fccfSAndroid Build Coastguard Worker 		i = b = e = 0;
551*33b1fccfSAndroid Build Coastguard Worker 		do {
552*33b1fccfSAndroid Build Coastguard Worker 			u32 n, m, freq;
553*33b1fccfSAndroid Build Coastguard Worker 
554*33b1fccfSAndroid Build Coastguard Worker 			n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
555*33b1fccfSAndroid Build Coastguard Worker 			freq = (p[n] & ~MASK);
556*33b1fccfSAndroid Build Coastguard Worker 			p[n] = (p[n] & MASK) | (e << NUM_BITS);
557*33b1fccfSAndroid Build Coastguard Worker 			m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
558*33b1fccfSAndroid Build Coastguard Worker 			freq += (p[m] & ~MASK);
559*33b1fccfSAndroid Build Coastguard Worker 			p[m] = (p[m] & MASK) | (e << NUM_BITS);
560*33b1fccfSAndroid Build Coastguard Worker 			p[e] = (p[e] & MASK) | freq;
561*33b1fccfSAndroid Build Coastguard Worker 			e++;
562*33b1fccfSAndroid Build Coastguard Worker 		} while (num - e > 1);
563*33b1fccfSAndroid Build Coastguard Worker 
564*33b1fccfSAndroid Build Coastguard Worker 		{
565*33b1fccfSAndroid Build Coastguard Worker 			u32 lenCounters[kMaxLen + 1];
566*33b1fccfSAndroid Build Coastguard Worker 
567*33b1fccfSAndroid Build Coastguard Worker 			for (i = 0; i <= kMaxLen; i++)
568*33b1fccfSAndroid Build Coastguard Worker 				lenCounters[i] = 0;
569*33b1fccfSAndroid Build Coastguard Worker 
570*33b1fccfSAndroid Build Coastguard Worker 			p[--e] &= MASK;
571*33b1fccfSAndroid Build Coastguard Worker 			lenCounters[1] = 2;
572*33b1fccfSAndroid Build Coastguard Worker 			while (e > 0) {
573*33b1fccfSAndroid Build Coastguard Worker 				u32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
574*33b1fccfSAndroid Build Coastguard Worker 
575*33b1fccfSAndroid Build Coastguard Worker 				p[e] = (p[e] & MASK) | (len << NUM_BITS);
576*33b1fccfSAndroid Build Coastguard Worker 				if (len >= maxLen)
577*33b1fccfSAndroid Build Coastguard Worker 					for (len = maxLen - 1; lenCounters[len] == 0; len--);
578*33b1fccfSAndroid Build Coastguard Worker 				lenCounters[len]--;
579*33b1fccfSAndroid Build Coastguard Worker 				lenCounters[(size_t)len + 1] += 2;
580*33b1fccfSAndroid Build Coastguard Worker 			}
581*33b1fccfSAndroid Build Coastguard Worker 
582*33b1fccfSAndroid Build Coastguard Worker 			{
583*33b1fccfSAndroid Build Coastguard Worker 				u32 len;
584*33b1fccfSAndroid Build Coastguard Worker 
585*33b1fccfSAndroid Build Coastguard Worker 				i = 0;
586*33b1fccfSAndroid Build Coastguard Worker 				for (len = maxLen; len != 0; len--) {
587*33b1fccfSAndroid Build Coastguard Worker 					u32 k;
588*33b1fccfSAndroid Build Coastguard Worker 					for (k = lenCounters[len]; k != 0; k--)
589*33b1fccfSAndroid Build Coastguard Worker 						lens[p[i++] & MASK] = (u8)len;
590*33b1fccfSAndroid Build Coastguard Worker 				}
591*33b1fccfSAndroid Build Coastguard Worker 			}
592*33b1fccfSAndroid Build Coastguard Worker 			deflate_genhuffcodes(lens, p, numSymbols, lenCounters);
593*33b1fccfSAndroid Build Coastguard Worker 		}
594*33b1fccfSAndroid Build Coastguard Worker 	}
595*33b1fccfSAndroid Build Coastguard Worker }
596*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_fixdynblock(struct kite_deflate * s)597*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_fixdynblock(struct kite_deflate *s)
598*33b1fccfSAndroid Build Coastguard Worker {
599*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_table *t = s->tab;
600*33b1fccfSAndroid Build Coastguard Worker 	unsigned int numlitlens, numdistlens, numblcodes;
601*33b1fccfSAndroid Build Coastguard Worker 	u32 levelFreqs[kLensTableSize] = {0};
602*33b1fccfSAndroid Build Coastguard Worker 	u32 opt_mainlen;
603*33b1fccfSAndroid Build Coastguard Worker 
604*33b1fccfSAndroid Build Coastguard Worker 	if (!s->freq_changed)
605*33b1fccfSAndroid Build Coastguard Worker 		return;
606*33b1fccfSAndroid Build Coastguard Worker 
607*33b1fccfSAndroid Build Coastguard Worker 	/* in order to match zlib */
608*33b1fccfSAndroid Build Coastguard Worker 	s->numHuffBits = kMaxLen;
609*33b1fccfSAndroid Build Coastguard Worker //	s->numHuffBits = (s->symbols > 18000 ? 12 :
610*33b1fccfSAndroid Build Coastguard Worker //		(s->symbols > 7000 ? 11 : (s->symbols > 2000 ? 10 : 9)));
611*33b1fccfSAndroid Build Coastguard Worker 
612*33b1fccfSAndroid Build Coastguard Worker 	Huffman_Generate(s->mainFreqs, t->mainCodes, t->litLenLevels,
613*33b1fccfSAndroid Build Coastguard Worker 			 kMainTableSize, s->numHuffBits);
614*33b1fccfSAndroid Build Coastguard Worker 	Huffman_Generate(s->distFreqs, t->distCodes, t->distLevels,
615*33b1fccfSAndroid Build Coastguard Worker 			 kDistTableSize32, s->numHuffBits);
616*33b1fccfSAndroid Build Coastguard Worker 
617*33b1fccfSAndroid Build Coastguard Worker 	/* code lengths for the literal/length alphabet */
618*33b1fccfSAndroid Build Coastguard Worker 	numlitlens = kMainTableSize;
619*33b1fccfSAndroid Build Coastguard Worker 	while (numlitlens > kNumLitLenCodesMin &&
620*33b1fccfSAndroid Build Coastguard Worker 	       !t->litLenLevels[numlitlens - 1])
621*33b1fccfSAndroid Build Coastguard Worker 		--numlitlens;
622*33b1fccfSAndroid Build Coastguard Worker 
623*33b1fccfSAndroid Build Coastguard Worker 	/* code lengths for the distance alphabet */
624*33b1fccfSAndroid Build Coastguard Worker 	numdistlens = kDistTableSize32;
625*33b1fccfSAndroid Build Coastguard Worker 	while (numdistlens > kNumDistCodesMin &&
626*33b1fccfSAndroid Build Coastguard Worker 	       !t->distLevels[numdistlens - 1])
627*33b1fccfSAndroid Build Coastguard Worker 		--numdistlens;
628*33b1fccfSAndroid Build Coastguard Worker 
629*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_scanlens(numlitlens, t->litLenLevels, levelFreqs);
630*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_scanlens(numdistlens, t->distLevels, levelFreqs);
631*33b1fccfSAndroid Build Coastguard Worker 	Huffman_Generate(levelFreqs, t->levelCodes, t->levelLens,
632*33b1fccfSAndroid Build Coastguard Worker 			 kLensTableSize, 7);
633*33b1fccfSAndroid Build Coastguard Worker 	numblcodes = kLensTableSize;
634*33b1fccfSAndroid Build Coastguard Worker 	while (numblcodes > kNumLensCodesMin &&
635*33b1fccfSAndroid Build Coastguard Worker 	       !t->levelLens[kCodeLengthAlphabetOrder[numblcodes - 1]])
636*33b1fccfSAndroid Build Coastguard Worker 		--numblcodes;
637*33b1fccfSAndroid Build Coastguard Worker 
638*33b1fccfSAndroid Build Coastguard Worker 	t->numlitlens = numlitlens;
639*33b1fccfSAndroid Build Coastguard Worker 	t->numdistlens = numdistlens;
640*33b1fccfSAndroid Build Coastguard Worker 	t->numblcodes = numblcodes;
641*33b1fccfSAndroid Build Coastguard Worker 
642*33b1fccfSAndroid Build Coastguard Worker 	opt_mainlen = Huffman_GetPriceEx(s->mainFreqs, t->litLenLevels,
643*33b1fccfSAndroid Build Coastguard Worker 			kMainTableSize, kLenExtraBits32, kSymbolMatch) +
644*33b1fccfSAndroid Build Coastguard Worker 		Huffman_GetPriceEx(s->distFreqs, t->distLevels,
645*33b1fccfSAndroid Build Coastguard Worker 			kDistTableSize32, kDistExtraBits, 0);
646*33b1fccfSAndroid Build Coastguard Worker 	s->costbits = 3 + 5 + 5 + 4 + 3 * numblcodes +
647*33b1fccfSAndroid Build Coastguard Worker 		Huffman_GetPriceEx(levelFreqs, t->levelLens,
648*33b1fccfSAndroid Build Coastguard Worker 			kLensTableSize, kLevelExtraBits, kTableDirectLevels) +
649*33b1fccfSAndroid Build Coastguard Worker 		opt_mainlen;
650*33b1fccfSAndroid Build Coastguard Worker 	s->freq_changed = false;
651*33b1fccfSAndroid Build Coastguard Worker }
652*33b1fccfSAndroid Build Coastguard Worker 
653*33b1fccfSAndroid Build Coastguard Worker 
654*33b1fccfSAndroid Build Coastguard Worker /*
655*33b1fccfSAndroid Build Coastguard Worker  * an array used used by the LZ-based encoder to hold the length-distance pairs
656*33b1fccfSAndroid Build Coastguard Worker  * found by LZ matchfinder.
657*33b1fccfSAndroid Build Coastguard Worker  */
658*33b1fccfSAndroid Build Coastguard Worker struct kite_match {
659*33b1fccfSAndroid Build Coastguard Worker 	unsigned int len;
660*33b1fccfSAndroid Build Coastguard Worker 	unsigned int dist;
661*33b1fccfSAndroid Build Coastguard Worker };
662*33b1fccfSAndroid Build Coastguard Worker 
663*33b1fccfSAndroid Build Coastguard Worker struct kite_matchfinder {
664*33b1fccfSAndroid Build Coastguard Worker 	/* pointer to buffer with data to be compressed */
665*33b1fccfSAndroid Build Coastguard Worker 	const u8 *buffer;
666*33b1fccfSAndroid Build Coastguard Worker 
667*33b1fccfSAndroid Build Coastguard Worker 	/* indicate the first byte that doesn't contain valid input data */
668*33b1fccfSAndroid Build Coastguard Worker 	const u8 *end;
669*33b1fccfSAndroid Build Coastguard Worker 
670*33b1fccfSAndroid Build Coastguard Worker 	/* LZ matchfinder hash chain representation */
671*33b1fccfSAndroid Build Coastguard Worker 	u32 *hash, *chain;
672*33b1fccfSAndroid Build Coastguard Worker 
673*33b1fccfSAndroid Build Coastguard Worker 	u32 base;
674*33b1fccfSAndroid Build Coastguard Worker 
675*33b1fccfSAndroid Build Coastguard Worker 	/* indicate the next byte to run through the match finder */
676*33b1fccfSAndroid Build Coastguard Worker 	u32 offset;
677*33b1fccfSAndroid Build Coastguard Worker 
678*33b1fccfSAndroid Build Coastguard Worker 	u32 cyclic_pos;
679*33b1fccfSAndroid Build Coastguard Worker 
680*33b1fccfSAndroid Build Coastguard Worker 	/* maximum length of a match that the matchfinder will try to find. */
681*33b1fccfSAndroid Build Coastguard Worker 	u16 nice_len;
682*33b1fccfSAndroid Build Coastguard Worker 
683*33b1fccfSAndroid Build Coastguard Worker 	/* the total sliding window size */
684*33b1fccfSAndroid Build Coastguard Worker 	u16 wsiz;
685*33b1fccfSAndroid Build Coastguard Worker 
686*33b1fccfSAndroid Build Coastguard Worker 	/* how many rounds a matchfinder searches on a hash chain for */
687*33b1fccfSAndroid Build Coastguard Worker 	u16 depth;
688*33b1fccfSAndroid Build Coastguard Worker 
689*33b1fccfSAndroid Build Coastguard Worker 	/* do not perform lazy search no less than this match length */
690*33b1fccfSAndroid Build Coastguard Worker 	u16 max_lazy;
691*33b1fccfSAndroid Build Coastguard Worker 
692*33b1fccfSAndroid Build Coastguard Worker 	/* reduce lazy search no less than this match length */
693*33b1fccfSAndroid Build Coastguard Worker 	u8  good_len;
694*33b1fccfSAndroid Build Coastguard Worker 
695*33b1fccfSAndroid Build Coastguard Worker 	/* current match for lazy matching */
696*33b1fccfSAndroid Build Coastguard Worker 	struct kite_match *matches;
697*33b1fccfSAndroid Build Coastguard Worker 	struct kite_match matches_matrix[2][4];
698*33b1fccfSAndroid Build Coastguard Worker };
699*33b1fccfSAndroid Build Coastguard Worker 
700*33b1fccfSAndroid Build Coastguard Worker /*
701*33b1fccfSAndroid Build Coastguard Worker  * This mysterious table is just the CRC of each possible byte. It can be
702*33b1fccfSAndroid Build Coastguard Worker  * computed using the standard bit-at-a-time methods. The polynomial can
703*33b1fccfSAndroid Build Coastguard Worker  * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12.
704*33b1fccfSAndroid Build Coastguard Worker  * Add the implicit x^16, and you have the standard CRC-CCITT.
705*33b1fccfSAndroid Build Coastguard Worker  */
706*33b1fccfSAndroid Build Coastguard Worker u16 const crc_ccitt_table[256] __attribute__((__aligned__(128))) = {
707*33b1fccfSAndroid Build Coastguard Worker 	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
708*33b1fccfSAndroid Build Coastguard Worker 	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
709*33b1fccfSAndroid Build Coastguard Worker 	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
710*33b1fccfSAndroid Build Coastguard Worker 	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
711*33b1fccfSAndroid Build Coastguard Worker 	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
712*33b1fccfSAndroid Build Coastguard Worker 	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
713*33b1fccfSAndroid Build Coastguard Worker 	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
714*33b1fccfSAndroid Build Coastguard Worker 	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
715*33b1fccfSAndroid Build Coastguard Worker 	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
716*33b1fccfSAndroid Build Coastguard Worker 	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
717*33b1fccfSAndroid Build Coastguard Worker 	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
718*33b1fccfSAndroid Build Coastguard Worker 	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
719*33b1fccfSAndroid Build Coastguard Worker 	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
720*33b1fccfSAndroid Build Coastguard Worker 	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
721*33b1fccfSAndroid Build Coastguard Worker 	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
722*33b1fccfSAndroid Build Coastguard Worker 	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
723*33b1fccfSAndroid Build Coastguard Worker 	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
724*33b1fccfSAndroid Build Coastguard Worker 	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
725*33b1fccfSAndroid Build Coastguard Worker 	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
726*33b1fccfSAndroid Build Coastguard Worker 	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
727*33b1fccfSAndroid Build Coastguard Worker 	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
728*33b1fccfSAndroid Build Coastguard Worker 	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
729*33b1fccfSAndroid Build Coastguard Worker 	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
730*33b1fccfSAndroid Build Coastguard Worker 	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
731*33b1fccfSAndroid Build Coastguard Worker 	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
732*33b1fccfSAndroid Build Coastguard Worker 	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
733*33b1fccfSAndroid Build Coastguard Worker 	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
734*33b1fccfSAndroid Build Coastguard Worker 	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
735*33b1fccfSAndroid Build Coastguard Worker 	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
736*33b1fccfSAndroid Build Coastguard Worker 	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
737*33b1fccfSAndroid Build Coastguard Worker 	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
738*33b1fccfSAndroid Build Coastguard Worker 	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
739*33b1fccfSAndroid Build Coastguard Worker };
740*33b1fccfSAndroid Build Coastguard Worker 
kite_mf_getmatches_hc3(struct kite_matchfinder * mf,u16 depth,u16 bestlen)741*33b1fccfSAndroid Build Coastguard Worker int kite_mf_getmatches_hc3(struct kite_matchfinder *mf, u16 depth, u16 bestlen)
742*33b1fccfSAndroid Build Coastguard Worker {
743*33b1fccfSAndroid Build Coastguard Worker 	const u8 *cur = mf->buffer + mf->offset;
744*33b1fccfSAndroid Build Coastguard Worker 	const u8 *qbase = mf->buffer - mf->base;
745*33b1fccfSAndroid Build Coastguard Worker 	u32 curMatch;
746*33b1fccfSAndroid Build Coastguard Worker 	unsigned int v, hv, i, k, p, wsiz;
747*33b1fccfSAndroid Build Coastguard Worker 
748*33b1fccfSAndroid Build Coastguard Worker 	if (mf->end - cur < bestlen + 1)
749*33b1fccfSAndroid Build Coastguard Worker 		return -1;
750*33b1fccfSAndroid Build Coastguard Worker 
751*33b1fccfSAndroid Build Coastguard Worker 	v = get_unaligned((u16 *)cur);
752*33b1fccfSAndroid Build Coastguard Worker 	hv = v ^ crc_ccitt_table[cur[2]];
753*33b1fccfSAndroid Build Coastguard Worker 	curMatch = mf->hash[hv];
754*33b1fccfSAndroid Build Coastguard Worker 	p = mf->base + mf->offset;
755*33b1fccfSAndroid Build Coastguard Worker 	mf->hash[hv] = p;
756*33b1fccfSAndroid Build Coastguard Worker 	mf->chain[mf->cyclic_pos] = curMatch;
757*33b1fccfSAndroid Build Coastguard Worker 	wsiz = mf->wsiz;
758*33b1fccfSAndroid Build Coastguard Worker 	k = 1;
759*33b1fccfSAndroid Build Coastguard Worker 
760*33b1fccfSAndroid Build Coastguard Worker 	if (depth) {
761*33b1fccfSAndroid Build Coastguard Worker 		unsigned int wpos = wsiz + mf->cyclic_pos;
762*33b1fccfSAndroid Build Coastguard Worker 
763*33b1fccfSAndroid Build Coastguard Worker 		hv = min_t(unsigned int, mf->nice_len, mf->end - cur);
764*33b1fccfSAndroid Build Coastguard Worker 		DBG_BUGON(hv > kMatchMaxLen32);
765*33b1fccfSAndroid Build Coastguard Worker 		do {
766*33b1fccfSAndroid Build Coastguard Worker 			unsigned int diff = p - curMatch;
767*33b1fccfSAndroid Build Coastguard Worker 			const u8 *q;
768*33b1fccfSAndroid Build Coastguard Worker 
769*33b1fccfSAndroid Build Coastguard Worker 			if (diff >= wsiz)
770*33b1fccfSAndroid Build Coastguard Worker 				break;
771*33b1fccfSAndroid Build Coastguard Worker 
772*33b1fccfSAndroid Build Coastguard Worker 			q = qbase + curMatch;
773*33b1fccfSAndroid Build Coastguard Worker 			curMatch = mf->chain[(wpos - diff) & (wsiz - 1)];
774*33b1fccfSAndroid Build Coastguard Worker 			if (v == get_unaligned((u16 *)q) && (bestlen < 3 || (
775*33b1fccfSAndroid Build Coastguard Worker 			    get_unaligned((u16 *)(cur + bestlen - 1)) ==
776*33b1fccfSAndroid Build Coastguard Worker 			    get_unaligned((u16 *)(q + bestlen - 1)) &&
777*33b1fccfSAndroid Build Coastguard Worker 			    !memcmp(cur + 3, q + 3, bestlen - 3)))) {
778*33b1fccfSAndroid Build Coastguard Worker 				DBG_BUGON(cur[2] != q[2]);
779*33b1fccfSAndroid Build Coastguard Worker 				i = erofs_memcmp2(cur + bestlen + 1,
780*33b1fccfSAndroid Build Coastguard Worker 					q + bestlen + 1, hv - bestlen - 1);
781*33b1fccfSAndroid Build Coastguard Worker 				bestlen += 1 + i;
782*33b1fccfSAndroid Build Coastguard Worker 
783*33b1fccfSAndroid Build Coastguard Worker 				k -= (k >= ARRAY_SIZE(mf->matches_matrix[0]));
784*33b1fccfSAndroid Build Coastguard Worker 				mf->matches[k++] = (struct kite_match) {
785*33b1fccfSAndroid Build Coastguard Worker 					.len = bestlen,
786*33b1fccfSAndroid Build Coastguard Worker 					.dist = diff,
787*33b1fccfSAndroid Build Coastguard Worker 				};
788*33b1fccfSAndroid Build Coastguard Worker 				if (bestlen >= hv)
789*33b1fccfSAndroid Build Coastguard Worker 					break;
790*33b1fccfSAndroid Build Coastguard Worker 			}
791*33b1fccfSAndroid Build Coastguard Worker 		} while (--depth);
792*33b1fccfSAndroid Build Coastguard Worker 	}
793*33b1fccfSAndroid Build Coastguard Worker 	mf->offset++;
794*33b1fccfSAndroid Build Coastguard Worker 	mf->cyclic_pos = (mf->cyclic_pos + 1) & (wsiz - 1);
795*33b1fccfSAndroid Build Coastguard Worker 	return k - 1;
796*33b1fccfSAndroid Build Coastguard Worker }
797*33b1fccfSAndroid Build Coastguard Worker 
kite_mf_hc3_skip(struct kite_matchfinder * mf)798*33b1fccfSAndroid Build Coastguard Worker static void kite_mf_hc3_skip(struct kite_matchfinder *mf)
799*33b1fccfSAndroid Build Coastguard Worker {
800*33b1fccfSAndroid Build Coastguard Worker 	if (kite_mf_getmatches_hc3(mf, 0, 2) >= 0)
801*33b1fccfSAndroid Build Coastguard Worker 		return;
802*33b1fccfSAndroid Build Coastguard Worker 	mf->offset++;
803*33b1fccfSAndroid Build Coastguard Worker 	/* mf->cyclic_pos = (mf->cyclic_pos + 1) & (mf->wsiz - 1); */
804*33b1fccfSAndroid Build Coastguard Worker }
805*33b1fccfSAndroid Build Coastguard Worker 
806*33b1fccfSAndroid Build Coastguard Worker /* let's align with zlib */
807*33b1fccfSAndroid Build Coastguard Worker static const struct kite_matchfinder_cfg {
808*33b1fccfSAndroid Build Coastguard Worker 	u16  good_length;	/* reduce lazy search above this match length */
809*33b1fccfSAndroid Build Coastguard Worker 	u16  max_lazy;	/* do not perform lazy search above this match length */
810*33b1fccfSAndroid Build Coastguard Worker 	u16  nice_length;	/* quit search above this match length */
811*33b1fccfSAndroid Build Coastguard Worker 	u16  depth;
812*33b1fccfSAndroid Build Coastguard Worker 	bool lazy_search;
813*33b1fccfSAndroid Build Coastguard Worker } kite_mfcfg[10] = {
814*33b1fccfSAndroid Build Coastguard Worker /*      good lazy nice depth */
815*33b1fccfSAndroid Build Coastguard Worker /* 0 */ {0,    0,  0,    0, false},	/* store only [unsupported] */
816*33b1fccfSAndroid Build Coastguard Worker /* 1 */ {4,    4,  8,    4, false},	/* maximum speed, no lazy matches */
817*33b1fccfSAndroid Build Coastguard Worker /* 2 */ {4,    5, 16,    8, false},
818*33b1fccfSAndroid Build Coastguard Worker /* 3 */ {4,    6, 32,   32, false},
819*33b1fccfSAndroid Build Coastguard Worker 
820*33b1fccfSAndroid Build Coastguard Worker /* 4 */ {4,    4,  16,   16, true},	/* lazy matches */
821*33b1fccfSAndroid Build Coastguard Worker /* 5 */ {8,   16,  32,   32, true},
822*33b1fccfSAndroid Build Coastguard Worker /* 6 */ {8,   16, 128,  128, true},
823*33b1fccfSAndroid Build Coastguard Worker /* 7 */ {8,   32, 128,  256, true},
824*33b1fccfSAndroid Build Coastguard Worker /* 8 */ {32, 128, 258, 1024, true},
825*33b1fccfSAndroid Build Coastguard Worker /* 9 */ {32, 258, 258, 4096, true},	/* maximum compression */
826*33b1fccfSAndroid Build Coastguard Worker };
827*33b1fccfSAndroid Build Coastguard Worker 
kite_mf_init(struct kite_matchfinder * mf,unsigned int wsiz,int level)828*33b1fccfSAndroid Build Coastguard Worker static int kite_mf_init(struct kite_matchfinder *mf, unsigned int wsiz,
829*33b1fccfSAndroid Build Coastguard Worker 			int level)
830*33b1fccfSAndroid Build Coastguard Worker {
831*33b1fccfSAndroid Build Coastguard Worker 	const struct kite_matchfinder_cfg *cfg;
832*33b1fccfSAndroid Build Coastguard Worker 
833*33b1fccfSAndroid Build Coastguard Worker 	if (!level || level >= ARRAY_SIZE(kite_mfcfg))
834*33b1fccfSAndroid Build Coastguard Worker 		return -EINVAL;
835*33b1fccfSAndroid Build Coastguard Worker 	cfg = &kite_mfcfg[level];
836*33b1fccfSAndroid Build Coastguard Worker 
837*33b1fccfSAndroid Build Coastguard Worker 	if (wsiz > kHistorySize32 || (1 << ilog2(wsiz)) != wsiz)
838*33b1fccfSAndroid Build Coastguard Worker 		return -EINVAL;
839*33b1fccfSAndroid Build Coastguard Worker 
840*33b1fccfSAndroid Build Coastguard Worker 	mf->hash = calloc(0x10000, sizeof(mf->hash[0]));
841*33b1fccfSAndroid Build Coastguard Worker 	if (!mf->hash)
842*33b1fccfSAndroid Build Coastguard Worker 		return -ENOMEM;
843*33b1fccfSAndroid Build Coastguard Worker 
844*33b1fccfSAndroid Build Coastguard Worker 	mf->chain = malloc(sizeof(mf->chain[0]) * wsiz);
845*33b1fccfSAndroid Build Coastguard Worker 	if (!mf->chain) {
846*33b1fccfSAndroid Build Coastguard Worker 		free(mf->hash);
847*33b1fccfSAndroid Build Coastguard Worker 		mf->hash = NULL;
848*33b1fccfSAndroid Build Coastguard Worker 		return -ENOMEM;
849*33b1fccfSAndroid Build Coastguard Worker 	}
850*33b1fccfSAndroid Build Coastguard Worker 	mf->wsiz = wsiz;
851*33b1fccfSAndroid Build Coastguard Worker 
852*33b1fccfSAndroid Build Coastguard Worker 	mf->good_len = cfg->good_length;
853*33b1fccfSAndroid Build Coastguard Worker 	mf->nice_len = cfg->nice_length;
854*33b1fccfSAndroid Build Coastguard Worker 	mf->depth = cfg->depth;
855*33b1fccfSAndroid Build Coastguard Worker 	mf->max_lazy = cfg->max_lazy;
856*33b1fccfSAndroid Build Coastguard Worker 	return cfg->lazy_search;
857*33b1fccfSAndroid Build Coastguard Worker }
858*33b1fccfSAndroid Build Coastguard Worker 
kite_mf_reset(struct kite_matchfinder * mf,const void * buffer,const void * end)859*33b1fccfSAndroid Build Coastguard Worker static void kite_mf_reset(struct kite_matchfinder *mf,
860*33b1fccfSAndroid Build Coastguard Worker 			  const void *buffer, const void *end)
861*33b1fccfSAndroid Build Coastguard Worker {
862*33b1fccfSAndroid Build Coastguard Worker 	mf->buffer = buffer;
863*33b1fccfSAndroid Build Coastguard Worker 	mf->end = end;
864*33b1fccfSAndroid Build Coastguard Worker 
865*33b1fccfSAndroid Build Coastguard Worker 	/*
866*33b1fccfSAndroid Build Coastguard Worker 	 * Set the initial value as max_distance + 1.  This would avoid hash
867*33b1fccfSAndroid Build Coastguard Worker 	 * zero initialization.
868*33b1fccfSAndroid Build Coastguard Worker 	 */
869*33b1fccfSAndroid Build Coastguard Worker 	mf->base += mf->offset + kHistorySize32 + 1;
870*33b1fccfSAndroid Build Coastguard Worker 
871*33b1fccfSAndroid Build Coastguard Worker 	/*
872*33b1fccfSAndroid Build Coastguard Worker 	 * Unlike other LZ encoders like liblzma [1], we simply reset the hash
873*33b1fccfSAndroid Build Coastguard Worker 	 * chain instead of normalization.  This avoids extra complexity, as we
874*33b1fccfSAndroid Build Coastguard Worker 	 * don't consider extreme large input buffers in one go.
875*33b1fccfSAndroid Build Coastguard Worker 	 *
876*33b1fccfSAndroid Build Coastguard Worker 	 * [1] https://github.com/tukaani-project/xz/blob/v5.4.0/src/liblzma/lz/lz_encoder_mf.c#L94
877*33b1fccfSAndroid Build Coastguard Worker 	 */
878*33b1fccfSAndroid Build Coastguard Worker 	if (__erofs_unlikely(mf->base > ((typeof(mf->base))-1) >> 1)) {
879*33b1fccfSAndroid Build Coastguard Worker 		mf->base = kHistorySize32 + 1;
880*33b1fccfSAndroid Build Coastguard Worker 		memset(mf->hash, 0, 0x10000 * sizeof(mf->hash[0]));
881*33b1fccfSAndroid Build Coastguard Worker 	}
882*33b1fccfSAndroid Build Coastguard Worker 	mf->offset = 0;
883*33b1fccfSAndroid Build Coastguard Worker 	mf->cyclic_pos = 0;
884*33b1fccfSAndroid Build Coastguard Worker 
885*33b1fccfSAndroid Build Coastguard Worker 	mf->matches = mf->matches_matrix[0];
886*33b1fccfSAndroid Build Coastguard Worker 	mf->matches_matrix[0][0].len =
887*33b1fccfSAndroid Build Coastguard Worker 		mf->matches_matrix[1][0].len = kMatchMinLen - 1;
888*33b1fccfSAndroid Build Coastguard Worker }
889*33b1fccfSAndroid Build Coastguard Worker 
deflate_count_code(struct kite_deflate * s,bool literal,unsigned int lenSlot,unsigned int distSlot)890*33b1fccfSAndroid Build Coastguard Worker static bool deflate_count_code(struct kite_deflate *s, bool literal,
891*33b1fccfSAndroid Build Coastguard Worker 			       unsigned int lenSlot, unsigned int distSlot)
892*33b1fccfSAndroid Build Coastguard Worker {
893*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_table *t = s->tab;
894*33b1fccfSAndroid Build Coastguard Worker 	unsigned int lenbase = (literal ? 0 : kSymbolMatch);
895*33b1fccfSAndroid Build Coastguard Worker 	u64 rem = (s->outlen - s->pos_out) * 8 - s->bitpos;
896*33b1fccfSAndroid Build Coastguard Worker 	bool recalc = false;
897*33b1fccfSAndroid Build Coastguard Worker 	unsigned int bits;
898*33b1fccfSAndroid Build Coastguard Worker 
899*33b1fccfSAndroid Build Coastguard Worker 	s->freq_changed = true;
900*33b1fccfSAndroid Build Coastguard Worker 	++s->mainFreqs[lenbase + lenSlot];
901*33b1fccfSAndroid Build Coastguard Worker 	if (!literal)
902*33b1fccfSAndroid Build Coastguard Worker 		++s->distFreqs[distSlot];
903*33b1fccfSAndroid Build Coastguard Worker 
904*33b1fccfSAndroid Build Coastguard Worker 	if (s->encode_mode == 1) {
905*33b1fccfSAndroid Build Coastguard Worker 		if (literal) {
906*33b1fccfSAndroid Build Coastguard Worker 			bits = kstaticHuff_litLenLevels[lenSlot];
907*33b1fccfSAndroid Build Coastguard Worker 			goto out;
908*33b1fccfSAndroid Build Coastguard Worker 		}
909*33b1fccfSAndroid Build Coastguard Worker 		bits = kstaticHuff_litLenLevels[kSymbolMatch + lenSlot] +
910*33b1fccfSAndroid Build Coastguard Worker 			kLenExtraBits32[lenSlot] + 5 + kDistExtraBits[distSlot];
911*33b1fccfSAndroid Build Coastguard Worker 		goto out;
912*33b1fccfSAndroid Build Coastguard Worker 	}
913*33b1fccfSAndroid Build Coastguard Worker 
914*33b1fccfSAndroid Build Coastguard Worker 	/* XXX: more ideas to be done later */
915*33b1fccfSAndroid Build Coastguard Worker 	recalc |= (!literal && !t->distLevels[distSlot]);
916*33b1fccfSAndroid Build Coastguard Worker 	recalc |= !t->litLenLevels[lenbase + lenSlot];
917*33b1fccfSAndroid Build Coastguard Worker 	if (recalc) {
918*33b1fccfSAndroid Build Coastguard Worker 		kite_dbg("recalc %c lS %u dS %u", literal ? 'l' : 'm',
919*33b1fccfSAndroid Build Coastguard Worker 			 lenSlot, distSlot);
920*33b1fccfSAndroid Build Coastguard Worker 		s->tab = s->tables + (s->tab == s->tables);
921*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_fixdynblock(s);
922*33b1fccfSAndroid Build Coastguard Worker 		bits = 0;
923*33b1fccfSAndroid Build Coastguard Worker 		goto out;
924*33b1fccfSAndroid Build Coastguard Worker 	}
925*33b1fccfSAndroid Build Coastguard Worker 
926*33b1fccfSAndroid Build Coastguard Worker 	if (literal) {
927*33b1fccfSAndroid Build Coastguard Worker 		bits = t->litLenLevels[lenSlot];
928*33b1fccfSAndroid Build Coastguard Worker 		goto out;
929*33b1fccfSAndroid Build Coastguard Worker 	}
930*33b1fccfSAndroid Build Coastguard Worker 
931*33b1fccfSAndroid Build Coastguard Worker 	bits = t->distLevels[distSlot] + kDistExtraBits[distSlot] +
932*33b1fccfSAndroid Build Coastguard Worker 		t->litLenLevels[kSymbolMatch + lenSlot] +
933*33b1fccfSAndroid Build Coastguard Worker 		kLenExtraBits32[lenSlot];
934*33b1fccfSAndroid Build Coastguard Worker out:
935*33b1fccfSAndroid Build Coastguard Worker 	if (rem < s->costbits + bits) {
936*33b1fccfSAndroid Build Coastguard Worker 		--s->mainFreqs[lenbase + lenSlot];
937*33b1fccfSAndroid Build Coastguard Worker 		if (!literal)
938*33b1fccfSAndroid Build Coastguard Worker 			--s->distFreqs[distSlot];
939*33b1fccfSAndroid Build Coastguard Worker 		if (recalc)
940*33b1fccfSAndroid Build Coastguard Worker 			s->tab = s->tables + (s->tab == s->tables);
941*33b1fccfSAndroid Build Coastguard Worker 		return false;
942*33b1fccfSAndroid Build Coastguard Worker 	}
943*33b1fccfSAndroid Build Coastguard Worker 	s->costbits += bits;
944*33b1fccfSAndroid Build Coastguard Worker 	return true;
945*33b1fccfSAndroid Build Coastguard Worker }
946*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_tally(struct kite_deflate * s,struct kite_match * match)947*33b1fccfSAndroid Build Coastguard Worker static bool kite_deflate_tally(struct kite_deflate *s,
948*33b1fccfSAndroid Build Coastguard Worker 			       struct kite_match *match)
949*33b1fccfSAndroid Build Coastguard Worker {
950*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate_symbol *sym = s->sym + s->symbols;
951*33b1fccfSAndroid Build Coastguard Worker 	u32 fixedcost = ~0;
952*33b1fccfSAndroid Build Coastguard Worker 	bool hassp;
953*33b1fccfSAndroid Build Coastguard Worker 
954*33b1fccfSAndroid Build Coastguard Worker 	*sym = (struct kite_deflate_symbol) {
955*33b1fccfSAndroid Build Coastguard Worker 		.len = match->len,
956*33b1fccfSAndroid Build Coastguard Worker 		.dist = match->dist,
957*33b1fccfSAndroid Build Coastguard Worker 	};
958*33b1fccfSAndroid Build Coastguard Worker 
959*33b1fccfSAndroid Build Coastguard Worker retry:
960*33b1fccfSAndroid Build Coastguard Worker 	if (sym->len < kMatchMinLen) {
961*33b1fccfSAndroid Build Coastguard Worker 		hassp = deflate_count_code(s, true, sym->dist, 0);
962*33b1fccfSAndroid Build Coastguard Worker 	} else {
963*33b1fccfSAndroid Build Coastguard Worker 		unsigned int lc = sym->len - kMatchMinLen;
964*33b1fccfSAndroid Build Coastguard Worker 		unsigned int lenSlot = g_LenSlots[lc];
965*33b1fccfSAndroid Build Coastguard Worker 		unsigned int distSlot = deflateDistSlot(sym->dist - 1);
966*33b1fccfSAndroid Build Coastguard Worker 
967*33b1fccfSAndroid Build Coastguard Worker 		hassp = deflate_count_code(s, false, lenSlot, distSlot);
968*33b1fccfSAndroid Build Coastguard Worker 	}
969*33b1fccfSAndroid Build Coastguard Worker 
970*33b1fccfSAndroid Build Coastguard Worker 	if (!hassp) {
971*33b1fccfSAndroid Build Coastguard Worker 		if (s->encode_mode == 1) {
972*33b1fccfSAndroid Build Coastguard Worker 			fixedcost = s->costbits;
973*33b1fccfSAndroid Build Coastguard Worker 			s->encode_mode = 2;
974*33b1fccfSAndroid Build Coastguard Worker 			goto retry;
975*33b1fccfSAndroid Build Coastguard Worker 		}
976*33b1fccfSAndroid Build Coastguard Worker 		s->lastblock = true;
977*33b1fccfSAndroid Build Coastguard Worker 		if (fixedcost <= s->costbits)
978*33b1fccfSAndroid Build Coastguard Worker 			s->encode_mode = 1;
979*33b1fccfSAndroid Build Coastguard Worker 		return true;
980*33b1fccfSAndroid Build Coastguard Worker 	}
981*33b1fccfSAndroid Build Coastguard Worker 	++s->symbols;
982*33b1fccfSAndroid Build Coastguard Worker 	return false;
983*33b1fccfSAndroid Build Coastguard Worker }
984*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_writestore(struct kite_deflate * s)985*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_writestore(struct kite_deflate *s)
986*33b1fccfSAndroid Build Coastguard Worker {
987*33b1fccfSAndroid Build Coastguard Worker 	bool fb = !s->startpos && !s->bitpos;
988*33b1fccfSAndroid Build Coastguard Worker 	unsigned int totalsiz = s->pos_in - s->prev_valid - s->startpos;
989*33b1fccfSAndroid Build Coastguard Worker 
990*33b1fccfSAndroid Build Coastguard Worker 	do {
991*33b1fccfSAndroid Build Coastguard Worker 		unsigned int len = min_t(unsigned int, totalsiz, 65535);
992*33b1fccfSAndroid Build Coastguard Worker 
993*33b1fccfSAndroid Build Coastguard Worker 		totalsiz -= len;
994*33b1fccfSAndroid Build Coastguard Worker 		writebits(s, (fb << 3) | (kStored << 1) |
995*33b1fccfSAndroid Build Coastguard Worker 			  (s->lastblock && !totalsiz), 3 + fb);
996*33b1fccfSAndroid Build Coastguard Worker 		flushbits(s);
997*33b1fccfSAndroid Build Coastguard Worker 		writebits(s, len, 16);
998*33b1fccfSAndroid Build Coastguard Worker 		writebits(s, len ^ 0xffff, 16);
999*33b1fccfSAndroid Build Coastguard Worker 		flushbits(s);
1000*33b1fccfSAndroid Build Coastguard Worker 		memcpy(s->out + s->pos_out, s->in + s->startpos, len);
1001*33b1fccfSAndroid Build Coastguard Worker 		s->pos_out += len;
1002*33b1fccfSAndroid Build Coastguard Worker 		s->startpos += len;
1003*33b1fccfSAndroid Build Coastguard Worker 	} while (totalsiz);
1004*33b1fccfSAndroid Build Coastguard Worker }
1005*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_endblock(struct kite_deflate * s)1006*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_endblock(struct kite_deflate *s)
1007*33b1fccfSAndroid Build Coastguard Worker {
1008*33b1fccfSAndroid Build Coastguard Worker 	if (s->encode_mode == 1) {
1009*33b1fccfSAndroid Build Coastguard Worker 		u32 fixedcost = s->costbits;
1010*33b1fccfSAndroid Build Coastguard Worker 		unsigned int storelen, storeblocks, storecost;
1011*33b1fccfSAndroid Build Coastguard Worker 
1012*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_fixdynblock(s);
1013*33b1fccfSAndroid Build Coastguard Worker 		if (fixedcost > s->costbits)
1014*33b1fccfSAndroid Build Coastguard Worker 			s->encode_mode = 2;
1015*33b1fccfSAndroid Build Coastguard Worker 		else
1016*33b1fccfSAndroid Build Coastguard Worker 			s->costbits = fixedcost;
1017*33b1fccfSAndroid Build Coastguard Worker 
1018*33b1fccfSAndroid Build Coastguard Worker 		storelen = s->pos_in - s->prev_valid - s->startpos;
1019*33b1fccfSAndroid Build Coastguard Worker 		storeblocks = max(DIV_ROUND_UP(storelen, 65535), 1U);
1020*33b1fccfSAndroid Build Coastguard Worker 		storecost = (8 - s->bitpos) + storeblocks - 1 +
1021*33b1fccfSAndroid Build Coastguard Worker 			storeblocks * 32 + storelen * 8;
1022*33b1fccfSAndroid Build Coastguard Worker 		if (s->costbits > storecost) {
1023*33b1fccfSAndroid Build Coastguard Worker 			s->costbits = storecost;
1024*33b1fccfSAndroid Build Coastguard Worker 			s->encode_mode = 0;
1025*33b1fccfSAndroid Build Coastguard Worker 		}
1026*33b1fccfSAndroid Build Coastguard Worker 	}
1027*33b1fccfSAndroid Build Coastguard Worker 
1028*33b1fccfSAndroid Build Coastguard Worker 	s->lastblock |= (s->costbits + s->bitpos >=
1029*33b1fccfSAndroid Build Coastguard Worker 			(s->outlen - s->pos_out) * 8);
1030*33b1fccfSAndroid Build Coastguard Worker }
1031*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_startblock(struct kite_deflate * s)1032*33b1fccfSAndroid Build Coastguard Worker static void kite_deflate_startblock(struct kite_deflate *s)
1033*33b1fccfSAndroid Build Coastguard Worker {
1034*33b1fccfSAndroid Build Coastguard Worker 	memset(s->mainFreqs, 0, sizeof(s->mainFreqs));
1035*33b1fccfSAndroid Build Coastguard Worker 	memset(s->distFreqs, 0, sizeof(s->distFreqs));
1036*33b1fccfSAndroid Build Coastguard Worker 	memset(s->tables, 0, sizeof(s->tables[0]));
1037*33b1fccfSAndroid Build Coastguard Worker 	s->symbols = 0;
1038*33b1fccfSAndroid Build Coastguard Worker 	s->mainFreqs[kSymbolEndOfBlock]++;
1039*33b1fccfSAndroid Build Coastguard Worker 	s->encode_mode = 1;
1040*33b1fccfSAndroid Build Coastguard Worker 	s->tab = s->tables;
1041*33b1fccfSAndroid Build Coastguard Worker 	s->costbits = 3 + kstaticHuff_litLenLevels[kSymbolEndOfBlock];
1042*33b1fccfSAndroid Build Coastguard Worker }
1043*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_commitblock(struct kite_deflate * s)1044*33b1fccfSAndroid Build Coastguard Worker static bool kite_deflate_commitblock(struct kite_deflate *s)
1045*33b1fccfSAndroid Build Coastguard Worker {
1046*33b1fccfSAndroid Build Coastguard Worker 	if (s->encode_mode == 1) {
1047*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_setfixedtrees(s);
1048*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_writeblock(s, true);
1049*33b1fccfSAndroid Build Coastguard Worker 	} else if (s->encode_mode == 2) {
1050*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_sendtrees(s);
1051*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_writeblock(s, false);
1052*33b1fccfSAndroid Build Coastguard Worker 	} else {
1053*33b1fccfSAndroid Build Coastguard Worker 		kite_deflate_writestore(s);
1054*33b1fccfSAndroid Build Coastguard Worker 	}
1055*33b1fccfSAndroid Build Coastguard Worker 	s->startpos = s->pos_in - s->prev_valid;
1056*33b1fccfSAndroid Build Coastguard Worker 	return s->lastblock;
1057*33b1fccfSAndroid Build Coastguard Worker }
1058*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_fast(struct kite_deflate * s)1059*33b1fccfSAndroid Build Coastguard Worker static bool kite_deflate_fast(struct kite_deflate *s)
1060*33b1fccfSAndroid Build Coastguard Worker {
1061*33b1fccfSAndroid Build Coastguard Worker 	struct kite_matchfinder *mf = s->mf;
1062*33b1fccfSAndroid Build Coastguard Worker 
1063*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_startblock(s);
1064*33b1fccfSAndroid Build Coastguard Worker 	while (1) {
1065*33b1fccfSAndroid Build Coastguard Worker 		int matches = kite_mf_getmatches_hc3(mf, mf->depth,
1066*33b1fccfSAndroid Build Coastguard Worker 				kMatchMinLen - 1);
1067*33b1fccfSAndroid Build Coastguard Worker 
1068*33b1fccfSAndroid Build Coastguard Worker 		if (matches > 0) {
1069*33b1fccfSAndroid Build Coastguard Worker 			unsigned int len = mf->matches[matches].len;
1070*33b1fccfSAndroid Build Coastguard Worker 			unsigned int dist = mf->matches[matches].dist;
1071*33b1fccfSAndroid Build Coastguard Worker 
1072*33b1fccfSAndroid Build Coastguard Worker 			if (len == kMatchMinLen && dist > ZLIB_DISTANCE_TOO_FAR)
1073*33b1fccfSAndroid Build Coastguard Worker 				goto nomatch;
1074*33b1fccfSAndroid Build Coastguard Worker 
1075*33b1fccfSAndroid Build Coastguard Worker 			kite_dbg("%u matches found: longest [%u,%u] of distance %u",
1076*33b1fccfSAndroid Build Coastguard Worker 				 matches, s->pos_in, s->pos_in + len - 1, dist);
1077*33b1fccfSAndroid Build Coastguard Worker 
1078*33b1fccfSAndroid Build Coastguard Worker 			if (kite_deflate_tally(s, mf->matches + matches))
1079*33b1fccfSAndroid Build Coastguard Worker 				break;
1080*33b1fccfSAndroid Build Coastguard Worker 			s->pos_in += len;
1081*33b1fccfSAndroid Build Coastguard Worker 			/* skip the rest bytes */
1082*33b1fccfSAndroid Build Coastguard Worker 			while (--len)
1083*33b1fccfSAndroid Build Coastguard Worker 				kite_mf_hc3_skip(mf);
1084*33b1fccfSAndroid Build Coastguard Worker 		} else {
1085*33b1fccfSAndroid Build Coastguard Worker nomatch:
1086*33b1fccfSAndroid Build Coastguard Worker 			mf->matches[0].dist = s->in[s->pos_in];
1087*33b1fccfSAndroid Build Coastguard Worker 			if (isprint(s->in[s->pos_in]))
1088*33b1fccfSAndroid Build Coastguard Worker 				kite_dbg("literal %c pos_in %u", s->in[s->pos_in], s->pos_in);
1089*33b1fccfSAndroid Build Coastguard Worker 			else
1090*33b1fccfSAndroid Build Coastguard Worker 				kite_dbg("literal %x pos_in %u", s->in[s->pos_in], s->pos_in);
1091*33b1fccfSAndroid Build Coastguard Worker 
1092*33b1fccfSAndroid Build Coastguard Worker 			if (kite_deflate_tally(s, mf->matches))
1093*33b1fccfSAndroid Build Coastguard Worker 				break;
1094*33b1fccfSAndroid Build Coastguard Worker 			++s->pos_in;
1095*33b1fccfSAndroid Build Coastguard Worker 		}
1096*33b1fccfSAndroid Build Coastguard Worker 
1097*33b1fccfSAndroid Build Coastguard Worker 		s->lastblock |= (s->pos_in >= s->inlen);
1098*33b1fccfSAndroid Build Coastguard Worker 		if (s->pos_in >= s->inlen || s->symbols >= s->max_symbols) {
1099*33b1fccfSAndroid Build Coastguard Worker 			kite_deflate_endblock(s);
1100*33b1fccfSAndroid Build Coastguard Worker 			break;
1101*33b1fccfSAndroid Build Coastguard Worker 		}
1102*33b1fccfSAndroid Build Coastguard Worker 	}
1103*33b1fccfSAndroid Build Coastguard Worker 	return kite_deflate_commitblock(s);
1104*33b1fccfSAndroid Build Coastguard Worker }
1105*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_slow(struct kite_deflate * s)1106*33b1fccfSAndroid Build Coastguard Worker static bool kite_deflate_slow(struct kite_deflate *s)
1107*33b1fccfSAndroid Build Coastguard Worker {
1108*33b1fccfSAndroid Build Coastguard Worker 	struct kite_matchfinder *mf = s->mf;
1109*33b1fccfSAndroid Build Coastguard Worker 	bool flush = false;
1110*33b1fccfSAndroid Build Coastguard Worker 
1111*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_startblock(s);
1112*33b1fccfSAndroid Build Coastguard Worker 	while (1) {
1113*33b1fccfSAndroid Build Coastguard Worker 		struct kite_match *prev_matches = mf->matches;
1114*33b1fccfSAndroid Build Coastguard Worker 		unsigned int len = kMatchMinLen - 1;
1115*33b1fccfSAndroid Build Coastguard Worker 		int matches;
1116*33b1fccfSAndroid Build Coastguard Worker 		unsigned int len0;
1117*33b1fccfSAndroid Build Coastguard Worker 
1118*33b1fccfSAndroid Build Coastguard Worker 		mf->matches = mf->matches_matrix[
1119*33b1fccfSAndroid Build Coastguard Worker 				mf->matches == mf->matches_matrix[0]];
1120*33b1fccfSAndroid Build Coastguard Worker 		mf->matches[0].dist = s->in[s->pos_in];
1121*33b1fccfSAndroid Build Coastguard Worker 
1122*33b1fccfSAndroid Build Coastguard Worker 		len0 = prev_matches[s->prev_longest].len;
1123*33b1fccfSAndroid Build Coastguard Worker 		if (len0 < mf->max_lazy) {
1124*33b1fccfSAndroid Build Coastguard Worker 			matches = kite_mf_getmatches_hc3(mf, mf->depth >>
1125*33b1fccfSAndroid Build Coastguard Worker 				(len0 >= mf->good_len), len0);
1126*33b1fccfSAndroid Build Coastguard Worker 			if (matches > 0) {
1127*33b1fccfSAndroid Build Coastguard Worker 				len = mf->matches[matches].len;
1128*33b1fccfSAndroid Build Coastguard Worker 				if (len == kMatchMinLen &&
1129*33b1fccfSAndroid Build Coastguard Worker 				    mf->matches[matches].dist > ZLIB_DISTANCE_TOO_FAR) {
1130*33b1fccfSAndroid Build Coastguard Worker 					matches = 0;
1131*33b1fccfSAndroid Build Coastguard Worker 					len = kMatchMinLen - 1;
1132*33b1fccfSAndroid Build Coastguard Worker 				}
1133*33b1fccfSAndroid Build Coastguard Worker 			} else {
1134*33b1fccfSAndroid Build Coastguard Worker 				matches = 0;
1135*33b1fccfSAndroid Build Coastguard Worker 			}
1136*33b1fccfSAndroid Build Coastguard Worker 		} else {
1137*33b1fccfSAndroid Build Coastguard Worker 			matches = 0;
1138*33b1fccfSAndroid Build Coastguard Worker 			kite_mf_hc3_skip(mf);
1139*33b1fccfSAndroid Build Coastguard Worker 		}
1140*33b1fccfSAndroid Build Coastguard Worker 
1141*33b1fccfSAndroid Build Coastguard Worker 		if (len < len0) {
1142*33b1fccfSAndroid Build Coastguard Worker 			if (kite_deflate_tally(s,
1143*33b1fccfSAndroid Build Coastguard Worker 					prev_matches + s->prev_longest))
1144*33b1fccfSAndroid Build Coastguard Worker 				break;
1145*33b1fccfSAndroid Build Coastguard Worker 
1146*33b1fccfSAndroid Build Coastguard Worker 			s->pos_in += --len0;
1147*33b1fccfSAndroid Build Coastguard Worker 			/* skip the rest bytes */
1148*33b1fccfSAndroid Build Coastguard Worker 			while (--len0)
1149*33b1fccfSAndroid Build Coastguard Worker 				kite_mf_hc3_skip(mf);
1150*33b1fccfSAndroid Build Coastguard Worker 			s->prev_valid = false;
1151*33b1fccfSAndroid Build Coastguard Worker 			s->prev_longest = 0;
1152*33b1fccfSAndroid Build Coastguard Worker 		} else {
1153*33b1fccfSAndroid Build Coastguard Worker 			if (!s->prev_valid)
1154*33b1fccfSAndroid Build Coastguard Worker 				s->prev_valid = true;
1155*33b1fccfSAndroid Build Coastguard Worker 			else if (kite_deflate_tally(s, prev_matches))
1156*33b1fccfSAndroid Build Coastguard Worker 				break;
1157*33b1fccfSAndroid Build Coastguard Worker 			++s->pos_in;
1158*33b1fccfSAndroid Build Coastguard Worker 			s->prev_longest = matches;
1159*33b1fccfSAndroid Build Coastguard Worker 		}
1160*33b1fccfSAndroid Build Coastguard Worker 
1161*33b1fccfSAndroid Build Coastguard Worker 		s->lastblock |= (s->pos_in >= s->inlen);
1162*33b1fccfSAndroid Build Coastguard Worker 		if (s->pos_in >= s->inlen) {
1163*33b1fccfSAndroid Build Coastguard Worker 			flush = true;
1164*33b1fccfSAndroid Build Coastguard Worker 			break;
1165*33b1fccfSAndroid Build Coastguard Worker 		}
1166*33b1fccfSAndroid Build Coastguard Worker 		if (s->symbols >= s->max_symbols) {
1167*33b1fccfSAndroid Build Coastguard Worker 			kite_deflate_endblock(s);
1168*33b1fccfSAndroid Build Coastguard Worker 			break;
1169*33b1fccfSAndroid Build Coastguard Worker 		}
1170*33b1fccfSAndroid Build Coastguard Worker 	}
1171*33b1fccfSAndroid Build Coastguard Worker 
1172*33b1fccfSAndroid Build Coastguard Worker 	if (flush && s->prev_valid) {
1173*33b1fccfSAndroid Build Coastguard Worker 		(void)kite_deflate_tally(s, mf->matches + s->prev_longest);
1174*33b1fccfSAndroid Build Coastguard Worker 		s->prev_valid = false;
1175*33b1fccfSAndroid Build Coastguard Worker 	}
1176*33b1fccfSAndroid Build Coastguard Worker 	return kite_deflate_commitblock(s);
1177*33b1fccfSAndroid Build Coastguard Worker }
1178*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_end(struct kite_deflate * s)1179*33b1fccfSAndroid Build Coastguard Worker void kite_deflate_end(struct kite_deflate *s)
1180*33b1fccfSAndroid Build Coastguard Worker {
1181*33b1fccfSAndroid Build Coastguard Worker 	if (s->mf) {
1182*33b1fccfSAndroid Build Coastguard Worker 		if (s->mf->hash)
1183*33b1fccfSAndroid Build Coastguard Worker 			free(s->mf->hash);
1184*33b1fccfSAndroid Build Coastguard Worker 		if (s->mf->chain)
1185*33b1fccfSAndroid Build Coastguard Worker 			free(s->mf->chain);
1186*33b1fccfSAndroid Build Coastguard Worker 		free(s->mf);
1187*33b1fccfSAndroid Build Coastguard Worker 	}
1188*33b1fccfSAndroid Build Coastguard Worker 	if (s->sym)
1189*33b1fccfSAndroid Build Coastguard Worker 		free(s->sym);
1190*33b1fccfSAndroid Build Coastguard Worker 	free(s);
1191*33b1fccfSAndroid Build Coastguard Worker }
1192*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_init(int level,unsigned int dict_size)1193*33b1fccfSAndroid Build Coastguard Worker struct kite_deflate *kite_deflate_init(int level, unsigned int dict_size)
1194*33b1fccfSAndroid Build Coastguard Worker {
1195*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate *s;
1196*33b1fccfSAndroid Build Coastguard Worker 	int err;
1197*33b1fccfSAndroid Build Coastguard Worker 
1198*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_init_once();
1199*33b1fccfSAndroid Build Coastguard Worker 	s = calloc(1, sizeof(*s));
1200*33b1fccfSAndroid Build Coastguard Worker 	if (!s)
1201*33b1fccfSAndroid Build Coastguard Worker 		return ERR_PTR(-ENOMEM);
1202*33b1fccfSAndroid Build Coastguard Worker 
1203*33b1fccfSAndroid Build Coastguard Worker 	s->max_symbols = 16384;
1204*33b1fccfSAndroid Build Coastguard Worker 	s->sym = malloc(sizeof(s->sym[0]) * s->max_symbols);
1205*33b1fccfSAndroid Build Coastguard Worker 	if (!s->sym) {
1206*33b1fccfSAndroid Build Coastguard Worker 		err = -ENOMEM;
1207*33b1fccfSAndroid Build Coastguard Worker 		goto err_out;
1208*33b1fccfSAndroid Build Coastguard Worker 	}
1209*33b1fccfSAndroid Build Coastguard Worker 
1210*33b1fccfSAndroid Build Coastguard Worker 	s->mf = malloc(sizeof(*s->mf));
1211*33b1fccfSAndroid Build Coastguard Worker 	if (!s->mf) {
1212*33b1fccfSAndroid Build Coastguard Worker 		err = -ENOMEM;
1213*33b1fccfSAndroid Build Coastguard Worker 		goto err_out;
1214*33b1fccfSAndroid Build Coastguard Worker 	}
1215*33b1fccfSAndroid Build Coastguard Worker 
1216*33b1fccfSAndroid Build Coastguard Worker 	if (!dict_size)
1217*33b1fccfSAndroid Build Coastguard Worker 		dict_size = kHistorySize32;
1218*33b1fccfSAndroid Build Coastguard Worker 
1219*33b1fccfSAndroid Build Coastguard Worker 	err = kite_mf_init(s->mf, dict_size, level);
1220*33b1fccfSAndroid Build Coastguard Worker 	if (err < 0)
1221*33b1fccfSAndroid Build Coastguard Worker 		goto err_out;
1222*33b1fccfSAndroid Build Coastguard Worker 
1223*33b1fccfSAndroid Build Coastguard Worker 	s->lazy_search = err;
1224*33b1fccfSAndroid Build Coastguard Worker 	return s;
1225*33b1fccfSAndroid Build Coastguard Worker err_out:
1226*33b1fccfSAndroid Build Coastguard Worker 	if (s->mf)
1227*33b1fccfSAndroid Build Coastguard Worker 		free(s->mf);
1228*33b1fccfSAndroid Build Coastguard Worker 	if (s->sym)
1229*33b1fccfSAndroid Build Coastguard Worker 		free(s->sym);
1230*33b1fccfSAndroid Build Coastguard Worker 	free(s);
1231*33b1fccfSAndroid Build Coastguard Worker 	return ERR_PTR(err);
1232*33b1fccfSAndroid Build Coastguard Worker }
1233*33b1fccfSAndroid Build Coastguard Worker 
kite_deflate_destsize(struct kite_deflate * s,const u8 * in,u8 * out,unsigned int * srcsize,unsigned int target_dstsize)1234*33b1fccfSAndroid Build Coastguard Worker int kite_deflate_destsize(struct kite_deflate *s, const u8 *in, u8 *out,
1235*33b1fccfSAndroid Build Coastguard Worker 			   unsigned int *srcsize, unsigned int target_dstsize)
1236*33b1fccfSAndroid Build Coastguard Worker {
1237*33b1fccfSAndroid Build Coastguard Worker 	memset(s, 0, offsetof(struct kite_deflate, mainFreqs));
1238*33b1fccfSAndroid Build Coastguard Worker 	s->in = in;
1239*33b1fccfSAndroid Build Coastguard Worker 	s->inlen = *srcsize;
1240*33b1fccfSAndroid Build Coastguard Worker 	s->out = out;
1241*33b1fccfSAndroid Build Coastguard Worker 	s->outlen = target_dstsize;
1242*33b1fccfSAndroid Build Coastguard Worker 	kite_mf_reset(s->mf, in, in + s->inlen);
1243*33b1fccfSAndroid Build Coastguard Worker 
1244*33b1fccfSAndroid Build Coastguard Worker 	if (s->lazy_search)
1245*33b1fccfSAndroid Build Coastguard Worker 		while (!kite_deflate_slow(s));
1246*33b1fccfSAndroid Build Coastguard Worker 	else
1247*33b1fccfSAndroid Build Coastguard Worker 		while (!kite_deflate_fast(s));
1248*33b1fccfSAndroid Build Coastguard Worker 	flushbits(s);
1249*33b1fccfSAndroid Build Coastguard Worker 
1250*33b1fccfSAndroid Build Coastguard Worker 	*srcsize = s->startpos;
1251*33b1fccfSAndroid Build Coastguard Worker 	return s->pos_out;
1252*33b1fccfSAndroid Build Coastguard Worker }
1253*33b1fccfSAndroid Build Coastguard Worker 
1254*33b1fccfSAndroid Build Coastguard Worker #if TEST
1255*33b1fccfSAndroid Build Coastguard Worker #include <unistd.h>
1256*33b1fccfSAndroid Build Coastguard Worker #include <fcntl.h>
1257*33b1fccfSAndroid Build Coastguard Worker #include <sys/mman.h>
1258*33b1fccfSAndroid Build Coastguard Worker 
main(int argc,char * argv[])1259*33b1fccfSAndroid Build Coastguard Worker int main(int argc, char *argv[])
1260*33b1fccfSAndroid Build Coastguard Worker {
1261*33b1fccfSAndroid Build Coastguard Worker 	int fd;
1262*33b1fccfSAndroid Build Coastguard Worker 	u64 filelength;
1263*33b1fccfSAndroid Build Coastguard Worker 	u8 out[1048576], *buf;
1264*33b1fccfSAndroid Build Coastguard Worker 	int dstsize = 4096;
1265*33b1fccfSAndroid Build Coastguard Worker 	unsigned int srcsize, outsize;
1266*33b1fccfSAndroid Build Coastguard Worker 	struct kite_deflate *s;
1267*33b1fccfSAndroid Build Coastguard Worker 
1268*33b1fccfSAndroid Build Coastguard Worker 	fd = open(argv[1], O_RDONLY);
1269*33b1fccfSAndroid Build Coastguard Worker 	if (fd < 0)
1270*33b1fccfSAndroid Build Coastguard Worker 		return -errno;
1271*33b1fccfSAndroid Build Coastguard Worker 	if (argc > 2)
1272*33b1fccfSAndroid Build Coastguard Worker 		dstsize = atoi(argv[2]);
1273*33b1fccfSAndroid Build Coastguard Worker 	filelength = lseek(fd, 0, SEEK_END);
1274*33b1fccfSAndroid Build Coastguard Worker 
1275*33b1fccfSAndroid Build Coastguard Worker 	s = kite_deflate_init(9, 0);
1276*33b1fccfSAndroid Build Coastguard Worker 	if (IS_ERR(s))
1277*33b1fccfSAndroid Build Coastguard Worker 		return PTR_ERR(s);
1278*33b1fccfSAndroid Build Coastguard Worker 
1279*33b1fccfSAndroid Build Coastguard Worker 	filelength = lseek(fd, 0, SEEK_END);
1280*33b1fccfSAndroid Build Coastguard Worker 	buf = mmap(NULL, filelength, PROT_READ, MAP_SHARED, fd, 0);
1281*33b1fccfSAndroid Build Coastguard Worker 	if (buf == MAP_FAILED)
1282*33b1fccfSAndroid Build Coastguard Worker 		return -errno;
1283*33b1fccfSAndroid Build Coastguard Worker 	close(fd);
1284*33b1fccfSAndroid Build Coastguard Worker 
1285*33b1fccfSAndroid Build Coastguard Worker 	srcsize = filelength;
1286*33b1fccfSAndroid Build Coastguard Worker 	outsize = kite_deflate_destsize(s, buf, out, &srcsize, dstsize);
1287*33b1fccfSAndroid Build Coastguard Worker 	fd = open("out.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
1288*33b1fccfSAndroid Build Coastguard Worker 	write(fd, out, outsize);
1289*33b1fccfSAndroid Build Coastguard Worker 	close(fd);
1290*33b1fccfSAndroid Build Coastguard Worker 	kite_deflate_end(s);
1291*33b1fccfSAndroid Build Coastguard Worker 	return 0;
1292*33b1fccfSAndroid Build Coastguard Worker }
1293*33b1fccfSAndroid Build Coastguard Worker #endif
1294