Logo

index : raylib-jai

---

  • summary
  • about
  • tree
  • log
  • branches
<< path: root/public/raylib-jai.git/html/Raylib/raylib/src/external/sinfl.h blob: c8d0f96d0a49cd97e12d64a28371ee08a661fddd [raw] [clear marker]

        
0/*
1# Small Deflate
2`sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90)
3which implements the Deflate (RFC 1951) compressed data format specification standard.
4It is mainly tuned to get as much speed and compression ratio from as little code
5as 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: 500 LoC
13- Webassembly:
14 - Deflate ~3.7 KB (~2.2KB compressed)
15 - Inflate ~3.6 KB (~2.2KB compressed)
16
17## Usage:
18This file behaves differently depending on what symbols you define
19before including it.
20
21Header-File mode:
22If you do not define `SINFL_IMPLEMENTATION` before including this file, it
23will operate in header only mode. In this mode it declares all used structs
24and the API of the library without including the implementation of the library.
25
26Implementation mode:
27If you define `SINFL_IMPLEMENTATION` before including this file, it will
28compile the implementation. Make sure that you only include
29this 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
51Results 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------------------------------------------------------------------------------
71This software is available under 2 licenses -- choose whichever you prefer.
72------------------------------------------------------------------------------
73ALTERNATIVE A - MIT License
74Copyright (c) 2020-2023 Micha Mettke
75Permission is hereby granted, free of charge, to any person obtaining a copy of
76this software and associated documentation files (the "Software"), to deal in
77the Software without restriction, including without limitation the rights to
78use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
79of the Software, and to permit persons to whom the Software is furnished to do
80so, subject to the following conditions:
81The above copyright notice and this permission notice shall be included in all
82copies or substantial portions of the Software.
83THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
84IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
85FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
86AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
87LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
88OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
89SOFTWARE.
90------------------------------------------------------------------------------
91ALTERNATIVE B - Public Domain (www.unlicense.org)
92This is free and unencumbered software released into the public domain.
93Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
94software, either in source code form or as a compiled binary, for any purpose,
95commercial or non-commercial, and by any means.
96In jurisdictions that recognize copyright laws, the author or authors of this
97software dedicate any and all copyright interest in the software to the public
98domain. We make this dedication for the benefit of the public at large and to
99the detriment of our heirs and successors. We intend this dedication to be an
100overt act of relinquishment in perpetuity of all present and future rights to
101this software under copyright law.
102THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
103IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
104FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
105AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
106ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
107WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
108------------------------------------------------------------------------------
109```
110*/
111#ifndef SINFL_H_INCLUDED
112#define SINFL_H_INCLUDED
113
114#ifdef __cplusplus
115extern "C" {
116#endif
117
118#define SINFL_PRE_TBL_SIZE 128
119#define SINFL_LIT_TBL_SIZE 1334
120#define SINFL_OFF_TBL_SIZE 402
121
122struct sinfl {
123 const unsigned char *bitptr;
124 const unsigned char *bitend; // @raysan5: added
125 unsigned long long bitbuf;
126 int bitcnt;
127
128 unsigned lits[SINFL_LIT_TBL_SIZE];
129 unsigned dsts[SINFL_OFF_TBL_SIZE];
130};
131extern int sinflate(void *out, int cap, const void *in, int size);
132extern int zsinflate(void *out, int cap, const void *in, int size);
133
134#ifdef __cplusplus
135}
136#endif
137
138#endif /* SINFL_H_INCLUDED */
139
140#ifdef SINFL_IMPLEMENTATION
141
142#include <string.h> /* memcpy, memset */
143#include <assert.h> /* assert */
144
145#if defined(__GNUC__) || defined(__clang__)
146#define sinfl_likely(x) __builtin_expect((x),1)
147#define sinfl_unlikely(x) __builtin_expect((x),0)
148#else
149#define sinfl_likely(x) (x)
150#define sinfl_unlikely(x) (x)
151#endif
152
153#ifndef SINFL_NO_SIMD
154#if defined(__x86_64__) || defined(_WIN32) || defined(_WIN64)
155 #include <emmintrin.h>
156 #define sinfl_char16 __m128i
157 #define sinfl_char16_ld(p) _mm_loadu_si128((const __m128i *)(void*)(p))
158 #define sinfl_char16_str(d,v) _mm_storeu_si128((__m128i*)(void*)(d), v)
159 #define sinfl_char16_char(c) _mm_set1_epi8(c)
160#elif defined(__arm__) || defined(__aarch64__)
161 #include <arm_neon.h>
162 #define sinfl_char16 uint8x16_t
163 #define sinfl_char16_ld(p) vld1q_u8((const unsigned char*)(p))
164 #define sinfl_char16_str(d,v) vst1q_u8((unsigned char*)(d), v)
165 #define sinfl_char16_char(c) vdupq_n_u8(c)
166#else
167 #define SINFL_NO_SIMD
168#endif
169#endif
170
171static int
172sinfl_bsr(unsigned n) {
173#if defined(_MSC_VER) && !defined(__llvm__) && !defined(__INTEL_COMPILER) // @raysan5, address PR #5367
174 unsigned long uln = 0;
175 _BitScanReverse(&uln, n);
176 return (int)(uln);
177#else // defined(__GNUC__) || defined(__clang__) || defined(__TINYC__)
178 return 31 - __builtin_clz(n);
179#endif
180}
181static unsigned long long
182sinfl_read64(const void *p) {
183 unsigned long long n;
184 memcpy(&n, p, 8);
185 return n;
186}
187static void
188sinfl_copy64(unsigned char **dst, unsigned char **src) {
189 //unsigned long long n;
190 //memcpy(&n, *src, 8);
191 //memcpy(*dst, &n, 8);
192 memcpy(*dst, *src, 8); // @raysan5
193 *dst += 8, *src += 8;
194}
195static unsigned char*
196sinfl_write64(unsigned char *dst, unsigned long long w) {
197 memcpy(dst, &w, 8);
198 return dst + 8;
199}
200#ifndef SINFL_NO_SIMD
201static unsigned char*
202sinfl_write128(unsigned char *dst, sinfl_char16 w) {
203 sinfl_char16_str(dst, w);
204 return dst + 8;
205}
206static void
207sinfl_copy128(unsigned char **dst, unsigned char **src) {
208 sinfl_char16 n = sinfl_char16_ld(*src);
209 sinfl_char16_str(*dst, n);
210 *dst += 16, *src += 16;
211}
212#endif
213static void
214sinfl_refill(struct sinfl *s) {
215 if (s->bitend - s->bitptr >= 8) {
216 // @raysan5: original code, only those 3 lines
217 s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt;
218 s->bitptr += (63 - s->bitcnt) >> 3;
219 s->bitcnt |= 56; /* bitcount in range [56,63] */
220 } else {
221 // @raysan5: added this case when bits remaining < 8
222 int bitswant = 63 - s->bitcnt;
223 int byteswant = bitswant >> 3;
224 int bytesuse = s->bitend - s->bitptr <= byteswant ? (int)(s->bitend - s->bitptr) : byteswant;
225 unsigned long long n = 0;
226 memcpy(&n, s->bitptr, bytesuse);
227 s->bitbuf |= n << s->bitcnt;
228 s->bitptr += bytesuse;
229 s->bitcnt += bytesuse << 3;
230 }
231}
232static int
233sinfl_peek(struct sinfl *s, int cnt) {
234 //assert(cnt >= 0 && cnt <= 56); // @raysan5: commented to avoid crash on decompression
235 //assert(cnt <= s->bitcnt);
236 return s->bitbuf & ((1ull << cnt) - 1);
237}
238static void
239sinfl_eat(struct sinfl *s, int cnt) {
240 //assert(cnt <= s->bitcnt); // @raysan5: commented
241 s->bitbuf >>= cnt;
242 s->bitcnt -= cnt;
243}
244static int
245sinfl__get(struct sinfl *s, int cnt) {
246 int res = sinfl_peek(s, cnt);
247 sinfl_eat(s, cnt);
248 return res;
249}
250static int
251sinfl_get(struct sinfl *s, int cnt) {
252 sinfl_refill(s);
253 return sinfl__get(s, cnt);
254}
255struct sinfl_gen {
256 int len;
257 int cnt;
258 int word;
259 short* sorted;
260};
261static int
262sinfl_build_tbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
263 const int *cnt) {
264 int tbl_end = 0;
265 while (!(gen->cnt = cnt[gen->len])) {
266 ++gen->len;
267 }
268 tbl_end = 1 << gen->len;
269 while (gen->len <= tbl_bits) {
270 do {unsigned bit = 0;
271 tbl[gen->word] = (*gen->sorted++ << 16) | gen->len;
272 if (gen->word == tbl_end - 1) {
273 for (; gen->len < tbl_bits; gen->len++) {
274 memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
275 tbl_end <<= 1;
276 }
277 return 1;
278 }
279 bit = 1 << sinfl_bsr((unsigned)(gen->word ^ (tbl_end - 1)));
280 gen->word &= bit - 1;
281 gen->word |= bit;
282 } while (--gen->cnt);
283 do {
284 if (++gen->len <= tbl_bits) {
285 memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0]));
286 tbl_end <<= 1;
287 }
288 } while (!(gen->cnt = cnt[gen->len]));
289 }
290 return 0;
291}
292static void
293sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
294 const int *cnt) {
295 int sub_bits = 0;
296 int sub_start = 0;
297 int sub_prefix = -1;
298 int tbl_end = 1 << tbl_bits;
299 while (1) {
300 unsigned entry;
301 int bit, stride, i;
302 /* start new sub-table */
303 if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) {
304 int used = 0;
305 sub_prefix = gen->word & ((1 << tbl_bits)-1);
306 sub_start = tbl_end;
307 sub_bits = gen->len - tbl_bits;
308 used = gen->cnt;
309 while (used < (1 << sub_bits)) {
310 sub_bits++;
311 used = (used << 1) + cnt[tbl_bits + sub_bits];
312 }
313 tbl_end = sub_start + (1 << sub_bits);
314 tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf);
315 }
316 /* fill sub-table */
317 entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf);
318 gen->sorted++;
319 i = sub_start + (gen->word >> tbl_bits);
320 stride = 1 << (gen->len - tbl_bits);
321 do {
322 tbl[i] = entry;
323 i += stride;
324 } while (i < tbl_end);
325 if (gen->word == (1 << gen->len)-1) {
326 return;
327 }
328 bit = 1 << sinfl_bsr(gen->word ^ ((1 << gen->len) - 1));
329 gen->word &= bit - 1;
330 gen->word |= bit;
331 gen->cnt--;
332 while (!gen->cnt) {
333 gen->cnt = cnt[++gen->len];
334 }
335 }
336}
337static void
338sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
339 int symcnt) {
340 int i, used = 0;
341 short sort[288];
342 int cnt[16] = {0}, off[16]= {0};
343 struct sinfl_gen gen = {0};
344 gen.sorted = sort;
345 gen.len = 1;
346
347 for (i = 0; i < symcnt; ++i)
348 cnt[lens[i]]++;
349 off[1] = cnt[0];
350 for (i = 1; i < maxlen; ++i) {
351 off[i + 1] = off[i] + cnt[i];
352 used = (used << 1) + cnt[i];
353 }
354 used = (used << 1) + cnt[i];
355 for (i = 0; i < symcnt; ++i)
356 gen.sorted[off[lens[i]]++] = (short)i;
357 gen.sorted += off[0];
358
359 if (used < (1 << maxlen)){
360 for (i = 0; i < 1 << tbl_bits; ++i)
361 tbl[i] = (0 << 16u) | 1;
362 return;
363 }
364 if (!sinfl_build_tbl(&gen, tbl, tbl_bits, cnt)){
365 sinfl_build_subtbl(&gen, tbl, tbl_bits, cnt);
366 }
367}
368static int
369sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) {
370 int idx = sinfl_peek(s, bit_len);
371 unsigned key = tbl[idx];
372 if (key & 0x10) {
373 /* sub-table lookup */
374 int len = key & 0x0f;
375 sinfl_eat(s, bit_len);
376 idx = sinfl_peek(s, len);
377 key = tbl[((key >> 16) & 0xffff) + (unsigned)idx];
378 }
379 sinfl_eat(s, key & 0x0f);
380 return (key >> 16) & 0x0fff;
381}
382static int
383sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) {
384 static const unsigned char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
385 static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,
386 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577};
387 static const unsigned char dbits[30+2] = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,
388 10,10,11,11,12,12,13,13,0,0};
389 static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,
390 43,51,59,67,83,99,115,131,163,195,227,258,0,0};
391 static const unsigned char lbits[29+2] = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,
392 4,4,4,5,5,5,5,0,0,0};
393
394 const unsigned char *oe = out + cap;
395 const unsigned char *e = in + size, *o = out;
396 enum sinfl_states {hdr,stored,fixed,dyn,blk};
397 enum sinfl_states state = hdr;
398 struct sinfl s = {0};
399 int last = 0;
400
401 s.bitptr = in;
402 s.bitend = e; // @raysan5: added
403 while (1) {
404 switch (state) {
405 case hdr: {
406 /* block header */
407 int type = 0;
408 sinfl_refill(&s);
409 last = sinfl__get(&s,1);
410 type = sinfl__get(&s,2);
411
412 switch (type) {default: return (int)(out-o);
413 case 0x00: state = stored; break;
414 case 0x01: state = fixed; break;
415 case 0x02: state = dyn; break;}
416 } break;
417 case stored: {
418 /* uncompressed block */
419 unsigned len, nlen;
420 sinfl__get(&s,s.bitcnt & 7);
421 len = (unsigned short)sinfl__get(&s,16);
422 nlen = (unsigned short)sinfl__get(&s,16);
423 s.bitptr -= s.bitcnt / 8;
424 s.bitbuf = s.bitcnt = 0;
425
426 if ((unsigned short)len != (unsigned short)~nlen)
427 return (int)(out-o);
428 if (len > (e - s.bitptr) || !len)
429 return (int)(out-o);
430
431 memcpy(out, s.bitptr, (size_t)len);
432 s.bitptr += len, out += len;
433 if (last) return (int)(out-o);
434 state = hdr;
435 } break;
436 case fixed: {
437 /* fixed huffman codes */
438 int n; unsigned char lens[288+32];
439 for (n = 0; n <= 143; n++) lens[n] = 8;
440 for (n = 144; n <= 255; n++) lens[n] = 9;
441 for (n = 256; n <= 279; n++) lens[n] = 7;
442 for (n = 280; n <= 287; n++) lens[n] = 8;
443 for (n = 0; n < 32; n++) lens[288+n] = 5;
444
445 /* build lit/dist tables */
446 sinfl_build(s.lits, lens, 10, 15, 288);
447 sinfl_build(s.dsts, lens + 288, 8, 15, 32);
448 state = blk;
449 } break;
450 case dyn: {
451 /* dynamic huffman codes */
452 int n, i;
453 unsigned hlens[SINFL_PRE_TBL_SIZE];
454 unsigned char nlens[19] = {0}, lens[288+32];
455
456 sinfl_refill(&s);
457 {int nlit = 257 + sinfl__get(&s,5);
458 int ndist = 1 + sinfl__get(&s,5);
459 int nlen = 4 + sinfl__get(&s,4);
460 for (n = 0; n < nlen; n++)
461 nlens[order[n]] = (unsigned char)sinfl_get(&s,3);
462 sinfl_build(hlens, nlens, 7, 7, 19);
463
464 /* decode code lengths */
465 for (n = 0; n < nlit + ndist;) {
466 int sym = 0;
467 sinfl_refill(&s);
468 sym = sinfl_decode(&s, hlens, 7);
469 switch (sym) {default: lens[n++] = (unsigned char)sym; break;
470 case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break;
471 case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break;
472 case 18: for (i=11+sinfl_get(&s,7);i;i--,n++) lens[n]=0; break;}
473 }
474 /* build lit/dist tables */
475 sinfl_build(s.lits, lens, 10, 15, nlit);
476 sinfl_build(s.dsts, lens + nlit, 8, 15, ndist);
477 state = blk;}
478 } break;
479 case blk: {
480 /* decompress block */
481 while (1) {
482 int sym;
483 sinfl_refill(&s);
484 sym = sinfl_decode(&s, s.lits, 10);
485 if (sym < 256) {
486 /* literal */
487 if (sinfl_unlikely(out >= oe)) {
488 return (int)(out-o);
489 }
490 *out++ = (unsigned char)sym;
491 sym = sinfl_decode(&s, s.lits, 10);
492 if (sym < 256) {
493 *out++ = (unsigned char)sym;
494 continue;
495 }
496 }
497 if (sinfl_unlikely(sym == 256)) {
498 /* end of block */
499 if (last) return (int)(out-o);
500 state = hdr;
501 break;
502 }
503 /* match */
504 if (sym >= 286) {
505 /* length codes 286 and 287 must not appear in compressed data */
506 return (int)(out-o);
507 }
508 sym -= 257;
509 {int len = sinfl__get(&s, lbits[sym]) + lbase[sym];
510 int dsym = sinfl_decode(&s, s.dsts, 8);
511 int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym];
512 unsigned char *dst = out, *src = out - offs;
513 if (sinfl_unlikely(offs > (int)(out-o))) {
514 return (int)(out-o);
515 }
516 out = out + len;
517
518#ifndef SINFL_NO_SIMD
519 if (sinfl_likely(oe - out >= 16 * 3)) {
520 if (offs >= 16) {
521 /* simd copy match */
522 sinfl_copy128(&dst, &src);
523 sinfl_copy128(&dst, &src);
524 do sinfl_copy128(&dst, &src);
525 while (dst < out);
526 } else if (offs >= 8) {
527 /* word copy match */
528 sinfl_copy64(&dst, &src);
529 sinfl_copy64(&dst, &src);
530 do sinfl_copy64(&dst, &src);
531 while (dst < out);
532 } else if (offs == 1) {
533 /* rle match copying */
534 sinfl_char16 w = sinfl_char16_char(src[0]);
535 dst = sinfl_write128(dst, w);
536 dst = sinfl_write128(dst, w);
537 do dst = sinfl_write128(dst, w);
538 while (dst < out);
539 } else {
540 /* byte copy match */
541 *dst++ = *src++;
542 *dst++ = *src++;
543 do *dst++ = *src++;
544 while (dst < out);
545 }
546 }
547#else
548 if (sinfl_likely(oe - out >= 3 * 8 - 3)) {
549 if (offs >= 8) {
550 /* word copy match */
551 sinfl_copy64(&dst, &src);
552 sinfl_copy64(&dst, &src);
553 do sinfl_copy64(&dst, &src);
554 while (dst < out);
555 } else if (offs == 1) {
556 /* rle match copying */
557 unsigned int c = src[0];
558 unsigned int hw = (c << 24u) | (c << 16u) | (c << 8u) | (unsigned)c;
559 unsigned long long w = (unsigned long long)hw << 32llu | hw;
560 dst = sinfl_write64(dst, w);
561 dst = sinfl_write64(dst, w);
562 do dst = sinfl_write64(dst, w);
563 while (dst < out);
564 } else {
565 /* byte copy match */
566 *dst++ = *src++;
567 *dst++ = *src++;
568 do *dst++ = *src++;
569 while (dst < out);
570 }
571 }
572#endif
573 else {
574 *dst++ = *src++;
575 *dst++ = *src++;
576 do *dst++ = *src++;
577 while (dst < out);
578 }}
579 }
580 } break;}
581 }
582 return (int)(out-o);
583}
584extern int
585sinflate(void *out, int cap, const void *in, int size) {
586 return sinfl_decompress((unsigned char*)out, cap, (const unsigned char*)in, size);
587}
588static unsigned
589sinfl_adler32(unsigned adler32, const unsigned char *in, int in_len) {
590 const unsigned ADLER_MOD = 65521;
591 unsigned s1 = adler32 & 0xffff;
592 unsigned s2 = adler32 >> 16;
593 unsigned blk_len, i;
594
595 blk_len = in_len % 5552;
596 while (in_len) {
597 for (i=0; i + 7 < blk_len; i += 8) {
598 s1 += in[0]; s2 += s1;
599 s1 += in[1]; s2 += s1;
600 s1 += in[2]; s2 += s1;
601 s1 += in[3]; s2 += s1;
602 s1 += in[4]; s2 += s1;
603 s1 += in[5]; s2 += s1;
604 s1 += in[6]; s2 += s1;
605 s1 += in[7]; s2 += s1;
606 in += 8;
607 }
608 for (; i < blk_len; ++i)
609 s1 += *in++, s2 += s1;
610 s1 %= ADLER_MOD; s2 %= ADLER_MOD;
611 in_len -= blk_len;
612 blk_len = 5552;
613 } return (unsigned)(s2 << 16) + (unsigned)s1;
614}
615extern int
616zsinflate(void *out, int cap, const void *mem, int size) {
617 const unsigned char *in = (const unsigned char*)mem;
618 if (size >= 6) {
619 const unsigned char *eob = in + size - 4;
620 int n = sinfl_decompress((unsigned char*)out, cap, in + 2u, size);
621 unsigned a = sinfl_adler32(1u, (unsigned char*)out, n);
622 unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0;
623 return a == h ? n : -1;
624 } else {
625 return -1;
626 }
627}
628#endif
629
630
Copyright 2026  E766CB298A6D1E64 | Git-Thing heavily inspired by cgit