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