~ubuntu-branches/debian/stretch/smplayer/stretch

« back to all changes in this revision

Viewing changes to zlib-1.2.6/gzread.c

  • Committer: Package Import Robot
  • Author(s): Maia Kozheva, Maia Kozheva, Alessio Treglia
  • Date: 2012-04-14 12:01:57 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20120414120157-mndwobcslgisomso
Tags: 0.8.0-1
[ Maia Kozheva ]
* New upstream release:
  - Changes since 0.7.1:
    + A toolbar editor has been added. Now it's possible to select the
      buttons and controls that want to appear in the toolbars.
    + New video filters: gradfun, blur and sharpen.
    + Now it's possible to change the GUI (default, mini, mpc) at runtime,
      no restart required.
    + sub files from opensubtitles should work again.
    + (Youtube) Recognize short urls (like this one:
      http://y2u.be/F5OcZBVPwOA)
    + Better support for chapters in video files.
    + Bug fix: remote m3u files work from the favorites menu or command line.
    + Internal changes in the single instance option (switch to 
      QtSingleApplication).
  - Fixes since 0.7.0:
    + SMPlayer took more than 10 seconds to show when running for the very
      first time.
    + The links to download subtitles from Opensubtitles were wrong.
    + SMPlayer crashed in the favorite editor when trying to select a file
      if the KDE open dialog was used.
  - Changes since 0.7.0:
    + By default the screenshots are saved in the user's pictures folder
      instead of the SMPlayer's config folder.
    + Now it's possible to change the opensubtitles server.
    + Youtube: seeking is slow with flv videos, so now flv videos have the
      lowest priority.
    + Youtube: now it's possible to search and download videos from youtube.
      This is provided by an external application (in linux you have to
      install an independent package: smtube).
* debian/copyright:
  - Rewrite according to DEP-5 specification.
* debian/control:
  - Depend on mplayer2 | mplayer. (Closes: #638279)
  - Update Standards-Version to 3.9.3.
* Remove debian/patches/handle_local_urls.diff, merged upstream.

[ Alessio Treglia ]
* Mention smplayer is also a front-end for MPlayer2.
* Fix small typo in the description.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* gzread.c -- zlib functions for reading gzip files
 
2
 * Copyright (C) 2004, 2005, 2010, 2011 Mark Adler
 
3
 * For conditions of distribution and use, see copyright notice in zlib.h
 
4
 */
 
5
 
 
6
#include "gzguts.h"
 
7
 
 
8
/* Local functions */
 
9
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
 
10
local int gz_avail OF((gz_statep));
 
11
local int gz_look OF((gz_statep));
 
12
local int gz_decomp OF((gz_statep));
 
13
local int gz_fetch OF((gz_statep));
 
14
local int gz_skip OF((gz_statep, z_off64_t));
 
15
 
 
16
/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
 
17
   state->fd, and update state->eof, state->err, and state->msg as appropriate.
 
18
   This function needs to loop on read(), since read() is not guaranteed to
 
19
   read the number of bytes requested, depending on the type of descriptor. */
 
20
local int gz_load(state, buf, len, have)
 
21
    gz_statep state;
 
22
    unsigned char *buf;
 
23
    unsigned len;
 
24
    unsigned *have;
 
25
{
 
26
    int ret;
 
27
 
 
28
    *have = 0;
 
29
    do {
 
30
        ret = read(state->fd, buf + *have, len - *have);
 
31
        if (ret <= 0)
 
32
            break;
 
33
        *have += ret;
 
34
    } while (*have < len);
 
35
    if (ret < 0) {
 
36
        gz_error(state, Z_ERRNO, zstrerror());
 
37
        return -1;
 
38
    }
 
39
    if (ret == 0)
 
40
        state->eof = 1;
 
41
    return 0;
 
42
}
 
43
 
 
44
/* Load up input buffer and set eof flag if last data loaded -- return -1 on
 
45
   error, 0 otherwise.  Note that the eof flag is set when the end of the input
 
46
   file is reached, even though there may be unused data in the buffer.  Once
 
47
   that data has been used, no more attempts will be made to read the file.
 
48
   If strm->avail_in != 0, then the current data is moved to the beginning of
 
49
   the input buffer, and then the remainder of the buffer is loaded with the
 
50
   available data from the input file. */
 
51
local int gz_avail(state)
 
52
    gz_statep state;
 
53
{
 
54
    unsigned got;
 
55
    z_streamp strm = &(state->strm);
 
56
 
 
57
    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
 
58
        return -1;
 
59
    if (state->eof == 0) {
 
60
        if (strm->avail_in)
 
61
            memmove(state->in, strm->next_in, strm->avail_in);
 
62
        if (gz_load(state, state->in + strm->avail_in,
 
63
                    state->size - strm->avail_in, &got) == -1)
 
64
            return -1;
 
65
        strm->avail_in += got;
 
66
        strm->next_in = state->in;
 
67
    }
 
68
    return 0;
 
69
}
 
70
 
 
71
/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
 
72
   If this is the first time in, allocate required memory.  state->how will be
 
73
   left unchanged if there is no more input data available, will be set to COPY
 
74
   if there is no gzip header and direct copying will be performed, or it will
 
75
   be set to GZIP for decompression.  If direct copying, then leftover input
 
76
   data from the input buffer will be copied to the output buffer.  In that
 
77
   case, all further file reads will be directly to either the output buffer or
 
78
   a user buffer.  If decompressing, the inflate state will be initialized.
 
79
   gz_look() will return 0 on success or -1 on failure. */
 
80
local int gz_look(state)
 
81
    gz_statep state;
 
82
{
 
83
    z_streamp strm = &(state->strm);
 
84
 
 
85
    /* allocate read buffers and inflate memory */
 
86
    if (state->size == 0) {
 
87
        /* allocate buffers */
 
88
        state->in = malloc(state->want);
 
89
        state->out = malloc(state->want << 1);
 
90
        if (state->in == NULL || state->out == NULL) {
 
91
            if (state->out != NULL)
 
92
                free(state->out);
 
93
            if (state->in != NULL)
 
94
                free(state->in);
 
95
            gz_error(state, Z_MEM_ERROR, "out of memory");
 
96
            return -1;
 
97
        }
 
98
        state->size = state->want;
 
99
 
 
100
        /* allocate inflate memory */
 
101
        state->strm.zalloc = Z_NULL;
 
102
        state->strm.zfree = Z_NULL;
 
103
        state->strm.opaque = Z_NULL;
 
104
        state->strm.avail_in = 0;
 
105
        state->strm.next_in = Z_NULL;
 
106
        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
 
107
            free(state->out);
 
108
            free(state->in);
 
109
            state->size = 0;
 
110
            gz_error(state, Z_MEM_ERROR, "out of memory");
 
111
            return -1;
 
112
        }
 
113
    }
 
114
 
 
115
    /* get at least the magic bytes in the input buffer */
 
116
    if (strm->avail_in < 2) {
 
117
        if (gz_avail(state) == -1)
 
118
            return -1;
 
119
        if (strm->avail_in == 0)
 
120
            return 0;
 
121
    }
 
122
 
 
123
    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
 
124
       a logical dilemma here when considering the case of a partially written
 
125
       gzip file, to wit, if a single 31 byte is written, then we cannot tell
 
126
       whether this is a single-byte file, or just a partially written gzip
 
127
       file -- for here we assume that if a gzip file is being written, then
 
128
       the header will be written in a single operation, so that reading a
 
129
       single byte is sufficient indication that it is not a gzip file) */
 
130
    if (strm->avail_in > 1 &&
 
131
            strm->next_in[0] == 31 && strm->next_in[1] == 139) {
 
132
        inflateReset(strm);
 
133
        state->how = GZIP;
 
134
        state->direct = 0;
 
135
        return 0;
 
136
    }
 
137
 
 
138
    /* no gzip header -- if we were decoding gzip before, then this is trailing
 
139
       garbage.  Ignore the trailing garbage and finish. */
 
140
    if (state->direct == 0) {
 
141
        strm->avail_in = 0;
 
142
        state->eof = 1;
 
143
        state->x.have = 0;
 
144
        return 0;
 
145
    }
 
146
 
 
147
    /* doing raw i/o, copy any leftover input to output -- this assumes that
 
148
       the output buffer is larger than the input buffer, which also assures
 
149
       space for gzungetc() */
 
150
    state->x.next = state->out;
 
151
    if (strm->avail_in) {
 
152
        memcpy(state->x.next, strm->next_in, strm->avail_in);
 
153
        state->x.have = strm->avail_in;
 
154
        strm->avail_in = 0;
 
155
    }
 
156
    state->how = COPY;
 
157
    state->direct = 1;
 
158
    return 0;
 
159
}
 
