Coverage Report

Created: 2025-07-12 06:16

/src/zlib-ng/deflate.c
Line
Count
Source (jump to first uncovered line)
1
/* deflate.c -- compress data using the deflation algorithm
2
 * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
5
6
/*
7
 *  ALGORITHM
8
 *
9
 *      The "deflation" process depends on being able to identify portions
10
 *      of the input text which are identical to earlier input (within a
11
 *      sliding window trailing behind the input currently being processed).
12
 *
13
 *      The most straightforward technique turns out to be the fastest for
14
 *      most input files: try all possible matches and select the longest.
15
 *      The key feature of this algorithm is that insertions into the string
16
 *      dictionary are very simple and thus fast, and deletions are avoided
17
 *      completely. Insertions are performed at each input character, whereas
18
 *      string matches are performed only when the previous match ends. So it
19
 *      is preferable to spend more time in matches to allow very fast string
20
 *      insertions and avoid deletions. The matching algorithm for small
21
 *      strings is inspired from that of Rabin & Karp. A brute force approach
22
 *      is used to find longer strings when a small match has been found.
23
 *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
24
 *      (by Leonid Broukhis).
25
 *         A previous version of this file used a more sophisticated algorithm
26
 *      (by Fiala and Greene) which is guaranteed to run in linear amortized
27
 *      time, but has a larger average cost, uses more memory and is patented.
28
 *      However the F&G algorithm may be faster for some highly redundant
29
 *      files if the parameter max_chain_length (described below) is too large.
30
 *
31
 *  ACKNOWLEDGEMENTS
32
 *
33
 *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
34
 *      I found it in 'freeze' written by Leonid Broukhis.
35
 *      Thanks to many people for bug reports and testing.
36
 *
37
 *  REFERENCES
38
 *
39
 *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
40
 *      Available in https://tools.ietf.org/html/rfc1951
41
 *
42
 *      A description of the Rabin and Karp algorithm is given in the book
43
 *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
44
 *
45
 *      Fiala,E.R., and Greene,D.H.
46
 *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
47
 *
48
 */
49
50
#include "zbuild.h"
51
#include "deflate.h"
52
#include "deflate_p.h"
53
#include "functable.h"
54
55
/* Avoid conflicts with zlib.h macros */
56
#ifdef ZLIB_COMPAT
57
# undef deflateInit
58
# undef deflateInit2
59
#endif
60
61
const char PREFIX(deflate_copyright)[] = " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler ";
62
/*
63
  If you use the zlib library in a product, an acknowledgment is welcome
64
  in the documentation of your product. If for some reason you cannot
65
  include such an acknowledgment, I would appreciate that you keep this
66
  copyright string in the executable of your product.
67
 */
68
69
/* ===========================================================================
70
 *  Architecture-specific hooks.
71
 */
72
#ifdef S390_DFLTCC_DEFLATE
73
#  include "arch/s390/dfltcc_deflate.h"
74
/* DFLTCC instructions require window to be page-aligned */
75
#  define PAD_WINDOW            PAD_4096
76
#  define WINDOW_PAD_SIZE       4096
77
#  define HINT_ALIGNED_WINDOW   HINT_ALIGNED_4096
78
#else
79
39.5k
#  define PAD_WINDOW            PAD_64
80
#  define WINDOW_PAD_SIZE       64
81
79.1k
#  define HINT_ALIGNED_WINDOW   HINT_ALIGNED_64
82
/* Adjust the window size for the arch-specific deflate code. */
83
39.5k
#  define DEFLATE_ADJUST_WINDOW_SIZE(n) (n)
84
/* Invoked at the beginning of deflateSetDictionary(). Useful for checking arch-specific window data. */
85
6.72k
#  define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
86
/* Invoked at the beginning of deflateGetDictionary(). Useful for adjusting arch-specific window data. */
87
0
#  define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
88
/* Invoked at the end of deflateResetKeep(). Useful for initializing arch-specific extension blocks. */
89
39.5k
#  define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
90
/* Invoked at the beginning of deflateParams(). Useful for updating arch-specific compression parameters. */
91
2.61k
#  define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0)
92
/* Returns whether the last deflate(flush) operation did everything it's supposed to do. */
93
0
#  define DEFLATE_DONE(strm, flush) 1
94
/* Adjusts the upper bound on compressed data length based on compression parameters and uncompressed data length.
95
 * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */
96
6.72k
#  define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0)
97
/* Returns whether an optimistic upper bound on compressed data length should *not* be used.
98
 * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */
99
13.4k
#  define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0
100
/* Invoked for each deflate() call. Useful for plugging arch-specific deflation code. */
101
150M
#  define DEFLATE_HOOK(strm, flush, bstate) 0
102
/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific deflation code already does that. */
103
150M
#  define DEFLATE_NEED_CHECKSUM(strm) 1
104
/* Returns whether reproducibility parameter can be set to a given value. */
105
0
#  define DEFLATE_CAN_SET_REPRODUCIBLE(strm, reproducible) 1
106
#endif
107
108
/* ===========================================================================
109
 *  Function prototypes.
110
 */
111
static int deflateStateCheck      (PREFIX3(stream) *strm);
112
Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush);
113
Z_INTERNAL block_state deflate_fast  (deflate_state *s, int flush);
114
Z_INTERNAL block_state deflate_quick (deflate_state *s, int flush);
115
#ifndef NO_MEDIUM_STRATEGY
116
Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush);
117
#endif
118
Z_INTERNAL block_state deflate_slow  (deflate_state *s, int flush);
119
Z_INTERNAL block_state deflate_rle   (deflate_state *s, int flush);
120
Z_INTERNAL block_state deflate_huff  (deflate_state *s, int flush);
121
static void lm_set_level         (deflate_state *s, int level);
122
static void lm_init              (deflate_state *s);
123
Z_INTERNAL unsigned read_buf  (PREFIX3(stream) *strm, unsigned char *buf, unsigned size);
124
125
/* ===========================================================================
126
 * Local data
127
 */
128
129
/* Values for max_lazy_match, good_match and max_chain_length, depending on
130
 * the desired pack level (0..9). The values given below have been tuned to
131
 * exclude worst case performance for pathological files. Better values may be
132
 * found for specific files.
133
 */
134
typedef struct config_s {
135
    uint16_t good_length; /* reduce lazy search above this match length */
136
    uint16_t max_lazy;    /* do not perform lazy search above this match length */
137
    uint16_t nice_length; /* quit search above this match length */
138
    uint16_t max_chain;
139
    compress_func func;
140
} config;
141
142
static const config configuration_table[10] = {
143
/*      good lazy nice chain */
144
/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
145
146
#ifdef NO_QUICK_STRATEGY
147
/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
148
/* 2 */ {4,    5, 16,    8, deflate_fast},
149
#else
150
/* 1 */ {0,    0,  0,    0, deflate_quick},
151
/* 2 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
152
#endif
153
154
#ifdef NO_MEDIUM_STRATEGY
155
/* 3 */ {4,    6, 32,   32, deflate_fast},
156
/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
157
/* 5 */ {8,   16, 32,   32, deflate_slow},
158
/* 6 */ {8,   16, 128, 128, deflate_slow},
159
#else
160
/* 3 */ {4,    6, 16,    6, deflate_medium},
161
/* 4 */ {4,   12, 32,   24, deflate_medium},  /* lazy matches */
162
/* 5 */ {8,   16, 32,   32, deflate_medium},
163
/* 6 */ {8,   16, 128, 128, deflate_medium},
164
#endif
165
166
/* 7 */ {8,   32, 128,  256, deflate_slow},
167
/* 8 */ {32, 128, 258, 1024, deflate_slow},
168
/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
169
170
/* Note: the deflate() code requires max_lazy >= STD_MIN_MATCH and max_chain >= 4
171
 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
172
 * meaning.
173
 */
174
175
/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
176
150M
#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
177
178
179
/* ===========================================================================
180
 * Initialize the hash table. prev[] will be initialized on the fly.
181
 */
182
43.1k
#define CLEAR_HASH(s) do { \
183
43.1k
    memset((unsigned char *)s->head, 0, HASH_SIZE * sizeof(*s->head)); \
184
43.1k
  } while (0)
185
186
187
#ifdef DEF_ALLOC_DEBUG
188
#  include <stdio.h>
189
#  define LOGSZ(name,size)           fprintf(stderr, "%s is %d bytes\n", name, size)
190
#  define LOGSZP(name,size,loc,pad)  fprintf(stderr, "%s is %d bytes, offset %d, padded %d\n", name, size, loc, pad)
191
#  define LOGSZPL(name,size,loc,pad) fprintf(stderr, "%s is %d bytes, offset %ld, padded %d\n", name, size, loc, pad)
192
#else
193
#  define LOGSZ(name,size)
194
#  define LOGSZP(name,size,loc,pad)
195
#  define LOGSZPL(name,size,loc,pad)
196
#endif
197
198
/* ===========================================================================
199
 * Allocate a big buffer and divide it up into the various buffers deflate needs.
200
 * Handles alignment of allocated buffer and alignment of individual buffers.
201
 */
