@@ -10,7 +10,7 @@ as needed to keep the implementation as concise as possible.
10
10
- Dual license with either MIT or public domain
11
11
- Small implementation
12
12
- Deflate: 525 LoC
13
- - Inflate: 500 LoC
13
+ - Inflate: 320 LoC
14
14
- Webassembly:
15
15
- Deflate ~3.7 KB (~2.2KB compressed)
16
16
- Inflate ~3.6 KB (~2.2KB compressed)
@@ -39,10 +39,10 @@ this file implementation in *one* C or C++ file to prevent collisions.
39
39
| zlib 1.2.11 -1 | 72 MB/s | 307 MB/s | 42298774 | 42.30 |
40
40
| zlib 1.2.11 -6 | 24 MB/s | 313 MB/s | 36548921 | 36.55 |
41
41
| zlib 1.2.11 -9 | 20 MB/s | 314 MB/s | 36475792 | 36.48 |
42
- | sdefl 1.0 -0 | 127 MB/s | 355 MB/s | 40004116 | 39.88 |
43
- | sdefl 1.0 -1 | 111 MB/s | 413 MB/s | 38940674 | 38.82 |
44
- | sdefl 1.0 -5 | 45 MB/s | 436 MB/s | 36577183 | 36.46 |
45
- | sdefl 1.0 -7 | 38 MB/s | 432 MB/s | 36523781 | 36.41 |
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
46
| libdeflate 1.3 -1 | 147 MB/s | 667 MB/s | 39597378 | 39.60 |
47
47
| libdeflate 1.3 -6 | 69 MB/s | 689 MB/s | 36648318 | 36.65 |
48
48
| libdeflate 1.3 -9 | 13 MB/s | 672 MB/s | 35197141 | 35.20 |
@@ -51,20 +51,20 @@ this file implementation in *one* C or C++ file to prevent collisions.
51
51
### Compression
52
52
Results on the [Silesia compression corpus](http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia):
53
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 |
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
68
69
69
## License
70
70
```
@@ -151,7 +151,7 @@ extern int zsinflate(void *out, int cap, const void *in, int size);
151
151
#endif
152
152
153
153
#ifndef SINFL_NO_SIMD
154
- #if defined( __x86_64__ ) || defined(_WIN32 ) || defined(_WIN64 )
154
+ #if __x86_64__ || defined(_WIN32 ) || defined(_WIN64 )
155
155
#include <emmintrin.h>
156
156
#define sinfl_char16 __m128i
157
157
#define sinfl_char16_ld (p ) _mm_loadu_si128((const __m128i *)(void*)(p))
@@ -183,18 +183,6 @@ sinfl_read64(const void *p) {
183
183
memcpy (& n , p , 8 );
184
184
return n ;
185
185
}
186
- static void
187
- sinfl_copy64 (unsigned char * * dst , unsigned char * * src ) {
188
- unsigned long long n ;
189
- memcpy (& n , * src , 8 );
190
- memcpy (* dst , & n , 8 );
191
- * dst += 8 , * src += 8 ;
192
- }
193
- static unsigned char *
194
- sinfl_write64 (unsigned char * dst , unsigned long long w ) {
195
- memcpy (dst , & w , 8 );
196
- return dst + 8 ;
197
- }
198
186
#ifndef SINFL_NO_SIMD
199
187
static unsigned char *
200
188
sinfl_write128 (unsigned char * dst , sinfl_char16 w ) {
@@ -207,12 +195,25 @@ sinfl_copy128(unsigned char **dst, unsigned char **src) {
207
195
sinfl_char16_str (* dst , n );
208
196
* dst += 16 , * src += 16 ;
209
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
+ }
210
211
#endif
211
212
static void
212
213
sinfl_refill (struct sinfl * s ) {
213
214
s -> bitbuf |= sinfl_read64 (s -> bitptr ) << s -> bitcnt ;
214
215
s -> bitptr += (63 - s -> bitcnt ) >> 3 ;
215
- s -> bitcnt |= 56 ; /* bitcount in range [56,63] */
216
+ s -> bitcnt |= 56 ; /* bitcount is in range [56,63] */
216
217
}
217
218
static int
218
219
sinfl_peek (struct sinfl * s , int cnt ) {
@@ -221,15 +222,15 @@ sinfl_peek(struct sinfl *s, int cnt) {
221
222
return s -> bitbuf & ((1ull << cnt ) - 1 );
222
223
}
223
224
static void
224
- sinfl_eat (struct sinfl * s , int cnt ) {
225
+ sinfl_consume (struct sinfl * s , int cnt ) {
225
226
assert (cnt <= s -> bitcnt );
226
227
s -> bitbuf >>= cnt ;
227
228
s -> bitcnt -= cnt ;
228
229
}
229
230
static int
230
231
sinfl__get (struct sinfl * s , int cnt ) {
231
232
int res = sinfl_peek (s , cnt );
232
- sinfl_eat (s , cnt );
233
+ sinfl_consume (s , cnt );
233
234
return res ;
234
235
}
235
236
static int
@@ -284,7 +285,7 @@ sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
284
285
while (1 ) {
285
286
unsigned entry ;
286
287
int bit , stride , i ;
287
- /* start new sub-table */
288
+ /* start new subtable */
288
289
if ((gen -> word & ((1 << tbl_bits )- 1 )) != sub_prefix ) {
289
290
int used = 0 ;
290
291
sub_prefix = gen -> word & ((1 << tbl_bits )- 1 );
@@ -298,7 +299,7 @@ sinfl_build_subtbl(struct sinfl_gen *gen, unsigned *tbl, int tbl_bits,
298
299
tbl_end = sub_start + (1 << sub_bits );
299
300
tbl [sub_prefix ] = (sub_start << 16 ) | 0x10 | (sub_bits & 0xf );
300
301
}
301
- /* fill sub-table */
302
+ /* fill subtable */
302
303
entry = (* gen -> sorted << 16 ) | ((gen -> len - tbl_bits ) & 0xf );
303
304
gen -> sorted ++ ;
304
305
i = sub_start + (gen -> word >> tbl_bits );
@@ -352,17 +353,18 @@ sinfl_build(unsigned *tbl, unsigned char *lens, int tbl_bits, int maxlen,
352
353
}
353
354
static int
354
355
sinfl_decode (struct sinfl * s , const unsigned * tbl , int bit_len ) {
355
- int idx = sinfl_peek (s , bit_len );
356
+ sinfl_refill (s );
357
+ {int idx = sinfl_peek (s , bit_len );
356
358
unsigned key = tbl [idx ];
357
359
if (key & 0x10 ) {
358
360
/* sub-table lookup */
359
361
int len = key & 0x0f ;
360
- sinfl_eat (s , bit_len );
362
+ sinfl_consume (s , bit_len );
361
363
idx = sinfl_peek (s , len );
362
364
key = tbl [((key >> 16 ) & 0xffff ) + (unsigned )idx ];
363
365
}
364
- sinfl_eat (s , key & 0x0f );
365
- return (key >> 16 ) & 0x0fff ;
366
+ sinfl_consume (s , key & 0x0f );
367
+ return (key >> 16 ) & 0x0fff ;}
366
368
}
367
369
static int
368
370
sinfl_decompress (unsigned char * out , int cap , const unsigned char * in , int size ) {
@@ -400,11 +402,11 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
400
402
} break ;
401
403
case stored : {
402
404
/* uncompressed block */
403
- int len , nlen ;
405
+ int len ;
404
406
sinfl_refill (& s );
405
407
sinfl__get (& s ,s .bitcnt & 7 );
406
408
len = sinfl__get (& s ,16 );
407
- nlen = sinfl__get (& s ,16 );
409
+ //int nlen = sinfl__get(&s,16); // @raysan5: Unused variable?
408
410
in -= 2 ; s .bitcnt = 0 ;
409
411
410
412
if (len > (e - in ) || !len )
@@ -428,58 +430,40 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
428
430
state = blk ;
429
431
} break ;
430
432
case dyn : {
431
- /* dynamic huffman codes */
432
- int n , i ;
433
- unsigned hlens [SINFL_PRE_TBL_SIZE ];
434
- unsigned char nlens [19 ] = {0 }, lens [288 + 32 ];
433
+ /* dynamic huffman codes */
434
+ int n , i ;
435
+ unsigned hlens [SINFL_PRE_TBL_SIZE ];
436
+ unsigned char nlens [19 ] = {0 }, lens [288 + 32 ];
435
437
436
- sinfl_refill (& s );
437
- {int nlit = 257 + sinfl__get (& s ,5 );
438
- int ndist = 1 + sinfl__get (& s ,5 );
439
- int nlen = 4 + sinfl__get (& s ,4 );
440
- for (n = 0 ; n < nlen ; n ++ )
441
- nlens [order [n ]] = (unsigned char )sinfl_get (& s ,3 );
442
- sinfl_build (hlens , nlens , 7 , 7 , 19 );
443
-
444
- /* decode code lengths */
445
- for (n = 0 ; n < nlit + ndist ;) {
446
438
sinfl_refill (& s );
447
- int sym = sinfl_decode (& s , hlens , 7 );
448
- switch (sym ) {default : lens [n ++ ] = (unsigned char )sym ; break ;
449
- case 16 : for (i = 3 + sinfl_get (& s ,2 );i ;i -- ,n ++ ) lens [n ]= lens [n - 1 ]; break ;
450
- case 17 : for (i = 3 + sinfl_get (& s ,3 );i ;i -- ,n ++ ) lens [n ]= 0 ; break ;
451
- case 18 : for (i = 11 + sinfl_get (& s ,7 );i ;i -- ,n ++ ) lens [n ]= 0 ; break ;}
452
- }
453
- /* build lit/dist tables */
454
- sinfl_build (s .lits , lens , 10 , 15 , nlit );
455
- sinfl_build (s .dsts , lens + nlit , 8 , 15 , ndist );
456
- state = blk ;}
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 ;}
457
458
} break ;
458
459
case blk : {
459
460
/* decompress block */
460
- while (1 ) {
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 */
461
466
sinfl_refill (& s );
462
- int sym = sinfl_decode (& s , s .lits , 10 );
463
- if (sym < 256 ) {
464
- /* literal */
465
- if (sinfl_unlikely (out >= oe )) {
466
- return (int )(out - o );
467
- }
468
- * out ++ = (unsigned char )sym ;
469
- sym = sinfl_decode (& s , s .lits , 10 );
470
- if (sym < 256 ) {
471
- * out ++ = (unsigned char )sym ;
472
- continue ;
473
- }
474
- }
475
- if (sinfl_unlikely (sym == 256 )) {
476
- /* end of block */
477
- if (last ) return (int )(out - o );
478
- state = hdr ;
479
- break ;
480
- }
481
- /* match */
482
- sym -= 257 ;
483
467
{int len = sinfl__get (& s , lbits [sym ]) + lbase [sym ];
484
468
int dsym = sinfl_decode (& s , s .dsts , 8 );
485
469
int offs = sinfl__get (& s , dbits [dsym ]) + dbase [dsym ];
@@ -492,17 +476,11 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
492
476
#ifndef SINFL_NO_SIMD
493
477
if (sinfl_likely (oe - out >= 16 * 3 )) {
494
478
if (offs >= 16 ) {
495
- /* simd copy match */
479
+ /* copy match */
496
480
sinfl_copy128 (& dst , & src );
497
481
sinfl_copy128 (& dst , & src );
498
482
do sinfl_copy128 (& dst , & src );
499
483
while (dst < out );
500
- } else if (offs >= 8 ) {
501
- /* word copy match */
502
- sinfl_copy64 (& dst , & src );
503
- sinfl_copy64 (& dst , & src );
504
- do sinfl_copy64 (& dst , & src );
505
- while (dst < out );
506
484
} else if (offs == 1 ) {
507
485
/* rle match copying */
508
486
sinfl_char16 w = sinfl_char16_char (src [0 ]);
@@ -511,7 +489,6 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
511
489
do dst = sinfl_write128 (dst , w );
512
490
while (dst < out );
513
491
} else {
514
- /* byte copy match */
515
492
* dst ++ = * src ++ ;
516
493
* dst ++ = * src ++ ;
517
494
do * dst ++ = * src ++ ;
@@ -521,7 +498,7 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
521
498
#else
522
499
if (sinfl_likely (oe - out >= 3 * 8 - 3 )) {
523
500
if (offs >= 8 ) {
524
- /* word copy match */
501
+ /* copy match */
525
502
sinfl_copy64 (& dst , & src );
526
503
sinfl_copy64 (& dst , & src );
527
504
do sinfl_copy64 (& dst , & src );
@@ -536,7 +513,6 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
536
513
do dst = sinfl_write64 (dst , w );
537
514
while (dst < out );
538
515
} else {
539
- /* byte copy match */
540
516
* dst ++ = * src ++ ;
541
517
* dst ++ = * src ++ ;
542
518
do * dst ++ = * src ++ ;
@@ -548,8 +524,13 @@ sinfl_decompress(unsigned char *out, int cap, const unsigned char *in, int size)
548
524
* dst ++ = * src ++ ;
549
525
* dst ++ = * src ++ ;
550
526
do * dst ++ = * src ++ ;
551
- while (dst < out );
552
- }}
527
+ while (dst < out );}
528
+ }
529
+ } else {
530
+ /* end of block */
531
+ if (last ) return (int )(out - o );
532
+ state = hdr ;
533
+ break ;
553
534
}
554
535
} break ;}
555
536
}
0 commit comments