160
 
 
161
/* Decompress from input to the provided next_out and avail_out in the state.
 
162
   On return, state->x.have and state->x.next point to the just decompressed
 
163
   data.  If the gzip stream completes, state->how is reset to LOOK to look for
 
164
   the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
 
165
   on success, -1 on failure. */
 
166
local int gz_decomp(state)
 
167
    gz_statep state;
 
168
{
 
169
    int ret = Z_OK;
 
170
    unsigned had;
 
171
    z_streamp strm = &(state->strm);
 
172
 
 
173
    /* fill output buffer up to end of deflate stream */
 
174
    had = strm->avail_out;
 
175
    do {
 
176
        /* get more input for inflate() */
 
177
        if (strm->avail_in == 0 && gz_avail(state) == -1)
 
178
            return -1;
 
179
        if (strm->avail_in == 0) {
 
180
            gz_error(state, Z_BUF_ERROR, "unexpected end of file");
 
181
            break;
 
182
        }
 
183
 
 
184
        /* decompress and handle errors */
 
185
        ret = inflate(strm, Z_NO_FLUSH);
 
186
        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
 
187
            gz_error(state, Z_STREAM_ERROR,
 
188
                     "internal error: inflate stream corrupt");
 
189
            return -1;
 
190
        }
 
191
        if (ret == Z_MEM_ERROR) {
 
192
            gz_error(state, Z_MEM_ERROR, "out of memory");
 
193
            return -1;
 
194
        }
 
195
        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
 
196
            gz_error(state, Z_DATA_ERROR,
 
197
                     strm->msg == NULL ? "compressed data error" : strm->msg);
 
198
            return -1;
 
199
        }
 
