Coverage Report

Created: 2026-08-14 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opencv/3rdparty/zlib/gzwrite.c
Line
Count
Source
1
/* gzwrite.c -- zlib functions for writing gzip files
2
 * Copyright (C) 2004-2026 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
5
6
#include "gzguts.h"
7
8
#ifdef HAVE_UNISTD_H
9
    #include <unistd.h>
10
#endif
11
12
/* Initialize state for writing a gzip file.  Mark initialization by setting
13
   state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on
14
   success. */
15
0
local int gz_init(gz_statep state) {
16
0
    int ret;
17
0
    z_streamp strm = &(state->strm);
18
19
    /* allocate input buffer (double size for gzprintf) */
20
0
    state->in = (unsigned char *)malloc(state->want << 1);
21
0
    if (state->in == NULL) {
22
0
        gz_error(state, Z_MEM_ERROR, "out of memory");
23
0
        return -1;
24
0
    }
25
26
    /* only need output buffer and deflate state if compressing */
27
0
    if (!state->direct) {
28
        /* allocate output buffer */
29
0
        state->out = (unsigned char *)malloc(state->want);
30
0
        if (state->out == NULL) {
31
0
            free(state->in);
32
0
            gz_error(state, Z_MEM_ERROR, "out of memory");
33
0
            return -1;
34
0
        }
35
36
        /* allocate deflate memory, set up for gzip compression */
37
0
        strm->zalloc = Z_NULL;
38
0
        strm->zfree = Z_NULL;
39
0
        strm->opaque = Z_NULL;
40
0
        ret = deflateInit2(strm, state->level, Z_DEFLATED,
41
0
                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
42
0
        if (ret != Z_OK) {
43
0
            free(state->out);
44
0
            free(state->in);
45
0
            gz_error(state, Z_MEM_ERROR, "out of memory");
46
0
            return -1;
47
0
        }
48
0
        strm->next_in = NULL;
49
0
    }
50
51
    /* mark state as initialized */
52
0
    state->size = state->want;
53
54
    /* initialize write buffer if compressing */
55
0
    if (!state->direct) {
56
0
        strm->avail_out = state->size;
57
0
        strm->next_out = state->out;
58
0
        state->x.next = strm->next_out;
59
0
    }
60
0
    return 0;
61
0
}
62
63
/* Compress whatever is at avail_in and next_in and write to the output file.
64
   Return -1 if there is an error writing to the output file or if gz_init()
65
   fails to allocate memory, otherwise 0.  flush is assumed to be a valid
66
   deflate() flush value.  If flush is Z_FINISH, then the deflate() state is
67
   reset to start a new gzip stream.  If gz->direct is true, then simply write
68
   to the output file without compressing, and ignore flush. */
69
0
local int gz_comp(gz_statep state, int flush) {
70
0
    int ret, writ;
71
0
    unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
72
0
    z_streamp strm = &(state->strm);
73
74
    /* allocate memory if this is the first time through */
75
0
    if (state->size == 0 && gz_init(state) == -1)
76
0
        return -1;
77
78
    /* write directly if requested */
79
0
    if (state->direct) {
80
0
        while (strm->avail_in) {
81
0
            errno = 0;
82
0
            state->again = 0;
83
0
            put = strm->avail_in > max ? max : strm->avail_in;
84
0
            writ = (int)write(state->fd, strm->next_in, put);
85
0
            if (writ < 0) {
86
0
                if (errno == EAGAIN || errno == EWOULDBLOCK)
87
0
                    state->again = 1;
88
0
                gz_error(state, Z_ERRNO, zstrerror());
89
0
                return -1;
90
0
            }
91
0
            strm->avail_in -= (unsigned)writ;
92
0
            strm->next_in += writ;
93
0
        }
94
0
        return 0;
95
0
    }
96
97
    /* check for a pending reset */
98
0
    if (state->reset) {
99
        /* don't start a new gzip member unless there is data to write and
100
           we're not flushing */
101
0
        if (strm->avail_in == 0 && flush == Z_NO_FLUSH)
102
0
            return 0;
103
0
        deflateReset(strm);
104
0
        state->reset = 0;
105
0
    }
106
107
    /* run deflate() on provided input until it produces no more output */
108
0
    ret = Z_OK;
109
0
    do {
110
        /* write out current buffer contents if full, or if flushing, but if
111
           doing Z_FINISH then don't write until we get to Z_STREAM_END */
112
0
        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
113
0
            (flush != Z_FINISH || ret == Z_STREAM_END))) {
114
0
            while (strm->next_out > state->x.next) {
115
0
                errno = 0;
116
0
                state->again = 0;
117
0
                put = strm->next_out - state->x.next > (int)max ? max :
118
0
                      (unsigned)(strm->next_out - state->x.next);
119
0
                writ = (int)write(state->fd, state->x.next, put);
120
0
                if (writ < 0) {
121
0
                    if (errno == EAGAIN || errno == EWOULDBLOCK)
122
0
                        state->again = 1;
123
0
                    gz_error(state, Z_ERRNO, zstrerror());
124
0
                    return -1;
125
0
                }
126
0
                state->x.next += writ;
127
0
            }
128
0
            if (strm->avail_out == 0) {
129
0
                strm->avail_out = state->size;
130
0
                strm->next_out = state->out;
131
0
                state->x.next = state->out;
132
0
            }
133
0
        }
134
135
        /* compress */
136
0
        have = strm->avail_out;
137
0
        ret = deflate(strm, flush);
138
0
        if (ret == Z_STREAM_ERROR) {
139
0
            gz_error(state, Z_STREAM_ERROR,
140
0
                      "internal error: deflate stream corrupt");
141
0
            return -1;
142
0
        }
143
0
        have -= strm->avail_out;
144
0
    } while (have);