202
39.5k
Z_INTERNAL deflate_allocs* alloc_deflate(PREFIX3(stream) *strm, int windowBits, int lit_bufsize) {
203
39.5k
    int curr_size = 0;
204
205
    /* Define sizes */
206
39.5k
    int window_size = DEFLATE_ADJUST_WINDOW_SIZE((1 << windowBits) * 2);
207
39.5k
    int prev_size = (1 << windowBits) * (int)sizeof(Pos);
208
39.5k
    int head_size = HASH_SIZE * sizeof(Pos);
209
39.5k
    int pending_size = lit_bufsize * LIT_BUFS;
210
39.5k
    int state_size = sizeof(deflate_state);
211
39.5k
    int alloc_size = sizeof(deflate_allocs);
212
213
    /* Calculate relative buffer positions and paddings */
214
39.5k
    LOGSZP("window", window_size, PAD_WINDOW(curr_size), PADSZ(curr_size,WINDOW_PAD_SIZE));
215
39.5k
    int window_pos = PAD_WINDOW(curr_size);
216
39.5k
    curr_size = window_pos + window_size;
217
218
39.5k
    LOGSZP("prev", prev_size, PAD_64(curr_size), PADSZ(curr_size,64));
219
39.5k
    int prev_pos = PAD_64(curr_size);
220
39.5k
    curr_size = prev_pos + prev_size;
221
222
39.5k
    LOGSZP("head", head_size, PAD_64(curr_size), PADSZ(curr_size,64));
223
39.5k
    int head_pos = PAD_64(curr_size);
224
39.5k
    curr_size = head_pos + head_size;
225
226
39.5k
    LOGSZP("pending", pending_size, PAD_64(curr_size), PADSZ(curr_size,64));
227
39.5k
    int pending_pos = PAD_64(curr_size);
228
39.5k
    curr_size = pending_pos + pending_size;
229
230
39.5k
    LOGSZP("state", state_size, PAD_64(curr_size), PADSZ(curr_size,64));
231
39.5k
    int state_pos = PAD_64(curr_size);
232
39.5k
    curr_size = state_pos + state_size;
233
234
39.5k
    LOGSZP("alloc", alloc_size, PAD_16(curr_size), PADSZ(curr_size,16));
235
39.5k
    int alloc_pos = PAD_16(curr_size);
236
39.5k
    curr_size = alloc_pos + alloc_size;
237
238
    /* Add 64-1 or 4096-1 to allow window alignment, and round size of buffer up to multiple of 64 */
239
39.5k
    int total_size = PAD_64(curr_size + (WINDOW_PAD_SIZE - 1));
240
241
    /* Allocate buffer, align to 64-byte cacheline, and zerofill the resulting buffer */
242
39.5k
    char *original_buf = (char *)strm->zalloc(strm->opaque, 1, total_size);
243
39.5k
    if (original_buf == NULL)
244
0
        return NULL;
245
246
39.5k
    char *buff = (char *)HINT_ALIGNED_WINDOW((char *)PAD_WINDOW(original_buf));
247
39.5k
    LOGSZPL("Buffer alloc", total_size, PADSZ((uintptr_t)original_buf,WINDOW_PAD_SIZE), PADSZ(curr_size,WINDOW_PAD_SIZE));
248
249
    /* Initialize alloc_bufs */
250
39.5k
    deflate_allocs *alloc_bufs  = (struct deflate_allocs_s *)(buff + alloc_pos);
251
39.5k
    alloc_bufs->buf_start = original_buf;
252
39.5k
    alloc_bufs->zfree = strm->zfree;
253
254
    /* Assign buffers */
255
39.5k
    alloc_bufs->window = (unsigned char *)HINT_ALIGNED_WINDOW(buff + window_pos);
256
39.5k
    alloc_bufs->prev = (Pos *)HINT_ALIGNED_64(buff + prev_pos);
257
39.5k
    alloc_bufs->head = (Pos *)HINT_ALIGNED_64(buff + head_pos);
258
39.5k
    alloc_bufs->pending_buf = (unsigned char *)HINT_ALIGNED_64(buff + pending_pos);
259
39.5k
    alloc_bufs->state = (deflate_state *)HINT_ALIGNED_16(buff + state_pos);
260
261
39.5k
    memset((char *)alloc_bufs->prev, 0, prev_size);
262
263
39.5k
    return alloc_bufs;
264
39.5k
}
265
266
/* ===========================================================================
267
 * Free all allocated deflate buffers
268
 */
269
39.5k
static inline void free_deflate(PREFIX3(stream) *strm) {
270
39.5k
    deflate_state *state = (deflate_state *)strm->state;
271
272
39.5k
    if (state->alloc_bufs != NULL) {
273
39.5k
        deflate_allocs *alloc_bufs = state->alloc_bufs;
274
39.5k
        alloc_bufs->zfree(strm->opaque, alloc_bufs->buf_start);
275
39.5k
        strm->state = NULL;
276
39.5k
    }
277
39.5k
}
278
279
/* ===========================================================================
280
 * Initialize deflate state and buffers.
281
 * This function is hidden in ZLIB_COMPAT builds.
282
 */
283
int32_t ZNG_CONDEXPORT PREFIX(deflateInit2)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits,
284
39.5k
                                            int32_t memLevel, int32_t strategy) {
285
    /* Todo: ignore strm->next_in if we use it as window */
286
39.5k
    deflate_state *s;
287
39.5k
    int wrap = 1;
288
289
    /* Initialize functable */
290
39.5k
    FUNCTABLE_INIT;
291
292
39.5k
    if (strm == NULL)
293
0
        return Z_STREAM_ERROR;
294
295
39.5k
    strm->msg = NULL;
296
39.5k
    if (strm->zalloc == NULL) {
297
39.5k
        strm->zalloc = PREFIX(zcalloc);
298
39.5k
        strm->opaque = NULL;
299
39.5k
    }
300
39.5k
    if (strm->zfree == NULL)
301
39.5k
        strm->zfree = PREFIX(zcfree);
302
303
39.5k
    if (level == Z_DEFAULT_COMPRESSION)
304
8.26k
        level = 6;
305
306
39.5k
    if (windowBits < 0) { /* suppress zlib wrapper */
307
0
        wrap = 0;
308
0
        if (windowBits < -MAX_WBITS)
309
0
            return Z_STREAM_ERROR;
310
0
        windowBits = -windowBits;
311
0
#ifdef GZIP
312
39.5k
    } else if (windowBits > MAX_WBITS) {
313
6.25k
        wrap = 2;       /* write gzip wrapper instead */
314
6.25k
        windowBits -= 16;
315
6.25k
#endif
316
6.25k
    }
317
39.5k
    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < MIN_WBITS ||
318
39.5k
        windowBits > MAX_WBITS || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED ||
319
39.5k
        (windowBits == 8 && wrap != 1)) {
320
0
        return Z_STREAM_ERROR;
321
0
    }
322
39.5k
    if (windowBits == 8)
323
2.34k
        windowBits = 9;  /* until 256-byte window bug fixed */
324
325
    /* Allocate buffers */
326
39.5k
    int lit_bufsize = 1 << (memLevel + 6);
327
39.5k
    deflate_allocs *alloc_bufs = alloc_deflate(strm, windowBits, lit_bufsize);
328
39.5k
    if (alloc_bufs == NULL)
329
0
        return Z_MEM_ERROR;
330
331
39.5k
    s = alloc_bufs->state;
332
39.5k
    s->alloc_bufs = alloc_bufs;
333
39.5k
    s->window = alloc_bufs->window;
334
39.5k
    s->prev = alloc_bufs->prev;
335
39.5k
    s->head = alloc_bufs->head;
336
39.5k
    s->pending_buf = alloc_bufs->pending_buf;
337
338
39.5k
    strm->state = (struct internal_state *)s;
339
39.5k
    s->strm = strm;
340
39.5k
    s->status = INIT_STATE;     /* to pass state test in deflateReset() */
341
342
39.5k
    s->wrap = wrap;
343
39.5k
    s->gzhead = NULL;
344
39.5k
    s->w_bits = (unsigned int)windowBits;
345
39.5k
    s->w_size = 1 << s->w_bits;
346
39.5k
    s->w_mask = s->w_size - 1;
