xref: /freebsd/sys/contrib/zlib/uncompr.c (revision 4717628ed859513a3262ea68259d0605f39de0b3)
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