145
146
    /* if that completed a deflate stream, allow another to start */
147
0
    if (flush == Z_FINISH)
148
0
        state->reset = 1;
149
150
    /* all done, no errors */
151
0
    return 0;
152
0
}
153
154
/* Compress state->skip (> 0) zeros to output.  Return -1 on a write error or
155
   memory allocation failure by gz_comp(), or 0 on success. state->skip is
156
   updated with the number of successfully written zeros, in case there is a
157
   stall on a non-blocking write destination. */
158
0
local int gz_zero(gz_statep state) {
159
0
    int first, ret;
160
0
    unsigned n;
161
0
    z_streamp strm = &(state->strm);
162
163
    /* consume whatever's left in the input buffer */
164
0
    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
165
0
        return -1;
166
167
    /* compress state->skip zeros */
168
0
    first = 1;
169
0
    do {
170
0
        n = GT_OFF(state->size) || (z_off64_t)state->size > state->skip ?
171
0
            (unsigned)state->skip : state->size;
172
0
        if (first) {
173
0
            memset(state->in, 0, n);
174
0
            first = 0;
175
0
        }
176
0
        strm->avail_in = n;
177
0
        strm->next_in = state->in;
178
0
        ret = gz_comp(state, Z_NO_FLUSH);
179
0
        n -= strm->avail_in;
180
0
        state->x.pos += n;
181
0
        state->skip -= n;
182
0
        if (ret == -1)
183
0
            return -1;
184
0
    } while (state->skip);
185
0
    return 0;
186
0
}
187
188
/* Write len bytes from buf to file.  Return the number of bytes written.  If
189
   the returned value is less than len, then there was an error. If the error
190
   was a non-blocking stall, then the number of bytes consumed is returned.
191
   For any other error, 0 is returned. */
192
0
local z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) {
193
0
    z_size_t put = len;
194
0
    int ret;
195
196
    /* if len is zero, avoid unnecessary operations */
197
0
    if (len == 0)
198
0
        return 0;
199
200
    /* allocate memory if this is the first time through */
201
0
    if (state->size == 0 && gz_init(state) == -1)
202
0
        return 0;
203
204
    /* check for seek request */
205
0
    if (state->skip && gz_zero(state) == -1)
206
0
        return 0;
207
208
    /* for small len, copy to input buffer, otherwise compress directly */
209
0
    if (len < state->size) {
210
        /* copy to input buffer, compress when full */
211
0
        for (;;) {
212
0
            unsigned have, copy;
213
214
0
            if (state->strm.avail_in == 0)
215
0
                state->strm.next_in = state->in;
216
0
            have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
217
0
                              state->in);
218
0
            copy = state->size - have;
219
0
            if (copy > len)
220
0
                copy = (unsigned)len;
221
0
            memcpy(state->in + have, buf, copy);
222
0
            state->strm.avail_in += copy;
223
0
            state->x.pos += copy;
224
0
            buf = (const char *)buf + copy;
225
0
            len -= copy;
226
0
            if (len == 0)
227
0
                break;
228
0
            if (gz_comp(state, Z_NO_FLUSH) == -1)
229
0
                return state->again ? put - len : 0;
230
0
        }
231
0
    }
