:: commit f8de2a2262ed840902771d034f2e059d0dbca8e3

mintsuki <mintsuki@protonmail.com> — 2023-06-05 23:16

parents: 4af9d4a863

misc: Remove tinf from tree, pull at bootstrap time

diff --git a/.gitignore b/.gitignore
index 4b2e9714..ffa9737b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
 /libgcc-binaries
 /common/flanterm
 /common/stb/stb_image.h
+/decompressor/tinf
 /ovmf*
 *.o
 *.d
diff --git a/GNUmakefile.in b/GNUmakefile.in
index 0183c91b..793a39df 100644
--- a/GNUmakefile.in
+++ b/GNUmakefile.in
@@ -333,7 +333,7 @@ distclean: clean
 
 .PHONY: maintainer-clean
 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
 common-uefi-x86-64:
diff --git a/bootstrap b/bootstrap
index c3a2d5b5..87251592 100755
--- a/bootstrap
+++ b/bootstrap
@@ -13,6 +13,14 @@ fi
 
 [ -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 )
+[ -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 )
 [ -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
diff --git a/decompressor/tinf.patch b/decompressor/tinf.patch
new file mode 100644
index 00000000..3f87e8e8
--- /dev/null
+++ b/decompressor/tinf.patch
@@ -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;
+ }
diff --git a/decompressor/tinf/tinf.h b/decompressor/tinf/tinf.h
deleted file mode 100644
index 6e56faa3..00000000
--- a/decompressor/tinf/tinf.h
+++ /dev/null
@@ -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 */
diff --git a/decompressor/tinf/tinfgzip.c b/decompressor/tinf/tinfgzip.c
deleted file mode 100644
index 7935a50e..00000000
--- a/decompressor/tinf/tinfgzip.c
+++ /dev/null
@@ -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;
-}
diff --git a/decompressor/tinf/tinflate.c b/decompressor/tinf/tinflate.c
deleted file mode 100644
index eb3c4907..00000000
--- a/decompressor/tinf/tinflate.c
+++ /dev/null
@@ -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;
-}
-
tab: 248 wrap: offon