347
348
39.5k
    s->high_water = 0;      /* nothing written to s->window yet */
349
350
39.5k
    s->lit_bufsize = lit_bufsize; /* 16K elements by default */
351
352
    /* We overlay pending_buf and sym_buf. This works since the average size
353
     * for length/distance pairs over any compressed block is assured to be 31
354
     * bits or less.
355
     *
356
     * Analysis: The longest fixed codes are a length code of 8 bits plus 5
357
     * extra bits, for lengths 131 to 257. The longest fixed distance codes are
358
     * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest
359
     * possible fixed-codes length/distance pair is then 31 bits total.
360
     *
361
     * sym_buf starts one-fourth of the way into pending_buf. So there are
362
     * three bytes in sym_buf for every four bytes in pending_buf. Each symbol
363
     * in sym_buf is three bytes -- two for the distance and one for the
364
     * literal/length. As each symbol is consumed, the pointer to the next
365
     * sym_buf value to read moves forward three bytes. From that symbol, up to
366
     * 31 bits are written to pending_buf. The closest the written pending_buf
367
     * bits gets to the next sym_buf symbol to read is just before the last
368
     * code is written. At that time, 31*(n-2) bits have been written, just
369
     * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at
370
     * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1
371
     * symbols are written.) The closest the writing gets to what is unread is
372
     * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and
373
     * can range from 128 to 32768.
374
     *
375
     * Therefore, at a minimum, there are 142 bits of space between what is
376
     * written and what is read in the overlain buffers, so the symbols cannot
377
     * be overwritten by the compressed data. That space is actually 139 bits,
378
     * due to the three-bit fixed-code block header.
379
     *
380
     * That covers the case where either Z_FIXED is specified, forcing fixed
381
     * codes, or when the use of fixed codes is chosen, because that choice
382
     * results in a smaller compressed block than dynamic codes. That latter
383
     * condition then assures that the above analysis also covers all dynamic
384
     * blocks. A dynamic-code block will only be chosen to be emitted if it has
385
     * fewer bits than a fixed-code block would for the same set of symbols.
386
     * Therefore its average symbol length is assured to be less than 31. So
387
     * the compressed data for a dynamic block also cannot overwrite the
388
     * symbols from which it is being constructed.
389
     */
390
391
39.5k
    s->pending_buf_size = s->lit_bufsize * 4;
392
393
39.5k
    if (s->window == NULL || s->prev == NULL || s->head == NULL || s->pending_buf == NULL) {
394
0
        s->status = FINISH_STATE;
395
0
        strm->msg = ERR_MSG(Z_MEM_ERROR);
396
0
        PREFIX(deflateEnd)(strm);
397
0
        return Z_MEM_ERROR;
398
0
    }
399
400
39.5k
#ifdef LIT_MEM
401
39.5k
    s->d_buf = (uint16_t *)(s->pending_buf + (s->lit_bufsize << 1));
402
39.5k
    s->l_buf = s->pending_buf + (s->lit_bufsize << 2);
403
39.5k
    s->sym_end = s->lit_bufsize - 1;
404
#else
405
    s->sym_buf = s->pending_buf + s->lit_bufsize;
406
    s->sym_end = (s->lit_bufsize - 1) * 3;
407
#endif
408
    /* We avoid equality with lit_bufsize*3 because of wraparound at 64K
409
     * on 16 bit machines and because stored blocks are restricted to
410
     * 64K-1 bytes.
411
     */
412
413
39.5k
    s->level = level;
414
39.5k
    s->strategy = strategy;
415
39.5k
    s->block_open = 0;
416
39.5k
    s->reproducible = 0;
417
418
39.5k
    return PREFIX(deflateReset)(strm);
419
39.5k
}
420
421
#ifndef ZLIB_COMPAT
422
26.6k
int32_t Z_EXPORT PREFIX(deflateInit)(PREFIX3(stream) *strm, int32_t level) {
423
26.6k
    return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
424
26.6k
}
425
#endif
426
427
/* Function used by zlib.h and zlib-ng version 2.0 macros */
428
0
int32_t Z_EXPORT PREFIX(deflateInit_)(PREFIX3(stream) *strm, int32_t level, const char *version, int32_t stream_size) {
429
0
    if (CHECK_VER_STSIZE(version, stream_size))
430
0
        return Z_VERSION_ERROR;
431
0
    return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
432
0
}
433
434
/* Function used by zlib.h and zlib-ng version 2.0 macros */
435
int32_t Z_EXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits,
436
0
                           int32_t memLevel, int32_t strategy, const char *version, int32_t stream_size) {
437
0
    if (CHECK_VER_STSIZE(version, stream_size))
438
0
        return Z_VERSION_ERROR;
439
0
    return PREFIX(deflateInit2)(strm, level, method, windowBits, memLevel, strategy);
440
0
}
441
442
/* =========================================================================
443
 * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
444
 */
445
254M
static int deflateStateCheck(PREFIX3(stream) *strm) {
446
254M
    deflate_state *s;
447
254M
    if (strm == NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
448
0
        return 1;
449
254M
    s = strm->state;
450
254M
    if (s == NULL || s->alloc_bufs == NULL || s->strm != strm || (s->status < INIT_STATE || s->status > MAX_STATE))
451
0
        return 1;
452
254M
    return 0;
453
254M
}
454
455
/* ========================================================================= */
456
6.72k
int32_t Z_EXPORT PREFIX(deflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) {
457
6.72k
    deflate_state *s;
458
6.72k
    unsigned int str, n;
459
6.72k
    int wrap;
460
6.72k
    uint32_t avail;
461
6.72k
    const unsigned char *next;
462
463
6.72k
    if (deflateStateCheck(strm) || dictionary == NULL)
464
0
        return Z_STREAM_ERROR;
465
6.72k
    s = strm->state;
466
6.72k
    wrap = s->wrap;
467
6.72k
    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
468
0
        return Z_STREAM_ERROR;
469
470
    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
471
6.72k
    if (wrap == 1)
472
6.72k
        strm->adler = FUNCTABLE_CALL(adler32)(strm->adler, dictionary, dictLength);
473
6.72k
    DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength);  /* hook for IBM Z DFLTCC */
474
6.72k
    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
475
476
    /* if dictionary would fill window, just replace the history */
477
6.72k
    if (dictLength >= s->w_size) {
478
0
        if (wrap == 0) {            /* already empty otherwise */
479
0
            CLEAR_HASH(s);
480
0
            s->strstart = 0;
481
0
            s->block_start = 0;
482
0
            s->insert = 0;
483
0
        }
484
0
        dictionary += dictLength - s->w_size;  /* use the tail */
485
0
        dictLength = s->w_size;
486
0
    }
487
488
    /* insert dictionary into window and hash */
489
6.72k
    avail = strm->avail_in;
490
6.72k
    next = strm->next_in;
491
6.72k
    strm->avail_in = dictLength;
492
6.72k
    strm->next_in = (z_const unsigned char *)dictionary;
493
6.72k
    PREFIX(fill_window)(s);
494
12.9k
    while (s->lookahead >= STD_MIN_MATCH) {
495
6.20k
        str = s->strstart;
496
6.20k
        n = s->lookahead - (STD_MIN_MATCH - 1);
497
6.20k
        s->insert_string(s, str, n);
498
6.20k
        s->strstart = str + n;
499
6.20k
        s->lookahead = STD_MIN_MATCH - 1;
500
6.20k
        PREFIX(fill_window)(s);
501
6.20k
    }
502
6.72k
    s->strstart += s->lookahead;
503
6.72k
    s->block_start = (int)s->strstart;
504
6.72k
    s->insert = s->lookahead;
505
6.72k
    s->lookahead = 0;
506
6.72k
    s->prev_length = 0;
507
6.72k
    s->match_available = 0;
508
6.72k
    strm->next_in = (z_const unsigned char *)next;
509
6.72k
    strm->avail_in = avail;
510
6.72k
    s->wrap = wrap;
511
6.72k
    return Z_OK;
512
6.72k
}
513
514
/* ========================================================================= */
515
0
int32_t Z_EXPORT PREFIX(deflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) {
516
0
    deflate_state *s;
517
0
    unsigned int len;
518
519
0
    if (deflateStateCheck(strm))
520
0
        return Z_STREAM_ERROR;
521
0
    DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength);  /* hook for IBM Z DFLTCC */
522
0
    s = strm->state;
523
0
    len = s->strstart + s->lookahead;
524
0
    if (len > s->w_size)
525
0
        len = s->w_size;
526
0
    if (dictionary != NULL && len)
527
0
        memcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
528
0
    if (dictLength != NULL)
529
0
        *dictLength = len;
530
0
    return Z_OK;
