github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/sinfl.h (about) 1 /* 2 # Small Deflate 3 `sdefl` is a small bare bone lossless compression library in ANSI C (ISO C90) 4 which implements the Deflate (RFC 1951) compressed data format specification standard. 5 It is mainly tuned to get as much speed and compression ratio from as little code 6 as needed to keep the implementation as concise as possible. 7 8 ## Features 9 - Portable single header and source file duo written in ANSI C (ISO C90) 10 - Dual license with either MIT or public domain 11 - Small implementation 12 - Deflate: 525 LoC 13 - Inflate: 320 LoC 14 - Webassembly: 15 - Deflate ~3.7 KB (~2.2KB compressed) 16 - Inflate ~3.6 KB (~2.2KB compressed) 17 18 ## Usage: 19 This file behaves differently depending on what symbols you define 20 before including it. 21 22 Header-File mode: 23 If you do not define `SINFL_IMPLEMENTATION` before including this file, it 24 will operate in header only mode. In this mode it declares all used structs 25 and the API of the library without including the implementation of the library. 26 27 Implementation mode: 28 If you define `SINFL_IMPLEMENTATION` before including this file, it will 29 compile the implementation. Make sure that you only include 30 this file implementation in *one* C or C++ file to prevent collisions. 31 32 ### Benchmark 33 34 | Compressor name | Compression| Decompress.| Compr. size | Ratio | 35 | ------------------------| -----------| -----------| ----------- | ----- | 36 | miniz 1.0 -1 | 122 MB/s | 208 MB/s | 48510028 | 48.51 | 37 | miniz 1.0 -6 | 27 MB/s | 260 MB/s | 36513697 | 36.51 | 38 | miniz 1.0 -9 | 23 MB/s | 261 MB/s | 36460101 | 36.46 | 39 | zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 | 40 | zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 | 41 | zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 | 42 | sdefl 1.0 -0 | 127 MB/s | 371 MB/s | 40004116 | 39.88 | 43 | sdefl 1.0 -1 | 111 MB/s | 398 MB/s | 38940674 | 38.82 | 44 | sdefl 1.0 -5 | 45 MB/s | 420 MB/s | 36577183 | 36.46 | 45 | sdefl 1.0 -7 | 38 MB/s | 423 MB/s | 36523781 | 36.41 | 46 | libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 | 47 | libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 | 48 | libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 | 49 | libdeflate 1.3 -12 | 8.13 MB/s | 670 MB/s | 35100568 | 35.10 | 50 51 ### Compression 52 Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia): 53 54 | File | Original | `sdefl 0` | `sdefl 5` | `sdefl 7` | 55 | :------ | ---------: | -----------------: | ---------: | ----------: | 56 | dickens | 10.192.446 | 4,260,187| 3,845,261| 3,833,657 | 57 | mozilla | 51.220.480 | 20,774,706 | 19,607,009 | 19,565,867 | 58 | mr | 9.970.564 | 3,860,531 | 3,673,460 | 3,665,627 | 59 | nci | 33.553.445 | 4,030,283 | 3,094,526 | 3,006,075 | 60 | ooffice | 6.152.192 | 3,320,063 | 3,186,373 | 3,183,815 | 61 | osdb | 10.085.684 | 3,919,646 | 3,649,510 | 3,649,477 | 62 | reymont | 6.627.202 | 2,263,378 | 1,857,588 | 1,827,237 | 63 | samba | 21.606.400 | 6,121,797 | 5,462,670 | 5,450,762 | 64 | sao | 7.251.944 | 5,612,421 | 5,485,380 | 5,481,765 | 65 | webster | 41.458.703 | 13,972,648 | 12,059,432 | 11,991,421 | 66 | xml | 5.345.280 | 886,620| 674,009 | 662,141 | 67 | x-ray | 8.474.240 | 6,304,655 | 6,244,779 | 6,244,779 | 68 69 ## License 70 ``` 71 ------------------------------------------------------------------------------ 72 This software is available under 2 licenses -- choose whichever you prefer. 73 ------------------------------------------------------------------------------ 74 ALTERNATIVE A - MIT License 75 Copyright (c) 2020 Micha Mettke 76 Permission is hereby granted, free of charge, to any person obtaining a copy of 77 this software and associated documentation files (the "Software"), to deal in 78 the Software without restriction, including without limitation the rights to 79 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 80 of the Software, and to permit persons to whom the Software is furnished to do 81 so, subject to the following conditions: 82 The above copyright notice and this permission notice shall be included in all 83 copies or substantial portions of the Software. 84 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 85 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 86 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 87 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 88 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 89 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 90 SOFTWARE. 91 ------------------------------------------------------------------------------ 92 ALTERNATIVE B - Public Domain (www.unlicense.org) 93 This is free and unencumbered software released into the public domain. 94 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this 95 software, either in source code form or as a compiled binary, for any purpose, 96 commercial or non-commercial, and by any means. 97 In jurisdictions that recognize copyright laws, the author or authors of this 98 software dedicate any and all copyright interest in the software to the public 99 domain. We make this dedication for the benefit of the public at large and to 100 the detriment of our heirs and successors. We intend this dedication to be an 101 overt act of relinquishment in perpetuity of all present and future rights to 102 this software under copyright law. 103 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 104 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 105 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 106 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 107 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 108 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 109 ------------------------------------------------------------------------------ 110 ``` 111 */ 112 #ifndef SINFL_H_INCLUDED 113 #define SINFL_H_INCLUDED 114 115 #ifdef __cplusplus 116 extern "C" { 117 #endif 118 119 #define SINFL_PRE_TBL_SIZE 128 120 #define SINFL_LIT_TBL_SIZE 1334 121 #define SINFL_OFF_TBL_SIZE 402 122 123 struct sinfl { 124 const unsigned char *bitptr; 125 unsigned long long bitbuf; 126 int bitcnt; 127 128 unsigned lits[SINFL_LIT_TBL_SIZE]; 129 unsigned dsts[SINFL_OFF_TBL_SIZE]; 130 }; 131 extern int sinflate(void *out, int cap, const void *in, int size); 132 extern 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 __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 171 static int 172 sinfl_bsr(unsigned n) { 173 #ifdef _MSC_VER 174 _BitScanReverse(&n, n); 175 return n; 176 #elif defined(__GNUC__) || defined(__clang__) 177 return 31 - __builtin_clz(n); 178 #endif 179 } 180 static unsigned long long 181 sinfl_read64(const void *p) { 182 unsigned long long n; 183 memcpy(&n, p, 8); 184 return n; 185 } 186 #ifndef SINFL_NO_SIMD 187 static unsigned char* 188 sinfl_write128(unsigned char *dst, sinfl_char16 w) { 189 sinfl_char16_str(dst, w); 190 return dst + 8; 191 } 192 static void 193 sinfl_copy128(unsigned char **dst, unsigned char **src) { 194 sinfl_char16 n = sinfl_char16_ld(*src); 195 sinfl_char16_str(*dst, n); 196 *dst += 16, *src += 16; 197 } 198 #else 199 static unsigned char* 200 sinfl_write64(unsigned char *dst, unsigned long long w) { 201 memcpy(dst, &w, 8); 202 return dst + 8; 203 } 204 static void 205 sinfl_copy64(unsigned char **dst, unsigned char **src) { 206 unsigned long long n; 207 memcpy(&n, *src, 8); 208 memcpy(*dst, &n, 8); 209 *dst += 8, *src += 8; 210 } 211 #endif 212 static void 213 sinfl_refill(struct sinfl *s) { 214 s->bitbuf |= sinfl_read64(s->bitptr) << s->bitcnt; 215 s->bitptr += (63 - s->bitcnt) >> 3; 216 s->bitcnt |= 56; /* bitcount is in range [56,63] */ 217 } 218 static int 219 sinfl_peek(struct sinfl *s, int cnt) { 220 assert(cnt >= 0 && cnt <= 56); 221 assert(cnt <= s->bitcnt); 222 return s->bitbuf & ((1ull << cnt) - 1); 223 } 224 static void 225 sinfl_consume(struct sinfl *s, int cnt) { 226 assert(cnt <= s->bitcnt); 227 s->bitbuf >>= cnt; 228 s->bitcnt -= cnt; 229 } 230 static int 231 sinfl__get(struct sinfl *s, int cnt) { 232 int res = sinfl_peek(s, cnt); 233 sinfl_consume(s, cnt); 234 return res; 235 } 236 static int 237 sinfl_get(struct sinfl *s, int cnt) { 238 sinfl_refill(s); 239 return sinfl__get(s, cnt); 240 } 241 struct sinfl_gen { 242 int len; 243 int cnt; 244 int word; 245 short* sorted; 246 }; 247 static int 248 sinfl_build_tbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits, 249 const int *cnt) { 250 int tbl_end = 0; 251 while (!(gen->cnt = cnt[gen->len])) { 252 ++gen->len; 253 } 254 tbl_end = 1 << gen->len; 255 while (gen->len <= tbl_bits) { 256 do {unsigned bit = 0; 257 tbl[gen->word] = (*gen->sorted++ << 16) | gen->len; 258 if (gen->word == tbl_end - 1) { 259 for (; gen->len < tbl_bits; gen->len++) { 260 memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0])); 261 tbl_end <<= 1; 262 } 263 return 1; 264 } 265 bit = 1 << sinfl_bsr((unsigned)(gen->word ^ (tbl_end - 1))); 266 gen->word &= bit - 1; 267 gen->word |= bit; 268 } while (--gen->cnt); 269 do { 270 if (++gen->len <= tbl_bits) { 271 memcpy(&tbl[tbl_end], tbl, (size_t)tbl_end * sizeof(tbl[0])); 272 tbl_end <<= 1; 273 } 274 } while (!(gen->cnt = cnt[gen->len])); 275 } 276 return 0; 277 } 278 static void 279 sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits, 280 const int *cnt) { 281 int sub_bits = 0; 282 int sub_start = 0; 283 int sub_prefix = -1; 284 int tbl_end = 1 << tbl_bits; 285 while (1) { 286 unsigned entry; 287 int bit, stride, i; 288 /* start new subtable */ 289 if ((gen->word & ((1 << tbl_bits)-1)) != sub_prefix) { 290 int used = 0; 291 sub_prefix = gen->word & ((1 << tbl_bits)-1); 292 sub_start = tbl_end; 293 sub_bits = gen->len - tbl_bits; 294 used = gen->cnt; 295 while (used < (1 << sub_bits)) { 296 sub_bits++; 297 used = (used << 1) + cnt[tbl_bits + sub_bits]; 298 } 299 tbl_end = sub_start + (1 << sub_bits); 300 tbl[sub_prefix] = (sub_start << 16) | 0x10 | (sub_bits & 0xf); 301 } 302 /* fill subtable */ 303 entry = (*gen->sorted << 16) | ((gen->len - tbl_bits) & 0xf); 304 gen->sorted++; 305 i = sub_start + (gen->word >> tbl_bits); 306 stride = 1 << (gen->len - tbl_bits); 307 do { 308 tbl[i] = entry; 309 i += stride; 310 } while (i < tbl_end); 311 if (gen->word == (1 << gen->len)-1) { 312 return; 313 } 314 bit = 1 << sinfl_bsr(gen->word ^ ((1 << gen->len) - 1)); 315 gen->word &= bit - 1; 316 gen->word |= bit; 317 gen->cnt--; 318 while (!gen->cnt) { 319 gen->cnt = cnt[++gen->len]; 320 } 321 } 322 } 323 static void 324 sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen, 325 int symcnt) { 326 int i, used = 0; 327 short sort[288]; 328 int cnt[16] = {0}, off[16]= {0}; 329 struct sinfl_gen gen = {0}; 330 gen.sorted = sort; 331 gen.len = 1; 332 333 for (i = 0; i < symcnt; ++i) 334 cnt[lens[i]]++; 335 off[1] = cnt[0]; 336 for (i = 1; i < maxlen; ++i) { 337 off[i + 1] = off[i] + cnt[i]; 338 used = (used << 1) + cnt[i]; 339 } 340 used = (used << 1) + cnt[i]; 341 for (i = 0; i < symcnt; ++i) 342 gen.sorted[off[lens[i]]++] = (short)i; 343 gen.sorted += off[0]; 344 345 if (used < (1 << maxlen)){ 346 for (i = 0; i < 1 << tbl_bits; ++i) 347 tbl[i] = (0 << 16u) | 1; 348 return; 349 } 350 if (!sinfl_build_tbl(&gen, tbl, tbl_bits, cnt)){ 351 sinfl_build_subtbl(&gen, tbl, tbl_bits, cnt); 352 } 353 } 354 static int 355 sinfl_decode(struct sinfl *s, const unsigned *tbl, int bit_len) { 356 sinfl_refill(s); 357 {int idx = sinfl_peek(s, bit_len); 358 unsigned key = tbl[idx]; 359 if (key & 0x10) { 360 /* sub-table lookup */ 361 int len = key & 0x0f; 362 sinfl_consume(s, bit_len); 363 idx = sinfl_peek(s, len); 364 key = tbl[((key >> 16) & 0xffff) + (unsigned)idx]; 365 } 366 sinfl_consume(s, key & 0x0f); 367 return (key >> 16) & 0x0fff;} 368 } 369 static int 370 sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size) { 371 static const unsigned char order[] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; 372 static const short dbase[30+2] = {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 373 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577}; 374 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, 375 10,10,11,11,12,12,13,13,0,0}; 376 static const short lbase[29+2] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35, 377 43,51,59,67,83,99,115,131,163,195,227,258,0,0}; 378 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, 379 4,4,4,5,5,5,5,0,0,0}; 380 381 const unsigned char *oe = out + cap; 382 const unsigned char *e = in + size, *o = out; 383 enum sinfl_states {hdr,stored,fixed,dyn,blk}; 384 enum sinfl_states state = hdr; 385 struct sinfl s = {0}; 386 int last = 0; 387 388 s.bitptr = in; 389 while (1) { 390 switch (state) { 391 case hdr: { 392 /* block header */ 393 int type = 0; 394 sinfl_refill(&s); 395 last = sinfl__get(&s,1); 396 type = sinfl__get(&s,2); 397 398 switch (type) {default: return (int)(out-o); 399 case 0x00: state = stored; break; 400 case 0x01: state = fixed; break; 401 case 0x02: state = dyn; break;} 402 } break; 403 case stored: { 404 /* uncompressed block */ 405 int len; 406 sinfl_refill(&s); 407 sinfl__get(&s,s.bitcnt & 7); 408 len = sinfl__get(&s,16); 409 //int nlen = sinfl__get(&s,16); // @raysan5: Unused variable? 410 in -= 2; s.bitcnt = 0; 411 412 if (len > (e-in) || !len) 413 return (int)(out-o); 414 memcpy(out, in, (size_t)len); 415 in += len, out += len; 416 state = hdr; 417 } break; 418 case fixed: { 419 /* fixed huffman codes */ 420 int n; unsigned char lens[288+32]; 421 for (n = 0; n <= 143; n++) lens[n] = 8; 422 for (n = 144; n <= 255; n++) lens[n] = 9; 423 for (n = 256; n <= 279; n++) lens[n] = 7; 424 for (n = 280; n <= 287; n++) lens[n] = 8; 425 for (n = 0; n < 32; n++) lens[288+n] = 5; 426 427 /* build lit/dist tables */ 428 sinfl_build(s.lits, lens, 10, 15, 288); 429 sinfl_build(s.dsts, lens + 288, 8, 15, 32); 430 state = blk; 431 } break; 432 case dyn: { 433 /* dynamic huffman codes */ 434 int n, i; 435 unsigned hlens[SINFL_PRE_TBL_SIZE]; 436 unsigned char nlens[19] = {0}, lens[288+32]; 437 438 sinfl_refill(&s); 439 {int nlit = 257 + sinfl__get(&s,5); 440 int ndist = 1 + sinfl__get(&s,5); 441 int nlen = 4 + sinfl__get(&s,4); 442 for (n = 0; n < nlen; n++) 443 nlens[order[n]] = (unsigned char)sinfl_get(&s,3); 444 sinfl_build(hlens, nlens, 7, 7, 19); 445 446 /* decode code lengths */ 447 for (n = 0; n < nlit + ndist;) { 448 int sym = sinfl_decode(&s, hlens, 7); 449 switch (sym) {default: lens[n++] = (unsigned char)sym; break; 450 case 16: for (i=3+sinfl_get(&s,2);i;i--,n++) lens[n]=lens[n-1]; break; 451 case 17: for (i=3+sinfl_get(&s,3);i;i--,n++) lens[n]=0; break; 452 case 18: for (i=11+sinfl_get(&s,7);i;i--,n++) lens[n]=0; break;} 453 } 454 /* build lit/dist tables */ 455 sinfl_build(s.lits, lens, 10, 15, nlit); 456 sinfl_build(s.dsts, lens + nlit, 8, 15, ndist); 457 state = blk;} 458 } break; 459 case blk: { 460 /* decompress block */ 461 int sym = sinfl_decode(&s, s.lits, 10); 462 if (sym < 256) { 463 /* literal */ 464 *out++ = (unsigned char)sym; 465 } else if (sym > 256) {sym -= 257; /* match symbol */ 466 sinfl_refill(&s); 467 {int len = sinfl__get(&s, lbits[sym]) + lbase[sym]; 468 int dsym = sinfl_decode(&s, s.dsts, 8); 469 int offs = sinfl__get(&s, dbits[dsym]) + dbase[dsym]; 470 unsigned char *dst = out, *src = out - offs; 471 if (sinfl_unlikely(offs > (int)(out-o))) { 472 return (int)(out-o); 473 } 474 out = out + len; 475 476 #ifndef SINFL_NO_SIMD 477 if (sinfl_likely(oe - out >= 16 * 3)) { 478 if (offs >= 16) { 479 /* copy match */ 480 sinfl_copy128(&dst, &src); 481 sinfl_copy128(&dst, &src); 482 do sinfl_copy128(&dst, &src); 483 while (dst < out); 484 } else if (offs == 1) { 485 /* rle match copying */ 486 sinfl_char16 w = sinfl_char16_char(src[0]); 487 dst = sinfl_write128(dst, w); 488 dst = sinfl_write128(dst, w); 489 do dst = sinfl_write128(dst, w); 490 while (dst < out); 491 } else { 492 *dst++ = *src++; 493 *dst++ = *src++; 494 do *dst++ = *src++; 495 while (dst < out); 496 } 497 } 498 #else 499 if (sinfl_likely(oe - out >= 3 * 8 - 3)) { 500 if (offs >= 8) { 501 /* copy match */ 502 sinfl_copy64(&dst, &src); 503 sinfl_copy64(&dst, &src); 504 do sinfl_copy64(&dst, &src); 505 while (dst < out); 506 } else if (offs == 1) { 507 /* rle match copying */ 508 unsigned int c = src[0]; 509 unsigned int hw = (c << 24u) | (c << 16u) | (c << 8u) | (unsigned)c; 510 unsigned long long w = (unsigned long long)hw << 32llu | hw; 511 dst = sinfl_write64(dst, w); 512 dst = sinfl_write64(dst, w); 513 do dst = sinfl_write64(dst, w); 514 while (dst < out); 515 } else { 516 *dst++ = *src++; 517 *dst++ = *src++; 518 do *dst++ = *src++; 519 while (dst < out); 520 } 521 } 522 #endif 523 else { 524 *dst++ = *src++; 525 *dst++ = *src++; 526 do *dst++ = *src++; 527 while (dst < out);} 528 } 529 } else { 530 /* end of block */ 531 if (last) return (int)(out-o); 532 state = hdr; 533 break; 534 } 535 } break;} 536 } 537 return (int)(out-o); 538 } 539 extern int 540 sinflate(void *out, int cap, const void *in, int size) { 541 return sinfl_decompress((unsigned char*)out, cap, (const unsigned char*)in, size); 542 } 543 static unsigned 544 sinfl_adler32(unsigned adler32, const unsigned char *in, int in_len) { 545 const unsigned ADLER_MOD = 65521; 546 unsigned s1 = adler32 & 0xffff; 547 unsigned s2 = adler32 >> 16; 548 unsigned blk_len, i; 549 550 blk_len = in_len % 5552; 551 while (in_len) { 552 for (i=0; i + 7 < blk_len; i += 8) { 553 s1 += in[0]; s2 += s1; 554 s1 += in[1]; s2 += s1; 555 s1 += in[2]; s2 += s1; 556 s1 += in[3]; s2 += s1; 557 s1 += in[4]; s2 += s1; 558 s1 += in[5]; s2 += s1; 559 s1 += in[6]; s2 += s1; 560 s1 += in[7]; s2 += s1; 561 in += 8; 562 } 563 for (; i < blk_len; ++i) 564 s1 += *in++, s2 += s1; 565 s1 %= ADLER_MOD; s2 %= ADLER_MOD; 566 in_len -= blk_len; 567 blk_len = 5552; 568 } return (unsigned)(s2 << 16) + (unsigned)s1; 569 } 570 extern int 571 zsinflate(void *out, int cap, const void *mem, int size) { 572 const unsigned char *in = (const unsigned char*)mem; 573 if (size >= 6) { 574 const unsigned char *eob = in + size - 4; 575 int n = sinfl_decompress((unsigned char*)out, cap, in + 2u, size); 576 unsigned a = sinfl_adler32(1u, (unsigned char*)out, n); 577 unsigned h = eob[0] << 24 | eob[1] << 16 | eob[2] << 8 | eob[3] << 0; 578 return a == h ? n : -1; 579 } else { 580 return -1; 581 } 582 } 583 #endif 584