forked from madler/zlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
deflate.c
1436 lines (1278 loc) · 53.6 KB
/
deflate.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* deflate.c -- compress data using the deflation algorithm
* Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
* ALGORITHM
*
* The "deflation" process depends on being able to identify portions
* of the input text which are identical to earlier input (within a
* sliding window trailing behind the input currently being processed).
*
* The most straightforward technique turns out to be the fastest for
* most input files: try all possible matches and select the longest.
* The key feature of this algorithm is that insertions into the string
* dictionary are very simple and thus fast, and deletions are avoided
* completely. Insertions are performed at each input character, whereas
* string matches are performed only when the previous match ends. So it
* is preferable to spend more time in matches to allow very fast string
* insertions and avoid deletions. The matching algorithm for small
* strings is inspired from that of Rabin & Karp. A brute force approach
* is used to find longer strings when a small match has been found.
* A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
* (by Leonid Broukhis).
* A previous version of this file used a more sophisticated algorithm
* (by Fiala and Greene) which is guaranteed to run in linear amortized
* time, but has a larger average cost, uses more memory and is patented.
* However the F&G algorithm may be faster for some highly redundant
* files if the parameter max_chain_length (described below) is too large.
*
* ACKNOWLEDGEMENTS
*
* The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
* I found it in 'freeze' written by Leonid Broukhis.
* Thanks to many people for bug reports and testing.
*
* REFERENCES
*
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
* Available in https://tools.ietf.org/html/rfc1951
*
* A description of the Rabin and Karp algorithm is given in the book
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
*
* Fiala,E.R., and Greene,D.H.
* Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
*
*/
#include "zbuild.h"
#include "zutil.h"
#include "cpu_features.h"
#include "deflate.h"
#include "deflate_p.h"
#include "functable.h"
/* Avoid conflicts with zlib.h macros */
#ifdef ZLIB_COMPAT
# undef deflateInit
# undef deflateInit2
#endif
#undef zng_deflateInit
#undef zng_deflateInit2
const char PREFIX(deflate_copyright)[] = " deflate 1.2.12.1.f Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler ";
/*
If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot
include such an acknowledgment, I would appreciate that you keep this
copyright string in the executable of your product.
*/
/* ===========================================================================
* Architecture-specific hooks.
*/
#ifdef S390_DFLTCC_DEFLATE
# include "arch/s390/dfltcc_deflate.h"
#else
/* Memory management for the deflate state. Useful for allocating arch-specific extension blocks. */
# define ZALLOC_DEFLATE_STATE(strm) ((deflate_state *)ZALLOC(strm, 1, sizeof(deflate_state)))
# define ZFREE_STATE(strm, addr) ZFREE(strm, addr)
# define ZCOPY_DEFLATE_STATE(dst, src) memcpy(dst, src, sizeof(deflate_state))
/* Memory management for the window. Useful for allocation the aligned window. */
# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size)
# define TRY_FREE_WINDOW(strm, addr) TRY_FREE(strm, addr)
/* Invoked at the beginning of deflateSetDictionary(). Useful for checking arch-specific window data. */
# define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
/* Invoked at the beginning of deflateGetDictionary(). Useful for adjusting arch-specific window data. */
# define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
/* Invoked at the end of deflateResetKeep(). Useful for initializing arch-specific extension blocks. */
# define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
/* Invoked at the beginning of deflateParams(). Useful for updating arch-specific compression parameters. */
# define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0)
/* Returns whether the last deflate(flush) operation did everything it's supposed to do. */
# define DEFLATE_DONE(strm, flush) 1
/* Adjusts the upper bound on compressed data length based on compression parameters and uncompressed data length.
* Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */
# define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0)
/* Returns whether an optimistic upper bound on compressed data length should *not* be used.
* Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */
# define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0
/* Invoked for each deflate() call. Useful for plugging arch-specific deflation code. */
# define DEFLATE_HOOK(strm, flush, bstate) 0
/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific deflation code already does that. */
# define DEFLATE_NEED_CHECKSUM(strm) 1
/* Returns whether reproducibility parameter can be set to a given value. */
# define DEFLATE_CAN_SET_REPRODUCIBLE(strm, reproducible) 1
#endif
/* ===========================================================================
* Function prototypes.
*/
static int deflateStateCheck (PREFIX3(stream) *strm);
Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush);
Z_INTERNAL block_state deflate_fast (deflate_state *s, int flush);
Z_INTERNAL block_state deflate_quick (deflate_state *s, int flush);
#ifndef NO_MEDIUM_STRATEGY
Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush);
#endif
Z_INTERNAL block_state deflate_slow (deflate_state *s, int flush);
Z_INTERNAL block_state deflate_rle (deflate_state *s, int flush);
Z_INTERNAL block_state deflate_huff (deflate_state *s, int flush);
static void lm_set_level (deflate_state *s, int level);
static void lm_init (deflate_state *s);
Z_INTERNAL unsigned read_buf (PREFIX3(stream) *strm, unsigned char *buf, unsigned size);
extern uint32_t update_hash_roll (deflate_state *const s, uint32_t h, uint32_t val);
extern void insert_string_roll (deflate_state *const s, uint32_t str, uint32_t count);
extern Pos quick_insert_string_roll(deflate_state *const s, uint32_t str);
/* ===========================================================================
* Local data
*/
/* Values for max_lazy_match, good_match and max_chain_length, depending on
* the desired pack level (0..9). The values given below have been tuned to
* exclude worst case performance for pathological files. Better values may be
* found for specific files.
*/
typedef struct config_s {
uint16_t good_length; /* reduce lazy search above this match length */
uint16_t max_lazy; /* do not perform lazy search above this match length */
uint16_t nice_length; /* quit search above this match length */
uint16_t max_chain;
compress_func func;
} config;
static const config configuration_table[10] = {
/* good lazy nice chain */
/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
#ifdef NO_QUICK_STRATEGY
/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
/* 2 */ {4, 5, 16, 8, deflate_fast},
#else
/* 1 */ {0, 0, 0, 0, deflate_quick},
/* 2 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
#endif
#ifdef NO_MEDIUM_STRATEGY
/* 3 */ {4, 6, 32, 32, deflate_fast},
/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
/* 5 */ {8, 16, 32, 32, deflate_slow},
/* 6 */ {8, 16, 128, 128, deflate_slow},
#else
/* 3 */ {4, 6, 16, 6, deflate_medium},
/* 4 */ {4, 12, 32, 24, deflate_medium}, /* lazy matches */
/* 5 */ {8, 16, 32, 32, deflate_medium},
/* 6 */ {8, 16, 128, 128, deflate_medium},
#endif
/* 7 */ {8, 32, 128, 256, deflate_slow},
/* 8 */ {32, 128, 258, 1024, deflate_slow},
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
/* Note: the deflate() code requires max_lazy >= STD_MIN_MATCH and max_chain >= 4
* For deflate_fast() (levels <= 3) good is ignored and lazy has a different
* meaning.
*/
/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
/* ===========================================================================
* Initialize the hash table. prev[] will be initialized on the fly.
*/
#define CLEAR_HASH(s) do { \
memset((unsigned char *)s->head, 0, HASH_SIZE * sizeof(*s->head)); \
} while (0)
/* ========================================================================= */
/* This function is hidden in ZLIB_COMPAT builds. */
int32_t ZNG_CONDEXPORT PREFIX(deflateInit2)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits,
int32_t memLevel, int32_t strategy) {
/* Todo: ignore strm->next_in if we use it as window */
uint32_t window_padding = 0;
deflate_state *s;
int wrap = 1;
cpu_check_features();
if (strm == NULL)
return Z_STREAM_ERROR;
strm->msg = NULL;
if (strm->zalloc == NULL) {
strm->zalloc = zng_calloc;
strm->opaque = NULL;
}
if (strm->zfree == NULL)
strm->zfree = zng_cfree;
if (level == Z_DEFAULT_COMPRESSION)
level = 6;
if (windowBits < 0) { /* suppress zlib wrapper */
wrap = 0;
if (windowBits < -15)
return Z_STREAM_ERROR;
windowBits = -windowBits;
#ifdef GZIP
} else if (windowBits > 15) {
wrap = 2; /* write gzip wrapper instead */
windowBits -= 16;
#endif
}
if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 ||
windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED ||
(windowBits == 8 && wrap != 1)) {
return Z_STREAM_ERROR;
}
if (windowBits == 8)
windowBits = 9; /* until 256-byte window bug fixed */
s = ZALLOC_DEFLATE_STATE(strm);
if (s == NULL)
return Z_MEM_ERROR;
memset(s, 0, sizeof(*s));
strm->state = (struct internal_state *)s;
s->strm = strm;
s->status = INIT_STATE; /* to pass state test in deflateReset() */
s->wrap = wrap;
s->gzhead = NULL;
s->w_bits = (unsigned int)windowBits;
s->w_size = 1 << s->w_bits;
s->w_mask = s->w_size - 1;
#ifdef X86_PCLMULQDQ_CRC
window_padding = 8;
#endif
/* Avoid use of unitialized values in the window, see crbug.com/1137613 and
* crbug.com/1144420 */
s->window = (unsigned char *) ZALLOC_WINDOW(strm, s->w_size + window_padding, 2*sizeof(unsigned char));
s->prev = (Pos *) ZALLOC(strm, s->w_size, sizeof(Pos));
/* Avoid use of uninitialized value, see:
* https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11360
*/
memset(s->prev, 0, s->w_size * sizeof(Pos));
s->head = (Pos *) ZALLOC(strm, HASH_SIZE, sizeof(Pos));
s->high_water = 0; /* nothing written to s->window yet */
s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
/* We overlay pending_buf and sym_buf. This works since the average size
* for length/distance pairs over any compressed block is assured to be 31
* bits or less.
*
* Analysis: The longest fixed codes are a length code of 8 bits plus 5
* extra bits, for lengths 131 to 257. The longest fixed distance codes are
* 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
* possible fixed-codes length/distance pair is then 31 bits total.
*
* sym_buf starts one-fourth of the way into pending_buf. So there are
* three bytes in sym_buf for every four bytes in pending_buf. Each symbol
* in sym_buf is three bytes -- two for the distance and one for the
* literal/length. As each symbol is consumed, the pointer to the next
* sym_buf value to read moves forward three bytes. From that symbol, up to
* 31 bits are written to pending_buf. The closest the written pending_buf
* bits gets to the next sym_buf symbol to read is just before the last
* code is written. At that time, 31*(n-2) bits have been written, just
* after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
* 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
* symbols are written.) The closest the writing gets to what is unread is
* then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
* can range from 128 to 32768.
*
* Therefore, at a minimum, there are 142 bits of space between what is
* written and what is read in the overlain buffers, so the symbols cannot
* be overwritten by the compressed data. That space is actually 139 bits,
* due to the three-bit fixed-code block header.
*
* That covers the case where either Z_FIXED is specified, forcing fixed
* codes, or when the use of fixed codes is chosen, because that choice
* results in a smaller compressed block than dynamic codes. That latter
* condition then assures that the above analysis also covers all dynamic
* blocks. A dynamic-code block will only be chosen to be emitted if it has
* fewer bits than a fixed-code block would for the same set of symbols.
* Therefore its average symbol length is assured to be less than 31. So
* the compressed data for a dynamic block also cannot overwrite the
* symbols from which it is being constructed.
*/
s->pending_buf = (unsigned char *) ZALLOC(strm, s->lit_bufsize, 4);
s->pending_buf_size = s->lit_bufsize * 4;
if (s->window == NULL || s->prev == NULL || s->head == NULL || s->pending_buf == NULL) {
s->status = FINISH_STATE;
strm->msg = ERR_MSG(Z_MEM_ERROR);
PREFIX(deflateEnd)(strm);
return Z_MEM_ERROR;
}
s->sym_buf = s->pending_buf + s->lit_bufsize;
s->sym_end = (s->lit_bufsize - 1) * 3;
/* We avoid equality with lit_bufsize*3 because of wraparound at 64K
* on 16 bit machines and because stored blocks are restricted to
* 64K-1 bytes.
*/
s->level = level;
s->strategy = strategy;
s->block_open = 0;
s->reproducible = 0;
return PREFIX(deflateReset)(strm);
}
#ifndef ZLIB_COMPAT
int32_t Z_EXPORT PREFIX(deflateInit)(PREFIX3(stream) *strm, int32_t level) {
return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
}
#endif
/* Function used by zlib.h and zlib-ng version 2.0 macros */
int32_t Z_EXPORT PREFIX(deflateInit_)(PREFIX3(stream) *strm, int32_t level, const char *version, int32_t stream_size) {
if (CHECK_VER_STSIZE(version, stream_size))
return Z_VERSION_ERROR;
return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
}
/* Function used by zlib.h and zlib-ng version 2.0 macros */
int32_t Z_EXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits,
int32_t memLevel, int32_t strategy, const char *version, int32_t stream_size) {
if (CHECK_VER_STSIZE(version, stream_size))
return Z_VERSION_ERROR;
return PREFIX(deflateInit2)(strm, level, method, windowBits, memLevel, strategy);
}
/* =========================================================================
* Check for a valid deflate stream state. Return 0 if ok, 1 if not.
*/
static int deflateStateCheck (PREFIX3(stream) *strm) {
deflate_state *s;
if (strm == NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
return 1;
s = strm->state;
if (s == NULL || s->strm != strm || (s->status != INIT_STATE &&
#ifdef GZIP
s->status != GZIP_STATE &&
s->status != EXTRA_STATE &&
s->status != NAME_STATE &&
s->status != COMMENT_STATE &&
s->status != HCRC_STATE &&
#endif
s->status != BUSY_STATE &&
s->status != FINISH_STATE))
return 1;
return 0;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) {
deflate_state *s;
unsigned int str, n;
int wrap;
uint32_t avail;
const unsigned char *next;
if (deflateStateCheck(strm) || dictionary == NULL)
return Z_STREAM_ERROR;
s = strm->state;
wrap = s->wrap;
if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
return Z_STREAM_ERROR;
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
if (wrap == 1)
strm->adler = functable.adler32(strm->adler, dictionary, dictLength);
DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */
s->wrap = 0; /* avoid computing Adler-32 in read_buf */
/* if dictionary would fill window, just replace the history */
if (dictLength >= s->w_size) {
if (wrap == 0) { /* already empty otherwise */
CLEAR_HASH(s);
s->strstart = 0;
s->block_start = 0;
s->insert = 0;
}
dictionary += dictLength - s->w_size; /* use the tail */
dictLength = s->w_size;
}
/* insert dictionary into window and hash */
avail = strm->avail_in;
next = strm->next_in;
strm->avail_in = dictLength;
strm->next_in = (z_const unsigned char *)dictionary;
fill_window(s);
while (s->lookahead >= STD_MIN_MATCH) {
str = s->strstart;
n = s->lookahead - (STD_MIN_MATCH - 1);
functable.insert_string(s, str, n);
s->strstart = str + n;
s->lookahead = STD_MIN_MATCH - 1;
fill_window(s);
}
s->strstart += s->lookahead;
s->block_start = (int)s->strstart;
s->insert = s->lookahead;
s->lookahead = 0;
s->prev_length = 0;
s->match_available = 0;
strm->next_in = (z_const unsigned char *)next;
strm->avail_in = avail;
s->wrap = wrap;
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) {
deflate_state *s;
unsigned int len;
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */
s = strm->state;
len = s->strstart + s->lookahead;
if (len > s->w_size)
len = s->w_size;
if (dictionary != NULL && len)
memcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
if (dictLength != NULL)
*dictLength = len;
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateResetKeep)(PREFIX3(stream) *strm) {
deflate_state *s;
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
strm->total_in = strm->total_out = 0;
strm->msg = NULL; /* use zfree if we ever allocate msg dynamically */
strm->data_type = Z_UNKNOWN;
s = (deflate_state *)strm->state;
s->pending = 0;
s->pending_out = s->pending_buf;
if (s->wrap < 0)
s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
s->status =
#ifdef GZIP
s->wrap == 2 ? GZIP_STATE :
#endif
INIT_STATE;
#ifdef GZIP
if (s->wrap == 2) {
strm->adler = functable.crc32_fold_reset(&s->crc_fold);
} else
#endif
strm->adler = ADLER32_INITIAL_VALUE;
s->last_flush = -2;
zng_tr_init(s);
DEFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateReset)(PREFIX3(stream) *strm) {
int ret;
ret = PREFIX(deflateResetKeep)(strm);
if (ret == Z_OK)
lm_init(strm->state);
return ret;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateSetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) {
if (deflateStateCheck(strm) || strm->state->wrap != 2)
return Z_STREAM_ERROR;
strm->state->gzhead = head;
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflatePending)(PREFIX3(stream) *strm, uint32_t *pending, int32_t *bits) {
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
if (pending != NULL)
*pending = strm->state->pending;
if (bits != NULL)
*bits = strm->state->bi_valid;
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) {
deflate_state *s;
uint64_t value64 = (uint64_t)value;
int32_t put;
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
s = strm->state;
if (bits < 0 || bits > BIT_BUF_SIZE || bits > (int32_t)(sizeof(value) << 3) ||
s->sym_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3))
return Z_BUF_ERROR;
do {
put = BIT_BUF_SIZE - s->bi_valid;
put = MIN(put, bits);
if (s->bi_valid == 0)
s->bi_buf = value64;
else
s->bi_buf |= (value64 & ((UINT64_C(1) << put) - 1)) << s->bi_valid;
s->bi_valid += put;
zng_tr_flush_bits(s);
value64 >>= put;
bits -= put;
} while (bits);
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateParams)(PREFIX3(stream) *strm, int32_t level, int32_t strategy) {
deflate_state *s;
compress_func func;
int hook_flush = Z_NO_FLUSH;
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
s = strm->state;
if (level == Z_DEFAULT_COMPRESSION)
level = 6;
if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED)
return Z_STREAM_ERROR;
DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); /* hook for IBM Z DFLTCC */
func = configuration_table[s->level].func;
if (((strategy != s->strategy || func != configuration_table[level].func) && s->last_flush != -2)
|| hook_flush != Z_NO_FLUSH) {
/* Flush the last buffer. Use Z_BLOCK mode, unless the hook requests a "stronger" one. */
int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK;
int err = PREFIX(deflate)(strm, flush);
if (err == Z_STREAM_ERROR)
return err;
if (strm->avail_in || ((int)s->strstart - s->block_start) + s->lookahead || !DEFLATE_DONE(strm, flush))
return Z_BUF_ERROR;
}
if (s->level != level) {
if (s->level == 0 && s->matches != 0) {
if (s->matches == 1) {
functable.slide_hash(s);
} else {
CLEAR_HASH(s);
}
s->matches = 0;
}
lm_set_level(s, level);
}
s->strategy = strategy;
return Z_OK;
}
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflateTune)(PREFIX3(stream) *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain) {
deflate_state *s;
if (deflateStateCheck(strm))
return Z_STREAM_ERROR;
s = strm->state;
s->good_match = (unsigned int)good_length;
s->max_lazy_match = (unsigned int)max_lazy;
s->nice_match = nice_length;
s->max_chain_length = (unsigned int)max_chain;
return Z_OK;
}
/* =========================================================================
* For the default windowBits of 15 and memLevel of 8, this function returns
* a close to exact, as well as small, upper bound on the compressed size.
* They are coded as constants here for a reason--if the #define's are
* changed, then this function needs to be changed as well. The return
* value for 15 and 8 only works for those exact settings.
*
* For any setting other than those defaults for windowBits and memLevel,
* the value returned is a conservative worst case for the maximum expansion
* resulting from using fixed blocks instead of stored blocks, which deflate
* can emit on compressed data for some combinations of the parameters.
*
* This function could be more sophisticated to provide closer upper bounds for
* every combination of windowBits and memLevel. But even the conservative
* upper bound of about 14% expansion does not seem onerous for output buffer
* allocation.
*/
unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long sourceLen) {
deflate_state *s;
unsigned long complen, wraplen;
/* conservative upper bound for compressed data */
complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen); /* hook for IBM Z DFLTCC */
/* if can't get parameters, return conservative bound plus zlib wrapper */
if (deflateStateCheck(strm))
return complen + 6;
/* compute wrapper length */
s = strm->state;
switch (s->wrap) {
case 0: /* raw deflate */
wraplen = 0;
break;
case 1: /* zlib wrapper */
wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0);
break;
#ifdef GZIP
case 2: /* gzip wrapper */
wraplen = GZIP_WRAPLEN;
if (s->gzhead != NULL) { /* user-supplied gzip header */
unsigned char *str;
if (s->gzhead->extra != NULL) {
wraplen += 2 + s->gzhead->extra_len;
}
str = s->gzhead->name;
if (str != NULL) {
do {
wraplen++;
} while (*str++);
}
str = s->gzhead->comment;
if (str != NULL) {
do {
wraplen++;
} while (*str++);
}
if (s->gzhead->hcrc)
wraplen += 2;
}
break;
#endif
default: /* for compiler happiness */
wraplen = ZLIB_WRAPLEN;
}
/* if not default parameters, return conservative bound */
if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || /* hook for IBM Z DFLTCC */
s->w_bits != 15 || HASH_BITS < 15)
return complen + wraplen;
#ifndef NO_QUICK_STRATEGY
return sourceLen /* The source size itself */
+ (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */
+ (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */
+ DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */
+ DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */
+ wraplen; /* none, zlib or gzip wrapper */
#else
return sourceLen + (sourceLen >> 4) + 7 + wraplen;
#endif
}
/* =========================================================================
* Flush as much pending output as possible. All deflate() output, except for
* some deflate_stored() output, goes through this function so some
* applications may wish to modify it to avoid allocating a large
* strm->next_out buffer and copying into it. (See also read_buf()).
*/
Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm) {
uint32_t len;
deflate_state *s = strm->state;
zng_tr_flush_bits(s);
len = s->pending;
if (len > strm->avail_out)
len = strm->avail_out;
if (len == 0)
return;
Tracev((stderr, "[FLUSH]"));
memcpy(strm->next_out, s->pending_out, len);
strm->next_out += len;
s->pending_out += len;
strm->total_out += len;
strm->avail_out -= len;
s->pending -= len;
if (s->pending == 0)
s->pending_out = s->pending_buf;
}
/* ===========================================================================
* Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
*/
#define HCRC_UPDATE(beg) \
do { \
if (s->gzhead->hcrc && s->pending > (beg)) \
strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \
} while (0)
/* ========================================================================= */
int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) {
int32_t old_flush; /* value of flush param for previous deflate call */
deflate_state *s;
if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0)
return Z_STREAM_ERROR;
s = strm->state;
if (strm->next_out == NULL || (strm->avail_in != 0 && strm->next_in == NULL)
|| (s->status == FINISH_STATE && flush != Z_FINISH)) {
ERR_RETURN(strm, Z_STREAM_ERROR);
}
if (strm->avail_out == 0) {
ERR_RETURN(strm, Z_BUF_ERROR);
}
old_flush = s->last_flush;
s->last_flush = flush;
/* Flush as much pending output as possible */
if (s->pending != 0) {
PREFIX(flush_pending)(strm);
if (strm->avail_out == 0) {
/* Since avail_out is 0, deflate will be called again with
* more output space, but possibly with both pending and
* avail_in equal to zero. There won't be anything to do,
* but this is not an error situation so make sure we
* return OK instead of BUF_ERROR at next call of deflate:
*/
s->last_flush = -1;
return Z_OK;
}
/* Make sure there is something to do and avoid duplicate consecutive
* flushes. For repeated and useless calls with Z_FINISH, we keep
* returning Z_STREAM_END instead of Z_BUF_ERROR.
*/
} else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) {
ERR_RETURN(strm, Z_BUF_ERROR);
}
/* User must not provide more input after the first FINISH: */
if (s->status == FINISH_STATE && strm->avail_in != 0) {
ERR_RETURN(strm, Z_BUF_ERROR);
}
/* Write the header */
if (s->status == INIT_STATE && s->wrap == 0)
s->status = BUSY_STATE;
if (s->status == INIT_STATE) {
/* zlib header */
unsigned int header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
unsigned int level_flags;
if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
level_flags = 0;
else if (s->level < 6)
level_flags = 1;
else if (s->level == 6)
level_flags = 2;
else
level_flags = 3;
header |= (level_flags << 6);
if (s->strstart != 0)
header |= PRESET_DICT;
header += 31 - (header % 31);
put_short_msb(s, (uint16_t)header);
/* Save the adler32 of the preset dictionary: */
if (s->strstart != 0)
put_uint32_msb(s, strm->adler);
strm->adler = ADLER32_INITIAL_VALUE;
s->status = BUSY_STATE;
/* Compression must start with an empty pending buffer */
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
#ifdef GZIP
if (s->status == GZIP_STATE) {
/* gzip header */
functable.crc32_fold_reset(&s->crc_fold);
put_byte(s, 31);
put_byte(s, 139);
put_byte(s, 8);
if (s->gzhead == NULL) {
put_uint32(s, 0);
put_byte(s, 0);
put_byte(s, s->level == 9 ? 2 :
(s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0));
put_byte(s, OS_CODE);
s->status = BUSY_STATE;
/* Compression must start with an empty pending buffer */
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
} else {
put_byte(s, (s->gzhead->text ? 1 : 0) +
(s->gzhead->hcrc ? 2 : 0) +
(s->gzhead->extra == NULL ? 0 : 4) +
(s->gzhead->name == NULL ? 0 : 8) +
(s->gzhead->comment == NULL ? 0 : 16)
);
put_uint32(s, s->gzhead->time);
put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0));
put_byte(s, s->gzhead->os & 0xff);
if (s->gzhead->extra != NULL)
put_short(s, (uint16_t)s->gzhead->extra_len);
if (s->gzhead->hcrc)
strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending);
s->gzindex = 0;
s->status = EXTRA_STATE;
}
}
if (s->status == EXTRA_STATE) {
if (s->gzhead->extra != NULL) {
uint32_t beg = s->pending; /* start of bytes to update crc */
uint32_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
while (s->pending + left > s->pending_buf_size) {
uint32_t copy = s->pending_buf_size - s->pending;
memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy);
s->pending = s->pending_buf_size;
HCRC_UPDATE(beg);
s->gzindex += copy;
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
beg = 0;
left -= copy;
}
memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, left);
s->pending += left;
HCRC_UPDATE(beg);
s->gzindex = 0;
}
s->status = NAME_STATE;
}
if (s->status == NAME_STATE) {
if (s->gzhead->name != NULL) {
uint32_t beg = s->pending; /* start of bytes to update crc */
unsigned char val;
do {
if (s->pending == s->pending_buf_size) {
HCRC_UPDATE(beg);
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
beg = 0;
}
val = s->gzhead->name[s->gzindex++];
put_byte(s, val);
} while (val != 0);
HCRC_UPDATE(beg);
s->gzindex = 0;
}
s->status = COMMENT_STATE;
}
if (s->status == COMMENT_STATE) {
if (s->gzhead->comment != NULL) {
uint32_t beg = s->pending; /* start of bytes to update crc */
unsigned char val;
do {
if (s->pending == s->pending_buf_size) {
HCRC_UPDATE(beg);
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
beg = 0;
}
val = s->gzhead->comment[s->gzindex++];
put_byte(s, val);
} while (val != 0);
HCRC_UPDATE(beg);
}
s->status = HCRC_STATE;
}
if (s->status == HCRC_STATE) {
if (s->gzhead->hcrc) {
if (s->pending + 2 > s->pending_buf_size) {
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
put_short(s, (uint16_t)strm->adler);
functable.crc32_fold_reset(&s->crc_fold);
}
s->status = BUSY_STATE;
/* Compression must start with an empty pending buffer */
PREFIX(flush_pending)(strm);
if (s->pending != 0) {
s->last_flush = -1;
return Z_OK;
}
}
#endif
/* Start a new block or continue the current one.
*/
if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
block_state bstate;
bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : /* hook for IBM Z DFLTCC */
s->level == 0 ? deflate_stored(s, flush) :
s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
s->strategy == Z_RLE ? deflate_rle(s, flush) :
(*(configuration_table[s->level].func))(s, flush);
if (bstate == finish_started || bstate == finish_done) {
s->status = FINISH_STATE;
}
if (bstate == need_more || bstate == finish_started) {
if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
}
return Z_OK;
/* If flush != Z_NO_FLUSH && avail_out == 0, the next call
* of deflate should use the same flush parameter to make sure
* that the flush is complete. So we don't have to output an
* empty block here, this will be done at next call. This also
* ensures that for a very small output buffer, we emit at most
* one empty block.
*/
}
if (bstate == block_done) {
if (flush == Z_PARTIAL_FLUSH) {
zng_tr_align(s);
} else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
zng_tr_stored_block(s, (char*)0, 0L, 0);
/* For a full flush, this empty block will be recognized
* as a special marker by inflate_sync().
*/
if (flush == Z_FULL_FLUSH) {
CLEAR_HASH(s); /* forget history */
if (s->lookahead == 0) {
s->strstart = 0;
s->block_start = 0;
s->insert = 0;
}
}
}
PREFIX(flush_pending)(strm);
if (strm->avail_out == 0) {
s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
return Z_OK;
}
}
}
if (flush != Z_FINISH)
return Z_OK;
/* Write the trailer */