531
0
}
532
533
/* ========================================================================= */
534
39.5k
int32_t Z_EXPORT PREFIX(deflateResetKeep)(PREFIX3(stream) *strm) {
535
39.5k
    deflate_state *s;
536
537
39.5k
    if (deflateStateCheck(strm))
538
0
        return Z_STREAM_ERROR;
539
540
39.5k
    strm->total_in = strm->total_out = 0;
541
39.5k
    strm->msg = NULL; /* use zfree if we ever allocate msg dynamically */
542
39.5k
    strm->data_type = Z_UNKNOWN;
543
544
39.5k
    s = (deflate_state *)strm->state;
545
39.5k
    s->pending = 0;
546
39.5k
    s->pending_out = s->pending_buf;
547
548
39.5k
    if (s->wrap < 0)
549
0
        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
550
551
39.5k
    s->status =
552
39.5k
#ifdef GZIP
553
39.5k
        s->wrap == 2 ? GZIP_STATE :
554
39.5k
#endif
555
39.5k
        INIT_STATE;
556
557
39.5k
#ifdef GZIP
558
39.5k
    if (s->wrap == 2) {
559
6.25k
        strm->adler = FUNCTABLE_CALL(crc32_fold_reset)(&s->crc_fold);
560
6.25k
    } else
561
33.3k
#endif
562
33.3k
        strm->adler = ADLER32_INITIAL_VALUE;
563
39.5k
    s->last_flush = -2;
564
565
39.5k
    zng_tr_init(s);
566
567
39.5k
    DEFLATE_RESET_KEEP_HOOK(strm);  /* hook for IBM Z DFLTCC */
568
569
39.5k
    return Z_OK;
570
39.5k
}
571
572
/* ========================================================================= */
573
39.5k
int32_t Z_EXPORT PREFIX(deflateReset)(PREFIX3(stream) *strm) {
574
39.5k
    int ret = PREFIX(deflateResetKeep)(strm);
575
39.5k
    if (ret == Z_OK)
576
39.5k
        lm_init(strm->state);
577
39.5k
    return ret;
578
39.5k
}
579
580
/* ========================================================================= */
581
0
int32_t Z_EXPORT PREFIX(deflateSetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) {
582
0
    if (deflateStateCheck(strm) || strm->state->wrap != 2)
583
0
        return Z_STREAM_ERROR;
584
0
    strm->state->gzhead = head;
585
0
    return Z_OK;
586
0
}
587
588
/* ========================================================================= */
589
0
int32_t Z_EXPORT PREFIX(deflatePending)(PREFIX3(stream) *strm, uint32_t *pending, int32_t *bits) {
590
0
    if (deflateStateCheck(strm))
591
0
        return Z_STREAM_ERROR;
592
0
    if (pending != NULL)
593
0
        *pending = strm->state->pending;
594
0
    if (bits != NULL)
595
0
        *bits = strm->state->bi_valid;
596
0
    return Z_OK;
597
0
}
598
599
/* ========================================================================= */
600
0
int32_t Z_EXPORT PREFIX(deflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) {
601
0
    deflate_state *s;
602
0
    uint64_t value64 = (uint64_t)value;
603
0
    int32_t put;
604
605
0
    if (deflateStateCheck(strm))
606
0
        return Z_STREAM_ERROR;
607
0
    s = strm->state;
608
609
0
#ifdef LIT_MEM
610
0
    if (bits < 0 || bits > BIT_BUF_SIZE ||
611
0
        (unsigned char *)s->d_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3))
612
0
        return Z_BUF_ERROR;
613
#else
614
    if (bits < 0 || bits > BIT_BUF_SIZE || bits > (int32_t)(sizeof(value) << 3) ||
615
        s->sym_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3))
616
        return Z_BUF_ERROR;
617
#endif
618
619
0
    do {
620
0
        put = BIT_BUF_SIZE - s->bi_valid;
621
0
        put = MIN(put, bits);
622
623
0
        if (s->bi_valid == 0)
624
0
            s->bi_buf = value64;
625
0
        else
626
0
            s->bi_buf |= (value64 & ((UINT64_C(1) << put) - 1)) << s->bi_valid;
627
0
        s->bi_valid += put;
628
0
        zng_tr_flush_bits(s);
629
0
        value64 >>= put;
630
0
        bits -= put;
631
0
    } while (bits);
632
0
    return Z_OK;
633
0
}
634
635
/* ========================================================================= */
636
2.61k
int32_t Z_EXPORT PREFIX(deflateParams)(PREFIX3(stream) *strm, int32_t level, int32_t strategy) {
637
2.61k
    deflate_state *s;
638
2.61k
    compress_func func;
639
2.61k
    int hook_flush = Z_NO_FLUSH;
640
641
2.61k
    if (deflateStateCheck(strm))
642
0
        return Z_STREAM_ERROR;
643
2.61k
    s = strm->state;
644
645
2.61k
    if (level == Z_DEFAULT_COMPRESSION)
646
0
        level = 6;
647
2.61k
    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED)
648
0
        return Z_STREAM_ERROR;
649
2.61k
    DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush);  /* hook for IBM Z DFLTCC */
650
2.61k
    func = configuration_table[s->level].func;
651
652
2.61k
    if (((strategy != s->strategy || func != configuration_table[level].func) && s->last_flush != -2)
653
2.61k
        || hook_flush != Z_NO_FLUSH) {
654
        /* Flush the last buffer. Use Z_BLOCK mode, unless the hook requests a "stronger" one. */
655
2.61k
        int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK;
656
2.61k
        int err = PREFIX(deflate)(strm, flush);
657
2.61k
        if (err == Z_STREAM_ERROR)
658
0
            return err;
659
2.61k
        if (strm->avail_in || ((int)s->strstart - s->block_start) + s->lookahead || !DEFLATE_DONE(strm, flush))
660
0
            return Z_BUF_ERROR;
661
2.61k
    }
662
2.61k
    if (s->level != level) {
663
2.61k
        if (s->level == 0 && s->matches != 0) {
664
27
            if (s->matches == 1) {
665
27
                FUNCTABLE_CALL(slide_hash)(s);
666
27
            } else {
667
0
                CLEAR_HASH(s);
668
0
            }
669
27
            s->matches = 0;
670
27
        }
671
672
2.61k
        lm_set_level(s, level);
673
2.61k
    }
674
2.61k
    s->strategy = strategy;
675
2.61k
    return Z_OK;
676
2.61k
}
677
678
/* ========================================================================= */
679
0
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) {
680
0
    deflate_state *s;
681
682
0
    if (deflateStateCheck(strm))
683
0
        return Z_STREAM_ERROR;
684
0
    s = strm->state;
685
0
    s->good_match = (unsigned int)good_length;
686
0
    s->max_lazy_match = (unsigned int)max_lazy;
687
0
    s->nice_match = nice_length;
688
0
    s->max_chain_length = (unsigned int)max_chain;
689
0
    return Z_OK;
690
0
}
691
692
/* =========================================================================
693
 * For the default windowBits of 15 and memLevel of 8, this function returns
694
 * a close to exact, as well as small, upper bound on the compressed size.
695
 * They are coded as constants here for a reason--if the #define's are
696
 * changed, then this function needs to be changed as well.  The return
697
 * value for 15 and 8 only works for those exact settings.
698
 *
699
 * For any setting other than those defaults for windowBits and memLevel,
700
 * the value returned is a conservative worst case for the maximum expansion
701
 * resulting from using fixed blocks instead of stored blocks, which deflate
702
 * can emit on compressed data for some combinations of the parameters.
703
 *
704
 * This function could be more sophisticated to provide closer upper bounds for
705
 * every combination of windowBits and memLevel.  But even the conservative
706
 * upper bound of about 14% expansion does not seem onerous for output buffer
707
 * allocation.
708
 */
709
6.72k
unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long sourceLen) {
710
6.72k
    deflate_state *s;
711
6.72k
    unsigned long complen, wraplen;
712
713
    /* conservative upper bound for compressed data */
714
6.72k
    complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
715
6.72k
    DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen);  /* hook for IBM Z DFLTCC */
716
717
    /* if can't get parameters, return conservative bound plus zlib wrapper */
718
6.72k
    if (deflateStateCheck(strm))
719
0
        return complen + 6;
720
721
    /* compute wrapper length */
722
6.72k
    s = strm->state;
723
6.72k
    switch (s->wrap) {
724
0
    case 0:                                 /* raw deflate */
725
0
        wraplen = 0;
726
0
        break;
727
6.72k
    case 1:                                 /* zlib wrapper */
728
6.72k
        wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0);
729
6.72k
        break;
730
0
#ifdef GZIP
731
0
    case 2:                                 /* gzip wrapper */