200
    } while (strm->avail_out && ret != Z_STREAM_END);
 
201
 
 
202
    /* update available output */
 
203
    state->x.have = had - strm->avail_out;
 
204
    state->x.next = strm->next_out - state->x.have;
 
205
 
 
206
    /* if the gzip stream completed successfully, look for another */
 
207
    if (ret == Z_STREAM_END)
 
208
        state->how = LOOK;
 
209
 
 
210
    /* good decompression */
 
211
    return 0;
 
212
}
 
213
 
 
214
/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
 
215
   Data is either copied from the input file or decompressed from the input
 
216
   file depending on state->how.  If state->how is LOOK, then a gzip header is
 
217
   looked for to determine whether to copy or decompress.  Returns -1 on error,
 
218
   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
 
219
   end of the input file has been reached and all data has been processed.  */
 
220
local int gz_fetch(state)
 
221
    gz_statep state;
 
222
{
 
223
    z_streamp strm = &(state->strm);
 
224
 
 
225
    do {
 
226
        switch(state->how) {
 
227
        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
 
228
            if (gz_look(state) == -1)
 
229
                return -1;
 
230
            if (state->how == LOOK)
 
231
                return 0;
 
232
            break;
 
233
        case COPY:      /* -> COPY */
 
234
            if (gz_load(state, state->out, state->size << 1, &(state->x.have))
 
235
                    == -1)
 
236
                return -1;
 
237
            state->x.next = state->out;
 
238
            return 0;
 
239
        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
 
240
            strm->avail_out = state->size << 1;
 
241
            strm->next_out = state->out;
 
242
            if (gz_decomp(state) == -1)
 
243
                return -1;
 
244
        }
 
245
    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
 
246
    return 0;
 
247
}
 
248
 
 
249
/* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
 
250
local int gz_skip(state, len)
 
251
    gz_statep state;
 
252
    z_off64_t len;
 
253
{
 
254
    unsigned n;
 
255
 
 
256
    /* skip over len bytes or reach end-of-file, whichever comes first */
 
257
    while (len)
 
258
        /* skip over whatever is in output buffer */
 
259
        if (state->x.have) {
 
260
            n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
 
261
                (unsigned)len : state->x.have;
 
262
            state->x.have -= n;
 
263
            state->x.next += n;
 
264
            state->x.pos += n;
 
265
            len -= n;
 
266
        }
 
267
 
 
268
        /* output buffer empty -- return if we're at the end of the input */
 
269
        else if (state->eof && state->strm.avail_in == 0)
 
270
            break;
 
271
 
 
272
        /* need more data to skip -- load up output buffer */
 
273
        else {
 
274
            /* get more output, looking for header if required */
 
275
            if (gz_fetch(state) == -1)
 
276
                return -1;
 
277
        }
 
278
    return 0;
 
279
}
 
