GCC Code Coverage Report


Directory: ./
File: submodules/raylib/src/external/sdefl.h
Date: 2023-09-29 04:53:15
Exec Total Coverage
Lines: 0 304 0.0%
Branches: 0 231 0.0%

Line Branch Exec Source
1 /*# Small Deflate
2 `sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
3 which implements the Deflate (RFC 1951) compressed data format specification standard.
4 It is mainly tuned to get as much speed and compression ratio from as little code
5 as needed to keep the implementation as concise as possible.
6
7 ## Features
8 - Portable single header and source file duo written in ANSI C (ISO C90)
9 - Dual license with either MIT or public domain
10 - Small implementation
11 - Deflate: 525 LoC
12 - Inflate: 320 LoC
13 - Webassembly:
14 - Deflate ~3.7 KB (~2.2KB compressed)
15 - Inflate ~3.6 KB (~2.2KB compressed)
16
17 ## Usage:
18 This file behaves differently depending on what symbols you define
19 before including it.
20
21 Header-File mode:
22 If you do not define `SDEFL_IMPLEMENTATION` before including this file, it
23 will operate in header only mode. In this mode it declares all used structs
24 and the API of the library without including the implementation of the library.
25
26 Implementation mode:
27 If you define `SDEFL_IMPLEMENTATION` before including this file, it will
28 compile the implementation . Make sure that you only include
29 this file implementation in *one* C or C++ file to prevent collisions.
30
31 ### Benchmark
32
33 | Compressor name | Compression| Decompress.| Compr. size | Ratio |
34 | ------------------------| -----------| -----------| ----------- | ----- |
35 | miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 |
36 | miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 |
37 | miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 |
38 | zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
39 | zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
40 | zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
41 | sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
42 | sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
43 | sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
44 | sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
45 | libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
46 | libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
47 | libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
48 | libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 |
49
50 ### Compression
51 Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
52
53 | File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` |
54 | --------| -----------| -------------| ---------- | ------------|
55 | dickens | 10.192.446 | 4,260,187 | 3,845,261 | 3,833,657 |
56 | mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 |
57 | mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 |
58 | nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 |
59 | ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 |
60 | osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 |
61 | reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 |
62 | samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 |
63 | sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 |
64 | webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 |
65 | xml | 5.345.280 | 886,620 | 674,009 | 662,141 |
66 | x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 |
67
68 ## License
69 ```
70 ------------------------------------------------------------------------------
71 This software is available under 2 licenses -- choose whichever you prefer.
72 ------------------------------------------------------------------------------
73 ALTERNATIVE A - MIT License
74 Copyright (c) 2020-2023 Micha Mettke
75 Permission is hereby granted, free of charge, to any person obtaining a copy of
76 this software and associated documentation files (the "Software"), to deal in
77 the Software without restriction, including without limitation the rights to
78 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
79 of the Software, and to permit persons to whom the Software is furnished to do
80 so, subject to the following conditions:
81 The above copyright notice and this permission notice shall be included in all
82 copies or substantial portions of the Software.
83 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
84 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
85 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
86 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
87 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
88 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
89 SOFTWARE.
90 ------------------------------------------------------------------------------
91 ALTERNATIVE B - Public Domain (www.unlicense.org)
92 This is free and unencumbered software released into the public domain.
93 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
94 software, either in source code form or as a compiled binary, for any purpose,
95 commercial or non-commercial, and by any means.
96 In jurisdictions that recognize copyright laws, the author or authors of this
97 software dedicate any and all copyright interest in the software to the public
98 domain. We make this dedication for the benefit of the public at large and to
99 the detriment of our heirs and successors. We intend this dedication to be an
100 overt act of relinquishment in perpetuity of all present and future rights to
101 this software under copyright law.
102 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
103 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
104 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
105 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
106 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
107 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
108 ------------------------------------------------------------------------------
109 ```
110 */
111 #ifndef SDEFL_H_INCLUDED
112 #define SDEFL_H_INCLUDED
113
114 #ifdef __cplusplus
115 extern "C" {
116 #endif
117
118 #define SDEFL_MAX_OFF (1 << 15)
119 #define SDEFL_WIN_SIZ SDEFL_MAX_OFF
120 #define SDEFL_WIN_MSK (SDEFL_WIN_SIZ-1)
121
122 #define SDEFL_HASH_BITS 15
123 #define SDEFL_HASH_SIZ (1 << SDEFL_HASH_BITS)
124 #define SDEFL_HASH_MSK (SDEFL_HASH_SIZ-1)
125
126 #define SDEFL_MIN_MATCH 4
127 #define SDEFL_BLK_MAX (256*1024)
128 #define SDEFL_SEQ_SIZ ((SDEFL_BLK_MAX+2)/3)
129
130 #define SDEFL_SYM_MAX (288)
131 #define SDEFL_OFF_MAX (32)
132 #define SDEFL_PRE_MAX (19)
133
134 #define SDEFL_LVL_MIN 0
135 #define SDEFL_LVL_DEF 5
136 #define SDEFL_LVL_MAX 8
137
138 struct sdefl_freq {
139 unsigned lit[SDEFL_SYM_MAX];
140 unsigned off[SDEFL_OFF_MAX];
141 };
142 struct sdefl_code_words {
143 unsigned lit[SDEFL_SYM_MAX];
144 unsigned off[SDEFL_OFF_MAX];
145 };
146 struct sdefl_lens {
147 unsigned char lit[SDEFL_SYM_MAX];
148 unsigned char off[SDEFL_OFF_MAX];
149 };
150 struct sdefl_codes {
151 struct sdefl_code_words word;
152 struct sdefl_lens len;
153 };
154 struct sdefl_seqt {
155 int off, len;
156 };
157 struct sdefl {
158 int bits, bitcnt;
159 int tbl[SDEFL_HASH_SIZ];
160 int prv[SDEFL_WIN_SIZ];
161
162 int seq_cnt;
163 struct sdefl_seqt seq[SDEFL_SEQ_SIZ];
164 struct sdefl_freq freq;
165 struct sdefl_codes cod;
166 };
167 extern int sdefl_bound(int in_len);
168 extern int sdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
169 extern int zsdeflate(struct sdefl *s, void *o, const void *i, int n, int lvl);
170
171 #ifdef __cplusplus
172 }
173 #endif
174
175 #endif /* SDEFL_H_INCLUDED */
176
177 #ifdef SDEFL_IMPLEMENTATION
178
179 #include <assert.h> /* assert */
180 #include <string.h> /* memcpy */
181 #include <limits.h> /* CHAR_BIT */
182
183 #define SDEFL_NIL (-1)
184 #define SDEFL_MAX_MATCH 258
185 #define SDEFL_MAX_CODE_LEN (15)
186 #define SDEFL_SYM_BITS (10u)
187 #define SDEFL_SYM_MSK ((1u << SDEFL_SYM_BITS)-1u)
188 #define SDEFL_RAW_BLK_SIZE (65535)
189 #define SDEFL_LIT_LEN_CODES (14)
190 #define SDEFL_OFF_CODES (15)
191 #define SDEFL_PRE_CODES (7)
192 #define SDEFL_CNT_NUM(n) ((((n)+3u/4u)+3u)&~3u)
193 #define SDEFL_EOB (256)
194
195 #define sdefl_npow2(n) (1 << (sdefl_ilog2((n)-1) + 1))
196 #define sdefl_div_round_up(n,d) (((n)+((d)-1))/(d))
197
198 static int
199 sdefl_ilog2(int n) {
200 if (!n) return 0;
201 #ifdef _MSC_VER
202 unsigned long msbp = 0;
203 _BitScanReverse(&msbp, (unsigned long)n);
204 return (int)msbp;
205 #elif defined(__GNUC__) || defined(__clang__)
206 return (int)sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl((unsigned long)n);
207 #else
208 #define lt(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
209 static const char tbl[256] = {
210 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,lt(4), lt(5), lt(5), lt(6), lt(6), lt(6), lt(6),
211 lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7), lt(7)};
212 int tt, t;
213 if ((tt = (n >> 16))) {
214 return (t = (tt >> 8)) ? 24 + tbl[t] : 16 + tbl[tt];
215 } else {
216 return (t = (n >> 8)) ? 8 + tbl[t] : tbl[n];
217 }
218 #undef lt
219 #endif
220 }
221 static unsigned
222 sdefl_uload32(const void *p) {
223 /* hopefully will be optimized to an unaligned read */
224 unsigned n = 0;
225 memcpy(&n, p, sizeof(n));
226 return n;
227 }
228 static unsigned
229 sdefl_hash32(const void *p) {
230 unsigned n = sdefl_uload32(p);
231 return (n * 0x9E377989) >> (32 - SDEFL_HASH_BITS);
232 }
233 static void
234 sdefl_put(unsigned char **dst, struct sdefl *s, int code, int bitcnt) {
235 s->bits |= (code << s->bitcnt);
236 s->bitcnt += bitcnt;
237 while (s->bitcnt >= 8) {
238 unsigned char *tar = *dst;
239 *tar = (unsigned char)(s->bits & 0xFF);
240 s->bits >>= 8;
241 s->bitcnt -= 8;
242 *dst = *dst + 1;
243 }
244 }
245 static void
246 sdefl_heap_sub(unsigned A[], unsigned len, unsigned sub) {
247 unsigned c, p = sub;
248 unsigned v = A[sub];
249 while ((c = p << 1) <= len) {
250 if (c < len && A[c + 1] > A[c]) c++;
251 if (v >= A[c]) break;
252 A[p] = A[c], p = c;
253 }
254 A[p] = v;
255 }
256 static void
257 sdefl_heap_array(unsigned *A, unsigned len) {
258 unsigned sub;
259 for (sub = len >> 1; sub >= 1; sub--)
260 sdefl_heap_sub(A, len, sub);
261 }
262 static void
263 sdefl_heap_sort(unsigned *A, unsigned n) {
264 A--;
265 sdefl_heap_array(A, n);
266 while (n >= 2) {
267 unsigned tmp = A[n];
268 A[n--] = A[1];
269 A[1] = tmp;
270 sdefl_heap_sub(A, n, 1);
271 }
272 }
273 static unsigned
274 sdefl_sort_sym(unsigned sym_cnt, unsigned *freqs,
275 unsigned char *lens, unsigned *sym_out) {
276 unsigned cnts[SDEFL_CNT_NUM(SDEFL_SYM_MAX)] = {0};
277 unsigned cnt_num = SDEFL_CNT_NUM(sym_cnt);
278 unsigned used_sym = 0;
279 unsigned sym, i;
280 for (sym = 0; sym < sym_cnt; sym++)
281 cnts[freqs[sym] < cnt_num-1 ? freqs[sym]: cnt_num-1]++;
282 for (i = 1; i < cnt_num; i++) {
283 unsigned cnt = cnts[i];
284 cnts[i] = used_sym;
285 used_sym += cnt;
286 }
287 for (sym = 0; sym < sym_cnt; sym++) {
288 unsigned freq = freqs[sym];
289 if (freq) {
290 unsigned idx = freq < cnt_num-1 ? freq : cnt_num-1;
291 sym_out[cnts[idx]++] = sym | (freq << SDEFL_SYM_BITS);
292 } else lens[sym] = 0;
293 }
294 sdefl_heap_sort(sym_out + cnts[cnt_num-2], cnts[cnt_num-1] - cnts[cnt_num-2]);
295 return used_sym;
296 }
297 static void
298 sdefl_build_tree(unsigned *A, unsigned sym_cnt) {
299 unsigned i = 0, b = 0, e = 0;
300 do {
301 unsigned m, n, freq_shift;
302 if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
303 m = i++;
304 else m = b++;
305 if (i != sym_cnt && (b == e || (A[i] >> SDEFL_SYM_BITS) <= (A[b] >> SDEFL_SYM_BITS)))
306 n = i++;
307 else n = b++;
308
309 freq_shift = (A[m] & ~SDEFL_SYM_MSK) + (A[n] & ~SDEFL_SYM_MSK);
310 A[m] = (A[m] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
311 A[n] = (A[n] & SDEFL_SYM_MSK) | (e << SDEFL_SYM_BITS);
312 A[e] = (A[e] & SDEFL_SYM_MSK) | freq_shift;
313 } while (sym_cnt - ++e > 1);
314 }
315 static void
316 sdefl_gen_len_cnt(unsigned *A, unsigned root, unsigned *len_cnt,
317 unsigned max_code_len) {
318 int n;
319 unsigned i;
320 for (i = 0; i <= max_code_len; i++)
321 len_cnt[i] = 0;
322 len_cnt[1] = 2;
323
324 A[root] &= SDEFL_SYM_MSK;
325 for (n = (int)root - 1; n >= 0; n--) {
326 unsigned p = A[n] >> SDEFL_SYM_BITS;
327 unsigned pdepth = A[p] >> SDEFL_SYM_BITS;
328 unsigned depth = pdepth + 1;
329 unsigned len = depth;
330
331 A[n] = (A[n] & SDEFL_SYM_MSK) | (depth << SDEFL_SYM_BITS);
332 if (len >= max_code_len) {
333 len = max_code_len;
334 do len--; while (!len_cnt[len]);
335 }
336 len_cnt[len]--;
337 len_cnt[len+1] += 2;
338 }
339 }
340 static void
341 sdefl_gen_codes(unsigned *A, unsigned char *lens, const unsigned *len_cnt,
342 unsigned max_code_word_len, unsigned sym_cnt) {
343 unsigned i, sym, len, nxt[SDEFL_MAX_CODE_LEN + 1];
344 for (i = 0, len = max_code_word_len; len >= 1; len--) {
345 unsigned cnt = len_cnt[len];
346 while (cnt--) lens[A[i++] & SDEFL_SYM_MSK] = (unsigned char)len;
347 }
348 nxt[0] = nxt[1] = 0;
349 for (len = 2; len <= max_code_word_len; len++)
350 nxt[len] = (nxt[len-1] + len_cnt[len-1]) << 1;
351 for (sym = 0; sym < sym_cnt; sym++)
352 A[sym] = nxt[lens[sym]]++;
353 }
354 static unsigned
355 sdefl_rev(unsigned c, unsigned char n) {
356 c = ((c & 0x5555) << 1) | ((c & 0xAAAA) >> 1);
357 c = ((c & 0x3333) << 2) | ((c & 0xCCCC) >> 2);
358 c = ((c & 0x0F0F) << 4) | ((c & 0xF0F0) >> 4);
359 c = ((c & 0x00FF) << 8) | ((c & 0xFF00) >> 8);
360 return c >> (16-n);
361 }
362 static void
363 sdefl_huff(unsigned char *lens, unsigned *codes, unsigned *freqs,
364 unsigned num_syms, unsigned max_code_len) {
365 unsigned c, *A = codes;
366 unsigned len_cnt[SDEFL_MAX_CODE_LEN + 1];
367 unsigned used_syms = sdefl_sort_sym(num_syms, freqs, lens, A);
368 if (!used_syms) return;
369 if (used_syms == 1) {
370 unsigned s = A[0] & SDEFL_SYM_MSK;
371 unsigned i = s ? s : 1;
372 codes[0] = 0, lens[0] = 1;
373 codes[i] = 1, lens[i] = 1;
374 return;
375 }
376 sdefl_build_tree(A, used_syms);
377 sdefl_gen_len_cnt(A, used_syms-2, len_cnt, max_code_len);
378 sdefl_gen_codes(A, lens, len_cnt, max_code_len, num_syms);
379 for (c = 0; c < num_syms; c++) {
380 codes[c] = sdefl_rev(codes[c], lens[c]);
381 }
382 }
383 struct sdefl_symcnt {
384 int items;
385 int lit;
386 int off;
387 };
388 static void
389 sdefl_precode(struct sdefl_symcnt *cnt, unsigned *freqs, unsigned *items,
390 const unsigned char *litlen, const unsigned char *offlen) {
391 unsigned *at = items;
392 unsigned run_start = 0;
393
394 unsigned total = 0;
395 unsigned char lens[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
396 for (cnt->lit = SDEFL_SYM_MAX; cnt->lit > 257; cnt->lit--)
397 if (litlen[cnt->lit - 1]) break;
398 for (cnt->off = SDEFL_OFF_MAX; cnt->off > 1; cnt->off--)
399 if (offlen[cnt->off - 1]) break;
400
401 total = (unsigned)(cnt->lit + cnt->off);
402 memcpy(lens, litlen, sizeof(unsigned char) * (size_t)cnt->lit);
403 memcpy(lens + cnt->lit, offlen, sizeof(unsigned char) * (size_t)cnt->off);
404 do {
405 unsigned len = lens[run_start];
406 unsigned run_end = run_start;
407 do run_end++; while (run_end != total && len == lens[run_end]);
408 if (!len) {
409 while ((run_end - run_start) >= 11) {
410 unsigned n = (run_end - run_start) - 11;
411 unsigned xbits = n < 0x7f ? n : 0x7f;
412 freqs[18]++;
413 *at++ = 18u | (xbits << 5u);
414 run_start += 11 + xbits;
415 }
416 if ((run_end - run_start) >= 3) {
417 unsigned n = (run_end - run_start) - 3;
418 unsigned xbits = n < 0x7 ? n : 0x7;
419 freqs[17]++;
420 *at++ = 17u | (xbits << 5u);
421 run_start += 3 + xbits;
422 }
423 } else if ((run_end - run_start) >= 4) {
424 freqs[len]++;
425 *at++ = len;
426 run_start++;
427 do {
428 unsigned xbits = (run_end - run_start) - 3;
429 xbits = xbits < 0x03 ? xbits : 0x03;
430 *at++ = 16 | (xbits << 5);
431 run_start += 3 + xbits;
432 freqs[16]++;
433 } while ((run_end - run_start) >= 3);
434 }
435 while (run_start != run_end) {
436 freqs[len]++;
437 *at++ = len;
438 run_start++;
439 }
440 } while (run_start != total);
441 cnt->items = (int)(at - items);
442 }
443 struct sdefl_match_codest {
444 int ls, lc;
445 int dc, dx;
446 };
447 static void
448 sdefl_match_codes(struct sdefl_match_codest *cod, int dist, int len) {
449 static const short dxmax[] = {0,6,12,24,48,96,192,384,768,1536,3072,6144,12288,24576};
450 static const unsigned char lslot[258+1] = {
451 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12,
452 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16,
453 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18,
454 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
455 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
456 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
457 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
458 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
459 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25,
460 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
461 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26,
462 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
463 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
464 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
465 27, 27, 28
466 };
467 assert(len <= 258);
468 assert(dist <= 32768);
469 cod->ls = lslot[len];
470 cod->lc = 257 + cod->ls;
471 assert(cod->lc <= 285);
472
473 cod->dx = sdefl_ilog2(sdefl_npow2(dist) >> 2);
474 cod->dc = cod->dx ? ((cod->dx + 1) << 1) + (dist > dxmax[cod->dx]) : dist-1;
475 }
476 enum sdefl_blk_type {
477 SDEFL_BLK_UCOMPR,
478 SDEFL_BLK_DYN
479 };
480 static enum sdefl_blk_type
481 sdefl_blk_type(const struct sdefl *s, int blk_len, int pre_item_len,
482 const unsigned *pre_freq, const unsigned char *pre_len) {
483 static const unsigned char x_pre_bits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
484 static const unsigned char x_len_bits[] = {0,0,0,0,0,0,0,0, 1,1,1,1,2,2,2,2,
485 3,3,3,3,4,4,4,4, 5,5,5,5,0};
486 static const unsigned char x_off_bits[] = {0,0,0,0,1,1,2,2, 3,3,4,4,5,5,6,6,
487 7,7,8,8,9,9,10,10, 11,11,12,12,13,13};
488
489 int dyn_cost = 0;
490 int fix_cost = 0;
491 int sym = 0;
492
493 dyn_cost += 5 + 5 + 4 + (3 * pre_item_len);
494 for (sym = 0; sym < SDEFL_PRE_MAX; sym++)
495 dyn_cost += pre_freq[sym] * (x_pre_bits[sym] + pre_len[sym]);
496 for (sym = 0; sym < 256; sym++)
497 dyn_cost += s->freq.lit[sym] * s->cod.len.lit[sym];
498 dyn_cost += s->cod.len.lit[SDEFL_EOB];
499 for (sym = 257; sym < 286; sym++)
500 dyn_cost += s->freq.lit[sym] * (x_len_bits[sym - 257] + s->cod.len.lit[sym]);
501 for (sym = 0; sym < 30; sym++)
502 dyn_cost += s->freq.off[sym] * (x_off_bits[sym] + s->cod.len.off[sym]);
503
504 fix_cost += 8*(5 * sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE) + blk_len + 1 + 2);
505 return (dyn_cost < fix_cost) ? SDEFL_BLK_DYN : SDEFL_BLK_UCOMPR;
506 }
507 static void
508 sdefl_put16(unsigned char **dst, unsigned short x) {
509 unsigned char *val = *dst;
510 val[0] = (unsigned char)(x & 0xff);
511 val[1] = (unsigned char)(x >> 8);
512 *dst = val + 2;
513 }
514 static void
515 sdefl_match(unsigned char **dst, struct sdefl *s, int dist, int len) {
516 static const char lxn[] = {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,5,5,5,0};
517 static const short lmin[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,
518 51,59,67,83,99,115,131,163,195,227,258};
519 static const short dmin[] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,
520 385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
521
522 struct sdefl_match_codest cod;
523 sdefl_match_codes(&cod, dist, len);
524 sdefl_put(dst, s, (int)s->cod.word.lit[cod.lc], s->cod.len.lit[cod.lc]);
525 sdefl_put(dst, s, len - lmin[cod.ls], lxn[cod.ls]);
526 sdefl_put(dst, s, (int)s->cod.word.off[cod.dc], s->cod.len.off[cod.dc]);
527 sdefl_put(dst, s, dist - dmin[cod.dc], cod.dx);
528 }
529 static void
530 sdefl_flush(unsigned char **dst, struct sdefl *s, int is_last,
531 const unsigned char *in, int blk_begin, int blk_end) {
532 int blk_len = blk_end - blk_begin;
533 int j, i = 0, item_cnt = 0;
534 struct sdefl_symcnt symcnt = {0};
535 unsigned codes[SDEFL_PRE_MAX];
536 unsigned char lens[SDEFL_PRE_MAX];
537 unsigned freqs[SDEFL_PRE_MAX] = {0};
538 unsigned items[SDEFL_SYM_MAX + SDEFL_OFF_MAX];
539 static const unsigned char perm[SDEFL_PRE_MAX] = {16,17,18,0,8,7,9,6,10,5,11,
540 4,12,3,13,2,14,1,15};
541
542 /* calculate huffman codes */
543 s->freq.lit[SDEFL_EOB]++;
544 sdefl_huff(s->cod.len.lit, s->cod.word.lit, s->freq.lit, SDEFL_SYM_MAX, SDEFL_LIT_LEN_CODES);
545 sdefl_huff(s->cod.len.off, s->cod.word.off, s->freq.off, SDEFL_OFF_MAX, SDEFL_OFF_CODES);
546 sdefl_precode(&symcnt, freqs, items, s->cod.len.lit, s->cod.len.off);
547 sdefl_huff(lens, codes, freqs, SDEFL_PRE_MAX, SDEFL_PRE_CODES);
548 for (item_cnt = SDEFL_PRE_MAX; item_cnt > 4; item_cnt--) {
549 if (lens[perm[item_cnt - 1]]){
550 break;
551 }
552 }
553 /* write block */
554 switch (sdefl_blk_type(s, blk_len, item_cnt, freqs, lens)) {
555 case SDEFL_BLK_UCOMPR: {
556 /* uncompressed blocks */
557 int n = sdefl_div_round_up(blk_len, SDEFL_RAW_BLK_SIZE);
558 for (i = 0; i < n; ++i) {
559 int fin = is_last && (i + 1 == n);
560 int amount = blk_len < SDEFL_RAW_BLK_SIZE ? blk_len : SDEFL_RAW_BLK_SIZE;
561 sdefl_put(dst, s, !!fin, 1); /* block */
562 sdefl_put(dst, s, 0x00, 2); /* stored block */
563 if (s->bitcnt) {
564 sdefl_put(dst, s, 0x00, 8 - s->bitcnt);
565 }
566 assert(s->bitcnt == 0);
567 sdefl_put16(dst, (unsigned short)amount);
568 sdefl_put16(dst, ~(unsigned short)amount);
569 memcpy(*dst, in + blk_begin + i * SDEFL_RAW_BLK_SIZE, amount);
570 *dst = *dst + amount;
571 blk_len -= amount;
572 }
573 } break;
574 case SDEFL_BLK_DYN: {
575 /* dynamic huffman block */
576 sdefl_put(dst, s, !!is_last, 1); /* block */
577 sdefl_put(dst, s, 0x02, 2); /* dynamic huffman */
578 sdefl_put(dst, s, symcnt.lit - 257, 5);
579 sdefl_put(dst, s, symcnt.off - 1, 5);
580 sdefl_put(dst, s, item_cnt - 4, 4);
581 for (i = 0; i < item_cnt; ++i) {
582 sdefl_put(dst, s, lens[perm[i]], 3);
583 }
584 for (i = 0; i < symcnt.items; ++i) {
585 unsigned sym = items[i] & 0x1F;
586 sdefl_put(dst, s, (int)codes[sym], lens[sym]);
587 if (sym < 16) continue;
588 if (sym == 16) sdefl_put(dst, s, items[i] >> 5, 2);
589 else if(sym == 17) sdefl_put(dst, s, items[i] >> 5, 3);
590 else sdefl_put(dst, s, items[i] >> 5, 7);
591 }
592 /* block sequences */
593 for (i = 0; i < s->seq_cnt; ++i) {
594 if (s->seq[i].off >= 0) {
595 for (j = 0; j < s->seq[i].len; ++j) {
596 int c = in[s->seq[i].off + j];
597 sdefl_put(dst, s, (int)s->cod.word.lit[c], s->cod.len.lit[c]);
598 }
599 } else {
600 sdefl_match(dst, s, -s->seq[i].off, s->seq[i].len);
601 }
602 }
603 sdefl_put(dst, s, (int)(s)->cod.word.lit[SDEFL_EOB], (s)->cod.len.lit[SDEFL_EOB]);
604 } break;}
605 memset(&s->freq, 0, sizeof(s->freq));
606 s->seq_cnt = 0;
607 }
608 static void
609 sdefl_seq(struct sdefl *s, int off, int len) {
610 assert(s->seq_cnt + 2 < SDEFL_SEQ_SIZ);
611 s->seq[s->seq_cnt].off = off;
612 s->seq[s->seq_cnt].len = len;
613 s->seq_cnt++;
614 }
615 static void
616 sdefl_reg_match(struct sdefl *s, int off, int len) {
617 struct sdefl_match_codest cod;
618 sdefl_match_codes(&cod, off, len);
619
620 assert(cod.lc < SDEFL_SYM_MAX);
621 assert(cod.dc < SDEFL_OFF_MAX);
622
623 s->freq.lit[cod.lc]++;
624 s->freq.off[cod.dc]++;
625 }
626 struct sdefl_match {
627 int off;
628 int len;
629 };
630 static void
631 sdefl_fnd(struct sdefl_match *m, const struct sdefl *s, int chain_len,
632 int max_match, const unsigned char *in, int p, int e) {
633 int i = s->tbl[sdefl_hash32(in + p)];
634 int limit = ((p - SDEFL_WIN_SIZ) < SDEFL_NIL) ? SDEFL_NIL : (p-SDEFL_WIN_SIZ);
635
636 assert(p < e);
637 assert(p + max_match <= e);
638 while (i > limit) {
639 assert(i + m->len < e);
640 assert(p + m->len < e);
641 assert(i + SDEFL_MIN_MATCH < e);
642 assert(p + SDEFL_MIN_MATCH < e);
643
644 if (in[i + m->len] == in[p + m->len] &&
645 (sdefl_uload32(&in[i]) == sdefl_uload32(&in[p]))) {
646 int n = SDEFL_MIN_MATCH;
647 while (n < max_match && in[i + n] == in[p + n]) {
648 assert(i + n < e);
649 assert(p + n < e);
650 n++;
651 }
652 if (n > m->len) {
653 m->len = n, m->off = p - i;
654 if (n == max_match)
655 break;
656 }
657 }
658 if (!(--chain_len)) break;
659 i = s->prv[i & SDEFL_WIN_MSK];
660 }
661 }
662 static int
663 sdefl_compr(struct sdefl *s, unsigned char *out, const unsigned char *in,
664 int in_len, int lvl) {
665 unsigned char *q = out;
666 static const unsigned char pref[] = {8,10,14,24,30,48,65,96,130};
667 int max_chain = (lvl < 8) ? (1 << (lvl + 1)): (1 << 13);
668 int n, i = 0, litlen = 0;
669 for (n = 0; n < SDEFL_HASH_SIZ; ++n) {
670 s->tbl[n] = SDEFL_NIL;
671 }
672 do {int blk_begin = i;
673 int blk_end = ((i + SDEFL_BLK_MAX) < in_len) ? (i + SDEFL_BLK_MAX) : in_len;
674 while (i < blk_end) {
675 struct sdefl_match m = {0};
676 int left = blk_end - i;
677 int max_match = (left > SDEFL_MAX_MATCH) ? SDEFL_MAX_MATCH : left;
678 int nice_match = pref[lvl] < max_match ? pref[lvl] : max_match;
679 int run = 1, inc = 1, run_inc = 0;
680 if (max_match > SDEFL_MIN_MATCH) {
681 sdefl_fnd(&m, s, max_chain, max_match, in, i, in_len);
682 }
683 if (lvl >= 5 && m.len >= SDEFL_MIN_MATCH && m.len + 1 < nice_match){
684 struct sdefl_match m2 = {0};
685 sdefl_fnd(&m2, s, max_chain, m.len + 1, in, i + 1, in_len);
686 m.len = (m2.len > m.len) ? 0 : m.len;
687 }
688 if (m.len >= SDEFL_MIN_MATCH) {
689 if (litlen) {
690 sdefl_seq(s, i - litlen, litlen);
691 litlen = 0;
692 }
693 sdefl_seq(s, -m.off, m.len);
694 sdefl_reg_match(s, m.off, m.len);
695 if (lvl < 2 && m.len >= nice_match) {
696 inc = m.len;
697 } else {
698 run = m.len;
699 }
700 } else {
701 s->freq.lit[in[i]]++;
702 litlen++;
703 }
704 run_inc = run * inc;
705 if (in_len - (i + run_inc) > SDEFL_MIN_MATCH) {
706 while (run-- > 0) {
707 unsigned h = sdefl_hash32(&in[i]);
708 s->prv[i&SDEFL_WIN_MSK] = s->tbl[h];
709 s->tbl[h] = i, i += inc;
710 assert(i <= blk_end);
711 }
712 } else {
713 i += run_inc;
714 assert(i <= blk_end);
715 }
716 }
717 if (litlen) {
718 sdefl_seq(s, i - litlen, litlen);
719 litlen = 0;
720 }
721 sdefl_flush(&q, s, blk_end == in_len, in, blk_begin, blk_end);
722 } while (i < in_len);
723 if (s->bitcnt) {
724 sdefl_put(&q, s, 0x00, 8 - s->bitcnt);
725 }
726 assert(s->bitcnt == 0);
727 return (int)(q - out);
728 }
729 extern int
730 sdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
731 s->bits = s->bitcnt = 0;
732 return sdefl_compr(s, (unsigned char*)out, (const unsigned char*)in, n, lvl);
733 }
734 static unsigned
735 sdefl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
736 #define SDEFL_ADLER_INIT (1)
737 const unsigned ADLER_MOD = 65521;
738 unsigned s1 = adler32 & 0xffff;
739 unsigned s2 = adler32 >> 16;
740 unsigned blk_len, i;
741
742 blk_len = in_len % 5552;
743 while (in_len) {
744 for (i = 0; i + 7 < blk_len; i += 8) {
745 s1 += in[0]; s2 += s1;
746 s1 += in[1]; s2 += s1;
747 s1 += in[2]; s2 += s1;
748 s1 += in[3]; s2 += s1;
749 s1 += in[4]; s2 += s1;
750 s1 += in[5]; s2 += s1;
751 s1 += in[6]; s2 += s1;
752 s1 += in[7]; s2 += s1;
753 in += 8;
754 }
755 for (; i < blk_len; ++i) {
756 s1 += *in++, s2 += s1;
757 }
758 s1 %= ADLER_MOD;
759 s2 %= ADLER_MOD;
760 in_len -= blk_len;
761 blk_len = 5552;
762 }
763 return (unsigned)(s2 << 16) + (unsigned)s1;
764 }
765 extern int
766 zsdeflate(struct sdefl *s, void *out, const void *in, int n, int lvl) {
767 int p = 0;
768 unsigned a = 0;
769 unsigned char *q = (unsigned char*)out;
770
771 s->bits = s->bitcnt = 0;
772 sdefl_put(&q, s, 0x78, 8); /* deflate, 32k window */
773 sdefl_put(&q, s, 0x01, 8); /* fast compression */
774 q += sdefl_compr(s, q, (const unsigned char*)in, n, lvl);
775
776 /* append adler checksum */
777 a = sdefl_adler32(SDEFL_ADLER_INIT, (const unsigned char*)in, n);
778 for (p = 0; p < 4; ++p) {
779 sdefl_put(&q, s, (a >> 24) & 0xFF, 8);
780 a <<= 8;
781 }
782 return (int)(q - (unsigned char*)out);
783 }
784 extern int
785 sdefl_bound(int len) {
786 int max_blocks = 1 + sdefl_div_round_up(len, SDEFL_RAW_BLK_SIZE);
787 int bound = 5 * max_blocks + len + 1 + 4 + 8;
788 return bound;
789 }
790 #endif /* SDEFL_IMPLEMENTATION */
791