1212397c6Schristos /* uncompr.c -- decompress a memory buffer
2796c32c9Schristos * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
3212397c6Schristos * For conditions of distribution and use, see copyright notice in zlib.h
4212397c6Schristos */
5212397c6Schristos
6*924795e6Schristos /* @(#) Id */
7212397c6Schristos
8212397c6Schristos #define ZLIB_INTERNAL
9212397c6Schristos #include "zlib.h"
10212397c6Schristos
11212397c6Schristos /* ===========================================================================
12796c32c9Schristos Decompresses the source buffer into the destination buffer. *sourceLen is
13796c32c9Schristos the byte length of the source buffer. Upon entry, *destLen is the total size
14796c32c9Schristos of the destination buffer, which must be large enough to hold the entire
15796c32c9Schristos uncompressed data. (The size of the uncompressed data must have been saved
16796c32c9Schristos previously by the compressor and transmitted to the decompressor by some
17796c32c9Schristos mechanism outside the scope of this compression library.) Upon exit,
18796c32c9Schristos *destLen is the size of the decompressed data and *sourceLen is the number
19796c32c9Schristos of source bytes consumed. Upon return, source + *sourceLen points to the
20796c32c9Schristos first unused input byte.
21212397c6Schristos
22796c32c9Schristos uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
23796c32c9Schristos memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
24796c32c9Schristos Z_DATA_ERROR if the input data was corrupted, including if the input data is
25796c32c9Schristos an incomplete zlib stream.
26212397c6Schristos */
uncompress2(dest,destLen,source,sourceLen)27796c32c9Schristos int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
28796c32c9Schristos Bytef *dest;
29796c32c9Schristos uLongf *destLen;
30796c32c9Schristos const Bytef *source;
31796c32c9Schristos uLong *sourceLen;
32796c32c9Schristos {
33796c32c9Schristos z_stream stream;
34796c32c9Schristos int err;
35796c32c9Schristos const uInt max = (uInt)-1;
36796c32c9Schristos uLong len, left;
37796c32c9Schristos Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
38796c32c9Schristos
39796c32c9Schristos len = *sourceLen;
40796c32c9Schristos if (*destLen) {
41796c32c9Schristos left = *destLen;
42796c32c9Schristos *destLen = 0;
43796c32c9Schristos }
44796c32c9Schristos else {
45796c32c9Schristos left = 1;
46796c32c9Schristos dest = buf;
47796c32c9Schristos }
48796c32c9Schristos
49796c32c9Schristos stream.next_in = (z_const Bytef *)source;
50796c32c9Schristos stream.avail_in = 0;
51796c32c9Schristos stream.zalloc = (alloc_func)0;
52796c32c9Schristos stream.zfree = (free_func)0;
53796c32c9Schristos stream.opaque = (voidpf)0;
54796c32c9Schristos
55796c32c9Schristos err = inflateInit(&stream);
56796c32c9Schristos if (err != Z_OK) return err;
57796c32c9Schristos
58796c32c9Schristos stream.next_out = dest;
59796c32c9Schristos stream.avail_out = 0;
60796c32c9Schristos
61796c32c9Schristos do {
62796c32c9Schristos if (stream.avail_out == 0) {
63796c32c9Schristos stream.avail_out = left > (uLong)max ? max : (uInt)left;
64796c32c9Schristos left -= stream.avail_out;
65796c32c9Schristos }
66796c32c9Schristos if (stream.avail_in == 0) {
67796c32c9Schristos stream.avail_in = len > (uLong)max ? max : (uInt)len;
68796c32c9Schristos len -= stream.avail_in;
69796c32c9Schristos }
70796c32c9Schristos err = inflate(&stream, Z_NO_FLUSH);
71796c32c9Schristos } while (err == Z_OK);
72796c32c9Schristos
73796c32c9Schristos *sourceLen -= len + stream.avail_in;
74796c32c9Schristos if (dest != buf)
75796c32c9Schristos *destLen = stream.total_out;
76796c32c9Schristos else if (stream.total_out && err == Z_BUF_ERROR)
77796c32c9Schristos left = 1;
78796c32c9Schristos
79796c32c9Schristos inflateEnd(&stream);
80796c32c9Schristos return err == Z_STREAM_END ? Z_OK :
81796c32c9Schristos err == Z_NEED_DICT ? Z_DATA_ERROR :
82796c32c9Schristos err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
83796c32c9Schristos err;
84796c32c9Schristos }
85796c32c9Schristos
uncompress(dest,destLen,source,sourceLen)86212397c6Schristos int ZEXPORT uncompress (dest, destLen, source, sourceLen)
87212397c6Schristos Bytef *dest;
88212397c6Schristos uLongf *destLen;
89212397c6Schristos const Bytef *source;
90212397c6Schristos uLong sourceLen;
91212397c6Schristos {
92796c32c9Schristos return uncompress2(dest, destLen, source, &sourceLen);
93212397c6Schristos }
94