732
0
        wraplen = GZIP_WRAPLEN;
733
0
        if (s->gzhead != NULL) {            /* user-supplied gzip header */
734
0
            unsigned char *str;
735
0
            if (s->gzhead->extra != NULL) {
736
0
                wraplen += 2 + s->gzhead->extra_len;
737
0
            }
738
0
            str = s->gzhead->name;
739
0
            if (str != NULL) {
740
0
                do {
741
0
                    wraplen++;
742
0
                } while (*str++);
743
0
            }
744
0
            str = s->gzhead->comment;
745
0
            if (str != NULL) {
746
0
                do {
747
0
                    wraplen++;
748
0
                } while (*str++);
749
0
            }
750
0
            if (s->gzhead->hcrc)
751
0
                wraplen += 2;
752
0
        }
753
0
        break;
754
0
#endif
755
0
    default:                                /* for compiler happiness */
756
0
        wraplen = ZLIB_WRAPLEN;
757
6.72k
    }
758
759
    /* if not default parameters, return conservative bound */
760
6.72k
    if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) ||  /* hook for IBM Z DFLTCC */
761
6.72k
            s->w_bits != MAX_WBITS || HASH_BITS < 15) {
762
5.37k
        if (s->level == 0) {
763
            /* upper bound for stored blocks with length 127 (memLevel == 1) --
764
               ~4% overhead plus a small constant */
765
0
            complen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + (sourceLen >> 11) + 7;
766
0
        }
767
768
5.37k
        return complen + wraplen;
769
5.37k
    }
770
771
1.34k
#ifndef NO_QUICK_STRATEGY
772
1.34k
    return sourceLen                       /* The source size itself */
773
1.34k
      + (sourceLen == 0 ? 1 : 0)           /* Always at least one byte for any input */
774
1.34k
      + (sourceLen < 9 ? 1 : 0)            /* One extra byte for lengths less than 9 */
775
1.34k
      + DEFLATE_QUICK_OVERHEAD(sourceLen)  /* Source encoding overhead, padded to next full byte */
776
1.34k
      + DEFLATE_BLOCK_OVERHEAD             /* Deflate block overhead bytes */
777
1.34k
      + wraplen;                           /* none, zlib or gzip wrapper */
778
#else
779
    return sourceLen + (sourceLen >> 4) + 7 + wraplen;
780
#endif
781
6.72k
}
782
783
/* =========================================================================
784
 * Flush as much pending output as possible. All deflate() output, except for
785
 * some deflate_stored() output, goes through this function so some
786
 * applications may wish to modify it to avoid allocating a large
787
 * strm->next_out buffer and copying into it. (See also read_buf()).
788
 */
789
104M
Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm) {
790
104M
    uint32_t len;
791
104M
    deflate_state *s = strm->state;
792
793
104M
    zng_tr_flush_bits(s);
794
104M
    len = MIN(s->pending, strm->avail_out);
795
104M
    if (len == 0)
796
11.7k
        return;
797
798
104M
    Tracev((stderr, "[FLUSH]"));
799
104M
    memcpy(strm->next_out, s->pending_out, len);
800
104M
    strm->next_out  += len;
801
104M
    s->pending_out  += len;
802
104M
    strm->total_out += len;
803
104M
    strm->avail_out -= len;
804
104M
    s->pending      -= len;
805
104M
    if (s->pending == 0)
806
217k
        s->pending_out = s->pending_buf;
807
104M
}
808
809
/* ===========================================================================
810
 * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
811
 */
812
#define HCRC_UPDATE(beg) \
813
0
    do { \
814
0
        if (s->gzhead->hcrc && s->pending > (beg)) \
815
0
            strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \
816
0
    } while (0)
817
818
/* ========================================================================= */
819
254M
int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) {
820
254M
    int32_t old_flush; /* value of flush param for previous deflate call */
821
254M
    deflate_state *s;
822
823
254M
    if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0)
824
0
        return Z_STREAM_ERROR;
825
254M
    s = strm->state;
826
827
254M
    if (strm->next_out == NULL || (strm->avail_in != 0 && strm->next_in == NULL)
828
254M
        || (s->status == FINISH_STATE && flush != Z_FINISH)) {
829
0
        ERR_RETURN(strm, Z_STREAM_ERROR);
830
0
    }
831
254M
    if (strm->avail_out == 0) {
832
0
        ERR_RETURN(strm, Z_BUF_ERROR);
833
0
    }
834
835
254M
    old_flush = s->last_flush;
836
254M
    s->last_flush = flush;
837
838
    /* Flush as much pending output as possible */
839
254M
    if (s->pending != 0) {
840
103M
        PREFIX(flush_pending)(strm);
841
103M
        if (strm->avail_out == 0) {
842
            /* Since avail_out is 0, deflate will be called again with
843
             * more output space, but possibly with both pending and
844
             * avail_in equal to zero. There won't be anything to do,
845
             * but this is not an error situation so make sure we
846
             * return OK instead of BUF_ERROR at next call of deflate:
847
             */
848
103M
            s->last_flush = -1;
849
103M
            return Z_OK;
850
103M
        }
851
852
        /* Make sure there is something to do and avoid duplicate consecutive
853
         * flushes. For repeated and useless calls with Z_FINISH, we keep
854
         * returning Z_STREAM_END instead of Z_BUF_ERROR.
855
         */
856
150M
    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) {
857
1.98k
        ERR_RETURN(strm, Z_BUF_ERROR);
858
1.98k
    }
859
860
    /* User must not provide more input after the first FINISH: */
861
150M
    if (s->status == FINISH_STATE && strm->avail_in != 0)   {
862
0
        ERR_RETURN(strm, Z_BUF_ERROR);
863
0
    }
864
865
    /* Write the header */
866
150M
    if (s->status == INIT_STATE && s->wrap == 0)
867
0
        s->status = BUSY_STATE;
868
150M
    if (s->status == INIT_STATE) {
869
        /* zlib header */
870
33.3k
        unsigned int header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
871
33.3k
        unsigned int level_flags;
872
873
33.3k
        if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
874
7.67k
            level_flags = 0;
875
25.6k
        else if (s->level < 6)
876
5.59k
            level_flags = 1;
877
20.0k
        else if (s->level == 6)
878
12.0k
            level_flags = 2;
879
8.04k
        else
880
8.04k
            level_flags = 3;
881
33.3k
        header |= (level_flags << 6);
882
33.3k
        if (s->strstart != 0)
883
6.41k
            header |= PRESET_DICT;
884
33.3k
        header += 31 - (header % 31);
885
886
33.3k
        put_short_msb(s, (uint16_t)header);
887
888
        /* Save the adler32 of the preset dictionary: */
889
33.3k
        if (s->strstart != 0)
890
6.41k
            put_uint32_msb(s, strm->adler);
891
33.3k
        strm->adler = ADLER32_INITIAL_VALUE;
892
33.3k
        s->status = BUSY_STATE;
893
894
        /* Compression must start with an empty pending buffer */
895
33.3k
        PREFIX(flush_pending)(strm);
896
33.3k
        if (s->pending != 0) {
897
2.78k
            s->last_flush = -1;
898
2.78k
            return Z_OK;
899
2.78k
        }
900
33.3k
    }
901
150M
#ifdef GZIP
902
150M
    if (s->status == GZIP_STATE) {
903
        /* gzip header */
904
6.25k
        FUNCTABLE_CALL(crc32_fold_reset)(&s->crc_fold);
905
6.25k
        put_byte(s, 31);
906
6.25k
        put_byte(s, 139);
907
6.25k
        put_byte(s, 8);
908
6.25k
        if (s->gzhead == NULL) {
909
6.25k
            put_uint32(s, 0);
910
6.25k
            put_byte(s, 0);
911
6.25k
            put_byte(s, s->level == 9 ? 2 :
912
6.25k
                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0));
913
6.25k
            put_byte(s, OS_CODE);
914
6.25k
            s->status = BUSY_STATE;
915
916
            /* Compression must start with an empty pending buffer */
917
6.25k
            PREFIX(flush_pending)(strm);
918
6.25k
            if (s->pending != 0) {
919
0
                s->last_flush = -1;
920
0
                return Z_OK;
921
0
            }
922
6.25k
        } else {
923
0
            put_byte(s, (s->gzhead->text ? 1 : 0) +
924
0
                     (s->gzhead->hcrc ? 2 : 0) +
925
0
                     (s->gzhead->extra == NULL ? 0 : 4) +
926
0
                     (s->gzhead->name == NULL ? 0 : 8) +
927
0
                     (s->gzhead->comment == NULL ? 0 : 16)
928
0
                     );
929
0
            put_uint32(s, s->gzhead->time);
930
0
            put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0));