280
 
 
281
/* -- see zlib.h -- */
 
282
int ZEXPORT gzread(file, buf, len)
 
283
    gzFile file;
 
284
    voidp buf;
 
285
    unsigned len;
 
286
{
 
287
    unsigned got, n;
 
288
    gz_statep state;
 
289
    z_streamp strm;
 
290
 
 
291
    /* get internal structure */
 
292
    if (file == NULL)
 
293
        return -1;
 
294
    state = (gz_statep)file;
 
295
    strm = &(state->strm);
 
296
 
 
297
    /* check that we're reading and that there's no (serious) error */
 
298
    if (state->mode != GZ_READ ||
 
299
            (state->err != Z_OK && state->err != Z_BUF_ERROR))
 
300
        return -1;
 
301
 
 
302
    /* since an int is returned, make sure len fits in one, otherwise return
 
303
       with an error (this avoids the flaw in the interface) */
 
304
    if ((int)len < 0) {
 
305
        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
 
306
        return -1;
 
307
    }
 
308
 
 
309
    /* if len is zero, avoid unnecessary operations */
 
310
    if (len == 0)
 
311
        return 0;
 
312
 
 
313
    /* process a skip request */
 
314
    if (state->seek) {
 
315
        state->seek = 0;
 
316
        if (gz_skip(state, state->skip) == -1)
 
317
            return -1;
 
318
    }
 
319
 
 
320
    /* get len bytes to buf, or less than len if at the end */
 
321
    got = 0;
 
322
    do {
 
323
        /* first just try copying data from the output buffer */
 
324
        if (state->x.have) {
 
325
            n = state->x.have > len ? len : state->x.have;
 
326
            memcpy(buf, state->x.next, n);
 
327
            state->x.next += n;
 
328
            state->x.have -= n;
 
329
        }
 
330
 
 
331
        /* output buffer empty -- return if we're at the end of the input */
 
332
        else if (state->eof && strm->avail_in == 0) {
 
333
            state->past = 1;        /* tried to read past end */
 
334
            break;
 
335
        }
 
336
 
 
337
        /* need output data -- for small len or new stream load up our output
 
338
           buffer */
 
339
        else if (state->how == LOOK || len < (state->size << 1)) {
 
340
            /* get more output, looking for header if required */
 
341
            if (gz_fetch(state) == -1)
 
342
                return -1;
 
343
            continue;       /* no progress yet -- go back to memcpy() above */
 
344
            /* the copy above assures that we will leave with space in the
 
345
               output buffer, allowing at least one gzungetc() to succeed */
 
346
        }
 
347
 
 
348
        /* large len -- read directly into user buffer */
 
349
        else if (state->how == COPY) {      /* read directly */
 
350
            if (gz_load(state, buf, len, &n) == -1)
 
351
                return -1;
 
352
        }
 
353
 
 
354
        /* large len -- decompress directly into user buffer */
 
355
        else {  /* state->how == GZIP */
 
356
            strm->avail_out = len;
 
357
            strm->next_out = buf;
 
358
            if (gz_decomp(state) == -1)
 
359
                return -1;
 
360
            n = state->x.have;
 
361
            state->x.have = 0;
 
362
        }
 
363
 
 
364
        /* update progress */
 
365
        len -= n;
 
366
        buf = (char *)buf + n;
 
367
        got += n;
 
368
        state->x.pos += n;
 
369
    } while (len);
 
370
 
 
371
    /* return number of bytes read into user buffer (will fit in int) */
 
372
    return (int)got;
 
373
}
 
