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