232
0
    else {
233
        /* consume whatever's left in the input buffer */
234
0
        if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
235
0
            return 0;
236
237
        /* directly compress user buffer to file */
238
0
        state->strm.next_in = (z_const Bytef *)buf;
239
0
        do {
240
0
            unsigned n = (unsigned)-1;
241
242
0
            if (n > len)
243
0
                n = (unsigned)len;
244
0
            state->strm.avail_in = n;
245
0
            ret = gz_comp(state, Z_NO_FLUSH);
246
0
            n -= state->strm.avail_in;
247
0
            state->x.pos += n;
248
0
            len -= n;
249
0
            if (ret == -1)
250
0
                return state->again ? put - len : 0;
251
0
        } while (len);
252
0
    }
253
254
    /* input was all buffered or compressed */
255
0
    return put;
256
0
}
257
258
/* -- see zlib.h -- */
259
0
int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) {
260
0
    gz_statep state;
261
262
    /* get internal structure */
263
0
    if (file == NULL)
264
0
        return 0;
265
0
    state = (gz_statep)file;
266
267
    /* check that we're writing and that there's no (serious) error */
268
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
269
0
        return 0;
270
0
    gz_error(state, Z_OK, NULL);
271
272
    /* since an int is returned, make sure len fits in one, otherwise return
273
       with an error (this avoids a flaw in the interface) */
274
0
    if ((int)len < 0) {
275
0
        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
276
0
        return 0;
277
0
    }
278
279
    /* write len bytes from buf (the return value will fit in an int) */
280
0
    return (int)gz_write(state, buf, len);
281
0
}
282
283
/* -- see zlib.h -- */
284
z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems,
285
0
                          gzFile file) {
286
0
    z_size_t len;
287
0
    gz_statep state;
288
289
    /* get internal structure */
290
0
    if (file == NULL)
291
0
        return 0;
292
0
    state = (gz_statep)file;
293
294
    /* check that we're writing and that there's no (serious) error */
295
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
296
0
        return 0;
297
0
    gz_error(state, Z_OK, NULL);
298
299
    /* compute bytes to read -- error on overflow */
300
0
    len = nitems * size;
301
0
    if (size && len / size != nitems) {
302
0
        gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
303
0
        return 0;
304
0
    }
305
306
    /* write len bytes to buf, return the number of full items written */
307
0
    return len ? gz_write(state, buf, len) / size : 0;
308
0
}
309
310
/* -- see zlib.h -- */
311
0
int ZEXPORT gzputc(gzFile file, int c) {
312
0
    unsigned have;
313
0
    unsigned char buf[1];
314
0
    gz_statep state;
315
0
    z_streamp strm;
316
317
    /* get internal structure */
318
0
    if (file == NULL)
319
0
        return -1;
320
0
    state = (gz_statep)file;
321
0
    strm = &(state->strm);
322
323
    /* check that we're writing and that there's no (serious) error */
324
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
325
0
        return -1;
326
0
    gz_error(state, Z_OK, NULL);
327
328
    /* check for seek request */
329
0
    if (state->skip && gz_zero(state) == -1)
330
0
        return -1;
331
332
    /* try writing to input buffer for speed (state->size == 0 if buffer not
333
       initialized) */
334
0
    if (state->size) {
335
0
        if (strm->avail_in == 0)
336
0
            strm->next_in = state->in;
337
0
        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
338
0
        if (have < state->size) {
339
0
            state->in[have] = (unsigned char)c;
340
0
            strm->avail_in++;
341
0
            state->x.pos++;
342
0
            return c & 0xff;
343
0
        }
344
0
    }
345
346
    /* no room in buffer or not initialized, use gz_write() */
347
0
    buf[0] = (unsigned char)c;
348
0
    if (gz_write(state, buf, 1) != 1)
349
0
        return -1;
350
0
    return c & 0xff;
351
0
}
352
353
/* -- see zlib.h -- */
354
0
int ZEXPORT gzputs(gzFile file, const char *s) {
355
0
    z_size_t len, put;
356
0
    gz_statep state;
357
358
    /* get internal structure */
359
0
    if (file == NULL)
360
0
        return -1;
361
0
    state = (gz_statep)file;
362
363
    /* check that we're writing and that there's no (serious) error */
364
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
365
0
        return -1;
366
0
    gz_error(state, Z_OK, NULL);
367
368
    /* write string */
369
0
    len = strlen(s);
370
0
    if ((int)len < 0 || (unsigned)len != len) {
371
0
        gz_error(state, Z_STREAM_ERROR, "string length does not fit in int");
372
0
        return -1;
373
0
    }
374
0
    put = gz_write(state, s, len);
375
0
    return len && put == 0 ? -1 : (int)put;
376
0
}
377
378
#if (((!defined(STDC) && !defined(Z_HAVE_STDARG_H)) || !defined(NO_vsnprintf)) && \
379
     (defined(STDC) || defined(Z_HAVE_STDARG_H) || !defined(NO_snprintf))) || \
