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