374
 
 
375
/* -- see zlib.h -- */
 
376
int ZEXPORT gzgetc_(file)
 
377
    gzFile file;
 
378
{
 
379
    int ret;
 
380
    unsigned char buf[1];
 
381
    gz_statep state;
 
382
 
 
383
    /* get internal structure */
 
384
    if (file == NULL)
 
385
        return -1;
 
386
    state = (gz_statep)file;
 
387
 
 
388
    /* check that we're reading and that there's no (serious) error */
 
389
    if (state->mode != GZ_READ ||
 
390
        (state->err != Z_OK && state->err != Z_BUF_ERROR))
 
391
        return -1;
 
392
 
 
393
    /* try output buffer (no need to check for skip request) */
 
394
    if (state->x.have) {
 
395
        state->x.have--;
 
396
        state->x.pos++;
 
397
        return *(state->x.next)++;
 
398
    }
 
399
 
 
400
    /* nothing there -- try gzread() */
 
401
    ret = gzread(file, buf, 1);
 
402
    return ret < 1 ? -1 : buf[0];
 
403
}
 
404
 
 
405
#undef gzgetc
 
406
int ZEXPORT gzgetc(file)
 
407
gzFile file;
 
408
{
 
409
    return gzgetc_(file);
 
410
}    
 
411
 
 
412
/* -- see zlib.h -- */
 
413
int ZEXPORT gzungetc(c, file)
 
414
    int c;
 
415
    gzFile file;
 
416
{
 
417
    gz_statep state;
 
418
 
 
419
    /* get internal structure */
 
420
    if (file == NULL)
 
421
        return -1;
 
422
    state = (gz_statep)file;
 
423
 
 
424
    /* check that we're reading and that there's no (serious) error */
 
425
    if (state->mode != GZ_READ ||
 
426
        (state->err != Z_OK && state->err != Z_BUF_ERROR))
 
427
        return -1;
 
428
 
 
429
    /* process a skip request */
 
430
    if (state->seek) {
 
431
        state->seek = 0;
 
432
        if (gz_skip(state, state->skip) == -1)
 
433
            return -1;
 
434
    }
 
435
 
 
436
    /* can't push EOF */
 
437
    if (c < 0)
 
438
        return -1;
 
439
 
 
440
    /* if output buffer empty, put byte at end (allows more pushing) */
 
441
    if (state->x.have == 0) {
 
442
        state->x.have = 1;
 
443
        state->x.next = state->out + (state->size << 1) - 1;
 
444
        state->x.next[0] = c;
 
445
        state->x.pos--;
 
446
        state->past = 0;
 
447
        return c;
 
448
    }
 
449
 
 
450
    /* if no room, give up (must have already done a gzungetc()) */
 
451
    if (state->x.have == (state->size << 1)) {
 
452
        gz_error(state, Z_DATA_ERROR, "out of room to push characters");
 
453
        return -1;
 
454
    }
 
455
 
 
456
    /* slide output data if needed and insert byte before existing data */
 
457
    if (state->x.next == state->out) {
 
458
        unsigned char *src = state->out + state->x.have;
 
459
        unsigned char *dest = state->out + (state->size << 1);
 
460
        while (src > state->out)
 
461
            *--dest = *--src;
 
462
        state->x.next = dest;
 
463
    }
 
464
    state->x.have++;
 
465
    state->x.next--;
 
466
    state->x.next[0] = c;
 
467
    state->x.pos--;
 
468
    state->past = 0;
 
469
    return c;
 
470
}
 
471
 
 
472
/* -- see zlib.h -- */
 
473
char * ZEXPORT gzgets(file, buf, len)
 
