misc: Remove tinf from tree, pull at bootstrap time
This commit is contained in:
parent
666c5dfcd1
commit
b78309b45a
|
@ -6,6 +6,7 @@
|
||||||
/libgcc-binaries
|
/libgcc-binaries
|
||||||
/common/flanterm
|
/common/flanterm
|
||||||
/common/stb/stb_image.h
|
/common/stb/stb_image.h
|
||||||
|
/decompressor/tinf
|
||||||
/ovmf*
|
/ovmf*
|
||||||
*.o
|
*.o
|
||||||
*.d
|
*.d
|
||||||
|
|
|
@ -322,7 +322,7 @@ distclean: clean
|
||||||
|
|
||||||
.PHONY: maintainer-clean
|
.PHONY: maintainer-clean
|
||||||
maintainer-clean: distclean
|
maintainer-clean: distclean
|
||||||
cd '$(call SHESCAPE,$(SRCDIR))' && rm -rf common/flanterm common/stb/stb_image.h freestanding-headers libgcc-binaries limine-efi freestanding-toolchain configure build-aux *'~' autom4te.cache *.tar.xz *.tar.gz
|
cd '$(call SHESCAPE,$(SRCDIR))' && rm -rf common/flanterm common/stb/stb_image.h decompressor/tinf freestanding-headers libgcc-binaries limine-efi freestanding-toolchain configure build-aux *'~' autom4te.cache *.tar.xz *.tar.gz
|
||||||
|
|
||||||
.PHONY: common-uefi-x86-64
|
.PHONY: common-uefi-x86-64
|
||||||
common-uefi-x86-64:
|
common-uefi-x86-64:
|
||||||
|
|
|
@ -13,6 +13,14 @@ fi
|
||||||
|
|
||||||
[ -d common/flanterm ] || git clone https://github.com/mintsuki/flanterm.git common/flanterm $SHALLOW_CLONE_FLAG
|
[ -d common/flanterm ] || git clone https://github.com/mintsuki/flanterm.git common/flanterm $SHALLOW_CLONE_FLAG
|
||||||
[ -f common/stb/stb_image.h ] || ( curl -Lo common/stb/stb_image.h https://github.com/nothings/stb/raw/dev/stb_image.h && patch -p0 < common/stb_image.patch )
|
[ -f common/stb/stb_image.h ] || ( curl -Lo common/stb/stb_image.h https://github.com/nothings/stb/raw/dev/stb_image.h && patch -p0 < common/stb_image.patch )
|
||||||
|
[ -d decompressor/tinf ] || (
|
||||||
|
set -e
|
||||||
|
mkdir -p decompressor/tinf
|
||||||
|
curl -Lo decompressor/tinf/tinf.h https://github.com/jibsen/tinf/raw/master/src/tinf.h
|
||||||
|
curl -Lo decompressor/tinf/tinflate.c https://github.com/jibsen/tinf/raw/master/src/tinflate.c
|
||||||
|
curl -Lo decompressor/tinf/tinfgzip.c https://github.com/jibsen/tinf/raw/master/src/tinfgzip.c
|
||||||
|
patch -p0 < decompressor/tinf.patch
|
||||||
|
)
|
||||||
[ -f freestanding-toolchain ] || ( curl -Lo freestanding-toolchain https://github.com/mintsuki/freestanding-toolchain/raw/trunk/freestanding-toolchain && chmod +x freestanding-toolchain )
|
[ -f freestanding-toolchain ] || ( curl -Lo freestanding-toolchain https://github.com/mintsuki/freestanding-toolchain/raw/trunk/freestanding-toolchain && chmod +x freestanding-toolchain )
|
||||||
[ -d freestanding-headers ] || git clone https://github.com/mintsuki/freestanding-headers.git $SHALLOW_CLONE_FLAG
|
[ -d freestanding-headers ] || git clone https://github.com/mintsuki/freestanding-headers.git $SHALLOW_CLONE_FLAG
|
||||||
[ -d limine-efi ] || git clone https://github.com/limine-bootloader/limine-efi.git $SHALLOW_CLONE_FLAG
|
[ -d limine-efi ] || git clone https://github.com/limine-bootloader/limine-efi.git $SHALLOW_CLONE_FLAG
|
||||||
|
|
|
@ -0,0 +1,264 @@
|
||||||
|
diff '--color=auto' -urN tinf-clean/tinf.h decompressor/tinf/tinf.h
|
||||||
|
--- tinf-clean/tinf.h 2023-06-06 00:57:04.683481827 +0200
|
||||||
|
+++ decompressor/tinf/tinf.h 2023-06-06 00:56:14.485629430 +0200
|
||||||
|
@@ -59,7 +59,9 @@
|
||||||
|
*
|
||||||
|
* @deprecated No longer required, may be removed in a future version.
|
||||||
|
*/
|
||||||
|
+/*
|
||||||
|
void TINFCC tinf_init(void);
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompress `sourceLen` bytes of deflate data from `source` to `dest`.
|
||||||
|
@@ -76,7 +78,7 @@
|
||||||
|
* @param sourceLen size of compressed data
|
||||||
|
* @return `TINF_OK` on success, error code on error
|
||||||
|
*/
|
||||||
|
-int TINFCC tinf_uncompress(void *dest, unsigned int *destLen,
|
||||||
|
+int TINFCC tinf_uncompress(void *dest,
|
||||||
|
const void *source, unsigned int sourceLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -94,7 +96,7 @@
|
||||||
|
* @param sourceLen size of compressed data
|
||||||
|
* @return `TINF_OK` on success, error code on error
|
||||||
|
*/
|
||||||
|
-int TINFCC tinf_gzip_uncompress(void *dest, unsigned int *destLen,
|
||||||
|
+int TINFCC tinf_gzip_uncompress(void *dest,
|
||||||
|
const void *source, unsigned int sourceLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -112,8 +114,10 @@
|
||||||
|
* @param sourceLen size of compressed data
|
||||||
|
* @return `TINF_OK` on success, error code on error
|
||||||
|
*/
|
||||||
|
+/*
|
||||||
|
int TINFCC tinf_zlib_uncompress(void *dest, unsigned int *destLen,
|
||||||
|
const void *source, unsigned int sourceLen);
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute Adler-32 checksum of `length` bytes starting at `data`.
|
||||||
|
@@ -122,7 +126,9 @@
|
||||||
|
* @param length size of data
|
||||||
|
* @return Adler-32 checksum
|
||||||
|
*/
|
||||||
|
+/*
|
||||||
|
unsigned int TINFCC tinf_adler32(const void *data, unsigned int length);
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute CRC32 checksum of `length` bytes starting at `data`.
|
||||||
|
@@ -131,7 +137,9 @@
|
||||||
|
* @param length size of data
|
||||||
|
* @return CRC32 checksum
|
||||||
|
*/
|
||||||
|
+/*
|
||||||
|
unsigned int TINFCC tinf_crc32(const void *data, unsigned int length);
|
||||||
|
+*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
diff '--color=auto' -urN tinf-clean/tinfgzip.c decompressor/tinf/tinfgzip.c
|
||||||
|
--- tinf-clean/tinfgzip.c 2023-06-06 00:57:16.983772372 +0200
|
||||||
|
+++ decompressor/tinf/tinfgzip.c 2023-06-06 01:09:39.119942087 +0200
|
||||||
|
@@ -39,6 +39,8 @@
|
||||||
|
| ((unsigned int) p[1] << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+
|
||||||
|
static unsigned int read_le32(const unsigned char *p)
|
||||||
|
{
|
||||||
|
return ((unsigned int) p[0])
|
||||||
|
@@ -47,13 +49,17 @@
|
||||||
|
| ((unsigned int) p[3] << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int tinf_gzip_uncompress(void *dest, unsigned int *destLen,
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+int tinf_gzip_uncompress(void *dest,
|
||||||
|
const void *source, unsigned int sourceLen)
|
||||||
|
{
|
||||||
|
const unsigned char *src = (const unsigned char *) source;
|
||||||
|
unsigned char *dst = (unsigned char *) dest;
|
||||||
|
const unsigned char *start;
|
||||||
|
+/*
|
||||||
|
unsigned int dlen, crc32;
|
||||||
|
+*/
|
||||||
|
int res;
|
||||||
|
unsigned char flg;
|
||||||
|
|
||||||
|
@@ -101,7 +107,7 @@
|
||||||
|
/* Skip file name if present */
|
||||||
|
if (flg & FNAME) {
|
||||||
|
do {
|
||||||
|
- if (start - src >= sourceLen) {
|
||||||
|
+ if (((unsigned int)(start - src)) >= sourceLen) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
} while (*start++);
|
||||||
|
@@ -110,7 +116,7 @@
|
||||||
|
/* Skip file comment if present */
|
||||||
|
if (flg & FCOMMENT) {
|
||||||
|
do {
|
||||||
|
- if (start - src >= sourceLen) {
|
||||||
|
+ if (((unsigned int)(start - src)) >= sourceLen) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
} while (*start++);
|
||||||
|
@@ -118,6 +124,7 @@
|
||||||
|
|
||||||
|
/* Check header crc if present */
|
||||||
|
if (flg & FHCRC) {
|
||||||
|
+/*
|
||||||
|
unsigned int hcrc;
|
||||||
|
|
||||||
|
if (start - src > sourceLen - 2) {
|
||||||
|
@@ -129,10 +136,12 @@
|
||||||
|
if (hcrc != (tinf_crc32(src, start - src) & 0x0000FFFF)) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
+*/
|
||||||
|
|
||||||
|
start += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
/* -- Get decompressed length -- */
|
||||||
|
|
||||||
|
dlen = read_le32(&src[sourceLen - 4]);
|
||||||
|
@@ -144,6 +153,7 @@
|
||||||
|
/* -- Get CRC32 checksum of original data -- */
|
||||||
|
|
||||||
|
crc32 = read_le32(&src[sourceLen - 8]);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
/* -- Decompress data -- */
|
||||||
|
|
||||||
|
@@ -151,13 +161,14 @@
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- res = tinf_uncompress(dst, destLen, start,
|
||||||
|
+ res = tinf_uncompress(dst, start,
|
||||||
|
(src + sourceLen) - start - 8);
|
||||||
|
|
||||||
|
if (res != TINF_OK) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if 0
|
||||||
|
if (*destLen != dlen) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
@@ -167,6 +178,7 @@
|
||||||
|
if (crc32 != tinf_crc32(dst, dlen)) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
return TINF_OK;
|
||||||
|
}
|
||||||
|
diff '--color=auto' -urN tinf-clean/tinflate.c decompressor/tinf/tinflate.c
|
||||||
|
--- tinf-clean/tinflate.c 2023-06-06 00:57:10.746958386 +0200
|
||||||
|
+++ decompressor/tinf/tinflate.c 2023-06-06 01:12:19.629674294 +0200
|
||||||
|
@@ -25,7 +25,7 @@
|
||||||
|
|
||||||
|
#include "tinf.h"
|
||||||
|
|
||||||
|
-#include <assert.h>
|
||||||
|
+#define assert(...)
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#if defined(UINT_MAX) && (UINT_MAX) < 0xFFFFFFFFUL
|
||||||
|
@@ -49,7 +49,9 @@
|
||||||
|
|
||||||
|
unsigned char *dest_start;
|
||||||
|
unsigned char *dest;
|
||||||
|
+/*
|
||||||
|
unsigned char *dest_end;
|
||||||
|
+*/
|
||||||
|
|
||||||
|
struct tinf_tree ltree; /* Literal/length tree */
|
||||||
|
struct tinf_tree dtree; /* Distance tree */
|
||||||
|
@@ -425,9 +427,12 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sym < 256) {
|
||||||
|
+/*
|
||||||
|
if (d->dest == d->dest_end) {
|
||||||
|
return TINF_BUF_ERROR;
|
||||||
|
}
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
*d->dest++ = sym;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@@ -465,9 +470,11 @@
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
if (d->dest_end - d->dest < length) {
|
||||||
|
return TINF_BUF_ERROR;
|
||||||
|
}
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/* Copy match */
|
||||||
|
for (i = 0; i < length; ++i) {
|
||||||
|
@@ -501,6 +508,7 @@
|
||||||
|
|
||||||
|
d->source += 4;
|
||||||
|
|
||||||
|
+/*
|
||||||
|
if (d->source_end - d->source < length) {
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
@@ -508,6 +516,7 @@
|
||||||
|
if (d->dest_end - d->dest < length) {
|
||||||
|
return TINF_BUF_ERROR;
|
||||||
|
}
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/* Copy block */
|
||||||
|
while (length--) {
|
||||||
|
@@ -548,13 +557,15 @@
|
||||||
|
/* -- Public functions -- */
|
||||||
|
|
||||||
|
/* Initialize global (static) data */
|
||||||
|
+/*
|
||||||
|
void tinf_init(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+*/
|
||||||
|
|
||||||
|
/* Inflate stream from source to dest */
|
||||||
|
-int tinf_uncompress(void *dest, unsigned int *destLen,
|
||||||
|
+int tinf_uncompress(void *dest,
|
||||||
|
const void *source, unsigned int sourceLen)
|
||||||
|
{
|
||||||
|
struct tinf_data d;
|
||||||
|
@@ -569,7 +580,9 @@
|
||||||
|
|
||||||
|
d.dest = (unsigned char *) dest;
|
||||||
|
d.dest_start = d.dest;
|
||||||
|
+/*
|
||||||
|
d.dest_end = d.dest + *destLen;
|
||||||
|
+*/
|
||||||
|
|
||||||
|
do {
|
||||||
|
unsigned int btype;
|
||||||
|
@@ -610,7 +623,9 @@
|
||||||
|
return TINF_DATA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
*destLen = d.dest - d.dest_start;
|
||||||
|
+*/
|
||||||
|
|
||||||
|
return TINF_OK;
|
||||||
|
}
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* tinf - tiny inflate library (inflate, gzip, zlib)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2019 Joergen Ibsen
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must
|
|
||||||
* not claim that you wrote the original software. If you use this
|
|
||||||
* software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must
|
|
||||||
* not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TINF_H_INCLUDED
|
|
||||||
#define TINF_H_INCLUDED
|
|
||||||
|
|
||||||
#define TINF_VER_MAJOR 1 /**< Major version number */
|
|
||||||
#define TINF_VER_MINOR 2 /**< Minor version number */
|
|
||||||
#define TINF_VER_PATCH 1 /**< Patch version number */
|
|
||||||
#define TINF_VER_STRING "1.2.1" /**< Version number as a string */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Status codes returned.
|
|
||||||
*
|
|
||||||
* @see tinf_uncompress, tinf_gzip_uncompress, tinf_zlib_uncompress
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
TINF_OK = 0, /**< Success */
|
|
||||||
TINF_DATA_ERROR = -3, /**< Input error */
|
|
||||||
TINF_BUF_ERROR = -5 /**< Not enough room for output */
|
|
||||||
} tinf_error_code;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decompress `sourceLen` bytes of deflate data from `source` to `dest`.
|
|
||||||
*
|
|
||||||
* The variable `destLen` points to must contain the size of `dest` on entry,
|
|
||||||
* and will be set to the size of the decompressed data on success.
|
|
||||||
*
|
|
||||||
* Reads at most `sourceLen` bytes from `source`.
|
|
||||||
* Writes at most `*destLen` bytes to `dest`.
|
|
||||||
*
|
|
||||||
* @param dest pointer to where to place decompressed data
|
|
||||||
* @param destLen pointer to variable containing size of `dest`
|
|
||||||
* @param source pointer to compressed data
|
|
||||||
* @param sourceLen size of compressed data
|
|
||||||
* @return `TINF_OK` on success, error code on error
|
|
||||||
*/
|
|
||||||
int tinf_uncompress(void *dest,
|
|
||||||
const void *source, unsigned int sourceLen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decompress `sourceLen` bytes of gzip data from `source` to `dest`.
|
|
||||||
*
|
|
||||||
* The variable `destLen` points to must contain the size of `dest` on entry,
|
|
||||||
* and will be set to the size of the decompressed data on success.
|
|
||||||
*
|
|
||||||
* Reads at most `sourceLen` bytes from `source`.
|
|
||||||
* Writes at most `*destLen` bytes to `dest`.
|
|
||||||
*
|
|
||||||
* @param dest pointer to where to place decompressed data
|
|
||||||
* @param destLen pointer to variable containing size of `dest`
|
|
||||||
* @param source pointer to compressed data
|
|
||||||
* @param sourceLen size of compressed data
|
|
||||||
* @return `TINF_OK` on success, error code on error
|
|
||||||
*/
|
|
||||||
int tinf_gzip_uncompress(void *dest,
|
|
||||||
const void *source, unsigned int sourceLen);
|
|
||||||
#endif /* TINF_H_INCLUDED */
|
|
|
@ -1,120 +0,0 @@
|
||||||
/*
|
|
||||||
* tinfgzip - tiny gzip decompressor
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2019 Joergen Ibsen
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must
|
|
||||||
* not claim that you wrote the original software. If you use this
|
|
||||||
* software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must
|
|
||||||
* not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tinf.h"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FTEXT = 1,
|
|
||||||
FHCRC = 2,
|
|
||||||
FEXTRA = 4,
|
|
||||||
FNAME = 8,
|
|
||||||
FCOMMENT = 16
|
|
||||||
} tinf_gzip_flag;
|
|
||||||
|
|
||||||
int tinf_gzip_uncompress(void *dest,
|
|
||||||
const void *source, unsigned int sourceLen) {
|
|
||||||
const unsigned char *src = (const unsigned char *) source;
|
|
||||||
unsigned char *dst = (unsigned char *) dest;
|
|
||||||
const unsigned char *start;
|
|
||||||
int res;
|
|
||||||
unsigned char flg;
|
|
||||||
|
|
||||||
/* -- Check header -- */
|
|
||||||
|
|
||||||
/* Check room for at least 10 byte header and 8 byte trailer */
|
|
||||||
if (sourceLen < 18) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check id bytes */
|
|
||||||
if (src[0] != 0x1F || src[1] != 0x8B) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check method is deflate */
|
|
||||||
if (src[2] != 8) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get flag byte */
|
|
||||||
flg = src[3];
|
|
||||||
|
|
||||||
/* Check that reserved bits are zero */
|
|
||||||
if (flg & 0xE0) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Find start of compressed data -- */
|
|
||||||
|
|
||||||
/* Skip base header of 10 bytes */
|
|
||||||
start = src + 10;
|
|
||||||
|
|
||||||
/* Skip extra data if present */
|
|
||||||
if (flg & FEXTRA) {
|
|
||||||
unsigned int xlen = *start;
|
|
||||||
|
|
||||||
if (xlen > sourceLen - 12) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
start += xlen + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip file name if present */
|
|
||||||
if (flg & FNAME) {
|
|
||||||
do {
|
|
||||||
if (((unsigned int)(start - src)) >= sourceLen) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
} while (*start++);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip file comment if present */
|
|
||||||
if (flg & FCOMMENT) {
|
|
||||||
do {
|
|
||||||
if (((unsigned int)(start - src)) >= sourceLen) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
} while (*start++);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flg & FHCRC) {
|
|
||||||
start += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Decompress data -- */
|
|
||||||
|
|
||||||
if ((src + sourceLen) - start < 8) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = tinf_uncompress(dst, start,
|
|
||||||
(src + sourceLen) - start - 8);
|
|
||||||
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
|
@ -1,562 +0,0 @@
|
||||||
/*
|
|
||||||
* tinflate - tiny inflate
|
|
||||||
*
|
|
||||||
* Copyright (c) 2003-2019 Joergen Ibsen
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any damages
|
|
||||||
* arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any purpose,
|
|
||||||
* including commercial applications, and to alter it and redistribute it
|
|
||||||
* freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must
|
|
||||||
* not claim that you wrote the original software. If you use this
|
|
||||||
* software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must
|
|
||||||
* not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "tinf.h"
|
|
||||||
|
|
||||||
/* -- Internal data structures -- */
|
|
||||||
|
|
||||||
struct tinf_tree {
|
|
||||||
unsigned short counts[16]; /* Number of codes with a given length */
|
|
||||||
unsigned short symbols[288]; /* Symbols sorted by code */
|
|
||||||
int max_sym;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tinf_data {
|
|
||||||
const unsigned char *source;
|
|
||||||
const unsigned char *source_end;
|
|
||||||
unsigned int tag;
|
|
||||||
int bitcount;
|
|
||||||
int overflow;
|
|
||||||
|
|
||||||
unsigned char *dest_start;
|
|
||||||
unsigned char *dest;
|
|
||||||
|
|
||||||
struct tinf_tree ltree; /* Literal/length tree */
|
|
||||||
struct tinf_tree dtree; /* Distance tree */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* -- Utility functions -- */
|
|
||||||
|
|
||||||
static unsigned int read_le16(const unsigned char *p) {
|
|
||||||
return ((unsigned int) p[0])
|
|
||||||
| ((unsigned int) p[1] << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build fixed Huffman trees */
|
|
||||||
static void tinf_build_fixed_trees(struct tinf_tree *lt, struct tinf_tree *dt) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Build fixed literal/length tree */
|
|
||||||
for (i = 0; i < 16; ++i) {
|
|
||||||
lt->counts[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lt->counts[7] = 24;
|
|
||||||
lt->counts[8] = 152;
|
|
||||||
lt->counts[9] = 112;
|
|
||||||
|
|
||||||
for (i = 0; i < 24; ++i) {
|
|
||||||
lt->symbols[i] = 256 + i;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 144; ++i) {
|
|
||||||
lt->symbols[24 + i] = i;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 8; ++i) {
|
|
||||||
lt->symbols[24 + 144 + i] = 280 + i;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 112; ++i) {
|
|
||||||
lt->symbols[24 + 144 + 8 + i] = 144 + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
lt->max_sym = 285;
|
|
||||||
|
|
||||||
/* Build fixed distance tree */
|
|
||||||
for (i = 0; i < 16; ++i) {
|
|
||||||
dt->counts[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt->counts[5] = 32;
|
|
||||||
|
|
||||||
for (i = 0; i < 32; ++i) {
|
|
||||||
dt->symbols[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt->max_sym = 29;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given an array of code lengths, build a tree */
|
|
||||||
static int tinf_build_tree(struct tinf_tree *t, const unsigned char *lengths,
|
|
||||||
unsigned int num) {
|
|
||||||
unsigned short offs[16];
|
|
||||||
unsigned int i, num_codes, available;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; ++i) {
|
|
||||||
t->counts[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
t->max_sym = -1;
|
|
||||||
|
|
||||||
/* Count number of codes for each non-zero length */
|
|
||||||
for (i = 0; i < num; ++i) {
|
|
||||||
|
|
||||||
if (lengths[i]) {
|
|
||||||
t->max_sym = i;
|
|
||||||
t->counts[lengths[i]]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute offset table for distribution sort */
|
|
||||||
for (available = 1, num_codes = 0, i = 0; i < 16; ++i) {
|
|
||||||
unsigned int used = t->counts[i];
|
|
||||||
|
|
||||||
/* Check length contains no more codes than available */
|
|
||||||
if (used > available) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
available = 2 * (available - used);
|
|
||||||
|
|
||||||
offs[i] = num_codes;
|
|
||||||
num_codes += used;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check all codes were used, or for the special case of only one
|
|
||||||
* code that it has length 1
|
|
||||||
*/
|
|
||||||
if ((num_codes > 1 && available > 0)
|
|
||||||
|| (num_codes == 1 && t->counts[1] != 1)) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in symbols sorted by code */
|
|
||||||
for (i = 0; i < num; ++i) {
|
|
||||||
if (lengths[i]) {
|
|
||||||
t->symbols[offs[lengths[i]]++] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For the special case of only one code (which will be 0) add a
|
|
||||||
* code 1 which results in a symbol that is too large
|
|
||||||
*/
|
|
||||||
if (num_codes == 1) {
|
|
||||||
t->counts[1] = 2;
|
|
||||||
t->symbols[1] = t->max_sym + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Decode functions -- */
|
|
||||||
|
|
||||||
static void tinf_refill(struct tinf_data *d, int num) {
|
|
||||||
|
|
||||||
/* Read bytes until at least num bits available */
|
|
||||||
while (d->bitcount < num) {
|
|
||||||
if (d->source != d->source_end) {
|
|
||||||
d->tag |= (unsigned int) *d->source++ << d->bitcount;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
d->overflow = 1;
|
|
||||||
}
|
|
||||||
d->bitcount += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int tinf_getbits_no_refill(struct tinf_data *d, int num) {
|
|
||||||
unsigned int bits;
|
|
||||||
|
|
||||||
|
|
||||||
/* Get bits from tag */
|
|
||||||
bits = d->tag & ((1UL << num) - 1);
|
|
||||||
|
|
||||||
/* Remove bits from tag */
|
|
||||||
d->tag >>= num;
|
|
||||||
d->bitcount -= num;
|
|
||||||
|
|
||||||
return bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get num bits from source stream */
|
|
||||||
static unsigned int tinf_getbits(struct tinf_data *d, int num) {
|
|
||||||
tinf_refill(d, num);
|
|
||||||
return tinf_getbits_no_refill(d, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a num bit value from stream and add base */
|
|
||||||
static unsigned int tinf_getbits_base(struct tinf_data *d, int num, int base) {
|
|
||||||
return base + (num ? tinf_getbits(d, num) : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a data stream and a tree, decode a symbol */
|
|
||||||
static int tinf_decode_symbol(struct tinf_data *d, const struct tinf_tree *t) {
|
|
||||||
int base = 0, offs = 0;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Get more bits while code index is above number of codes
|
|
||||||
*
|
|
||||||
* Rather than the actual code, we are computing the position of the
|
|
||||||
* code in the sorted order of codes, which is the index of the
|
|
||||||
* corresponding symbol.
|
|
||||||
*
|
|
||||||
* Conceptually, for each code length (level in the tree), there are
|
|
||||||
* counts[len] leaves on the left and internal nodes on the right.
|
|
||||||
* The index we have decoded so far is base + offs, and if that
|
|
||||||
* falls within the leaves we are done. Otherwise we adjust the range
|
|
||||||
* of offs and add one more bit to it.
|
|
||||||
*/
|
|
||||||
for (len = 1; ; ++len) {
|
|
||||||
offs = 2 * offs + tinf_getbits(d, 1);
|
|
||||||
|
|
||||||
if (offs < t->counts[len]) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
base += t->counts[len];
|
|
||||||
offs -= t->counts[len];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return t->symbols[base + offs];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a data stream, decode dynamic trees from it */
|
|
||||||
static int tinf_decode_trees(struct tinf_data *d, struct tinf_tree *lt,
|
|
||||||
struct tinf_tree *dt) {
|
|
||||||
unsigned char lengths[288 + 32];
|
|
||||||
|
|
||||||
/* Special ordering of code length codes */
|
|
||||||
static const unsigned char clcidx[19] = {
|
|
||||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5,
|
|
||||||
11, 4, 12, 3, 13, 2, 14, 1, 15
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned int hlit, hdist, hclen;
|
|
||||||
unsigned int i, num, length;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
/* Get 5 bits HLIT (257-286) */
|
|
||||||
hlit = tinf_getbits_base(d, 5, 257);
|
|
||||||
|
|
||||||
/* Get 5 bits HDIST (1-32) */
|
|
||||||
hdist = tinf_getbits_base(d, 5, 1);
|
|
||||||
|
|
||||||
/* Get 4 bits HCLEN (4-19) */
|
|
||||||
hclen = tinf_getbits_base(d, 4, 4);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The RFC limits the range of HLIT to 286, but lists HDIST as range
|
|
||||||
* 1-32, even though distance codes 30 and 31 have no meaning. While
|
|
||||||
* we could allow the full range of HLIT and HDIST to make it possible
|
|
||||||
* to decode the fixed trees with this function, we consider it an
|
|
||||||
* error here.
|
|
||||||
*
|
|
||||||
* See also: https://github.com/madler/zlib/issues/82
|
|
||||||
*/
|
|
||||||
if (hlit > 286 || hdist > 30) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 19; ++i) {
|
|
||||||
lengths[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read code lengths for code length alphabet */
|
|
||||||
for (i = 0; i < hclen; ++i) {
|
|
||||||
/* Get 3 bits code length (0-7) */
|
|
||||||
unsigned int clen = tinf_getbits(d, 3);
|
|
||||||
|
|
||||||
lengths[clcidx[i]] = clen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build code length tree (in literal/length tree to save space) */
|
|
||||||
res = tinf_build_tree(lt, lengths, 19);
|
|
||||||
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check code length tree is not empty */
|
|
||||||
if (lt->max_sym == -1) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decode code lengths for the dynamic trees */
|
|
||||||
for (num = 0; num < hlit + hdist; ) {
|
|
||||||
int sym = tinf_decode_symbol(d, lt);
|
|
||||||
|
|
||||||
if (sym > lt->max_sym) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (sym) {
|
|
||||||
case 16:
|
|
||||||
/* Copy previous code length 3-6 times (read 2 bits) */
|
|
||||||
if (num == 0) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
sym = lengths[num - 1];
|
|
||||||
length = tinf_getbits_base(d, 2, 3);
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
/* Repeat code length 0 for 3-10 times (read 3 bits) */
|
|
||||||
sym = 0;
|
|
||||||
length = tinf_getbits_base(d, 3, 3);
|
|
||||||
break;
|
|
||||||
case 18:
|
|
||||||
/* Repeat code length 0 for 11-138 times (read 7 bits) */
|
|
||||||
sym = 0;
|
|
||||||
length = tinf_getbits_base(d, 7, 11);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Values 0-15 represent the actual code lengths */
|
|
||||||
length = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > hlit + hdist - num) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (length--) {
|
|
||||||
lengths[num++] = sym;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check EOB symbol is present */
|
|
||||||
if (lengths[256] == 0) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build dynamic trees */
|
|
||||||
res = tinf_build_tree(lt, lengths, hlit);
|
|
||||||
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = tinf_build_tree(dt, lengths + hlit, hdist);
|
|
||||||
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Block inflate functions -- */
|
|
||||||
|
|
||||||
/* Given a stream and two trees, inflate a block of data */
|
|
||||||
static int tinf_inflate_block_data(struct tinf_data *d, struct tinf_tree *lt,
|
|
||||||
struct tinf_tree *dt) {
|
|
||||||
/* Extra bits and base tables for length codes */
|
|
||||||
static const unsigned char length_bits[30] = {
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
||||||
1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
|
|
||||||
4, 4, 4, 4, 5, 5, 5, 5, 0, 127
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned short length_base[30] = {
|
|
||||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
|
|
||||||
15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
|
|
||||||
67, 83, 99, 115, 131, 163, 195, 227, 258, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Extra bits and base tables for distance codes */
|
|
||||||
static const unsigned char dist_bits[30] = {
|
|
||||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
|
||||||
4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
|
||||||
9, 9, 10, 10, 11, 11, 12, 12, 13, 13
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned short dist_base[30] = {
|
|
||||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
|
|
||||||
33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
|
|
||||||
1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
|
|
||||||
};
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
int sym = tinf_decode_symbol(d, lt);
|
|
||||||
|
|
||||||
/* Check for overflow in bit reader */
|
|
||||||
if (d->overflow) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sym < 256) {
|
|
||||||
*d->dest++ = sym;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int length, dist, offs;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Check for end of block */
|
|
||||||
if (sym == 256) {
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check sym is within range and distance tree is not empty */
|
|
||||||
if (sym > lt->max_sym || sym - 257 > 28 || dt->max_sym == -1) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
sym -= 257;
|
|
||||||
|
|
||||||
/* Possibly get more bits from length code */
|
|
||||||
length = tinf_getbits_base(d, length_bits[sym],
|
|
||||||
length_base[sym]);
|
|
||||||
|
|
||||||
dist = tinf_decode_symbol(d, dt);
|
|
||||||
|
|
||||||
/* Check dist is within range */
|
|
||||||
if (dist > dt->max_sym || dist > 29) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Possibly get more bits from distance code */
|
|
||||||
offs = tinf_getbits_base(d, dist_bits[dist],
|
|
||||||
dist_base[dist]);
|
|
||||||
|
|
||||||
if (offs > d->dest - d->dest_start) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy match */
|
|
||||||
for (i = 0; i < length; ++i) {
|
|
||||||
d->dest[i] = d->dest[i - offs];
|
|
||||||
}
|
|
||||||
|
|
||||||
d->dest += length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inflate an uncompressed block of data */
|
|
||||||
static int tinf_inflate_uncompressed_block(struct tinf_data *d) {
|
|
||||||
unsigned int length, invlength;
|
|
||||||
|
|
||||||
if (d->source_end - d->source < 4) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get length */
|
|
||||||
length = read_le16(d->source);
|
|
||||||
|
|
||||||
/* Get one's complement of length */
|
|
||||||
invlength = read_le16(d->source + 2);
|
|
||||||
|
|
||||||
/* Check length */
|
|
||||||
if (length != (~invlength & 0x0000FFFF)) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->source += 4;
|
|
||||||
|
|
||||||
/* Copy block */
|
|
||||||
while (length--) {
|
|
||||||
*d->dest++ = *d->source++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure we start next block on a byte boundary */
|
|
||||||
d->tag = 0;
|
|
||||||
d->bitcount = 0;
|
|
||||||
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inflate a block of data compressed with fixed Huffman trees */
|
|
||||||
static int tinf_inflate_fixed_block(struct tinf_data *d) {
|
|
||||||
/* Build fixed Huffman trees */
|
|
||||||
tinf_build_fixed_trees(&d->ltree, &d->dtree);
|
|
||||||
|
|
||||||
/* Decode block using fixed trees */
|
|
||||||
return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inflate a block of data compressed with dynamic Huffman trees */
|
|
||||||
static int tinf_inflate_dynamic_block(struct tinf_data *d) {
|
|
||||||
/* Decode trees from stream */
|
|
||||||
int res = tinf_decode_trees(d, &d->ltree, &d->dtree);
|
|
||||||
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decode block using decoded trees */
|
|
||||||
return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Public functions -- */
|
|
||||||
|
|
||||||
/* Inflate stream from source to dest */
|
|
||||||
int tinf_uncompress(void *dest,
|
|
||||||
const void *source, unsigned int sourceLen) {
|
|
||||||
struct tinf_data d;
|
|
||||||
int bfinal;
|
|
||||||
|
|
||||||
/* Initialise data */
|
|
||||||
d.source = (const unsigned char *) source;
|
|
||||||
d.source_end = d.source + sourceLen;
|
|
||||||
d.tag = 0;
|
|
||||||
d.bitcount = 0;
|
|
||||||
d.overflow = 0;
|
|
||||||
|
|
||||||
d.dest = (unsigned char *) dest;
|
|
||||||
d.dest_start = d.dest;
|
|
||||||
|
|
||||||
do {
|
|
||||||
unsigned int btype;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
/* Read final block flag */
|
|
||||||
bfinal = tinf_getbits(&d, 1);
|
|
||||||
|
|
||||||
/* Read block type (2 bits) */
|
|
||||||
btype = tinf_getbits(&d, 2);
|
|
||||||
|
|
||||||
/* Decompress block */
|
|
||||||
switch (btype) {
|
|
||||||
case 0:
|
|
||||||
/* Decompress uncompressed block */
|
|
||||||
res = tinf_inflate_uncompressed_block(&d);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* Decompress block with fixed Huffman trees */
|
|
||||||
res = tinf_inflate_fixed_block(&d);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* Decompress block with dynamic Huffman trees */
|
|
||||||
res = tinf_inflate_dynamic_block(&d);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res = TINF_DATA_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != TINF_OK) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
} while (!bfinal);
|
|
||||||
|
|
||||||
/* Check for overflow in bit reader */
|
|
||||||
if (d.overflow) {
|
|
||||||
return TINF_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TINF_OK;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue