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