474
    gzFile file;
 
475
    char *buf;
 
476
    int len;
 
477
{
 
478
    unsigned left, n;
 
479
    char *str;
 
480
    unsigned char *eol;
 
481
    gz_statep state;
 
482
 
 
483
    /* check parameters and get internal structure */
 
484
    if (file == NULL || buf == NULL || len < 1)
 
485
        return NULL;
 
486
    state = (gz_statep)file;
 
487
 
 
488
    /* check that we're reading and that there's no (serious) error */
 
489
    if (state->mode != GZ_READ ||
 
490
        (state->err != Z_OK && state->err != Z_BUF_ERROR))
 
491
        return NULL;
 
492
 
 
493
    /* process a skip request */
 
494
    if (state->seek) {
 
495
        state->seek = 0;
 
496
        if (gz_skip(state, state->skip) == -1)
 
497
            return NULL;
 
498
    }
 
499
 
 
500
    /* copy output bytes up to new line or len - 1, whichever comes first --
 
501
       append a terminating zero to the string (we don't check for a zero in
 
502
       the contents, let the user worry about that) */
 
503
    str = buf;
 
504
    left = (unsigned)len - 1;
 
505
    if (left) do {
 
506
        /* assure that something is in the output buffer */
 
507
        if (state->x.have == 0 && gz_fetch(state) == -1)
 
508
            return NULL;                /* error */
 
509
        if (state->x.have == 0) {       /* end of file */
 
510
            state->past = 1;            /* read past end */
 
511
            break;                      /* return what we have */
 
512
        }
 
513
 
 
514
        /* look for end-of-line in current output buffer */
 
515
        n = state->x.have > left ? left : state->x.have;
 
516
        eol = memchr(state->x.next, '\n', n);
 
517
        if (eol != NULL)
 
518
            n = (unsigned)(eol - state->x.next) + 1;
 
519
 
 
520
        /* copy through end-of-line, or remainder if not found */
 
521
        memcpy(buf, state->x.next, n);
 
522
        state->x.have -= n;
 
523
        state->x.next += n;
 
524
        state->x.pos += n;
 
525
        left -= n;
 
526
        buf += n;
 
527
    } while (left && eol == NULL);
 
528
 
 
529
    /* return terminated string, or if nothing, end of file */
 
530
    if (buf == str)
 
531
        return NULL;
 
532
    buf[0] = 0;
 
533
    return str;
 
534
}
 
535
 
 
536
/* -- see zlib.h -- */
 
537
int ZEXPORT gzdirect(file)
 
538
    gzFile file;
 
539
{
 
540
    gz_statep state;
 
541
 
 
542
    /* get internal structure */
 
543
    if (file == NULL)
 
544
        return 0;
 
545
    state = (gz_statep)file;
 
546
 
 
547
    /* if the state is not known, but we can find out, then do so (this is
 
548
       mainly for right after a gzopen() or gzdopen()) */
 
549
    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
 
550
        (void)gz_look(state);
 
551
 
 
552
    /* return 1 if transparent, 0 if processing a gzip stream */
 
553
    return state->direct;
 
554
}
 
555
 
 
556
/* -- see zlib.h -- */
 
557
int ZEXPORT gzclose_r(file)
 
558
    gzFile file;
 
559
{
 
560
    int ret, err;
 
561
    gz_statep state;
 
562
 
 
563
    /* get internal structure */
 
564
    if (file == NULL)
 
565
        return Z_STREAM_ERROR;
 
566
    state = (gz_statep)file;
 
567
 
 
568
    /* check that we're reading */
 
569
    if (state->mode != GZ_READ)
 
570
        return Z_STREAM_ERROR;
 
571
 
 
572
    /* free memory and close file */
 
573
    if (state->size) {
 
574
        inflateEnd(&(state->strm));
 
575
        free(state->out);
 
576
        free(state->in);
 
577
    }
 
578
    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
 
579
    gz_error(state, Z_OK, NULL);
 
580
    free(state->path);
 
581
    ret = close(state->fd);
 
582
    free(state);
 
583
    return ret ? Z_ERRNO : err;
 
584
}