uncompr.c revision 1.5 1 1.5 christos /* $NetBSD: uncompr.c,v 1.5 2024/09/22 19:12:27 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.4 christos /* @(#) Id */
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.5 christos int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source,
30 1.5 christos uLong *sourceLen) {
31 1.1 christos z_stream stream;
32 1.1 christos int err;
33 1.3 christos const uInt max = (uInt)-1;
34 1.3 christos uLong len, left;
35 1.3 christos Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
36 1.3 christos
37 1.3 christos len = *sourceLen;
38 1.3 christos if (*destLen) {
39 1.3 christos left = *destLen;
40 1.3 christos *destLen = 0;
41 1.3 christos }
42 1.3 christos else {
43 1.3 christos left = 1;
44 1.3 christos dest = buf;
45 1.3 christos }
46 1.1 christos
47 1.3 christos stream.next_in = __UNCONST(source);
48 1.3 christos stream.avail_in = 0;
49 1.1 christos stream.zalloc = (alloc_func)0;
50 1.1 christos stream.zfree = (free_func)0;
51 1.3 christos stream.opaque = (voidpf)0;
52 1.1 christos
53 1.1 christos err = inflateInit(&stream);
54 1.1 christos if (err != Z_OK) return err;
55 1.1 christos
56 1.3 christos stream.next_out = dest;
57 1.3 christos stream.avail_out = 0;
58 1.3 christos
59 1.3 christos do {
60 1.3 christos if (stream.avail_out == 0) {
61 1.3 christos stream.avail_out = left > (uLong)max ? max : (uInt)left;
62 1.3 christos left -= stream.avail_out;
63 1.3 christos }
64 1.3 christos if (stream.avail_in == 0) {
65 1.3 christos stream.avail_in = len > (uLong)max ? max : (uInt)len;
66 1.3 christos len -= stream.avail_in;
67 1.3 christos }
68 1.3 christos err = inflate(&stream, Z_NO_FLUSH);
69 1.3 christos } while (err == Z_OK);
70 1.3 christos
71 1.3 christos *sourceLen -= len + stream.avail_in;
72 1.3 christos if (dest != buf)
73 1.3 christos *destLen = stream.total_out;
74 1.3 christos else if (stream.total_out && err == Z_BUF_ERROR)
75 1.3 christos left = 1;
76 1.3 christos
77 1.3 christos inflateEnd(&stream);
78 1.3 christos return err == Z_STREAM_END ? Z_OK :
79 1.3 christos err == Z_NEED_DICT ? Z_DATA_ERROR :
80 1.3 christos err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
81 1.3 christos err;
82 1.3 christos }
83 1.1 christos
84 1.5 christos int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source,
85 1.5 christos uLong sourceLen) {
86 1.3 christos return uncompress2(dest, destLen, source, &sourceLen);
87 1.1 christos }
88