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