380
    defined(ZLIB_INSECURE)
381
/* If the second half of the input buffer is occupied, write out the contents.
382
   If there is any input remaining due to a non-blocking stall on write, move
383
   it to the start of the buffer. Return true if this did not open up the
384
   second half of the buffer.  state->err should be checked after this to
385
   handle a gz_comp() error. */
386
0
local int gz_vacate(gz_statep state) {
387
0
    z_streamp strm;
388
389
0
    strm = &(state->strm);
390
0
    if (strm->next_in + strm->avail_in <= state->in + state->size)
391
0
        return 0;
392
0
    (void)gz_comp(state, Z_NO_FLUSH);
393
0
    if (strm->avail_in == 0) {
394
0
        strm->next_in = state->in;
395
0
        return 0;
396
0
    }
397
0
    memmove(state->in, strm->next_in, strm->avail_in);
398
0
    strm->next_in = state->in;
399
0
    return strm->avail_in > state->size;
400
0
}
401
#endif
402
403
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
404
#include <stdarg.h>
405
406
/* -- see zlib.h -- */
407
0
int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) {
408
#if defined(NO_vsnprintf) && !defined(ZLIB_INSECURE)
409
#warning "vsnprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR"
410
#warning "you can recompile with ZLIB_INSECURE defined to use vsprintf()"
411
    /* prevent use of insecure vsprintf(), unless purposefully requested */
412
    (void)file, (void)format, (void)va;
413
    return Z_STREAM_ERROR;
414
#else
415
0
    int len, ret;
416
0
    char *next;
417
0
    gz_statep state;
418
0
    z_streamp strm;
419
420
    /* get internal structure */
421
0
    if (file == NULL)
422
0
        return Z_STREAM_ERROR;
423
0
    state = (gz_statep)file;
424
0
    strm = &(state->strm);
425
426
    /* check that we're writing and that there's no (serious) error */
427
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
428
0
        return Z_STREAM_ERROR;
429
0
    gz_error(state, Z_OK, NULL);
430
431
    /* make sure we have some buffer space */
432
0
    if (state->size == 0 && gz_init(state) == -1)
433
0
        return state->err;
434
435
    /* check for seek request */
436
0
    if (state->skip && gz_zero(state) == -1)
437
0
        return state->err;
438
439
    /* do the printf() into the input buffer, put length in len -- the input
440
       buffer is double-sized just for this function, so there should be
441
       state->size bytes available after the current contents */
442
0
    ret = gz_vacate(state);
443
0
    if (state->err) {
444
0
        if (ret && state->again) {
445
            /* There was a non-blocking stall on write, resulting in the part
446
               of the second half of the output buffer being occupied.  Return
447
               a Z_BUF_ERROR to let the application know that this gzprintf()
448
               needs to be retried. */
449
0
            gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf");
450
0
        }
451
0
        if (!state->again)
452
0
            return state->err;
453
0
    }
454
0
    if (strm->avail_in == 0)
455
0
        strm->next_in = state->in;
456
0
    next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
457
0
    next[state->size - 1] = 0;
458
#ifdef NO_vsnprintf
459
#  ifdef HAS_vsprintf_void
460
    (void)vsprintf(next, format, va);
461
    for (len = 0; len < state->size; len++)
462
        if (next[len] == 0) break;
463
#  else
464
    len = vsprintf(next, format, va);
465
#  endif
466
#else
467
#  ifdef HAS_vsnprintf_void
468
    (void)vsnprintf(next, state->size, format, va);
469
    len = strlen(next);
470
#  else
471
0
    len = vsnprintf(next, state->size, format, va);
472
0
#  endif
473
0
#endif
474
475
    /* check that printf() results fit in buffer */
476
0
    if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
477
0
        return 0;
478
479
    /* update buffer and position */
480
0
    strm->avail_in += (unsigned)len;
481
0
    state->x.pos += len;
482
483
    /* write out buffer if more than half is occupied */
484
0
    ret = gz_vacate(state);
485
0
    if (state->err && !state->again)
486
0
        return state->err;
487
0
    return len;
488
0
#endif
489
0
}
490
491
0
int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) {
492
0
    va_list va;
493
0
    int ret;
494
495
0
    va_start(va, format);
496
0
    ret = gzvprintf(file, format, va);
497
0
    va_end(va);
498
0
    return ret;
499
0
}
500
501
#else /* !STDC && !Z_HAVE_STDARG_H */
502
503
/* -- see zlib.h -- */
504
int ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3,
505
                       int a4, int a5, int a6, int a7, int a8, int a9, int a10,
