Files
erofs-freebsd-out-tree/decompressor_deflate.c
T
2026-08-14 12:01:38 +02:00

68 lines
1.5 KiB
C

/* SPDX-License-Identifier: BSD-2-Clause */
/* Minimal DEFLATE decompressor for EROFS FreeBSD */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <contrib/zlib/zlib.h>
#include "internal.h"
int
z_erofs_load_deflate_config(struct erofs_mount *em, const void *data,
size_t size)
{
const struct z_erofs_deflate_cfgs *deflate;
if (size < sizeof(*deflate))
return (EINVAL);
deflate = data;
if (deflate->windowbits < 8 || deflate->windowbits > 15)
return (EOPNOTSUPP);
em->deflate_windowbits = deflate->windowbits;
return (0);
}
int
deflate_decompress(void *src, size_t srclen, void *dst, size_t dstlen, int n,
bool partial)
{
z_stream strm;
uInt in_before, out_before;
int endret, ret;
if (n < 8 || n > MAX_WBITS || srclen > (size_t)(uInt)-1 ||
dstlen > (size_t)(uInt)-1 || dstlen == 0)
return (-1);
bzero(&strm, sizeof(strm));
strm.next_in = src;
strm.avail_in = srclen;
strm.next_out = dst;
strm.avail_out = dstlen;
ret = inflateInit2(&strm, -n);
if (ret != Z_OK)
return (-1);
ret = Z_OK;
while (strm.avail_out != 0) {
in_before = strm.avail_in;
out_before = strm.avail_out;
ret = inflate(&strm, Z_SYNC_FLUSH);
if (ret == Z_STREAM_END)
break;
if (ret != Z_OK ||
(strm.avail_in == in_before && strm.avail_out == out_before))
break;
}
endret = inflateEnd(&strm);
if (endret != Z_OK || strm.avail_out != 0)
return (-1);
if (partial)
return (ret == Z_OK || ret == Z_STREAM_END ? 0 : -1);
if (ret != Z_STREAM_END || strm.avail_in != 0)
return (-1);
return (0);
}