931
0
            put_byte(s, s->gzhead->os & 0xff);
932
0
            if (s->gzhead->extra != NULL)
933
0
                put_short(s, (uint16_t)s->gzhead->extra_len);
934
0
            if (s->gzhead->hcrc)
935
0
                strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending);
936
0
            s->gzindex = 0;
937
0
            s->status = EXTRA_STATE;
938
0
        }
939
6.25k
    }
940
150M
    if (s->status == EXTRA_STATE) {
941
0
        if (s->gzhead->extra != NULL) {
942
0
            uint32_t beg = s->pending;   /* start of bytes to update crc */
943
0
            uint32_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
944
945
0
            while (s->pending + left > s->pending_buf_size) {
946
0
                uint32_t copy = s->pending_buf_size - s->pending;
947
0
                memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy);
948
0
                s->pending = s->pending_buf_size;
949
0
                HCRC_UPDATE(beg);
950
0
                s->gzindex += copy;
951
0
                PREFIX(flush_pending)(strm);
952
0
                if (s->pending != 0) {
953
0
                    s->last_flush = -1;
954
0
                    return Z_OK;
955
0
                }
956
0
                beg = 0;
957
0
                left -= copy;
958
0
            }
959
0
            memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, left);
960
0
            s->pending += left;
961
0
            HCRC_UPDATE(beg);
962
0
            s->gzindex = 0;
963
0
        }
964
0
        s->status = NAME_STATE;
965
0
    }
966
150M
    if (s->status == NAME_STATE) {
967
0
        if (s->gzhead->name != NULL) {
968
0
            uint32_t beg = s->pending;   /* start of bytes to update crc */
969
0
            unsigned char val;
970
971
0
            do {
972
0
                if (s->pending == s->pending_buf_size) {
973
0
                    HCRC_UPDATE(beg);
974
0
                    PREFIX(flush_pending)(strm);
975
0
                    if (s->pending != 0) {
976
0
                        s->last_flush = -1;
977
0
                        return Z_OK;
978
0
                    }
979
0
                    beg = 0;
980
0
                }
981
0
                val = s->gzhead->name[s->gzindex++];
982
0
                put_byte(s, val);
983
0
            } while (val != 0);
984
0
            HCRC_UPDATE(beg);
985
0
            s->gzindex = 0;
986
0
        }
987
0
        s->status = COMMENT_STATE;
988
0
    }
989
150M
    if (s->status == COMMENT_STATE) {
990
0
        if (s->gzhead->comment != NULL) {
991
0
            uint32_t beg = s->pending;  /* start of bytes to update crc */
992
0
            unsigned char val;
993
994
0
            do {
995
0
                if (s->pending == s->pending_buf_size) {
996
0
                    HCRC_UPDATE(beg);
997
0
                    PREFIX(flush_pending)(strm);
998
0
                    if (s->pending != 0) {
999
0
                        s->last_flush = -1;
1000
0
                        return Z_OK;
1001
0
                    }
1002
0
                    beg = 0;
1003
0
                }
1004
0
                val = s->gzhead->comment[s->gzindex++];
1005
0
                put_byte(s, val);
1006
0
            } while (val != 0);
1007
0
            HCRC_UPDATE(beg);
1008
0
        }
1009
0
        s->status = HCRC_STATE;
1010
0
    }
1011
150M
    if (s->status == HCRC_STATE) {
1012
0
        if (s->gzhead->hcrc) {
1013
0
            if (s->pending + 2 > s->pending_buf_size) {
1014
0
                PREFIX(flush_pending)(strm);
1015
0
                if (s->pending != 0) {
1016
0
                    s->last_flush = -1;
1017
0
                    return Z_OK;
1018
0
                }
1019
0
            }
1020
0
            put_short(s, (uint16_t)strm->adler);
1021
0
            FUNCTABLE_CALL(crc32_fold_reset)(&s->crc_fold);
1022
0
        }
1023
0
        s->status = BUSY_STATE;
1024
1025
        /* Compression must start with an empty pending buffer */
1026
0
        PREFIX(flush_pending)(strm);
1027
0
        if (s->pending != 0) {
1028
0
            s->last_flush = -1;
1029
0
            return Z_OK;
1030
0
        }
1031
0
    }
1032
150M
#endif
1033
1034
    /* Start a new block or continue the current one.
1035
     */
1036
150M
    if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
1037
150M
        block_state bstate;
1038
1039
150M
        bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate :  /* hook for IBM Z DFLTCC */
1040
150M
                 s->level == 0 ? deflate_stored(s, flush) :
1041
150M
                 s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
1042
150M
                 s->strategy == Z_RLE ? deflate_rle(s, flush) :
1043
150M
                 (*(configuration_table[s->level].func))(s, flush);
1044
1045
150M
        if (bstate == finish_started || bstate == finish_done) {
1046
39.5k
            s->status = FINISH_STATE;
1047
39.5k
        }
1048
150M
        if (bstate == need_more || bstate == finish_started) {
1049
150M
            if (strm->avail_out == 0) {
1050
10.4k
                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
1051
10.4k
            }
1052
150M
            return Z_OK;
1053
            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
1054
             * of deflate should use the same flush parameter to make sure
1055
             * that the flush is complete. So we don't have to output an
1056
             * empty block here, this will be done at next call. This also
1057
             * ensures that for a very small output buffer, we emit at most
1058
             * one empty block.
1059
             */
1060
150M
        }
1061
42.7k
        if (bstate == block_done) {
1062
6.18k
            if (flush == Z_PARTIAL_FLUSH) {
1063
0
                zng_tr_align(s);
1064
6.18k
            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
1065
3.57k
                zng_tr_stored_block(s, (char*)0, 0L, 0);
1066
                /* For a full flush, this empty block will be recognized
1067
                 * as a special marker by inflate_sync().
1068
                 */
1069
3.57k
                if (flush == Z_FULL_FLUSH) {
1070
3.57k
                    CLEAR_HASH(s);             /* forget history */
1071
3.57k
                    if (s->lookahead == 0) {
1072
3.57k
                        s->strstart = 0;
1073
3.57k
                        s->block_start = 0;
1074
3.57k
                        s->insert = 0;
1075
3.57k
                    }
1076
3.57k
                }
1077
3.57k
            }
1078
6.18k
            PREFIX(flush_pending)(strm);
1079
6.18k
            if (strm->avail_out == 0) {
1080
0
                s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
1081
0
                return Z_OK;
1082
0
            }
1083
6.18k
        }
1084
42.7k
    }
1085
1086
55.0k
    if (flush != Z_FINISH)
1087
6.41k
        return Z_OK;
1088
1089
    /* Write the trailer */
1090
48.6k
#ifdef GZIP
1091
48.6k
    if (s->wrap == 2) {
1092
6.25k
        strm->adler = FUNCTABLE_CALL(crc32_fold_final)(&s->crc_fold);
1093
1094
6.25k
        put_uint32(s, strm->adler);
1095
6.25k
        put_uint32(s, (uint32_t)strm->total_in);
1096
6.25k
    } else
1097
42.4k
#endif
1098
42.4k
    {
1099
42.4k
        if (s->wrap == 1)
1100
33.3k
            put_uint32_msb(s, strm->adler);
1101
42.4k
    }
1102
48.6k
    PREFIX(flush_pending)(strm);
1103
    /* If avail_out is zero, the application will call deflate again
1104
     * to flush the rest.
1105
     */
1106
48.6k
    if (s->wrap > 0)
1107
39.5k
        s->wrap = -s->wrap; /* write the trailer only once! */
1108
48.6k
    if (s->pending == 0) {
1109
45.8k
        Assert(s->bi_valid == 0, "bi_buf not flushed");
1110
45.8k
        return Z_STREAM_END;
1111
45.8k
    }
1112
2.80k
    return Z_OK;
1113
48.6k
}
1114
1115
/* ========================================================================= */
1116
39.5k
int32_t Z_EXPORT PREFIX(deflateEnd)(PREFIX3(stream) *strm) {
1117
39.5k
    if (deflateStateCheck(strm))
1118
0
        return Z_STREAM_ERROR;
1119
1120
39.5k
    int32_t status = strm->state->status;
1121
1122
    /* Free allocated buffers */
1123
39.5k
    free_deflate(strm);
1124
1125
39.5k
    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
1126
39.5k
}
1127
1128
/* =========================================================================
1129
 * Copy the source state to the destination state.
1130
 */
1131
0
int32_t Z_EXPORT PREFIX(deflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) {
1132
0
    deflate_state *ds;
1133
0
    deflate_state *ss;
1134
1135
0
    if (deflateStateCheck(source) || dest == NULL)
1136
0
        return Z_STREAM_ERROR;
1137
1138
0
    ss = source->state;
1139
1140
0
    memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream)));