506
                       int a11, int a12, int a13, int a14, int a15, int a16,
507
                       int a17, int a18, int a19, int a20) {
508
#if defined(NO_snprintf) && !defined(ZLIB_INSECURE)
509
#warning "snprintf() not available -- gzprintf() stub returns Z_STREAM_ERROR"
510
#warning "you can recompile with ZLIB_INSECURE defined to use sprintf()"
511
    /* prevent use of insecure sprintf(), unless purposefully requested */
512
    (void)file, (void)format, (void)a1, (void)a2, (void)a3, (void)a4, (void)a5,
513
    (void)a6, (void)a7, (void)a8, (void)a9, (void)a10, (void)a11, (void)a12,
514
    (void)a13, (void)a14, (void)a15, (void)a16, (void)a17, (void)a18,
515
    (void)a19, (void)a20;
516
    return Z_STREAM_ERROR;
517
#else
518
    int ret;
519
    unsigned len, left;
520
    char *next;
521
    gz_statep state;
522
    z_streamp strm;
523
524
    /* get internal structure */
525
    if (file == NULL)
526
        return Z_STREAM_ERROR;
527
    state = (gz_statep)file;
528
    strm = &(state->strm);
529
530
    /* check that can really pass pointer in ints */
531
    if (sizeof(int) != sizeof(void *))
532
        return Z_STREAM_ERROR;
533
534
    /* check that we're writing and that there's no (serious) error */
535
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
536
        return Z_STREAM_ERROR;
537
    gz_error(state, Z_OK, NULL);
538
539
    /* make sure we have some buffer space */
540
    if (state->size == 0 && gz_init(state) == -1)
541
        return state->err;
542
543
    /* check for seek request */
544
    if (state->skip && gz_zero(state) == -1)
545
        return state->err;
546
547
    /* do the printf() into the input buffer, put length in len -- the input
548
       buffer is double-sized just for this function, so there is guaranteed to
549
       be state->size bytes available after the current contents */
550
    ret = gz_vacate(state);
551
    if (state->err) {
552
        if (ret && state->again) {
553
            /* There was a non-blocking stall on write, resulting in the part
554
               of the second half of the output buffer being occupied.  Return
555
               a Z_BUF_ERROR to let the application know that this gzprintf()
556
               needs to be retried. */
557
            gz_error(state, Z_BUF_ERROR, "stalled write on gzprintf");
558
        }
559
        if (!state->again)
560
            return state->err;
561
    }
562
    if (strm->avail_in == 0)
563
        strm->next_in = state->in;
564
    next = (char *)(strm->next_in + strm->avail_in);
565
    next[state->size - 1] = 0;
566
#ifdef NO_snprintf
567
#  ifdef HAS_sprintf_void
568
    sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
569
            a13, a14, a15, a16, a17, a18, a19, a20);
570
    for (len = 0; len < size; len++)
571
        if (next[len] == 0)
572
            break;
573
#  else
574
    len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
