Line data Source code
1 : /* uncompr.c -- decompress a memory buffer
2 : * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
3 : * For conditions of distribution and use, see copyright notice in zlib.h
4 : */
5 :
6 : /* @(#) $Id$ */
7 :
8 : #define ZLIB_INTERNAL
9 : #include "zlib.h"
10 :
11 : /* ===========================================================================
12 : Decompresses the source buffer into the destination buffer. *sourceLen is
13 : the byte length of the source buffer. Upon entry, *destLen is the total size
14 : of the destination buffer, which must be large enough to hold the entire
15 : uncompressed data. (The size of the uncompressed data must have been saved
16 : previously by the compressor and transmitted to the decompressor by some
17 : mechanism outside the scope of this compression library.) Upon exit,
18 : *destLen is the size of the decompressed data and *sourceLen is the number
19 : of source bytes consumed. Upon return, source + *sourceLen points to the
20 : first unused input byte.
21 :
22 : uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
23 : memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
24 : Z_DATA_ERROR if the input data was corrupted, including if the input data is
25 : an incomplete zlib stream.
26 : */
27 72 : int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
28 : Bytef *dest;
29 : uLongf *destLen;
30 : const Bytef *source;
31 : uLong *sourceLen;
32 : {
33 : z_stream stream;
34 : int err;
35 72 : const uInt max = (uInt)-1;
36 : uLong len, left;
37 : Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
38 :
39 72 : len = *sourceLen;
40 72 : if (*destLen) {
41 0 : left = *destLen;
42 0 : *destLen = 0;
43 : }
44 : else {
45 72 : left = 1;
46 72 : dest = buf;
47 : }
48 :
49 72 : stream.next_in = (z_const Bytef *)source;
50 72 : stream.avail_in = 0;
51 72 : stream.zalloc = (alloc_func)0;
52 72 : stream.zfree = (free_func)0;
53 72 : stream.opaque = (voidpf)0;
54 :
55 72 : err = inflateInit(&stream);
56 72 : if (err != Z_OK) return err;
57 :
58 72 : stream.next_out = dest;
59 72 : stream.avail_out = 0;
60 :
61 : do {
62 72 : if (stream.avail_out == 0) {
63 72 : stream.avail_out = left > (uLong)max ? max : (uInt)left;
64 72 : left -= stream.avail_out;
65 : }
66 72 : if (stream.avail_in == 0) {
67 72 : stream.avail_in = len > (uLong)max ? max : (uInt)len;
68 72 : len -= stream.avail_in;
69 : }
70 72 : err = inflate(&stream, Z_NO_FLUSH);
71 72 : } while (err == Z_OK);
72 :
73 72 : *sourceLen -= len + stream.avail_in;
74 72 : if (dest != buf)
75 0 : *destLen = stream.total_out;
76 72 : else if (stream.total_out && err == Z_BUF_ERROR)
77 0 : left = 1;
78 :
79 72 : inflateEnd(&stream);
80 72 : return err == Z_STREAM_END ? Z_OK :
81 0 : err == Z_NEED_DICT ? Z_DATA_ERROR :
82 0 : err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
83 : err;
84 : }
85 :
86 72 : int ZEXPORT uncompress (dest, destLen, source, sourceLen)
87 : Bytef *dest;
88 : uLongf *destLen;
89 : const Bytef *source;
90 : uLong sourceLen;
91 : {
92 72 : return uncompress2(dest, destLen, source, &sourceLen);
93 : }
|