1141
1142
0
    deflate_allocs *alloc_bufs = alloc_deflate(dest, ss->w_bits, ss->lit_bufsize);
1143
0
    if (alloc_bufs == NULL)
1144
0
        return Z_MEM_ERROR;
1145
1146
0
    ds = alloc_bufs->state;
1147
1148
0
    dest->state = (struct internal_state *) ds;
1149
0
    memcpy(ds, ss, sizeof(deflate_state));
1150
0
    ds->strm = dest;
1151
1152
0
    ds->alloc_bufs = alloc_bufs;
1153
0
    ds->window = alloc_bufs->window;
1154
0
    ds->prev = alloc_bufs->prev;
1155
0
    ds->head = alloc_bufs->head;
1156
0
    ds->pending_buf = alloc_bufs->pending_buf;
1157
1158
0
    if (ds->window == NULL || ds->prev == NULL || ds->head == NULL || ds->pending_buf == NULL) {
1159
0
        PREFIX(deflateEnd)(dest);
1160
0
        return Z_MEM_ERROR;
1161
0
    }
1162
1163
0
    memcpy(ds->window, ss->window, DEFLATE_ADJUST_WINDOW_SIZE(ds->w_size * 2 * sizeof(unsigned char)));
1164
0
    memcpy((void *)ds->prev, (void *)ss->prev, ds->w_size * sizeof(Pos));
1165
0
    memcpy((void *)ds->head, (void *)ss->head, HASH_SIZE * sizeof(Pos));
1166
0
    memcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS);
1167
1168
0
    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
1169
0
#ifdef LIT_MEM
1170
0
    ds->d_buf = (uint16_t *)(ds->pending_buf + (ds->lit_bufsize << 1));
1171
0
    ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2);
1172
#else
1173
    ds->sym_buf = ds->pending_buf + ds->lit_bufsize;
1174
#endif
1175
1176
0
    ds->l_desc.dyn_tree = ds->dyn_ltree;
1177
0
    ds->d_desc.dyn_tree = ds->dyn_dtree;
1178
0
    ds->bl_desc.dyn_tree = ds->bl_tree;
1179
1180
0
    return Z_OK;
1181
0
}
1182
1183
/* ===========================================================================
1184
 * Read a new buffer from the current input stream, update the adler32
1185
 * and total number of bytes read.  All deflate() input goes through
1186
 * this function so some applications may wish to modify it to avoid
1187
 * allocating a large strm->next_in buffer and copying from it.
1188
 * (See also flush_pending()).
1189
 */
1190
150M
Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) {
1191
150M
    uint32_t len = MIN(strm->avail_in, size);
1192
150M
    if (len == 0)
1193
0
        return 0;
1194
1195
150M
    strm->avail_in  -= len;
1196
1197
150M
    if (!DEFLATE_NEED_CHECKSUM(strm)) {
1198
0
        memcpy(buf, strm->next_in, len);
1199
0
#ifdef GZIP
1200
150M
    } else if (strm->state->wrap == 2) {
1201
16.1k
        FUNCTABLE_CALL(crc32_fold_copy)(&strm->state->crc_fold, buf, strm->next_in, len);
1202
16.1k
#endif
1203
150M
    } else if (strm->state->wrap == 1) {
1204
150M
        strm->adler = FUNCTABLE_CALL(adler32_fold_copy)(strm->adler, buf, strm->next_in, len);
1205
150M
    } else {
1206
6.41k
        memcpy(buf, strm->next_in, len);
1207
6.41k
    }
1208
150M
    strm->next_in  += len;
1209
150M
    strm->total_in += len;
1210
1211
150M
    return len;
1212
150M
}
1213
1214
/* ===========================================================================
1215
 * Set longest match variables based on level configuration
1216
 */
1217
42.2k
static void lm_set_level(deflate_state *s, int level) {
1218
42.2k
    s->max_lazy_match   = configuration_table[level].max_lazy;
1219
42.2k
    s->good_match       = configuration_table[level].good_length;
1220
42.2k
    s->nice_match       = configuration_table[level].nice_length;
1221
42.2k
    s->max_chain_length = configuration_table[level].max_chain;
1222
1223
    /* Use rolling hash for deflate_slow algorithm with level 9. It allows us to
1224
     * properly lookup different hash chains to speed up longest_match search. Since hashing
1225
     * method changes depending on the level we cannot put this into functable. */
1226
42.2k
    if (s->max_chain_length > 1024) {
1227
6.01k
        s->update_hash = &update_hash_roll;
1228
6.01k
        s->insert_string = &insert_string_roll;
1229
6.01k
        s->quick_insert_string = &quick_insert_string_roll;
1230
36.1k
    } else {
1231
36.1k
        s->update_hash = update_hash;
1232
36.1k
        s->insert_string = insert_string;
1233
36.1k
        s->quick_insert_string = quick_insert_string;
1234
36.1k
    }
1235
1236
42.2k
    s->level = level;
1237
42.2k
}
1238
1239
/* ===========================================================================
1240
 * Initialize the "longest match" routines for a new zlib stream
1241
 */
1242
39.5k
static void lm_init(deflate_state *s) {
1243
39.5k
    s->window_size = 2 * s->w_size;
1244
1245
39.5k
    CLEAR_HASH(s);
1246
1247
    /* Set the default configuration parameters:
1248
     */
1249
39.5k
    lm_set_level(s, s->level);
1250
1251
39.5k
    s->strstart = 0;
1252
39.5k
    s->block_start = 0;
1253
39.5k
    s->lookahead = 0;
1254
39.5k
    s->insert = 0;
1255
39.5k
    s->prev_length = 0;
1256
39.5k
    s->match_available = 0;
1257
39.5k
    s->match_start = 0;
1258
39.5k
    s->ins_h = 0;
1259
39.5k
}
1260
1261
/* ===========================================================================
1262
 * Fill the window when the lookahead becomes insufficient.
1263
 * Updates strstart and lookahead.
1264
 *
1265
 * IN assertion: lookahead < MIN_LOOKAHEAD
1266
 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
1267
 *    At least one byte has been read, or avail_in == 0; reads are
1268
 *    performed for at least two bytes (required for the zip translate_eol
1269
 *    option -- not supported here).
1270
 */