575
                  a12, a13, a14, a15, a16, a17, a18, a19, a20);
576
#  endif
577
#else
578
#  ifdef HAS_snprintf_void
579
    snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
580
             a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
581
    len = strlen(next);
582
#  else
583
    len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
584
                   a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
585
#  endif
586
#endif
587
588
    /* check that printf() results fit in buffer */
589
    if (len == 0 || len >= state->size || next[state->size - 1] != 0)
590
        return 0;
591
592
    /* update buffer and position, compress first half if past that */
593
    strm->avail_in += len;
594
    state->x.pos += len;
595
596
    /* write out buffer if more than half is occupied */
597
    ret = gz_vacate(state);
598
    if (state->err && !state->again)
599
        return state->err;
600
    return (int)len;
601
#endif
602
}
603
604
#endif
605
606
/* -- see zlib.h -- */
607
0
int ZEXPORT gzflush(gzFile file, int flush) {
608
0
    gz_statep state;
609
610
    /* get internal structure */
611
0
    if (file == NULL)
612
0
        return Z_STREAM_ERROR;
613
0
    state = (gz_statep)file;
614
615
    /* check that we're writing and that there's no (serious) error */
616
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again))
617
0
        return Z_STREAM_ERROR;
618
0
    gz_error(state, Z_OK, NULL);
619
620
    /* check flush parameter */
621
0
    if (flush < 0 || flush > Z_FINISH)
622
0
        return Z_STREAM_ERROR;
623
624
    /* check for seek request */
625
0
    if (state->skip && gz_zero(state) == -1)
626
0
        return state->err;
627
628
    /* compress remaining data with requested flush */
629
0
    (void)gz_comp(state, flush);
630
0
    return state->err;
631
0
}
632
633
/* -- see zlib.h -- */
634
0
int ZEXPORT gzsetparams(gzFile file, int level, int strategy) {
635
0
    gz_statep state;
636
0
    z_streamp strm;
637
638
    /* get internal structure */
639
0
    if (file == NULL)
640
0
        return Z_STREAM_ERROR;
641
0
    state = (gz_statep)file;
642
0
    strm = &(state->strm);
643
644
    /* check that we're compressing and that there's no (serious) error */
645
0
    if (state->mode != GZ_WRITE || (state->err != Z_OK && !state->again) ||
646
0
            state->direct)
647
0
        return Z_STREAM_ERROR;
648
0
    gz_error(state, Z_OK, NULL);
649
650
    /* if no change is requested, then do nothing */
651
0
    if (level == state->level && strategy == state->strategy)
652
0
        return Z_OK;
653
654
    /* check for seek request */
655
0
    if (state->skip && gz_zero(state) == -1)
656
0
        return state->err;
657
658
    /* change compression parameters for subsequent input */
659
0
    if (state->size) {
660
        /* flush previous input with previous parameters before changing */
661
0
        if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
662
0
            return state->err;
663
0
        deflateParams(strm, level, strategy);
664
0
    }
665
0
    state->level = level;
666
0
    state->strategy = strategy;
667
0
    return Z_OK;
668
0
}
669
670
/* -- see zlib.h -- */
671
0
int ZEXPORT gzclose_w(gzFile file) {
672
0
    int ret = Z_OK;
673
0
    gz_statep state;
674
675
    /* get internal structure */
676
0
    if (file == NULL)
677
0
        return Z_STREAM_ERROR;
678
0
    state = (gz_statep)file;
679
680
    /* check that we're writing */
681
0
    if (state->mode != GZ_WRITE)
682
0
        return Z_STREAM_ERROR;
683
684
    /* check for seek request */
685
0
    if (state->skip && gz_zero(state) == -1)
686
0
        ret = state->err;
687
688
    /* flush, free memory, and close file */
689
0
    if (gz_comp(state, Z_FINISH) == -1)
690
0
        ret = state->err;
691
0
    if (state->size) {
692
0
        if (!state->direct) {
693
0
            (void)deflateEnd(&(state->strm));
694
0
            free(state->out);
695
0
        }
696
0
        free(state->in);
697
0
    }
698
0
    gz_error(state, Z_OK, NULL);
699
0
    free(state->path);
700
0
    if (close(state->fd) == -1)
701
0
        ret = Z_ERRNO;
702
0
    free(state);
703
0
    return ret;
704
0
}