Adds programs/test_zlib.c which currently does the following:
1. Create some dummy data and compress it
2. Try to decompress with libdeflate_zlib_decompress
3. Try to decompress with libdeflate_zlib_decompress, with unnecessary
trailing bytes after the compressed data
4. Try to decompress with libdeflate_zlib_decompress_ex, with
unnecessary trailing bytes after the compressed data
In each step, we check that we get back the original data.
Additionally, libdeflate_zlib_decompress now returns successfully in
case there are additional trailing bytes in the input buffer after the
compressed stream.
Unfortunately, MSVC only accepts __stdcall after the return type, while
gcc only accepts __attribute__((visibility("default"))) before the
return type. So we need a macro in each location.
Also, MSVC doesn't define __i386__; that's gcc specific. So instead use
'_WIN32 && !_WIN64' to detect 32-bit Windows.
Not all programming languages support the cdecl calling convention.
stdcall is what the Win32 API uses, and it seems to be the better choice
for maximum compatibility with other programming languages.
So, switch from cdecl to stdcall.
Resolves https://github.com/ebiggers/libdeflate/issues/58
On macOS, shared libraries end in "$(SOVERSION).dylib", not
".so.$(SOVERSION)" like on Linux. Also, a different linker option is
needed to set the equivalent of the soname.
This is based on patches from:
Elmar Pruesse <elmar.pruesse@ucdenver.edu>
and
Roy Storey <kiwiroy@users.noreply.github.com>
but refactored, and fixed to not break the Windows build.
Apparently, mmap'ing /dev/zero fails on macOS. So contrary to the
intent, it's not actually portable. Switch to MAP_ANONYMOUS instead,
with a fallback to MAP_ANON if it's not defined.
The API returns the compressed size as a size_t, so
deflate_flush_output() needs to return size_t as well, not u32.
Otherwise sizes >= 4 GiB are truncated.
This bug has been there since the beginning.
(This only matters if you compress a buffer that large in a single go,
which obviously is not a good idea, but no matter -- it's a bug.)
Resolves https://github.com/ebiggers/libdeflate/issues/44
libdeflate's 'gunzip' program fails if the uncompressed file size is a
nonzero multiple of 4 GiB because then the ISIZE field in the gzip file
is 0, so gunzip allocates no space for the decompressed data. Then when
libdeflate returns LIBDEFLATE_INSUFFICIENT_SPACE, gunzip doubles the
buffer size which stays 0, causing it to report "file corrupt or too
large to be processed by this program".
While neither libdeflate nor its 'gunzip' program is designed for single
gzip streams this large anyway, this particular bug can easily be fixed
by always allocating at least one byte for the decompressed data.
Add the user-specified CFLAGS after the default optimization flags
rather than before, so that the default optimization flags can be
overridden.
[EB - updated comment and improved commit message]
The Makefile forced installation into $(PREFIX)/lib, e.g. /usr/lib.
But many distros use /usr/lib64 instead.
Therefore, allow specifying a custom BINDIR, INCDIR, and/or LIBDIR.
This allows the parent shell to call on Gentoo Linux:
make install DESTDIR="${DESTDIR}/${EPREFIX}" LIBDIR=/usr/"$(get_libdir)"
[EB - improved commit message]
Move program utility functions that are used only by "test programs"
(i.e. not by gzip/gunzip) from prog_util.{c,h} into test_util.{c,h}.
This reduces the code that is compiled for the default build target,
which excludes the test programs.
Another build_decode_table() optimization: rather than filling all the
entries for each codeword using strided stores, just fill one initially
and fill the rest by memcpy()s as the table is incrementally expanded.
Also make some other cleanups and small optimizations.
Further improve build_decode_table() performance by splitting the "fill
direct entries" and "fill subtable pointers and subtables" steps into
separate loops and making some other optimizations.