Initial commit of tinf v1.00 source.
This commit is contained in:
commit
93352fca2a
27 changed files with 2229 additions and 0 deletions
BIN
bin/tgunzip.exe
Normal file
BIN
bin/tgunzip.exe
Normal file
Binary file not shown.
31
examples/tgunzip/makefile.b32
Normal file
31
examples/tgunzip/makefile.b32
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## Borland C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = tgunzip.exe
|
||||
objects = tgunzip.obj
|
||||
libs = ..\..\lib\tinf.lib
|
||||
temps = tgunzip.tds
|
||||
|
||||
cflags = -a16 -K -O2 -OS -I..\..\src
|
||||
ldflags = -C -q -Gn -x -Gz -ap -Tpe
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
ilink32 $(ldflags) c0x32 $(objects), $@ , , import32 cw32 $(libs) , ,
|
||||
|
||||
%.obj : %.c
|
||||
bcc32 $(cflags) -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target) $(temps)
|
||||
30
examples/tgunzip/makefile.dj2
Normal file
30
examples/tgunzip/makefile.dj2
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## DJGPP makefile
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = tgunzip.exe
|
||||
objects = tgunzip.o
|
||||
libs = ../../lib/libtinf.a
|
||||
|
||||
cflags = -s -Wall -Os -fomit-frame-pointer -I../../src
|
||||
ldflags = $(cflags)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
gcc $(ldflags) -o $@ $^ $(libs)
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target)
|
||||
31
examples/tgunzip/makefile.dmc
Normal file
31
examples/tgunzip/makefile.dmc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## Digital Mars C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = tgunzip.exe
|
||||
objects = tgunzip.obj
|
||||
libs = ..\..\lib\tinf.lib
|
||||
temps = tgunzip.map
|
||||
|
||||
cflags = -s -mn -o+all -I..\..\src
|
||||
ldflags = $(cflags)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
dmc $(ldflags) -o$@ $^ $(libs)
|
||||
|
||||
%.obj : %.c
|
||||
dmc $(cflags) -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target) $(temps)
|
||||
30
examples/tgunzip/makefile.elf
Normal file
30
examples/tgunzip/makefile.elf
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## GCC makefile (Linux, FreeBSD, BeOS and QNX)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = tgunzip
|
||||
objects = tgunzip.o
|
||||
libs = ../../lib/libtinf.a
|
||||
|
||||
cflags = -s -Wall -Os -I../../src
|
||||
ldflags = $(cflags)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
gcc $(ldflags) -o $@ $^ $(libs)
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target)
|
||||
28
examples/tgunzip/makefile.mgw
Normal file
28
examples/tgunzip/makefile.mgw
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## MinGW / Cygwin makefile
|
||||
##
|
||||
## Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
|
||||
target = tgunzip.exe
|
||||
objects = tgunzip.o
|
||||
libs = ../../lib/libtinf.a
|
||||
|
||||
cflags = -s -Wall -Os -fomit-frame-pointer -I../../src
|
||||
ldflags = $(cflags)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
gcc $(ldflags) -o $@ $^ $(libs)
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(target) $(objects)
|
||||
28
examples/tgunzip/makefile.vc
Normal file
28
examples/tgunzip/makefile.vc
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## Visual C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
|
||||
target = tgunzip.exe
|
||||
objects = tgunzip.obj
|
||||
libs = ../../lib/tinf.lib
|
||||
|
||||
cflags = /nologo /W3 /O1 /G6 /W3 /Gy /GF /I..\..\src
|
||||
ldflags = /nologo /release /opt:ref /opt:icf
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
link $(ldflags) /out:$@ $^ $(libs)
|
||||
|
||||
%.obj : %.c
|
||||
cl $(cflags) -c $<
|
||||
|
||||
clean:
|
||||
$(RM) $(target) $(objects)
|
||||
31
examples/tgunzip/makefile.wat
Normal file
31
examples/tgunzip/makefile.wat
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
##
|
||||
## tgunzip - gzip decompressor example
|
||||
##
|
||||
## Watcom / OpenWatcom C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = tgunzip.exe
|
||||
objects = tgunzip.obj
|
||||
libs = ../../lib/tinf.lib
|
||||
system = nt
|
||||
|
||||
cflags = -bt=$(system) -d0 -ox -I..\..\src
|
||||
ldflags = system $(system)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
wlink $(ldflags) name $@ file {$^} library {$(libs)}
|
||||
|
||||
%.obj : %.c
|
||||
wcc386 $(cflags) $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target)
|
||||
115
examples/tgunzip/tgunzip.c
Normal file
115
examples/tgunzip/tgunzip.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* tgunzip - gzip decompressor example
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tinf.h"
|
||||
|
||||
void exit_error(const char *what)
|
||||
{
|
||||
printf("ERROR: %s\n", what);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fin, *fout;
|
||||
unsigned int len, dlen, outlen;
|
||||
unsigned char *source, *dest;
|
||||
int res;
|
||||
|
||||
printf("tgunzip - example from the tiny inflate library (www.ibsensoftware.com)\n\n");
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
printf(
|
||||
"Syntax: tgunzip <source> <destination>\n\n"
|
||||
"Both input and output are kept in memory, so do not use this on huge files.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
tinf_init();
|
||||
|
||||
/* -- open files -- */
|
||||
|
||||
if ((fin = fopen(argv[1], "rb")) == NULL) exit_error("source file");
|
||||
|
||||
if ((fout = fopen(argv[2], "wb")) == NULL) exit_error("destination file");
|
||||
|
||||
/* -- read source -- */
|
||||
|
||||
fseek(fin, 0, SEEK_END);
|
||||
|
||||
len = ftell(fin);
|
||||
|
||||
fseek(fin, 0, SEEK_SET);
|
||||
|
||||
source = (unsigned char *)malloc(len);
|
||||
|
||||
if (source == NULL) exit_error("memory");
|
||||
|
||||
if (fread(source, 1, len, fin) != len) exit_error("read");
|
||||
|
||||
fclose(fin);
|
||||
|
||||
/* -- get decompressed length -- */
|
||||
|
||||
dlen = source[len - 1];
|
||||
dlen = 256*dlen + source[len - 2];
|
||||
dlen = 256*dlen + source[len - 3];
|
||||
dlen = 256*dlen + source[len - 4];
|
||||
|
||||
dest = (unsigned char *)malloc(dlen);
|
||||
|
||||
if (dest == NULL) exit_error("memory");
|
||||
|
||||
/* -- decompress data -- */
|
||||
|
||||
outlen = dlen;
|
||||
|
||||
res = tinf_gzip_uncompress(dest, &outlen, source, len);
|
||||
|
||||
if ((res != TINF_OK) || (outlen != dlen)) exit_error("inflate");
|
||||
|
||||
printf("decompressed %u bytes\n", outlen);
|
||||
|
||||
/* -- write output -- */
|
||||
|
||||
fwrite(dest, 1, outlen, fout);
|
||||
|
||||
fclose(fout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
lib/empty.dir
Normal file
1
lib/empty.dir
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- empty dir ---
|
||||
214
readme.txt
Normal file
214
readme.txt
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
|
||||
|
||||
tinf - tiny inflate library
|
||||
|
||||
Version 1.00
|
||||
|
||||
Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
All Rights Reserved
|
||||
|
||||
http://www.ibsensoftware.com/
|
||||
|
||||
|
||||
|
||||
About
|
||||
-----
|
||||
|
||||
tinf is a small library implementing the decompression algorithm for the
|
||||
deflate compressed data format (called 'inflate'). Deflate compression is
|
||||
used in e.g. zlib, gzip, zip and png.
|
||||
|
||||
I wrote it because I needed a small in-memory zlib decompressor for a self-
|
||||
extracting archive, and the zlib library added 15k to my program. The tinf
|
||||
code added only 2k.
|
||||
|
||||
Naturally the size difference is insignificant in most cases. Also, the
|
||||
zlib library has many more features, is more secure, and mostly faster.
|
||||
But if you have a project that calls for a small and simple deflate
|
||||
decompressor, give it a try :-)
|
||||
|
||||
While the implementation should be fairly compliant, it does assume it is
|
||||
given valid compressed data, and that there is sufficient space for the
|
||||
decompressed data.
|
||||
|
||||
Simple wrappers for decompressing zlib streams and gzip'ed data in memory
|
||||
are supplied.
|
||||
|
||||
tgunzip, an example command-line gzip decompressor in C, is included.
|
||||
|
||||
The inflate algorithm and data format are from 'DEFLATE Compressed Data
|
||||
Format Specification version 1.3' (RFC 1951).
|
||||
|
||||
The zlib data format is from 'ZLIB Compressed Data Format Specification
|
||||
version 3.3' (RFC 1950).
|
||||
|
||||
The gzip data format is from 'GZIP file format specification version 4.3'
|
||||
(RFC 1952).
|
||||
|
||||
Ideas for future versions:
|
||||
|
||||
- the fixed Huffman trees could be built by tinf_decode_trees()
|
||||
using a small table
|
||||
- memory for the TINF_DATA object should be passed, to avoid using
|
||||
more than 1k of stack space
|
||||
- wrappers for unpacking zip archives and png images
|
||||
- implement more in x86 assembler
|
||||
- more sanity checks
|
||||
- in tinf_uncompress, the (entry value of) destLen and sourceLen
|
||||
are not used
|
||||
- blocking of some sort, so everything does not have to be in mem
|
||||
- optional table-based huffman decoder
|
||||
|
||||
|
||||
Functionality
|
||||
-------------
|
||||
|
||||
void tinf_init();
|
||||
|
||||
Initialise the global uninitialised data used by the decompression code.
|
||||
This function must be called once before any calls to the decompression
|
||||
functions.
|
||||
|
||||
int tinf_uncompress(void *dest,
|
||||
unsigned int *destLen,
|
||||
const void *source,
|
||||
unsigned int sourceLen);
|
||||
|
||||
Decompress data in deflate compressed format from source[] to dest[].
|
||||
destLen is set to the length of the decompressed data. Returns TINF_OK
|
||||
on success, and TINF_DATA_ERROR on error.
|
||||
|
||||
int tinf_gzip_uncompress(void *dest,
|
||||
unsigned int *destLen,
|
||||
const void *source,
|
||||
unsigned int sourceLen);
|
||||
|
||||
Decompress data in gzip compressed format from source[] to dest[]. destLen
|
||||
is set to the length of the decompressed data. Returns TINF_OK on success,
|
||||
and TINF_DATA_ERROR on error.
|
||||
|
||||
int tinf_zlib_uncompress(void *dest,
|
||||
unsigned int *destLen,
|
||||
const void *source,
|
||||
unsigned int sourceLen);
|
||||
|
||||
Decompress data in zlib compressed format from source[] to dest[]. destLen
|
||||
is set to the length of the decompressed data. Returns TINF_OK on success,
|
||||
and TINF_DATA_ERROR on error.
|
||||
|
||||
unsigned int tinf_adler32(const void *data,
|
||||
unsigned int length);
|
||||
|
||||
Computes the Adler-32 checksum of length bytes starting at data. Used by
|
||||
tinf_zlib_uncompress().
|
||||
|
||||
unsigned int tinf_crc32(const void *data,
|
||||
unsigned int length);
|
||||
|
||||
Computes the CRC32 checksum of length bytes starting at data. Used by
|
||||
tinf_gzip_uncompress().
|
||||
|
||||
|
||||
Source Code
|
||||
-----------
|
||||
|
||||
The source code is ANSI C, and assumes that int is 32-bit. It has been
|
||||
tested on the x86 platform under Windows and Linux.
|
||||
|
||||
The decompression functions should be endian-neutral, and also reentrant
|
||||
and thread-safe (not tested).
|
||||
|
||||
In src/nasm there are 32-bit x86 assembler (386+) versions of some of the
|
||||
files.
|
||||
|
||||
Makefiles (GNU Make style) for a number of compilers are included.
|
||||
|
||||
|
||||
Frequently Asked Questions
|
||||
--------------------------
|
||||
|
||||
Q: Is it really free? Can I use it in my commercial ExpenZip software?
|
||||
A: It's open-source software, available under the zlib license (see
|
||||
later), which means you can use it for free -- even in commercial
|
||||
products. If you do, please be kind enough to add an acknowledgement.
|
||||
|
||||
Q: Did you just strip stuff from the zlib source to make it smaller?
|
||||
A: No, tinf was written from scratch, using the RFC documentation of
|
||||
the formats it supports.
|
||||
|
||||
Q: What do you mean by: 'the zlib library .. is more secure'?
|
||||
A: The zlib decompression code checks the compressed data for validity
|
||||
while decompressing, so even on corrupted data it will not crash.
|
||||
The tinf code assumes it is given valid compressed data.
|
||||
|
||||
Q: I'm a Delphi programmer, can I use tinf?
|
||||
A: Sure, the object files produced by both Borland C and Watcom C should
|
||||
be linkable with Delphi.
|
||||
|
||||
Q: Will tinf work on UltraSTRANGE machines running WhackOS?
|
||||
A: I have no idea .. please try it out and let me know!
|
||||
|
||||
Q: Why are all the makefiles in GNU Make style?
|
||||
A: I'm used to GNU Make, and it has a number of features that are missing
|
||||
in some of the other Make utilities.
|
||||
|
||||
Q: This is the first release, how can there be frequently asked questions?
|
||||
A: Ok, ok .. I made the questions up ;-)
|
||||
|
||||
|
||||
Greetings and Thanks
|
||||
--------------------
|
||||
|
||||
- Jean-loup Gailly and Mark Adler for the zlib library.
|
||||
- Eugene Suslikov (SEN) for making HIEW.
|
||||
- Oleh Yuschuk for making OllyDbg.
|
||||
- MinGW development team for making MinGW.
|
||||
- NASM development team for making NASM.
|
||||
|
||||
A special thanks to the beta-testers:
|
||||
|
||||
- Gautier
|
||||
- Lawrence E. Boothby
|
||||
- METALBRAIN
|
||||
- Oleg Prokhorov
|
||||
- Veit Kannegieser
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
tinf is made available under the zlib license:
|
||||
|
||||
tinf - tiny inflate library
|
||||
|
||||
Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
All Rights Reserved
|
||||
|
||||
http://www.ibsensoftware.com/
|
||||
|
||||
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.
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
v1.00 *: First release.
|
||||
|
||||
Project started September 14th 2003.
|
||||
78
src/adler32.c
Normal file
78
src/adler32.c
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Adler-32 checksum
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Adler-32 algorithm taken from the zlib source, which is
|
||||
* Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
|
||||
*/
|
||||
|
||||
#include "tinf.h"
|
||||
|
||||
#define A32_BASE 65521
|
||||
#define A32_NMAX 5552
|
||||
|
||||
unsigned int tinf_adler32(const void *data, unsigned int length)
|
||||
{
|
||||
const unsigned char *buf = (const unsigned char *)data;
|
||||
|
||||
unsigned int s1 = 1;
|
||||
unsigned int s2 = 0;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
int k = length < A32_NMAX ? length : A32_NMAX;
|
||||
int i;
|
||||
|
||||
for (i = k / 16; i; --i, buf += 16)
|
||||
{
|
||||
s1 += buf[0]; s2 += s1; s1 += buf[1]; s2 += s1;
|
||||
s1 += buf[2]; s2 += s1; s1 += buf[3]; s2 += s1;
|
||||
s1 += buf[4]; s2 += s1; s1 += buf[5]; s2 += s1;
|
||||
s1 += buf[6]; s2 += s1; s1 += buf[7]; s2 += s1;
|
||||
|
||||
s1 += buf[8]; s2 += s1; s1 += buf[9]; s2 += s1;
|
||||
s1 += buf[10]; s2 += s1; s1 += buf[11]; s2 += s1;
|
||||
s1 += buf[12]; s2 += s1; s1 += buf[13]; s2 += s1;
|
||||
s1 += buf[14]; s2 += s1; s1 += buf[15]; s2 += s1;
|
||||
}
|
||||
|
||||
for (i = k % 16; i; --i) { s1 += *buf++; s2 += s1; }
|
||||
|
||||
s1 %= A32_BASE;
|
||||
s2 %= A32_BASE;
|
||||
|
||||
length -= k;
|
||||
}
|
||||
|
||||
return (s2 << 16) | s1;
|
||||
}
|
||||
64
src/crc32.c
Normal file
64
src/crc32.c
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* CRC32 checksum
|
||||
*
|
||||
* Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CRC32 algorithm taken from the zlib source, which is
|
||||
* Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
|
||||
*/
|
||||
|
||||
#include "tinf.h"
|
||||
|
||||
static const unsigned int tinf_crc32tab[16] = {
|
||||
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190,
|
||||
0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344,
|
||||
0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278,
|
||||
0xbdbdf21c
|
||||
};
|
||||
|
||||
unsigned int tinf_crc32(const void *data, unsigned int length)
|
||||
{
|
||||
const unsigned char *buf = (const unsigned char *)data;
|
||||
unsigned int crc = 0xffffffff;
|
||||
unsigned int i;
|
||||
|
||||
if (length == 0) return 0;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
crc ^= buf[i];
|
||||
crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4);
|
||||
crc = tinf_crc32tab[crc & 0x0f] ^ (crc >> 4);
|
||||
}
|
||||
|
||||
return crc ^ 0xffffffff;
|
||||
}
|
||||
34
src/makefile.b32
Normal file
34
src/makefile.b32
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## Borland C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = ..\lib\tinf.lib
|
||||
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
|
||||
|
||||
cflags = -a16 -K -O2 -OS
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
echo $(patsubst %,+%,$(objects)) >> lib.cmd
|
||||
tlib $@ /C @lib.cmd
|
||||
$(RM) lib.cmd
|
||||
|
||||
%.obj : %.c
|
||||
bcc32 $(cflags) -c $<
|
||||
|
||||
%.obj : %.nas
|
||||
nasm -o $@ -f obj -D_OBJ_ -O3 -Inasm/ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target) $(temps)
|
||||
33
src/makefile.dj2
Normal file
33
src/makefile.dj2
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## DJGPP makefile
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = ../lib/libtinf.a
|
||||
objects = tinflate.o tinfgzip.o tinfzlib.o adler32.o crc32.o
|
||||
|
||||
cflags = -s -Wall -Os -fomit-frame-pointer
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
ar -frsv $@ $^
|
||||
ranlib $@
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -o $@ -c $<
|
||||
|
||||
%.o : %.nas
|
||||
nasm -o $@ -f coff -O3 -Inasm/ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target)
|
||||
32
src/makefile.dmc
Normal file
32
src/makefile.dmc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## Digital Mars C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = ..\lib\tinf.lib
|
||||
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
|
||||
|
||||
cflags = -s -mn -o+all
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
lib -c $@ $^
|
||||
|
||||
%.obj : %.c
|
||||
dmc $(cflags) -c $<
|
||||
|
||||
%.obj : %.nas
|
||||
nasm -o $@ -f obj -D_OBJ_ -O3 $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target) $(temps)
|
||||
34
src/makefile.elf
Normal file
34
src/makefile.elf
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## GCC makefile (Linux, FreeBSD, BeOS and QNX)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = ../lib/libtinf.a
|
||||
objects = tinflate.o tinfgzip.o tinfzlib.o adler32.o crc32.o
|
||||
|
||||
cflags = -s -Wall -Os
|
||||
ldflags = $(cflags)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
ar -frsv $@ $^
|
||||
ranlib $@
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -o $@ -c $<
|
||||
|
||||
%.o : %.nas
|
||||
nasm -o $@ -f elf -D_ELF_ -O3 -Inasm/ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target)
|
||||
31
src/makefile.mgw
Normal file
31
src/makefile.mgw
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## MinGW / Cygwin makefile
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
|
||||
target = ../lib/libtinf.a
|
||||
objects = tinflate.o tinfgzip.o tinfzlib.o adler32.o crc32.o
|
||||
|
||||
cflags = -s -Wall -Os -fomit-frame-pointer
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
ar -frsv $@ $^
|
||||
ranlib $@
|
||||
|
||||
%.o : %.c
|
||||
gcc $(cflags) -o $@ -c $<
|
||||
|
||||
%.o : %.nas
|
||||
nasm -o $@ -f win32 -O3 -Inasm/ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(target) $(objects)
|
||||
30
src/makefile.vc
Normal file
30
src/makefile.vc
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## Visual C++ Makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
|
||||
target = ../lib/tinf.lib
|
||||
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
|
||||
|
||||
cflags = /nologo /W3 /O1 /G6 /W3 /Gy /GF
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
lib /OUT:$@ $^
|
||||
|
||||
%.obj : %.c
|
||||
cl $(cflags) -c $<
|
||||
|
||||
%.obj : %.nas
|
||||
nasm -o $@ -f win32 -O3 -Inasm/ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(target) $(objects)
|
||||
35
src/makefile.wat
Normal file
35
src/makefile.wat
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
##
|
||||
## tinflib - tiny inflate library (inflate, gzip, zlib)
|
||||
##
|
||||
## Watcom / OpenWatcom C/C++ makefile (GNU Make)
|
||||
##
|
||||
## Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
## All Rights Reserved
|
||||
##
|
||||
## http://www.ibsensoftware.com/
|
||||
##
|
||||
|
||||
target = ..\lib\tinf.lib
|
||||
objects = tinflate.obj tinfgzip.obj tinfzlib.obj adler32.obj crc32.obj
|
||||
system = nt
|
||||
|
||||
cflags = -bt=$(system) -d0 -obmlrs -s -zl
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(target)
|
||||
|
||||
$(target): $(objects)
|
||||
$(RM) $@
|
||||
echo $(patsubst %,+%,$(objects)) >> lib.cmd
|
||||
wlib -c -n -q -s -fo -io $@ @lib.cmd
|
||||
$(RM) lib.cmd
|
||||
|
||||
%.obj : %.c
|
||||
wcc386 $(cflags) $<
|
||||
|
||||
%.obj : %.nas
|
||||
nasm -o $@ -f obj -D_OBJ_ -O3 -Inasm/ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(objects) $(target)
|
||||
118
src/nasm/crc32.nas
Normal file
118
src/nasm/crc32.nas
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
;;
|
||||
;; NASM assembler crc32
|
||||
;;
|
||||
;; Copyright (c) 1998-2003 by Joergen Ibsen / Jibz
|
||||
;; All Rights Reserved
|
||||
;;
|
||||
;; http://www.ibsensoftware.com/
|
||||
;;
|
||||
;; 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.
|
||||
;;
|
||||
|
||||
; CRC32 algorithm taken from the zlib source, which is
|
||||
; Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
|
||||
|
||||
cpu 386
|
||||
|
||||
bits 32
|
||||
|
||||
%include "nasmlcm.inc"
|
||||
|
||||
section lcmtext
|
||||
|
||||
lcmglobal tinf_crc32,8
|
||||
|
||||
lcmexport tinf_crc32,8
|
||||
|
||||
; =============================================================
|
||||
|
||||
lcmlabel tinf_crc32,8
|
||||
; tinf_crc32(const void *data,
|
||||
; unsigned int length);
|
||||
|
||||
.len$ equ 2*4 + 4 + 4
|
||||
.dat$ equ 2*4 + 4
|
||||
|
||||
push esi
|
||||
push edi
|
||||
|
||||
mov esi, [esp + .dat$] ; esi -> buffer
|
||||
mov ecx, [esp + .len$] ; ecx = length
|
||||
|
||||
sub eax, eax ; crc = 0
|
||||
|
||||
test esi, esi
|
||||
jz short .c_exit
|
||||
|
||||
test ecx, ecx
|
||||
jz short .c_exit
|
||||
|
||||
dec eax ; crc = 0xffffffff
|
||||
|
||||
%ifdef _OBJ_
|
||||
mov edi, tinf_crc32tab wrt FLAT ; edi -> crctab
|
||||
%else
|
||||
mov edi, tinf_crc32tab ; edi -> crctab
|
||||
%endif
|
||||
|
||||
.c_next_byte:
|
||||
xor al, [esi]
|
||||
inc esi
|
||||
|
||||
mov edx, 0x0f
|
||||
and edx, eax
|
||||
|
||||
shr eax, 4
|
||||
|
||||
xor eax, [edi + edx*4]
|
||||
|
||||
mov edx, 0x0f
|
||||
and edx, eax
|
||||
|
||||
shr eax, 4
|
||||
|
||||
xor eax, [edi + edx*4]
|
||||
|
||||
dec ecx
|
||||
jnz short .c_next_byte
|
||||
|
||||
not eax
|
||||
|
||||
.c_exit:
|
||||
pop edi
|
||||
pop esi
|
||||
|
||||
lcmret 8
|
||||
|
||||
; =============================================================
|
||||
|
||||
section lcmdata
|
||||
|
||||
tinf_crc32tab dd 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190
|
||||
dd 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344
|
||||
dd 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278
|
||||
dd 0xbdbdf21c
|
||||
|
||||
; =============================================================
|
||||
326
src/nasm/nasmlcm.inc
Normal file
326
src/nasm/nasmlcm.inc
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
;;
|
||||
;; NASM linker compatibility macros 2002.07.24
|
||||
;;
|
||||
;; Copyright (c) 2001-2003 by Joergen Ibsen / Jibz
|
||||
;; All Rights Reserved
|
||||
;;
|
||||
;; http://www.ibsensoftware.com/
|
||||
;;
|
||||
|
||||
; define _ELF_ for ELF32 object files
|
||||
; define _OBJ_ for OMF object files
|
||||
; define _OBJ_ and _DLL_ for OMF object files for a dll (stdcall)
|
||||
; define _MSLIBS_ for MS style Win32 import libs (lcmwinextern)
|
||||
; default is DJGPP/WIN32 COFF object files
|
||||
|
||||
; remember to do lcm*extern before lcmimport
|
||||
|
||||
; ====================================================================
|
||||
;
|
||||
; There are differences between how the object formats that NASM
|
||||
; supports work, and what features they support. Similarly there
|
||||
; are differences between how complete and standard compliant the
|
||||
; support for these formats are in linkers.
|
||||
;
|
||||
; The NASM linker compatibility macros (nasmlcm) were put together
|
||||
; to ease my work by allowing a single source file to be assembled
|
||||
; for use with a number of compilers/linkers.
|
||||
;
|
||||
; Currently obj/omf, win32/coff, djgpp/coff and elf32 output formats
|
||||
; are supported. The following macros are available:
|
||||
;
|
||||
; lcmtext - section name for the code section
|
||||
; lcmdata - section name for the initialized data section
|
||||
; lcmbss - section name for the uninitialized data section
|
||||
;
|
||||
; lcmglobal - declare a function (two arguments) or data (one
|
||||
; argument) as global in the current format
|
||||
; lcmcglobal - same as lcmglobal, but uses C name decoration
|
||||
;
|
||||
; lcmextern - declare a function (two arguments) or data (one
|
||||
; argument) as extern in the current format
|
||||
; lcmcextern - same as lcmextern, but uses C name decoration
|
||||
; lcmdllextern - same as lcmextern, but uses dll name decoration
|
||||
; lcmwinextern - same as lcmextern, but uses name decoration for
|
||||
; calling Win32 Api functions (see _MSLIBS_)
|
||||
;
|
||||
; lcmimport - declares a function (two arguments) or data (one
|
||||
; argument) as imported in the current format
|
||||
; lcmexport - declares a function (two arguments) or data (one
|
||||
; argument) as exported in the current format
|
||||
;
|
||||
; lcmlabel - start label for a function in the current format
|
||||
; lcmclabel - start label for a function with C name decoration
|
||||
; lcmadjust - adjust stack after a function call in the current
|
||||
; format
|
||||
; lcmret - return from a function in the current format
|
||||
; lcmcret - return from a C function
|
||||
;
|
||||
; The following defines change the format and behaviour:
|
||||
;
|
||||
; _ELF_ - the lcm*global macro adds :function and :data type
|
||||
; specifiers
|
||||
;
|
||||
; _OBJ_ - section names are similar to those produced by
|
||||
; Borland tools to increase compatibility with
|
||||
; various OMF compatible linkers
|
||||
;
|
||||
; _DLL_ - functions are exported and imported with added
|
||||
; size specifiers (_SomeFunction@12), lcmret adjusts
|
||||
; stack (stdcall)
|
||||
;
|
||||
; _MSLIBS_ - the lcmwinextern macro prepends an underscore and
|
||||
; adds size specification for functions, allowing
|
||||
; the object file to be linked with MS libraries.
|
||||
;
|
||||
; ====================================================================
|
||||
|
||||
%ifndef NASMLCM_INC_INCLUDED
|
||||
%define NASMLCM_INC_INCLUDED
|
||||
|
||||
%ifdef _DLL_
|
||||
%ifndef _OBJ_
|
||||
%error "_DLL_ needs _OBJ_ defined!"
|
||||
%endif
|
||||
%endif
|
||||
|
||||
; --- define lcm- section names ---
|
||||
;
|
||||
; a number of linkers require omf objects where the section
|
||||
; names are equal to those produces by tasm.
|
||||
|
||||
%ifdef _OBJ_
|
||||
|
||||
%define lcmtext _TEXT class=CODE public use32 align=4 FLAT
|
||||
%define lcmdata _DATA class=DATA public use32 align=4
|
||||
%define lcmbss _BSS class=BSS public use32 align=4 FLAT
|
||||
|
||||
group FLAT
|
||||
group DGROUP _DATA
|
||||
|
||||
%else ; _OBJ_
|
||||
|
||||
%define lcmtext .text
|
||||
%define lcmdata .data
|
||||
%define lcmbss .bss
|
||||
|
||||
%endif ; _OBJ_
|
||||
|
||||
; --- define lcmglobal and lcm*extern macros ---
|
||||
;
|
||||
; special handling of functions and data for ELF32
|
||||
|
||||
%ifdef _ELF_
|
||||
|
||||
%macro lcmglobal 2
|
||||
global %{1}:function
|
||||
%endmacro
|
||||
%macro lcmglobal 1
|
||||
global %{1}:data
|
||||
%endmacro
|
||||
|
||||
%define lcmcglobal lcmglobal
|
||||
|
||||
%macro lcmextern 1-2
|
||||
extern %1
|
||||
%endmacro
|
||||
|
||||
%macro lcmcextern 0
|
||||
%error lcmcextern not supported in ELF format
|
||||
%endmacro
|
||||
|
||||
%macro lcmdllextern 0
|
||||
%error lcmdllextern not supported in ELF format
|
||||
%endmacro
|
||||
|
||||
%else ; _ELF_
|
||||
|
||||
%ifdef _DLL_
|
||||
|
||||
%macro lcmglobal 2
|
||||
global _%1
|
||||
global _%1@%2
|
||||
%endmacro
|
||||
%macro lcmglobal 1
|
||||
global _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro lcmcglobal 2
|
||||
global _%1
|
||||
%endmacro
|
||||
%macro lcmcglobal 1
|
||||
global _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro lcmextern 2
|
||||
extern _%1@%2
|
||||
%define %1 _%1@%2
|
||||
%endmacro
|
||||
%macro lcmextern 1
|
||||
extern _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%else
|
||||
|
||||
%macro lcmglobal 2
|
||||
global _%1
|
||||
%endmacro
|
||||
%macro lcmglobal 1
|
||||
global _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%define lcmcglobal lcmglobal
|
||||
|
||||
%macro lcmextern 1-2
|
||||
extern _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%endif
|
||||
|
||||
%macro lcmcextern 1-2
|
||||
extern _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro lcmdllextern 2
|
||||
extern _%1@%2
|
||||
%define %1 _%1@%2
|
||||
%endmacro
|
||||
%macro lcmdllextern 1
|
||||
extern _%1
|
||||
%define %1 _%1
|
||||
%endmacro
|
||||
|
||||
%macro lcmwinextern 2
|
||||
%ifdef _MSLIBS_
|
||||
extern _%1@%2
|
||||
%define %1 _%1@%2
|
||||
%else
|
||||
extern %1
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%endif ; _ELF_
|
||||
|
||||
; --- define lcmimport and lcmexport ---
|
||||
;
|
||||
|
||||
%ifdef _OBJ_
|
||||
|
||||
%macro lcmimport 2-3
|
||||
import %1 %2 %3
|
||||
%rotate 1
|
||||
%endmacro
|
||||
|
||||
%ifdef _DLL_
|
||||
|
||||
%macro lcmexport 2
|
||||
export _%1
|
||||
export _%1@%2
|
||||
%endmacro
|
||||
%macro lcmexport 1
|
||||
export _%1
|
||||
%endmacro
|
||||
|
||||
%else
|
||||
|
||||
%macro lcmexport 1-2
|
||||
%endmacro
|
||||
|
||||
%endif
|
||||
|
||||
%else ; _OBJ_
|
||||
|
||||
%macro lcmimport 2-3
|
||||
%endmacro
|
||||
|
||||
%macro lcmexport 1-2
|
||||
%endmacro
|
||||
|
||||
%endif ; _OBJ_
|
||||
|
||||
; --- define lcmlabel, lcmadjust and lcmret macros ---
|
||||
;
|
||||
; we need special labels and stdcall calling convention when
|
||||
; assembling for a dll
|
||||
|
||||
%ifdef _ELF_
|
||||
|
||||
%macro lcmlabel 2
|
||||
%1:
|
||||
%endmacro
|
||||
|
||||
%define lcmclabel lcmlabel
|
||||
|
||||
%macro lcmadjust 1
|
||||
%if %1 < 128
|
||||
add esp, byte %1
|
||||
%else
|
||||
add esp, %1
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro lcmret 1
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%define lcmcret lcmret
|
||||
|
||||
%else ; _ELF_
|
||||
|
||||
%ifdef _DLL_
|
||||
%macro lcmlabel 2
|
||||
_%1:
|
||||
_%1@%2:
|
||||
%endmacro
|
||||
|
||||
%macro lcmclabel 2
|
||||
_%1:
|
||||
%endmacro
|
||||
|
||||
%macro lcmadjust 1
|
||||
%endmacro
|
||||
|
||||
%macro lcmret 1
|
||||
%if %1 > 0
|
||||
ret %1
|
||||
%else
|
||||
ret
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro lcmcret 1
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%else
|
||||
|
||||
%macro lcmlabel 2
|
||||
_%1:
|
||||
%endmacro
|
||||
|
||||
%define lcmclabel lcmlabel
|
||||
|
||||
%macro lcmadjust 1
|
||||
%if %1 < 128
|
||||
add esp, byte %1
|
||||
%else
|
||||
add esp, %1
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
%macro lcmret 1
|
||||
ret
|
||||
%endmacro
|
||||
|
||||
%define lcmcret lcmret
|
||||
%endif
|
||||
|
||||
%endif ; _ELF_
|
||||
|
||||
%endif ; NASMLCM_INC_INCLUDED
|
||||
160
src/nasm/tinfzlib.nas
Normal file
160
src/nasm/tinfzlib.nas
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
;;
|
||||
;; tinfzlib - tiny zlib uncompress
|
||||
;;
|
||||
;; Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
;; All Rights Reserved
|
||||
;;
|
||||
;; http://www.ibsensoftware.com/
|
||||
;;
|
||||
;; 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.
|
||||
;;
|
||||
|
||||
TINF_OK equ 0
|
||||
TINF_DATA_ERROR equ (-3)
|
||||
|
||||
cpu 386
|
||||
|
||||
bits 32
|
||||
|
||||
%include "nasmlcm.inc"
|
||||
|
||||
section lcmtext
|
||||
|
||||
lcmglobal tinf_zlib_uncompress,16
|
||||
|
||||
lcmexport tinf_zlib_uncompress,16
|
||||
|
||||
lcmextern tinf_uncompress,16
|
||||
lcmextern tinf_adler32,8
|
||||
|
||||
; =============================================================
|
||||
|
||||
lcmlabel tinf_zlib_uncompress,16
|
||||
; tinf_zlib_uncompress(void *dest,
|
||||
; unsigned int *destLen,
|
||||
; const void *source,
|
||||
; unsigned int sourceLen)
|
||||
|
||||
.slen$ equ 2*4 + 4 + 12
|
||||
.src$ equ 2*4 + 4 + 8
|
||||
.dlen$ equ 2*4 + 4 + 4
|
||||
.dst$ equ 2*4 + 4
|
||||
|
||||
push esi
|
||||
push ebx
|
||||
|
||||
mov esi, [esp + .src$] ; esi -> source
|
||||
|
||||
; -- get header bytes --
|
||||
|
||||
movzx eax, word [esi] ; al = cmf, ah = flg,
|
||||
|
||||
; -- check format --
|
||||
|
||||
; check method is deflate
|
||||
; if ((cmf & 0x0f) != 8) return TINF_DATA_ERROR;
|
||||
mov cl, 0x0f
|
||||
and cl, al
|
||||
cmp cl, 8
|
||||
jne short .return_error
|
||||
|
||||
; check window size is valid
|
||||
; if ((cmf >> 4) > 7) return TINF_DATA_ERROR;
|
||||
mov ch, al
|
||||
shr ch, 4
|
||||
cmp ch, cl ; cl = 8 from above
|
||||
jae short .return_error
|
||||
|
||||
; check there is no preset dictionary
|
||||
; if (flg & 0x20) return TINF_DATA_ERROR;
|
||||
test ah, 0x20
|
||||
jnz short .return_error
|
||||
|
||||
; check checksum
|
||||
; if ((256*cmf + flg) % 31) return TINF_DATA_ERROR;
|
||||
xchg al, ah
|
||||
xor edx, edx
|
||||
lea ebx, [edx + 31]
|
||||
div ebx
|
||||
test edx, edx
|
||||
jnz short .return_error
|
||||
|
||||
; -- get adler32 checksum --
|
||||
|
||||
mov ecx, [esp + .slen$] ; ecx = sourceLen
|
||||
mov ebx, [esi + ecx - 4]
|
||||
|
||||
%ifdef BSWAP_OK
|
||||
bswap ebx
|
||||
%else ; BSWAP_OK
|
||||
xchg bl, bh
|
||||
rol ebx, 16
|
||||
xchg bl, bh
|
||||
%endif ; BSWAP_OK
|
||||
|
||||
; -- inflate --
|
||||
|
||||
; res = tinf_uncompress(dst, destLen, src + 2, sourceLen - 6);
|
||||
lea eax, [ecx - 6]
|
||||
push eax
|
||||
lea eax, [esi + 2]
|
||||
push eax
|
||||
push dword [esp + 8 + .dlen$]
|
||||
push dword [esp + 12 + .dst$]
|
||||
call tinf_uncompress
|
||||
add esp, byte 16
|
||||
|
||||
; if (res != TINF_OK) return TINF_DATA_ERROR;
|
||||
test eax, eax
|
||||
jnz short .return_error
|
||||
|
||||
; -- check adler32 checksum --
|
||||
|
||||
; if (a32 != tinf_adler32(dst, *destLen)) return TINF_DATA_ERROR;
|
||||
mov eax, [esp + .dlen$];
|
||||
push dword [eax]
|
||||
push dword [esp + 4 + .dst$]
|
||||
call tinf_adler32
|
||||
add esp, byte 8
|
||||
|
||||
sub eax, ebx
|
||||
jz short .return_eax
|
||||
|
||||
.return_error:
|
||||
mov eax, TINF_DATA_ERROR
|
||||
|
||||
.return_eax:
|
||||
pop ebx
|
||||
pop esi
|
||||
|
||||
lcmret 16
|
||||
|
||||
; =============================================================
|
||||
|
||||
%ifdef _OBJ_
|
||||
section lcmdata
|
||||
%endif
|
||||
|
||||
; =============================================================
|
||||
52
src/tinf.h
Normal file
52
src/tinf.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* tinf - tiny inflate library (inflate, gzip, zlib)
|
||||
*
|
||||
* version 1.00
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*/
|
||||
|
||||
#ifndef TINF_H_INCLUDED
|
||||
#define TINF_H_INCLUDED
|
||||
|
||||
/* calling convention */
|
||||
#ifndef TINFCC
|
||||
#ifdef __WATCOMC__
|
||||
#define TINFCC __cdecl
|
||||
#else
|
||||
#define TINFCC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TINF_OK 0
|
||||
#define TINF_DATA_ERROR (-3)
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
void TINFCC tinf_init();
|
||||
|
||||
int TINFCC tinf_uncompress(void *dest, unsigned int *destLen,
|
||||
const void *source, unsigned int sourceLen);
|
||||
|
||||
int TINFCC tinf_gzip_uncompress(void *dest, unsigned int *destLen,
|
||||
const void *source, unsigned int sourceLen);
|
||||
|
||||
int TINFCC tinf_zlib_uncompress(void *dest, unsigned int *destLen,
|
||||
const void *source, unsigned int sourceLen);
|
||||
|
||||
unsigned int TINFCC tinf_adler32(const void *data, unsigned int length);
|
||||
|
||||
unsigned int TINFCC tinf_crc32(const void *data, unsigned int length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* TINF_H_INCLUDED */
|
||||
124
src/tinfgzip.c
Normal file
124
src/tinfgzip.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* tinfgzip - tiny gzip decompressor
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* 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"
|
||||
|
||||
#define FTEXT 1
|
||||
#define FHCRC 2
|
||||
#define FEXTRA 4
|
||||
#define FNAME 8
|
||||
#define FCOMMENT 16
|
||||
|
||||
int tinf_gzip_uncompress(void *dest, unsigned int *destLen,
|
||||
const void *source, unsigned int sourceLen)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)source;
|
||||
unsigned char *dst = (unsigned char *)dest;
|
||||
unsigned char *start;
|
||||
unsigned int dlen, crc32;
|
||||
int res;
|
||||
unsigned char flg;
|
||||
|
||||
/* -- check format -- */
|
||||
|
||||
/* 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[1];
|
||||
xlen = 256*xlen + start[0];
|
||||
start += xlen + 2;
|
||||
}
|
||||
|
||||
/* skip file name if present */
|
||||
if (flg & FNAME) { while (*start) ++start; ++start; }
|
||||
|
||||
/* skip file comment if present */
|
||||
if (flg & FCOMMENT) { while (*start) ++start; ++start; }
|
||||
|
||||
/* check header crc if present */
|
||||
if (flg & FHCRC)
|
||||
{
|
||||
unsigned int hcrc = start[1];
|
||||
hcrc = 256*hcrc + start[0];
|
||||
|
||||
if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff))
|
||||
return TINF_DATA_ERROR;
|
||||
|
||||
start += 2;
|
||||
}
|
||||
|
||||
/* -- get decompressed length -- */
|
||||
|
||||
dlen = src[sourceLen - 1];
|
||||
dlen = 256*dlen + src[sourceLen - 2];
|
||||
dlen = 256*dlen + src[sourceLen - 3];
|
||||
dlen = 256*dlen + src[sourceLen - 4];
|
||||
|
||||
/* -- get crc32 of decompressed data -- */
|
||||
|
||||
crc32 = src[sourceLen - 5];
|
||||
crc32 = 256*crc32 + src[sourceLen - 6];
|
||||
crc32 = 256*crc32 + src[sourceLen - 7];
|
||||
crc32 = 256*crc32 + src[sourceLen - 8];
|
||||
|
||||
/* -- decompress data -- */
|
||||
|
||||
res = tinf_uncompress(dst, destLen, start, src + sourceLen - start - 8);
|
||||
|
||||
if (res != TINF_OK) return TINF_DATA_ERROR;
|
||||
|
||||
if (*destLen != dlen) return TINF_DATA_ERROR;
|
||||
|
||||
/* -- check CRC32 checksum -- */
|
||||
|
||||
if (crc32 != tinf_crc32(dst, dlen)) return TINF_DATA_ERROR;
|
||||
|
||||
return TINF_OK;
|
||||
}
|
||||
457
src/tinflate.c
Normal file
457
src/tinflate.c
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
* tinflate - tiny inflate
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* 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 -- *
|
||||
* ------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
unsigned short table[16]; /* table of code length counts */
|
||||
unsigned short trans[288]; /* code -> symbol translation table */
|
||||
} TINF_TREE;
|
||||
|
||||
typedef struct {
|
||||
const unsigned char *source;
|
||||
unsigned int tag;
|
||||
unsigned int bitcount;
|
||||
|
||||
unsigned char *dest;
|
||||
unsigned int *destLen;
|
||||
|
||||
TINF_TREE ltree; /* dynamic length/symbol tree */
|
||||
TINF_TREE dtree; /* dynamic distance tree */
|
||||
} TINF_DATA;
|
||||
|
||||
/* --------------------------------------------------- *
|
||||
* -- uninitialized global data (static structures) -- *
|
||||
* --------------------------------------------------- */
|
||||
|
||||
TINF_TREE sltree; /* fixed length/symbol tree */
|
||||
TINF_TREE sdtree; /* fixed distance tree */
|
||||
|
||||
/* extra bits and base tables for length codes */
|
||||
unsigned char length_bits[30];
|
||||
unsigned short length_base[30];
|
||||
|
||||
/* extra bits and base tables for distance codes */
|
||||
unsigned char dist_bits[30];
|
||||
unsigned short dist_base[30];
|
||||
|
||||
/* special ordering of code length codes */
|
||||
const unsigned char clcidx[] = {
|
||||
16, 17, 18, 0, 8, 7, 9, 6,
|
||||
10, 5, 11, 4, 12, 3, 13, 2,
|
||||
14, 1, 15
|
||||
};
|
||||
|
||||
/* ----------------------- *
|
||||
* -- utility functions -- *
|
||||
* ----------------------- */
|
||||
|
||||
/* build extra bits and base tables */
|
||||
static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first)
|
||||
{
|
||||
int i, sum;
|
||||
|
||||
/* build bits table */
|
||||
for (i = 0; i < delta; ++i) bits[i] = 0;
|
||||
for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta;
|
||||
|
||||
/* build base table */
|
||||
for (sum = first, i = 0; i < 30; ++i)
|
||||
{
|
||||
base[i] = sum;
|
||||
sum += 1 << bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* build the fixed huffman trees */
|
||||
static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* build fixed length tree */
|
||||
for (i = 0; i < 7; ++i) lt->table[i] = 0;
|
||||
|
||||
lt->table[7] = 24;
|
||||
lt->table[8] = 152;
|
||||
lt->table[9] = 112;
|
||||
|
||||
for (i = 0; i < 24; ++i) lt->trans[i] = 256 + i;
|
||||
for (i = 0; i < 144; ++i) lt->trans[24 + i] = i;
|
||||
for (i = 0; i < 8; ++i) lt->trans[24 + 144 + i] = 280 + i;
|
||||
for (i = 0; i < 112; ++i) lt->trans[24 + 144 + 8 + i] = 144 + i;
|
||||
|
||||
/* build fixed distance tree */
|
||||
for (i = 0; i < 5; ++i) dt->table[i] = 0;
|
||||
|
||||
dt->table[5] = 32;
|
||||
|
||||
for (i = 0; i < 32; ++i) dt->trans[i] = i;
|
||||
}
|
||||
|
||||
/* given an array of code lengths, build a tree */
|
||||
static void tinf_build_tree(TINF_TREE *t, const unsigned char *lengths, unsigned int num)
|
||||
{
|
||||
unsigned short offs[16];
|
||||
unsigned int i, sum;
|
||||
|
||||
/* clear code length count table */
|
||||
for (i = 0; i < 16; ++i) t->table[i] = 0;
|
||||
|
||||
/* scan symbol lengths, and sum code length counts */
|
||||
for (i = 0; i < num; ++i) t->table[lengths[i]]++;
|
||||
|
||||
t->table[0] = 0;
|
||||
|
||||
/* compute offset table for distribution sort */
|
||||
for (sum = 0, i = 0; i < 16; ++i)
|
||||
{
|
||||
offs[i] = sum;
|
||||
sum += t->table[i];
|
||||
}
|
||||
|
||||
/* create code->symbol translation table (symbols sorted by code) */
|
||||
for (i = 0; i < num; ++i)
|
||||
{
|
||||
if (lengths[i]) t->trans[offs[lengths[i]]++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------- *
|
||||
* -- decode functions -- *
|
||||
* ---------------------- */
|
||||
|
||||
/* get one bit from source stream */
|
||||
static int tinf_getbit(TINF_DATA *d)
|
||||
{
|
||||
unsigned int bit;
|
||||
|
||||
/* check if tag is empty */
|
||||
if (!d->bitcount--)
|
||||
{
|
||||
/* load next tag */
|
||||
d->tag = *d->source++;
|
||||
d->bitcount = 7;
|
||||
}
|
||||
|
||||
/* shift bit out of tag */
|
||||
bit = d->tag & 0x01;
|
||||
d->tag >>= 1;
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
/* read a num bit value from a stream and add base */
|
||||
static unsigned int tinf_read_bits(TINF_DATA *d, int num, int base)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
/* read num bits */
|
||||
if (num)
|
||||
{
|
||||
unsigned int limit = 1 << (num);
|
||||
unsigned int mask;
|
||||
|
||||
for (mask = 1; mask < limit; mask *= 2)
|
||||
if (tinf_getbit(d)) val += mask;
|
||||
}
|
||||
|
||||
return val + base;
|
||||
}
|
||||
|
||||
/* given a data stream and a tree, decode a symbol */
|
||||
static int tinf_decode_symbol(TINF_DATA *d, TINF_TREE *t)
|
||||
{
|
||||
int sum = 0, cur = 0, len = 0;
|
||||
|
||||
/* get more bits while code value is above sum */
|
||||
do {
|
||||
|
||||
cur = 2*cur + tinf_getbit(d);
|
||||
|
||||
++len;
|
||||
|
||||
sum += t->table[len];
|
||||
cur -= t->table[len];
|
||||
|
||||
} while (cur >= 0);
|
||||
|
||||
return t->trans[sum + cur];
|
||||
}
|
||||
|
||||
/* given a data stream, decode dynamic trees from it */
|
||||
static void tinf_decode_trees(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
|
||||
{
|
||||
TINF_TREE code_tree;
|
||||
unsigned char lengths[288+32];
|
||||
unsigned int hlit, hdist, hclen;
|
||||
unsigned int i, num, length;
|
||||
|
||||
/* get 5 bits HLIT (257-286) */
|
||||
hlit = tinf_read_bits(d, 5, 257);
|
||||
|
||||
/* get 5 bits HDIST (1-32) */
|
||||
hdist = tinf_read_bits(d, 5, 1);
|
||||
|
||||
/* get 4 bits HCLEN (4-19) */
|
||||
hclen = tinf_read_bits(d, 4, 4);
|
||||
|
||||
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_read_bits(d, 3, 0);
|
||||
|
||||
lengths[clcidx[i]] = clen;
|
||||
}
|
||||
|
||||
/* build code length tree */
|
||||
tinf_build_tree(&code_tree, lengths, 19);
|
||||
|
||||
/* decode code lengths for the dynamic trees */
|
||||
for (num = 0; num < hlit + hdist; )
|
||||
{
|
||||
int sym = tinf_decode_symbol(d, &code_tree);
|
||||
|
||||
switch (sym)
|
||||
{
|
||||
case 16:
|
||||
/* copy previous code length 3-6 times (read 2 bits) */
|
||||
{
|
||||
unsigned char prev = lengths[num - 1];
|
||||
for (length = tinf_read_bits(d, 2, 3); length; --length)
|
||||
{
|
||||
lengths[num++] = prev;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
/* repeat code length 0 for 3-10 times (read 3 bits) */
|
||||
for (length = tinf_read_bits(d, 3, 3); length; --length)
|
||||
{
|
||||
lengths[num++] = 0;
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
/* repeat code length 0 for 11-138 times (read 7 bits) */
|
||||
for (length = tinf_read_bits(d, 7, 11); length; --length)
|
||||
{
|
||||
lengths[num++] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* values 0-15 represent the actual code lengths */
|
||||
lengths[num++] = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* build dynamic trees */
|
||||
tinf_build_tree(lt, lengths, hlit);
|
||||
tinf_build_tree(dt, lengths + hlit, hdist);
|
||||
}
|
||||
|
||||
/* ----------------------------- *
|
||||
* -- block inflate functions -- *
|
||||
* ----------------------------- */
|
||||
|
||||
/* given a stream and two trees, inflate a block of data */
|
||||
static int tinf_inflate_block_data(TINF_DATA *d, TINF_TREE *lt, TINF_TREE *dt)
|
||||
{
|
||||
/* remember current output position */
|
||||
unsigned char *start = d->dest;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int sym = tinf_decode_symbol(d, lt);
|
||||
|
||||
/* check for end of block */
|
||||
if (sym == 256)
|
||||
{
|
||||
*d->destLen += d->dest - start;
|
||||
return TINF_OK;
|
||||
}
|
||||
|
||||
if (sym < 256)
|
||||
{
|
||||
*d->dest++ = sym;
|
||||
|
||||
} else {
|
||||
|
||||
int length, dist, offs;
|
||||
int i;
|
||||
|
||||
sym -= 257;
|
||||
|
||||
/* possibly get more bits from length code */
|
||||
length = tinf_read_bits(d, length_bits[sym], length_base[sym]);
|
||||
|
||||
dist = tinf_decode_symbol(d, dt);
|
||||
|
||||
/* possibly get more bits from distance code */
|
||||
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
|
||||
|
||||
/* 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(TINF_DATA *d)
|
||||
{
|
||||
unsigned int length, invlength;
|
||||
unsigned int i;
|
||||
|
||||
/* get length */
|
||||
length = d->source[1];
|
||||
length = 256*length + d->source[0];
|
||||
|
||||
/* get one's complement of length */
|
||||
invlength = d->source[3];
|
||||
invlength = 256*invlength + d->source[2];
|
||||
|
||||
/* check length */
|
||||
if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR;
|
||||
|
||||
d->source += 4;
|
||||
|
||||
/* copy block */
|
||||
for (i = length; i; --i) *d->dest++ = *d->source++;
|
||||
|
||||
/* make sure we start next block on a byte boundary */
|
||||
d->bitcount = 0;
|
||||
|
||||
*d->destLen += length;
|
||||
|
||||
return TINF_OK;
|
||||
}
|
||||
|
||||
/* inflate a block of data compressed with fixed huffman trees */
|
||||
static int tinf_inflate_fixed_block(TINF_DATA *d)
|
||||
{
|
||||
/* decode block using fixed trees */
|
||||
return tinf_inflate_block_data(d, &sltree, &sdtree);
|
||||
}
|
||||
|
||||
/* inflate a block of data compressed with dynamic huffman trees */
|
||||
static int tinf_inflate_dynamic_block(TINF_DATA *d)
|
||||
{
|
||||
/* decode trees from stream */
|
||||
tinf_decode_trees(d, &d->ltree, &d->dtree);
|
||||
|
||||
/* decode block using decoded trees */
|
||||
return tinf_inflate_block_data(d, &d->ltree, &d->dtree);
|
||||
}
|
||||
|
||||
/* ---------------------- *
|
||||
* -- public functions -- *
|
||||
* ---------------------- */
|
||||
|
||||
/* initialize global (static) data */
|
||||
void tinf_init()
|
||||
{
|
||||
/* build fixed huffman trees */
|
||||
tinf_build_fixed_trees(&sltree, &sdtree);
|
||||
|
||||
/* build extra bits and base tables */
|
||||
tinf_build_bits_base(length_bits, length_base, 4, 3);
|
||||
tinf_build_bits_base(dist_bits, dist_base, 2, 1);
|
||||
|
||||
/* fix a special case */
|
||||
length_bits[28] = 0;
|
||||
length_base[28] = 258;
|
||||
}
|
||||
|
||||
/* inflate stream from source to dest */
|
||||
int tinf_uncompress(void *dest, unsigned int *destLen,
|
||||
const void *source, unsigned int sourceLen)
|
||||
{
|
||||
TINF_DATA d;
|
||||
int bfinal;
|
||||
|
||||
/* initialise data */
|
||||
d.source = (const unsigned char *)source;
|
||||
d.bitcount = 0;
|
||||
|
||||
d.dest = (unsigned char *)dest;
|
||||
d.destLen = destLen;
|
||||
|
||||
*destLen = 0;
|
||||
|
||||
do {
|
||||
|
||||
unsigned int btype;
|
||||
int res;
|
||||
|
||||
/* read final block flag */
|
||||
bfinal = tinf_getbit(&d);
|
||||
|
||||
/* read block type (2 bits) */
|
||||
btype = tinf_read_bits(&d, 2, 0);
|
||||
|
||||
/* 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:
|
||||
return TINF_DATA_ERROR;
|
||||
}
|
||||
|
||||
if (res != TINF_OK) return TINF_DATA_ERROR;
|
||||
|
||||
} while (!bfinal);
|
||||
|
||||
return TINF_OK;
|
||||
}
|
||||
82
src/tinfzlib.c
Normal file
82
src/tinfzlib.c
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* tinfzlib - tiny zlib decompressor
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
*
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* 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"
|
||||
|
||||
int tinf_zlib_uncompress(void *dest, unsigned int *destLen,
|
||||
const void *source, unsigned int sourceLen)
|
||||
{
|
||||
unsigned char *src = (unsigned char *)source;
|
||||
unsigned char *dst = (unsigned char *)dest;
|
||||
unsigned int a32;
|
||||
int res;
|
||||
unsigned char cmf, flg;
|
||||
|
||||
/* -- get header bytes -- */
|
||||
|
||||
cmf = src[0];
|
||||
flg = src[1];
|
||||
|
||||
/* -- check format -- */
|
||||
|
||||
/* check checksum */
|
||||
if ((256*cmf + flg) % 31) return TINF_DATA_ERROR;
|
||||
|
||||
/* check method is deflate */
|
||||
if ((cmf & 0x0f) != 8) return TINF_DATA_ERROR;
|
||||
|
||||
/* check window size is valid */
|
||||
if ((cmf >> 4) > 7) return TINF_DATA_ERROR;
|
||||
|
||||
/* check there is no preset dictionary */
|
||||
if (flg & 0x20) return TINF_DATA_ERROR;
|
||||
|
||||
/* -- get adler32 checksum -- */
|
||||
|
||||
a32 = src[sourceLen - 4];
|
||||
a32 = 256*a32 + src[sourceLen - 3];
|
||||
a32 = 256*a32 + src[sourceLen - 2];
|
||||
a32 = 256*a32 + src[sourceLen - 1];
|
||||
|
||||
/* -- inflate -- */
|
||||
|
||||
res = tinf_uncompress(dst, destLen, src + 2, sourceLen - 6);
|
||||
|
||||
if (res != TINF_OK) return TINF_DATA_ERROR;
|
||||
|
||||
/* -- check adler32 checksum -- */
|
||||
|
||||
if (a32 != tinf_adler32(dst, *destLen)) return TINF_DATA_ERROR;
|
||||
|
||||
return TINF_OK;
|
||||
}
|
||||
Loading…
Reference in a new issue