1271
1272
259M
void Z_INTERNAL PREFIX(fill_window)(deflate_state *s) {
1273
259M
    unsigned n;
1274
259M
    unsigned int more;    /* Amount of free space at the end of the window. */
1275
259M
    unsigned int wsize = s->w_size;
1276
1277
259M
    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
1278
1279
259M
    do {
1280
259M
        more = s->window_size - s->lookahead - s->strstart;
1281
1282
        /* If the window is almost full and there is insufficient lookahead,
1283
         * move the upper half to the lower one to make room in the upper half.
1284
         */
1285
259M
        if (s->strstart >= wsize+MAX_DIST(s)) {
1286
70.6k
            memcpy(s->window, s->window+wsize, (unsigned)wsize);
1287
70.6k
            if (s->match_start >= wsize) {
1288
48.0k
                s->match_start -= wsize;
1289
48.0k
            } else {
1290
22.6k
                s->match_start = 0;
1291
22.6k
                s->prev_length = 0;
1292
22.6k
            }
1293
70.6k
            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
1294
70.6k
            s->block_start -= (int)wsize;
1295
70.6k
            if (s->insert > s->strstart)
1296
0
                s->insert = s->strstart;
1297
70.6k
            FUNCTABLE_CALL(slide_hash)(s);
1298
70.6k
            more += wsize;
1299
70.6k
        }
1300
259M
        if (s->strm->avail_in == 0)
1301
109M
            break;
1302
1303
        /* If there was no sliding:
1304
         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
1305
         *    more == window_size - lookahead - strstart
1306
         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
1307
         * => more >= window_size - 2*WSIZE + 2
1308
         * In the BIG_MEM or MMAP case (not yet supported),
1309
         *   window_size == input_size + MIN_LOOKAHEAD  &&
1310
         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
1311
         * Otherwise, window_size == 2*WSIZE so more >= 2.
1312
         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
1313
         */
1314
150M
        Assert(more >= 2, "more < 2");
1315
1316
150M
        n = PREFIX(read_buf)(s->strm, s->window + s->strstart + s->lookahead, more);
1317
150M
        s->lookahead += n;
1318
1319
        /* Initialize the hash value now that we have some input: */
1320
150M
        if (s->lookahead + s->insert >= STD_MIN_MATCH) {
1321
150M
            unsigned int str = s->strstart - s->insert;
1322
150M
            if (UNLIKELY(s->max_chain_length > 1024)) {
1323
27.0k
                s->ins_h = s->update_hash(s->window[str], s->window[str+1]);
1324
150M
            } else if (str >= 1) {
1325
149M
                s->quick_insert_string(s, str + 2 - STD_MIN_MATCH);
1326
149M
            }
1327
150M
            unsigned int count = s->insert;
1328
150M
            if (UNLIKELY(s->lookahead == 1)) {
1329
0
                count -= 1;
1330
0
            }
1331
150M
            if (count > 0) {
1332
7.66k
                s->insert_string(s, str, count);
1333
7.66k
                s->insert -= count;
1334
7.66k
            }
1335
150M
        }
1336
        /* If the whole input has less than STD_MIN_MATCH bytes, ins_h is garbage,
1337
         * but this is not important since only literal bytes will be emitted.
1338
         */
1339
150M
    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
1340
1341
    /* If the WIN_INIT bytes after the end of the current data have never been
1342
     * written, then zero those bytes in order to avoid memory check reports of
1343
     * the use of uninitialized (or uninitialised as Julian writes) bytes by
1344
     * the longest match routines.  Update the high water mark for the next
1345
     * time through here.  WIN_INIT is set to STD_MAX_MATCH since the longest match
1346
     * routines allow scanning to strstart + STD_MAX_MATCH, ignoring lookahead.
1347
     */
1348
259M
    if (s->high_water < s->window_size) {
1349
66.9M
        unsigned int curr = s->strstart + s->lookahead;
1350
66.9M
        unsigned int init;
1351
1352
66.9M
        if (s->high_water < curr) {
1353
            /* Previous high water mark below current data -- zero WIN_INIT
1354
             * bytes or up to end of window, whichever is less.
1355
             */
1356
44.6k
            init = s->window_size - curr;
1357
44.6k
            if (init > WIN_INIT)
1358
38.6k
                init = WIN_INIT;
1359
44.6k
            memset(s->window + curr, 0, init);
1360
44.6k
            s->high_water = curr + init;
1361
66.8M
        } else if (s->high_water < curr + WIN_INIT) {
1362
            /* High water mark at or above current data, but below current data
1363
             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
1364
             * to end of window, whichever is less.
1365
             */
1366
38.6M
            init = curr + WIN_INIT - s->high_water;
1367
38.6M
            if (init > s->window_size - s->high_water)
1368
0
                init = s->window_size - s->high_water;
1369
38.6M
            memset(s->window + s->high_water, 0, init);
1370
38.6M
            s->high_water += init;
1371
38.6M
        }
1372
66.9M
    }
1373
1374
259M
    Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD,
1375
259M
           "not enough room for search");
1376
259M
}
1377
1378
#ifndef ZLIB_COMPAT
1379
/* =========================================================================
1380
 * Checks whether buffer size is sufficient and whether this parameter is a duplicate.
1381
 */
1382
0
static int32_t deflateSetParamPre(zng_deflate_param_value **out, size_t min_size, zng_deflate_param_value *param) {
1383
0
    int32_t buf_error = param->size < min_size;
1384
1385
0
    if (*out != NULL) {
1386
0
        (*out)->status = Z_BUF_ERROR;
1387
0
        buf_error = 1;
1388
0
    }
1389
0
    *out = param;
1390
0
    return buf_error;
1391
0
}
1392
1393
/* ========================================================================= */
1394
0
int32_t Z_EXPORT zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) {
1395
0
    size_t i;
1396
0
    deflate_state *s;
1397
0
    zng_deflate_param_value *new_level = NULL;
1398
0
    zng_deflate_param_value *new_strategy = NULL;
1399
0
    zng_deflate_param_value *new_reproducible = NULL;
1400
0
    int param_buf_error;
1401
0
    int version_error = 0;
1402
0
    int buf_error = 0;
1403
0
    int stream_error = 0;
1404
1405
    /* Initialize the statuses. */
1406
0
    for (i = 0; i < count; i++)
1407
0
        params[i].status = Z_OK;
1408
1409
    /* Check whether the stream state is consistent. */
1410
0
    if (deflateStateCheck(strm))
1411
0
        return Z_STREAM_ERROR;
1412
0
    s = strm->state;
1413
1414
    /* Check buffer sizes and detect duplicates. */
1415
0
    for (i = 0; i < count; i++) {
1416
0
        switch (params[i].param) {
1417
0
            case Z_DEFLATE_LEVEL:
1418
0
                param_buf_error = deflateSetParamPre(&new_level, sizeof(int), &params[i]);
1419
0
                break;
1420
0
            case Z_DEFLATE_STRATEGY:
1421
0
                param_buf_error = deflateSetParamPre(&new_strategy, sizeof(int), &params[i]);
1422
0
                break;
1423
0
            case Z_DEFLATE_REPRODUCIBLE:
1424
0
                param_buf_error = deflateSetParamPre(&new_reproducible, sizeof(int), &params[i]);
1425
0
                break;
1426
0
            default:
1427
0
                params[i].status = Z_VERSION_ERROR;
1428
0
                version_error = 1;
1429
0
                param_buf_error = 0;
1430
0
                break;
1431
0
        }
1432
0
        if (param_buf_error) {
1433
0
            params[i].status = Z_BUF_ERROR;
1434
0
            buf_error = 1;
1435
0
        }
1436
0
    }
1437
    /* Exit early if small buffers or duplicates are detected. */
1438
0
    if (buf_error)
1439
0
        return Z_BUF_ERROR;
1440
1441
    /* Apply changes, remember if there were errors. */
1442
0
    if (new_level != NULL || new_strategy != NULL) {
1443
0
        int ret = PREFIX(deflateParams)(strm, new_level == NULL ? s->level : *(int *)new_level->buf,
1444
0
                                        new_strategy == NULL ? s->strategy : *(int *)new_strategy->buf);
1445
0
        if (ret != Z_OK) {
1446
0
            if (new_level != NULL)
1447
0
                new_level->status = Z_STREAM_ERROR;
1448
0
            if (new_strategy != NULL)
1449
0
                new_strategy->status = Z_STREAM_ERROR;
1450
0
            stream_error = 1;
1451
0
        }
1452
0
    }
1453
0
    if (new_reproducible != NULL) {
1454
0
        int val = *(int *)new_reproducible->buf;
1455
0
        if (DEFLATE_CAN_SET_REPRODUCIBLE(strm, val)) {
1456
0
            s->reproducible = val;
1457
0
        } else {
1458
0
            new_reproducible->status = Z_STREAM_ERROR;
1459
0
            stream_error = 1;
1460
0
        }
1461
0
    }
1462
1463
    /* Report version errors only if there are no real errors. */
1464
0
    return stream_error ? Z_STREAM_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK);
1465
0
}
1466
1467
/* ========================================================================= */
1468
0
int32_t Z_EXPORT zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) {
1469
0
    deflate_state *s;
1470
0
    size_t i;
1471
0
    int32_t buf_error = 0;
1472
0
    int32_t version_error = 0;
1473
1474
    /* Initialize the statuses. */
1475
0
    for (i = 0; i < count; i++)
1476
0
        params[i].status = Z_OK;
1477
1478
    /* Check whether the stream state is consistent. */
1479
0
    if (deflateStateCheck(strm))
1480
0
        return Z_STREAM_ERROR;
1481
0
    s = strm->state;
1482
1483
0
    for (i = 0; i < count; i++) {
1484
0
        switch (params[i].param) {
1485
0
            case Z_DEFLATE_LEVEL:
1486
0
                if (params[i].size < sizeof(int))
1487
0
                    params[i].status = Z_BUF_ERROR;
1488
0
                else
1489
0
                    *(int *)params[i].buf = s->level;
1490
0
                break;
1491
0
            case Z_DEFLATE_STRATEGY:
1492
0
                if (params[i].size < sizeof(int))
1493
0
                    params[i].status = Z_BUF_ERROR;
1494
0
                else
1495
0
                    *(int *)params[i].buf = s->strategy;
1496
0
                break;
1497
0
            case Z_DEFLATE_REPRODUCIBLE:
1498
0
                if (params[i].size < sizeof(int))
1499
0
                    params[i].status = Z_BUF_ERROR;
1500
0
                else
1501
0
                    *(int *)params[i].buf = s->reproducible;
1502
0
                break;
1503
0
            default:
1504
0
                params[i].status = Z_VERSION_ERROR;
1505
0
                version_error = 1;
1506
0
                break;
1507
0
        }
1508
0
        if (params[i].status == Z_BUF_ERROR)
1509
0
            buf_error = 1;
1510
0
    }
1511
0
    return buf_error ? Z_BUF_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK);
1512
0
}
1513
#endif