Merging upstream version 1.12.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
4f55f2a35b
commit
e62d82c53f
40 changed files with 3224 additions and 1857 deletions
8
AUTHORS
8
AUTHORS
|
@ -1,7 +1,7 @@
|
|||
Lzlib was written by Antonio Diaz Diaz.
|
||||
|
||||
The ideas embodied in lzlib are due to (at least) the following people:
|
||||
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for
|
||||
the definition of Markov chains), G.N.N. Martin (for the definition of
|
||||
range encoding), Igor Pavlov (for putting all the above together in
|
||||
LZMA), and Julian Seward (for bzip2's CLI).
|
||||
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
|
||||
definition of Markov chains), G.N.N. Martin (for the definition of range
|
||||
encoding), Igor Pavlov (for putting all the above together in LZMA), and
|
||||
Julian Seward (for bzip2's CLI).
|
||||
|
|
4
COPYING
4
COPYING
|
@ -6,10 +6,10 @@
|
|||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
|
135
ChangeLog
135
ChangeLog
|
@ -1,16 +1,55 @@
|
|||
2021-01-02 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.12 released.
|
||||
* lzlib.h: Define LZ_API_VERSION as 1000 * major + minor. 1.12 = 1012.
|
||||
This change does not affect the soversion.
|
||||
* lzlib.h, lzlib.c: New function LZ_api_version.
|
||||
* LZd_try_verify_trailer: Return 2 if EOF at trailer or EOS marker.
|
||||
* Decompression speed has been slightly increased.
|
||||
* decoder.h: Increase 'rd_min_available_bytes' from 8 to 10.
|
||||
* encoder_base.c (LZeb_try_sync_flush):
|
||||
Compensate for the increase in 'rd_min_available_bytes'.
|
||||
* main.c (do_decompress): Fix false report about library stall.
|
||||
* main.c: New option '--check-lib'.
|
||||
* main.c (main): Report an error if a file name is empty.
|
||||
Make '-o' behave like '-c', but writing to file instead of stdout.
|
||||
Make '-c' and '-o' check whether the output is a terminal only once.
|
||||
Do not open output if input is a terminal.
|
||||
Replace 'decompressed', 'compressed' with 'out', 'in' in output.
|
||||
Set a valid invocation_name even if argc == 0.
|
||||
* lzlib.texi: Document the new way of verifying the library version.
|
||||
Document that 'LZ_(de)compress_close' and 'LZ_(de)compress_errno'
|
||||
can be called with a null argument.
|
||||
Document that sync flush marker is not allowed in lzip files.
|
||||
Document the consequences of not calling 'LZ_decompress_finish'.
|
||||
Document that 'LZ_decompress_read' returns at least once per member.
|
||||
Document that 'LZ_(de)compress_read' can be called with a null
|
||||
buffer pointer argument.
|
||||
Real code examples for common uses have been added to the tutorial.
|
||||
* bbexample.c: Don't use 'LZ_(de)compress_write_size'.
|
||||
* lzcheck.c: New options '-s' (sync) and '-m' (member by member).
|
||||
Test member by member without 'LZ_decompress_finish'.
|
||||
* ffexample.c: New file containing example functions for file-to-file
|
||||
compression/decompression.
|
||||
* Document extraction from tar.lz in '--help' output and man page.
|
||||
* Makefile.in: 'install-bin' no longer installs the man page.
|
||||
New targets 'install-bin-compress' and 'install-bin-strip-compress'.
|
||||
* testsuite: Add 9 new test files.
|
||||
|
||||
2019-01-02 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.11 released.
|
||||
* File_* renamed to Lzip_*.
|
||||
* Rename File_* to Lzip_*.
|
||||
* LZ_decompress_read: Don't return error until all data is read.
|
||||
* decoder.c (LZd_decode_member): Decode truncated data until EOF.
|
||||
* cbuffer.c (Cb_read_data): Allow a null buffer pointer.
|
||||
* main.c: Don't allow mixing different operations (-d and -t).
|
||||
* main.c: Check return value of close( infd ).
|
||||
* main.c: Compile on DOS with DJGPP.
|
||||
* lzlib.texi: Improved descriptions of '-0..-9', '-m' and '-s'.
|
||||
* lzlib.texi: Improve descriptions of '-0..-9', '-m', and '-s'.
|
||||
Document that 'LZ_(de)compress_finish' can be called repeatedly.
|
||||
* configure: Accept appending to CFLAGS, 'CFLAGS+=OPTIONS'.
|
||||
* Makefile.in: Targets 'install-bin*' renamed to 'install-lib*'.
|
||||
* Makefile.in: Rename targets 'install-bin*' to 'install-lib*'.
|
||||
* Makefile.in: Targets 'install-bin*' now install minilzip.
|
||||
* INSTALL: Document use of CFLAGS+='-D __USE_MINGW_ANSI_STDIO'.
|
||||
|
||||
|
@ -19,13 +58,13 @@
|
|||
* Version 1.10 released.
|
||||
* LZ_compress_finish now adjusts dictionary size for each member.
|
||||
* lzlib.c (LZ_decompress_read): Detect corrupt header with HD=3.
|
||||
* main.c: Added new option '--loose-trailing'.
|
||||
* main.c: New option '--loose-trailing'.
|
||||
* main.c (main): Option '-S, --volume-size' now keeps input files.
|
||||
* main.c: Replaced 'bits/byte' with inverse compression ratio.
|
||||
* main.c: Replace 'bits/byte' with inverse compression ratio.
|
||||
* main.c: Show final diagnostic when testing multiple files.
|
||||
* main.c: Do not add a second .lz extension to the arg of -o.
|
||||
* main.c: Show dictionary size at verbosity level 4 (-vvvv).
|
||||
* lzlib.texi: Added chapter 'Invoking minilzip'.
|
||||
* lzlib.texi: New chapter 'Invoking minilzip'.
|
||||
|
||||
2017-04-11 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
|
@ -34,14 +73,15 @@
|
|||
* Compression time of options -1 to -9 has been reduced by 1%.
|
||||
* Decompression time has been reduced by 3%.
|
||||
* main.c: Continue testing if any input file is a terminal.
|
||||
* License of the library changed to "2-clause BSD".
|
||||
* Change the license of the library to "2-clause BSD".
|
||||
|
||||
2016-05-17 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.8 released.
|
||||
* lzlib.h: Define LZ_API_VERSION to 1.
|
||||
* decoder.c (LZd_verify_trailer): Removed test of final code.
|
||||
* main.c: Added new option '-a, --trailing-error'.
|
||||
* lzlib.c (LZ_decompress_sync_to_member): Add skipped size to in_size.
|
||||
* decoder.c (LZd_verify_trailer): Remove test of final code.
|
||||
* main.c: New option '-a, --trailing-error'.
|
||||
* main.c (main): Delete '--output' file if infd is a terminal.
|
||||
* main.c (main): Don't use stdin more than once.
|
||||
* configure: Avoid warning on some shells when testing for gcc.
|
||||
|
@ -52,26 +92,25 @@
|
|||
2015-07-08 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.7 released.
|
||||
* Ported fast encoder and option '-0' from lzip.
|
||||
* Port fast encoder and option '-0' from lzip.
|
||||
* If open-->write-->finish, produce same dictionary size as lzip.
|
||||
* Makefile.in: Added new targets 'install*-compress'.
|
||||
* Makefile.in: New targets 'install*-compress'.
|
||||
|
||||
2014-08-27 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.6 released.
|
||||
* Compression ratio of option '-9' has been slightly increased.
|
||||
* configure: Added new option '--disable-static'.
|
||||
* configure: Added new option '--disable-ldconfig'.
|
||||
* configure: New options '--disable-static' and '--disable-ldconfig'.
|
||||
* Makefile.in: Ignore errors from ldconfig.
|
||||
* Makefile.in: Use 'CFLAGS' in every invocation of 'CC'.
|
||||
* main.c (close_and_set_permissions): Behave like 'cp -p'.
|
||||
* lzlib.texinfo: Renamed to lzlib.texi.
|
||||
* License changed to "GPL version 2 or later with link exception".
|
||||
* lzlib.texinfo: Rename to lzlib.texi.
|
||||
* Change license to "GPL version 2 or later with link exception".
|
||||
|
||||
2013-09-15 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.5 released.
|
||||
* Removed decompression support for version 0 files.
|
||||
* Remove decompression support for version 0 files.
|
||||
* The LZ_compress_sync_flush mechanism has been fixed (again).
|
||||
* Minor fixes.
|
||||
|
||||
|
@ -82,12 +121,11 @@
|
|||
* Compression ratio has been slightly increased.
|
||||
* Compression time has been reduced by 8%.
|
||||
* Decompression time has been reduced by 7%.
|
||||
* lzlib.h: Changed 'long long' values to 'unsigned long long'.
|
||||
* lzlib.h: Change 'long long' values to 'unsigned long long'.
|
||||
* encoder.c (Mf_init): Reduce minimum buffer size to 64KiB.
|
||||
* lzlib.c (LZ_decompress_read): Tell LZ_header_error from
|
||||
LZ_unexpected_eof the same way as lzip does.
|
||||
* Makefile.in: Added new target 'install-as-lzip'.
|
||||
* Makefile.in: Added new target 'install-bin'.
|
||||
* Makefile.in: New targets 'install-as-lzip' and 'install-bin'.
|
||||
* main.c: Use 'setmode' instead of '_setmode' on Windows and OS/2.
|
||||
* main.c: Define 'strtoull' to 'strtoul' on Windows.
|
||||
|
||||
|
@ -95,7 +133,7 @@
|
|||
|
||||
* Version 1.3 released.
|
||||
* Translated to C from the C++ source of lzlib 1.2.
|
||||
* configure: 'datadir' renamed to 'datarootdir'.
|
||||
* configure: Rename 'datadir' to 'datarootdir'.
|
||||
|
||||
2011-10-25 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
|
@ -104,10 +142,9 @@
|
|||
independently of the value of 'pos_state'. This gives better
|
||||
compression for large values of '--match-length' without being
|
||||
slower.
|
||||
* encoder.h encoder.cc: Optimize pair price calculations. This
|
||||
reduces compression time for large values of '--match-length'
|
||||
by up to 6%.
|
||||
* main.cc: Added new option '-F, --recompress'.
|
||||
* encoder.h, encoder.cc: Optimize pair price calculations, reducing
|
||||
compression time for large values of '--match-length' by up to 6%.
|
||||
* main.cc: New option '-F, --recompress'.
|
||||
* Makefile.in: 'make install' no longer tries to run
|
||||
'/sbin/ldconfig' on systems lacking it.
|
||||
|
||||
|
@ -117,7 +154,7 @@
|
|||
* Compression time has been reduced by 2%.
|
||||
* All declarations not belonging to the API have been
|
||||
encapsulated in the namespace 'Lzlib'.
|
||||
* testsuite: 'test1' renamed to 'test.txt'. Added new tests.
|
||||
* testsuite: Rename 'test1' to 'test.txt'. New tests.
|
||||
* Match length limits set by options -1 to -9 of minilzip have
|
||||
been changed to match those of lzip 1.11.
|
||||
* main.cc: Set stdin/stdout in binary mode on OS2.
|
||||
|
@ -127,14 +164,11 @@
|
|||
2010-05-08 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 1.0 released.
|
||||
* Added new function LZ_decompress_member_finished.
|
||||
* Added new function LZ_decompress_member_version.
|
||||
* Added new function LZ_decompress_dictionary_size.
|
||||
* Added new function LZ_decompress_data_crc.
|
||||
* Variables declared 'extern' have been encapsulated in a
|
||||
namespace.
|
||||
* main.cc: Fixed warning about fchown's return value being ignored.
|
||||
* decoder.h: Input_buffer integrated in Range_decoder.
|
||||
* New functions LZ_decompress_member_version, LZ_decompress_data_crc,
|
||||
LZ_decompress_member_finished, and LZ_decompress_dictionary_size.
|
||||
* Variables declared 'extern' have been encapsulated in a namespace.
|
||||
* main.cc: Fix warning about fchown's return value being ignored.
|
||||
* decoder.h: Integrate Input_buffer in Range_decoder.
|
||||
|
||||
2010-02-10 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
|
@ -145,28 +179,26 @@
|
|||
2010-01-17 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.8 released.
|
||||
* Added new function LZ_decompress_reset.
|
||||
* Added new function LZ_decompress_sync_to_member.
|
||||
* Added new function LZ_decompress_write_size.
|
||||
* Added new function LZ_strerror.
|
||||
* lzlib.h: API change. Replaced 'enum' with functions for values
|
||||
of dictionary size limits to make interface names consistent.
|
||||
* lzlib.h: API change. 'LZ_errno' replaced with 'LZ_Errno'.
|
||||
* lzlib.h: API change. Replaced 'void *' with 'struct LZ_Encoder *'
|
||||
* New functions LZ_decompress_reset, LZ_decompress_sync_to_member,
|
||||
LZ_decompress_write_size, and LZ_strerror.
|
||||
* lzlib.h: API change. Replace 'enum' with functions for values of
|
||||
dictionary size limits to make interface names consistent.
|
||||
* lzlib.h: API change. Rename 'LZ_errno' to 'LZ_Errno'.
|
||||
* lzlib.h: API change. Replace 'void *' with 'struct LZ_Encoder *'
|
||||
and 'struct LZ_Decoder *' to make interface type safe.
|
||||
* decoder.cc: Truncated member trailer is now correctly detected.
|
||||
* decoder.cc: A truncated member trailer is now correctly detected.
|
||||
* encoder.cc: Matchfinder::reset now also clears at_stream_end_,
|
||||
allowing LZ_compress_restart_member to restart a finished stream.
|
||||
* lzlib.cc: Accept only query or close operations after a fatal
|
||||
error has occurred.
|
||||
* Shared version of lzlib is no longer built by default.
|
||||
* The shared version of lzlib is no longer built by default.
|
||||
* check.sh: Use 'test1' instead of 'COPYING' for testing.
|
||||
|
||||
2009-10-20 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.7 released.
|
||||
* Compression time has been reduced by 4%.
|
||||
* check.sh: Removed -9 to run in less than 256MiB of RAM.
|
||||
* check.sh: Remove -9 to run in less than 256MiB of RAM.
|
||||
* lzcheck.cc: Read files of any size up to 2^63 bytes.
|
||||
|
||||
2009-09-02 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
@ -178,15 +210,14 @@
|
|||
|
||||
* Version 0.5 released.
|
||||
* Decompression speed has been improved.
|
||||
* main.cc (signal_handler): Declared as 'extern "C"'.
|
||||
* main.cc (signal_handler): Declare as 'extern "C"'.
|
||||
|
||||
2009-06-03 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.4 released.
|
||||
* Added new function LZ_compress_sync_flush.
|
||||
* Added new function LZ_compress_write_size.
|
||||
* New functions LZ_compress_sync_flush and LZ_compress_write_size.
|
||||
* Decompression speed has been improved.
|
||||
* Added chapter 'Buffering' to the manual.
|
||||
* lzlib.texinfo: New chapter 'Buffering'.
|
||||
|
||||
2009-05-03 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
|
@ -196,16 +227,16 @@
|
|||
2009-04-26 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.2 released.
|
||||
* Fixed a segfault when decompressing trailing garbage.
|
||||
* Fixed a false positive in LZ_(de)compress_finished.
|
||||
* Fix a segfault when decompressing trailing garbage.
|
||||
* Fix a false positive in LZ_(de)compress_finished.
|
||||
|
||||
2009-04-21 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.1 released.
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This file is a collection of facts, and thus it is not copyrightable,
|
||||
but just in case, you have unlimited permission to copy, distribute and
|
||||
but just in case, you have unlimited permission to copy, distribute, and
|
||||
modify it.
|
||||
|
|
36
INSTALL
36
INSTALL
|
@ -1,13 +1,13 @@
|
|||
Requirements
|
||||
------------
|
||||
You will need a C compiler.
|
||||
I use gcc 5.3.0 and 4.1.2, but the code should compile with any standards
|
||||
You will need a C99 compiler. (gcc 3.3.6 or newer is recommended).
|
||||
I use gcc 6.1.0 and 4.1.2, but the code should compile with any standards
|
||||
compliant compiler.
|
||||
Gcc is available at http://gcc.gnu.org.
|
||||
|
||||
The operating system must allow signal handlers read access to objects with
|
||||
static storage duration so that the cleanup handler for Control-C can delete
|
||||
the partial output file.
|
||||
the partial output file. (This requirement is for minilzip only).
|
||||
|
||||
|
||||
Procedure
|
||||
|
@ -41,27 +41,29 @@ the main archive.
|
|||
documentation. (You may need to run ldconfig also).
|
||||
|
||||
Or type 'make install-compress', which additionally compresses the
|
||||
info manual after installation. (Installing compressed docs may
|
||||
become the default in the future).
|
||||
info manual after installation.
|
||||
(Installing compressed docs may become the default in the future).
|
||||
|
||||
You can install only the library, the info manual or the man page by
|
||||
typing 'make install-lib', 'make install-info' or 'make install-man'
|
||||
respectively.
|
||||
You can install only the library or the info manual by typing
|
||||
'make install-lib' or 'make install-info' respectively.
|
||||
|
||||
'make install-bin' installs the minilzip program and its man page.
|
||||
'install-bin' installs a shared minilzip if the shared library has
|
||||
'make install-bin install-man' installs the program minilzip and its man
|
||||
page. 'install-bin' installs a shared minilzip if the shared library has
|
||||
been configured. Else it installs a static minilzip.
|
||||
'make install-as-lzip' runs 'make install-bin' and then links
|
||||
minilzip to the name 'lzip'.
|
||||
'make install-bin-compress' additionally compresses the man page after
|
||||
installation.
|
||||
|
||||
'make install-as-lzip' runs 'make install-bin' and then links minilzip to
|
||||
the name 'lzip'.
|
||||
|
||||
|
||||
Another way
|
||||
-----------
|
||||
You can also compile lzlib into a separate directory.
|
||||
To do this, you must use a version of 'make' that supports the 'VPATH'
|
||||
variable, such as GNU 'make'. 'cd' to the directory where you want the
|
||||
To do this, you must use a version of 'make' that supports the variable
|
||||
'VPATH', such as GNU 'make'. 'cd' to the directory where you want the
|
||||
object files and executables to go and run the 'configure' script.
|
||||
'configure' automatically checks for the source code in '.', in '..' and
|
||||
'configure' automatically checks for the source code in '.', in '..', and
|
||||
in the directory that 'configure' is in.
|
||||
|
||||
'configure' recognizes the option '--srcdir=DIR' to control where to
|
||||
|
@ -72,7 +74,7 @@ After running 'configure', you can run 'make' and 'make install' as
|
|||
explained above.
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute and modify it.
|
||||
distribute, and modify it.
|
||||
|
|
31
Makefile.in
31
Makefile.in
|
@ -15,8 +15,10 @@ objs = carg_parser.o main.o
|
|||
.PHONY : all install install-bin install-info install-man \
|
||||
install-strip install-compress install-strip-compress \
|
||||
install-bin-strip install-info-compress install-man-compress \
|
||||
install-lib install-lib-strip uninstall-lib install-as-lzip \
|
||||
uninstall uninstall-bin uninstall-info uninstall-man \
|
||||
install-bin-compress install-bin-strip-compress \
|
||||
install-lib install-lib-strip \
|
||||
install-as-lzip \
|
||||
uninstall uninstall-bin uninstall-lib uninstall-info uninstall-man \
|
||||
doc info man check dist clean distclean
|
||||
|
||||
all : $(progname_static) $(progname_shared)
|
||||
|
@ -36,6 +38,9 @@ $(progname)_shared : $(objs) lib$(libname).so.$(pkgversion)
|
|||
bbexample : bbexample.o lib$(libname).a
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ bbexample.o lib$(libname).a
|
||||
|
||||
ffexample : ffexample.o lib$(libname).a
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ ffexample.o lib$(libname).a
|
||||
|
||||
lzcheck : lzcheck.o lib$(libname).a
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ lzcheck.o lib$(libname).a
|
||||
|
||||
|
@ -57,6 +62,7 @@ lzlib.o : Makefile $(lzdeps)
|
|||
lzlib_sh.o : Makefile $(lzdeps)
|
||||
main.o : carg_parser.h lzlib.h
|
||||
bbexample.o : Makefile lzlib.h
|
||||
ffexample.o : Makefile lzlib.h
|
||||
lzcheck.o : Makefile lzlib.h
|
||||
|
||||
|
||||
|
@ -75,15 +81,17 @@ $(VPATH)/doc/$(progname).1 : $(progname)
|
|||
Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
|
||||
./config.status
|
||||
|
||||
check : $(progname) bbexample lzcheck
|
||||
check : $(progname) bbexample ffexample lzcheck
|
||||
@$(VPATH)/testsuite/check.sh $(VPATH)/testsuite $(pkgversion)
|
||||
|
||||
install : install-lib install-info
|
||||
install-strip : install-lib-strip install-info
|
||||
install-compress : install-lib install-info-compress
|
||||
install-strip-compress : install-lib-strip install-info-compress
|
||||
install-bin-compress : install-bin install-man-compress
|
||||
install-bin-strip-compress : install-bin-strip install-man-compress
|
||||
|
||||
install-bin : all install-man
|
||||
install-bin : all
|
||||
if [ ! -d "$(DESTDIR)$(bindir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(bindir)" ; fi
|
||||
$(INSTALL_PROGRAM) ./$(progname_lzip) "$(DESTDIR)$(bindir)/$(progname)"
|
||||
|
||||
|
@ -139,7 +147,7 @@ install-as-lzip : install-bin
|
|||
|
||||
uninstall : uninstall-info uninstall-lib
|
||||
|
||||
uninstall-bin : uninstall-man
|
||||
uninstall-bin :
|
||||
-rm -f "$(DESTDIR)$(bindir)/$(progname)"
|
||||
|
||||
uninstall-lib :
|
||||
|
@ -177,16 +185,19 @@ dist : doc
|
|||
$(DISTNAME)/*.c \
|
||||
$(DISTNAME)/testsuite/check.sh \
|
||||
$(DISTNAME)/testsuite/test.txt \
|
||||
$(DISTNAME)/testsuite/test2.txt \
|
||||
$(DISTNAME)/testsuite/fox_lf \
|
||||
$(DISTNAME)/testsuite/fox.lz \
|
||||
$(DISTNAME)/testsuite/fox_*.lz \
|
||||
$(DISTNAME)/testsuite/test_sync.lz \
|
||||
$(DISTNAME)/testsuite/test.txt.lz
|
||||
$(DISTNAME)/testsuite/test.txt.lz \
|
||||
$(DISTNAME)/testsuite/test_em.txt.lz
|
||||
rm -f $(DISTNAME)
|
||||
lzip -v -9 $(DISTNAME).tar
|
||||
|
||||
clean :
|
||||
-rm -f $(progname) $(objs)
|
||||
-rm -f $(progname)_shared lzlib_sh.o *.so.$(pkgversion)
|
||||
-rm -f bbexample bbexample.o lzcheck lzcheck.o lzlib.o *.a
|
||||
-rm -f $(progname) $(objs) lzlib.o lib$(libname).a
|
||||
-rm -f $(progname)_shared lzlib_sh.o lib$(libname).so*
|
||||
-rm -f bbexample bbexample.o ffexample ffexample.o lzcheck lzcheck.o
|
||||
|
||||
distclean : clean
|
||||
-rm -f Makefile config.status *.tar *.tar.lz
|
||||
|
|
104
NEWS
104
NEWS
|
@ -1,30 +1,92 @@
|
|||
Changes in version 1.11:
|
||||
Changes in version 1.12:
|
||||
|
||||
In case of decompression error caused by corrupt or truncated data,
|
||||
LZ_decompress_read now does not signal the error immediately to the
|
||||
application, but waits until all decoded bytes have been read. This
|
||||
allows tools like tarlz to recover as much data as possible from damaged
|
||||
members.
|
||||
The value of the version test macro 'LZ_API_VERSION' is now defined as
|
||||
1000 * major + minor. For version 1.12 it is 1012.
|
||||
This change does not affect the soversion.
|
||||
|
||||
It is now an error to specify two different operations to minilzip in
|
||||
the command line (--decompress and --test).
|
||||
The new function 'LZ_api_version', which returns the LZ_API_VERSION of the
|
||||
library object code being used, has been added to lzlib.
|
||||
|
||||
Minilzip now also checks for errors when closing the input file.
|
||||
If end of file is found at member trailer or EOS marker,
|
||||
'LZ_decompress_errno' now returns 'LZ_unexpected_eof' instead of
|
||||
'LZ_data_error'.
|
||||
|
||||
Minilzip now compiles on DOS with DJGPP. (Patch from Robert Riebisch).
|
||||
Decompression speed has been slightly increased.
|
||||
|
||||
The descriptions of '-0..-9', '-m' and '-s' in the manual have been
|
||||
improved.
|
||||
A bug has been fixed in minilzip that falsely reported a library stall when
|
||||
decompressing a file with empty members.
|
||||
|
||||
It has been documented that it is safe to call 'LZ_(de)compress_finish'
|
||||
as many times as needed. Examples in the manual have been simplified.
|
||||
The new option '--check-lib', which compares the version of lzlib used to
|
||||
compile minilzip with the version actually being used, has been added to
|
||||
minilzip.
|
||||
|
||||
The configure script now accepts appending options to CFLAGS using the
|
||||
syntax 'CFLAGS+=OPTIONS'.
|
||||
Minilzip now reports an error if a file name is empty (minilzip -t "").
|
||||
|
||||
Makefile targets 'install-bin*' have been renamed to 'install-lib*'. New
|
||||
'install-bin*' targets have been created that install a shared minilzip,
|
||||
or a static minilzip if the shared library has not been configured.
|
||||
Option '-o, --output' now behaves like '-c, --stdout', but sending the
|
||||
output unconditionally to a file instead of to standard output. See the new
|
||||
description of '-o' in the manual. This change is not backwards compatible.
|
||||
Therefore commands like:
|
||||
minilzip -o foo.lz - bar < foo
|
||||
must now be split into:
|
||||
minilzip -o foo.lz - < foo
|
||||
minilzip bar
|
||||
or rewritten as:
|
||||
minilzip - bar < foo > foo.lz
|
||||
|
||||
It has been documented in INSTALL the use of
|
||||
CFLAGS+='-D __USE_MINGW_ANSI_STDIO' when compiling on MinGW.
|
||||
When using '-c' or '-o', minilzip now checks whether the output is a
|
||||
terminal only once.
|
||||
|
||||
Minilzip now does not even open the output file if the input file is a terminal.
|
||||
|
||||
The words 'decompressed' and 'compressed' have been replaced with the
|
||||
shorter 'out' and 'in' in the verbose output of minilzip when decompressing
|
||||
or testing.
|
||||
|
||||
It has been documented in the manual that 'LZ_(de)compress_close' and
|
||||
'LZ_(de)compress_errno' can be called with a null argument.
|
||||
|
||||
It has been documented in the manual that the LZMA marker '3' ("Sync Flush"
|
||||
marker) is not allowed in lzip files. Marker '3' is a device for interactive
|
||||
communication between applications using lzlib, but is useless and wasteful
|
||||
in a file, and is excluded from the media type 'application/lzip'. The LZMA
|
||||
marker '2' ("End Of Stream" marker) is the only marker allowed in lzip
|
||||
files.
|
||||
|
||||
It has been documented in the manual that not calling 'LZ_decompress_finish'
|
||||
prevents lzlib from detecting a truncated member.
|
||||
|
||||
It has been documented in the manual that 'LZ_decompress_read' returns at
|
||||
least once per member so that 'LZ_decompress_member_finished' can be called
|
||||
(and trailer data retrieved) for each member, even for empty members.
|
||||
Therefore, 'LZ_decompress_read' returning 0 does not mean that the end of
|
||||
the stream has been reached.
|
||||
|
||||
It has been documented in the manual that 'LZ_(de)compress_read' can be
|
||||
called with a null buffer pointer argument.
|
||||
|
||||
Real code examples for the most common uses of the library have been added
|
||||
to the tutorial.
|
||||
|
||||
'bbexample.c' has been simplified to not use 'LZ_(de)compress_write_size'.
|
||||
|
||||
'lzcheck' now accepts options '-s' (to check LZ_compress_sync_flush) and
|
||||
'-m' (to check member by member decompression).
|
||||
|
||||
'lzcheck.c' now also tests member by member decompression without
|
||||
intermediate calls to 'LZ_decompress_finish'.
|
||||
|
||||
The new file 'ffexample.c', containing example functions for file-to-file
|
||||
compression/decompression, has been added to the distribution.
|
||||
|
||||
The commands needed to extract files from a tar.lz archive have been
|
||||
documented in the output of 'minilzip --help' and in the man page.
|
||||
|
||||
'make install-bin' no longer installs the minilzip man page. This is to
|
||||
prevent 'make install-bin install-man-compress' from installing the man page
|
||||
twice before compressing it.
|
||||
|
||||
The new targets 'install-bin-compress' and 'install-bin-strip-compress',
|
||||
which install a (stripped) minilzip and a compressed man page, have been
|
||||
added to the Makefile.
|
||||
|
||||
9 new test files have been added to the testsuite.
|
||||
|
|
114
README
114
README
|
@ -1,65 +1,64 @@
|
|||
Description
|
||||
|
||||
Lzlib is a data compression library providing in-memory LZMA compression
|
||||
and decompression functions, including integrity checking of the
|
||||
decompressed data. The compressed data format used by the library is the
|
||||
lzip format. Lzlib is written in C.
|
||||
Lzlib is a data compression library providing in-memory LZMA compression and
|
||||
decompression functions, including integrity checking of the decompressed
|
||||
data. The compressed data format used by the library is the lzip format.
|
||||
Lzlib is written in C.
|
||||
|
||||
The lzip file format is designed for data sharing and long-term archiving,
|
||||
taking into account both data integrity and decoder availability:
|
||||
|
||||
* The lzip format provides very safe integrity checking and some data
|
||||
recovery means. The lziprecover program can repair bit flip errors
|
||||
(one of the most common forms of data corruption) in lzip files,
|
||||
and provides data recovery capabilities, including error-checked
|
||||
merging of damaged copies of a file.
|
||||
recovery means. The program lziprecover can repair bit flip errors
|
||||
(one of the most common forms of data corruption) in lzip files, and
|
||||
provides data recovery capabilities, including error-checked merging
|
||||
of damaged copies of a file.
|
||||
|
||||
* The lzip format is as simple as possible (but not simpler). The
|
||||
lzip manual provides the source code of a simple decompressor
|
||||
along with a detailed explanation of how it works, so that with
|
||||
the only help of the lzip manual it would be possible for a
|
||||
digital archaeologist to extract the data from a lzip file long
|
||||
after quantum computers eventually render LZMA obsolete.
|
||||
* The lzip format is as simple as possible (but not simpler). The lzip
|
||||
manual provides the source code of a simple decompressor along with a
|
||||
detailed explanation of how it works, so that with the only help of the
|
||||
lzip manual it would be possible for a digital archaeologist to extract
|
||||
the data from a lzip file long after quantum computers eventually
|
||||
render LZMA obsolete.
|
||||
|
||||
* Additionally the lzip reference implementation is copylefted, which
|
||||
guarantees that it will remain free forever.
|
||||
|
||||
A nice feature of the lzip format is that a corrupt byte is easier to
|
||||
repair the nearer it is from the beginning of the file. Therefore, with
|
||||
the help of lziprecover, losing an entire archive just because of a
|
||||
corrupt byte near the beginning is a thing of the past.
|
||||
A nice feature of the lzip format is that a corrupt byte is easier to repair
|
||||
the nearer it is from the beginning of the file. Therefore, with the help of
|
||||
lziprecover, losing an entire archive just because of a corrupt byte near
|
||||
the beginning is a thing of the past.
|
||||
|
||||
The functions and variables forming the interface of the compression
|
||||
library are declared in the file 'lzlib.h'. Usage examples of the
|
||||
library are given in the files 'main.c' and 'bbexample.c' from the
|
||||
source distribution.
|
||||
The functions and variables forming the interface of the compression library
|
||||
are declared in the file 'lzlib.h'. Usage examples of the library are given
|
||||
in the files 'bbexample.c', 'ffexample.c', and 'main.c' from the source
|
||||
distribution.
|
||||
|
||||
Compression/decompression is done by repeatedly calling a couple of
|
||||
read/write functions until all the data have been processed by the
|
||||
library. This interface is safer and less error prone than the
|
||||
traditional zlib interface.
|
||||
read/write functions until all the data have been processed by the library.
|
||||
This interface is safer and less error prone than the traditional zlib
|
||||
interface.
|
||||
|
||||
Compression/decompression is done when the read function is called. This
|
||||
means the value returned by the position functions will not be updated
|
||||
until a read call, even if a lot of data are written. If you want the
|
||||
data to be compressed in advance, just call the read function with a
|
||||
size equal to 0.
|
||||
means the value returned by the position functions will not be updated until
|
||||
a read call, even if a lot of data are written. If you want the data to be
|
||||
compressed in advance, just call the read function with a size equal to 0.
|
||||
|
||||
If all the data to be compressed are written in advance, lzlib will
|
||||
automatically adjust the header of the compressed data to use the
|
||||
largest dictionary size that does not exceed neither the data size nor
|
||||
the limit given to LZ_compress_open. This feature reduces the amount of
|
||||
memory needed for decompression and allows minilzip to produce identical
|
||||
compressed output as lzip.
|
||||
automatically adjust the header of the compressed data to use the largest
|
||||
dictionary size that does not exceed neither the data size nor the limit
|
||||
given to 'LZ_compress_open'. This feature reduces the amount of memory
|
||||
needed for decompression and allows minilzip to produce identical compressed
|
||||
output as lzip.
|
||||
|
||||
Lzlib will correctly decompress a data stream which is the concatenation
|
||||
of two or more compressed data streams. The result is the concatenation
|
||||
of the corresponding decompressed data streams. Integrity testing of
|
||||
concatenated compressed data streams is also supported.
|
||||
Lzlib will correctly decompress a data stream which is the concatenation of
|
||||
two or more compressed data streams. The result is the concatenation of the
|
||||
corresponding decompressed data streams. Integrity testing of concatenated
|
||||
compressed data streams is also supported.
|
||||
|
||||
Lzlib is able to compress and decompress streams of unlimited size by
|
||||
automatically creating multimember output. The members so created are
|
||||
large, about 2 PiB each.
|
||||
automatically creating multimember output. The members so created are large,
|
||||
about 2 PiB each.
|
||||
|
||||
All the library functions are thread safe. The library does not install
|
||||
any signal handler. The decoder checks the consistency of the compressed
|
||||
|
@ -67,16 +66,15 @@ data, so the library should never crash even in case of corrupted input.
|
|||
|
||||
In spite of its name (Lempel-Ziv-Markov chain-Algorithm), LZMA is not a
|
||||
concrete algorithm; it is more like "any algorithm using the LZMA coding
|
||||
scheme". For example, the option '-0' of lzip uses the scheme in almost
|
||||
the simplest way possible; issuing the longest match it can find, or a
|
||||
literal byte if it can't find a match. Inversely, a much more elaborated
|
||||
way of finding coding sequences of minimum size than the one currently
|
||||
used by lzip could be developed, and the resulting sequence could also
|
||||
be coded using the LZMA coding scheme.
|
||||
scheme". For example, the option '-0' of lzip uses the scheme in almost the
|
||||
simplest way possible; issuing the longest match it can find, or a literal
|
||||
byte if it can't find a match. Inversely, a much more elaborated way of
|
||||
finding coding sequences of minimum size than the one currently used by lzip
|
||||
could be developed, and the resulting sequence could also be coded using the
|
||||
LZMA coding scheme.
|
||||
|
||||
Lzlib currently implements two variants of the LZMA algorithm; fast
|
||||
(used by option '-0' of minilzip) and normal (used by all other
|
||||
compression levels).
|
||||
Lzlib currently implements two variants of the LZMA algorithm; fast (used by
|
||||
option '-0' of minilzip) and normal (used by all other compression levels).
|
||||
|
||||
The high compression of LZMA comes from combining two basic, well-proven
|
||||
compression ideas: sliding dictionaries (LZ77/78) and markov models (the
|
||||
|
@ -85,20 +83,20 @@ similar order-0 entropy coder as its last stage) with segregation of
|
|||
contexts according to what the bits are used for.
|
||||
|
||||
The ideas embodied in lzlib are due to (at least) the following people:
|
||||
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for
|
||||
the definition of Markov chains), G.N.N. Martin (for the definition of
|
||||
range encoding), Igor Pavlov (for putting all the above together in
|
||||
LZMA), and Julian Seward (for bzip2's CLI).
|
||||
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
|
||||
definition of Markov chains), G.N.N. Martin (for the definition of range
|
||||
encoding), Igor Pavlov (for putting all the above together in LZMA), and
|
||||
Julian Seward (for bzip2's CLI).
|
||||
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never
|
||||
have been compressed. Decompressed is used to refer to data which have
|
||||
undergone the process of decompression.
|
||||
LANGUAGE NOTE: Uncompressed = not compressed = plain data; it may never have
|
||||
been compressed. Decompressed is used to refer to data which have undergone
|
||||
the process of decompression.
|
||||
|
||||
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute and modify it.
|
||||
distribute, and modify it.
|
||||
|
||||
The file Makefile.in is a data file used by configure to produce the
|
||||
Makefile. It has the same copyright owner and permissions that configure
|
||||
|
|
371
bbexample.c
371
bbexample.c
|
@ -1,21 +1,20 @@
|
|||
/* Buffer to buffer example - Test program for the lzlib library
|
||||
Copyright (C) 2010-2019 Antonio Diaz Diaz.
|
||||
/* Buffer to buffer example - Test program for the library lzlib
|
||||
Copyright (C) 2010-2021 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you have unlimited permission
|
||||
to copy, distribute and modify it.
|
||||
to copy, distribute, and modify it.
|
||||
|
||||
Usage is:
|
||||
bbexample filename
|
||||
Usage: bbexample filename
|
||||
|
||||
This program is an example of how buffer-to-buffer
|
||||
compression/decompression can be implemented using lzlib.
|
||||
*/
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -24,6 +23,10 @@
|
|||
|
||||
#include "lzlib.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
|
||||
/* Returns the address of a malloc'd buffer containing the file data and
|
||||
the file size in '*file_sizep'.
|
||||
|
@ -35,28 +38,26 @@ uint8_t * read_file( const char * const name, long * const file_sizep )
|
|||
uint8_t * buffer, * tmp;
|
||||
FILE * const f = fopen( name, "rb" );
|
||||
if( !f )
|
||||
{
|
||||
fprintf( stderr, "bbexample: Can't open input file '%s': %s\n",
|
||||
name, strerror( errno ) );
|
||||
return 0;
|
||||
}
|
||||
{ fprintf( stderr, "bbexample: Can't open input file '%s': %s\n",
|
||||
name, strerror( errno ) ); return 0; }
|
||||
|
||||
buffer = (uint8_t *)malloc( buffer_size );
|
||||
if( !buffer )
|
||||
{ fputs( "bbexample: Not enough memory.\n", stderr ); return 0; }
|
||||
{ fputs( "bbexample: read_file: Not enough memory.\n", stderr );
|
||||
fclose( f ); return 0; }
|
||||
file_size = fread( buffer, 1, buffer_size, f );
|
||||
while( file_size >= buffer_size )
|
||||
{
|
||||
if( buffer_size >= LONG_MAX )
|
||||
{
|
||||
fprintf( stderr, "bbexample: Input file '%s' is too large.\n", name );
|
||||
free( buffer ); return 0;
|
||||
free( buffer ); fclose( f ); return 0;
|
||||
}
|
||||
buffer_size = ( buffer_size <= LONG_MAX / 2 ) ? 2 * buffer_size : LONG_MAX;
|
||||
tmp = (uint8_t *)realloc( buffer, buffer_size );
|
||||
if( !tmp )
|
||||
{ fputs( "bbexample: Not enough memory.\n", stderr );
|
||||
free( buffer ); return 0; }
|
||||
{ fputs( "bbexample: read_file: Not enough memory.\n", stderr );
|
||||
free( buffer ); fclose( f ); return 0; }
|
||||
buffer = tmp;
|
||||
file_size += fread( buffer + file_size, 1, buffer_size - file_size, f );
|
||||
}
|
||||
|
@ -64,7 +65,7 @@ uint8_t * read_file( const char * const name, long * const file_sizep )
|
|||
{
|
||||
fprintf( stderr, "bbexample: Error reading file '%s': %s\n",
|
||||
name, strerror( errno ) );
|
||||
free( buffer ); return 0;
|
||||
free( buffer ); fclose( f ); return 0;
|
||||
}
|
||||
fclose( f );
|
||||
*file_sizep = file_size;
|
||||
|
@ -72,13 +73,13 @@ uint8_t * read_file( const char * const name, long * const file_sizep )
|
|||
}
|
||||
|
||||
|
||||
/* Compresses 'size' bytes from 'data'. Returns the address of a
|
||||
malloc'd buffer containing the compressed data and its size in
|
||||
'*out_sizep'.
|
||||
In case of error, returns 0 and does not modify '*out_sizep'.
|
||||
/* Compresses 'insize' bytes from 'inbuf'.
|
||||
Returns the address of a malloc'd buffer containing the compressed data,
|
||||
and the size of the data in '*outlenp'.
|
||||
In case of error, returns 0 and does not modify '*outlenp'.
|
||||
*/
|
||||
uint8_t * bbcompress( const uint8_t * const data, const long size,
|
||||
const int level, long * const out_sizep )
|
||||
uint8_t * bbcompressl( const uint8_t * const inbuf, const long insize,
|
||||
const int level, long * const outlenp )
|
||||
{
|
||||
struct Lzma_options
|
||||
{
|
||||
|
@ -100,132 +101,246 @@ uint8_t * bbcompress( const uint8_t * const data, const long size,
|
|||
{ 3 << 23, 132 }, /* -8 */
|
||||
{ 1 << 25, 273 } }; /* -9 */
|
||||
struct Lzma_options encoder_options;
|
||||
const unsigned long long member_size = 0x7FFFFFFFFFFFFFFFULL; /* INT64_MAX */
|
||||
struct LZ_Encoder * encoder;
|
||||
uint8_t * new_data;
|
||||
const long delta_size = ( size / 4 ) + 64; /* size may be zero */
|
||||
long new_data_size = delta_size; /* initial size */
|
||||
long new_pos = 0;
|
||||
long written = 0;
|
||||
uint8_t * outbuf;
|
||||
const long delta_size = ( insize / 4 ) + 64; /* insize may be zero */
|
||||
long outsize = delta_size; /* initial outsize */
|
||||
long inpos = 0;
|
||||
long outpos = 0;
|
||||
bool error = false;
|
||||
|
||||
if( level < 0 || level > 9 ) return 0;
|
||||
encoder_options = option_mapping[level];
|
||||
|
||||
if( encoder_options.dictionary_size > size && level != 0 )
|
||||
encoder_options.dictionary_size = size; /* saves memory */
|
||||
if( encoder_options.dictionary_size > insize && level != 0 )
|
||||
encoder_options.dictionary_size = insize; /* saves memory */
|
||||
if( encoder_options.dictionary_size < LZ_min_dictionary_size() )
|
||||
encoder_options.dictionary_size = LZ_min_dictionary_size();
|
||||
encoder = LZ_compress_open( encoder_options.dictionary_size,
|
||||
encoder_options.match_len_limit, member_size );
|
||||
if( !encoder || LZ_compress_errno( encoder ) != LZ_ok )
|
||||
{ LZ_compress_close( encoder ); return 0; }
|
||||
|
||||
new_data = (uint8_t *)malloc( new_data_size );
|
||||
if( !new_data )
|
||||
{ LZ_compress_close( encoder ); return 0; }
|
||||
encoder_options.match_len_limit, INT64_MAX );
|
||||
outbuf = (uint8_t *)malloc( outsize );
|
||||
if( !encoder || LZ_compress_errno( encoder ) != LZ_ok || !outbuf )
|
||||
{ free( outbuf ); LZ_compress_close( encoder ); return 0; }
|
||||
|
||||
while( true )
|
||||
{
|
||||
int rd;
|
||||
if( LZ_compress_write_size( encoder ) > 0 )
|
||||
{
|
||||
if( written < size )
|
||||
{
|
||||
const int wr = LZ_compress_write( encoder, data + written,
|
||||
size - written );
|
||||
if( wr < 0 ) { error = true; break; }
|
||||
written += wr;
|
||||
}
|
||||
if( written >= size ) LZ_compress_finish( encoder );
|
||||
}
|
||||
rd = LZ_compress_read( encoder, new_data + new_pos,
|
||||
new_data_size - new_pos );
|
||||
if( rd < 0 ) { error = true; break; }
|
||||
new_pos += rd;
|
||||
int ret = LZ_compress_write( encoder, inbuf + inpos,
|
||||
min( INT_MAX, insize - inpos ) );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
inpos += ret;
|
||||
if( inpos >= insize ) LZ_compress_finish( encoder );
|
||||
ret = LZ_compress_read( encoder, outbuf + outpos,
|
||||
min( INT_MAX, outsize - outpos ) );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
outpos += ret;
|
||||
if( LZ_compress_finished( encoder ) == 1 ) break;
|
||||
if( new_pos >= new_data_size )
|
||||
if( outpos >= outsize )
|
||||
{
|
||||
uint8_t * tmp;
|
||||
if( new_data_size > LONG_MAX - delta_size ) { error = true; break; }
|
||||
new_data_size += delta_size;
|
||||
tmp = (uint8_t *)realloc( new_data, new_data_size );
|
||||
if( outsize > LONG_MAX - delta_size ) { error = true; break; }
|
||||
outsize += delta_size;
|
||||
tmp = (uint8_t *)realloc( outbuf, outsize );
|
||||
if( !tmp ) { error = true; break; }
|
||||
new_data = tmp;
|
||||
outbuf = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if( LZ_compress_close( encoder ) < 0 ) error = true;
|
||||
if( error ) { free( new_data ); return 0; }
|
||||
*out_sizep = new_pos;
|
||||
return new_data;
|
||||
if( error ) { free( outbuf ); return 0; }
|
||||
*outlenp = outpos;
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
|
||||
/* Decompresses 'size' bytes from 'data'. Returns the address of a
|
||||
malloc'd buffer containing the decompressed data and its size in
|
||||
'*out_sizep'.
|
||||
In case of error, returns 0 and does not modify '*out_sizep'.
|
||||
/* Decompresses 'insize' bytes from 'inbuf'.
|
||||
Returns the address of a malloc'd buffer containing the decompressed
|
||||
data, and the size of the data in '*outlenp'.
|
||||
In case of error, returns 0 and does not modify '*outlenp'.
|
||||
*/
|
||||
uint8_t * bbdecompress( const uint8_t * const data, const long size,
|
||||
long * const out_sizep )
|
||||
uint8_t * bbdecompressl( const uint8_t * const inbuf, const long insize,
|
||||
long * const outlenp )
|
||||
{
|
||||
struct LZ_Decoder * const decoder = LZ_decompress_open();
|
||||
uint8_t * new_data;
|
||||
const long delta_size = size; /* size must be > zero */
|
||||
long new_data_size = delta_size; /* initial size */
|
||||
long new_pos = 0;
|
||||
long written = 0;
|
||||
const long delta_size = insize; /* insize must be > zero */
|
||||
long outsize = delta_size; /* initial outsize */
|
||||
uint8_t * outbuf = (uint8_t *)malloc( outsize );
|
||||
long inpos = 0;
|
||||
long outpos = 0;
|
||||
bool error = false;
|
||||
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok )
|
||||
{ LZ_decompress_close( decoder ); return 0; }
|
||||
|
||||
new_data = (uint8_t *)malloc( new_data_size );
|
||||
if( !new_data )
|
||||
{ LZ_decompress_close( decoder ); return 0; }
|
||||
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok || !outbuf )
|
||||
{ free( outbuf ); LZ_decompress_close( decoder ); return 0; }
|
||||
|
||||
while( true )
|
||||
{
|
||||
int rd;
|
||||
if( LZ_decompress_write_size( decoder ) > 0 )
|
||||
{
|
||||
if( written < size )
|
||||
{
|
||||
const int wr = LZ_decompress_write( decoder, data + written,
|
||||
size - written );
|
||||
if( wr < 0 ) { error = true; break; }
|
||||
written += wr;
|
||||
}
|
||||
if( written >= size ) LZ_decompress_finish( decoder );
|
||||
}
|
||||
rd = LZ_decompress_read( decoder, new_data + new_pos,
|
||||
new_data_size - new_pos );
|
||||
if( rd < 0 ) { error = true; break; }
|
||||
new_pos += rd;
|
||||
int ret = LZ_decompress_write( decoder, inbuf + inpos,
|
||||
min( INT_MAX, insize - inpos ) );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
inpos += ret;
|
||||
if( inpos >= insize ) LZ_decompress_finish( decoder );
|
||||
ret = LZ_decompress_read( decoder, outbuf + outpos,
|
||||
min( INT_MAX, outsize - outpos ) );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
outpos += ret;
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) break;
|
||||
if( new_pos >= new_data_size )
|
||||
if( outpos >= outsize )
|
||||
{
|
||||
uint8_t * tmp;
|
||||
if( new_data_size > LONG_MAX - delta_size ) { error = true; break; }
|
||||
new_data_size += delta_size;
|
||||
tmp = (uint8_t *)realloc( new_data, new_data_size );
|
||||
if( outsize > LONG_MAX - delta_size ) { error = true; break; }
|
||||
outsize += delta_size;
|
||||
tmp = (uint8_t *)realloc( outbuf, outsize );
|
||||
if( !tmp ) { error = true; break; }
|
||||
new_data = tmp;
|
||||
outbuf = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if( LZ_decompress_close( decoder ) < 0 ) error = true;
|
||||
if( error ) { free( new_data ); return 0; }
|
||||
*out_sizep = new_pos;
|
||||
return new_data;
|
||||
if( error ) { free( outbuf ); return 0; }
|
||||
*outlenp = outpos;
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
|
||||
/* Test the whole file at all levels. */
|
||||
int full_test( const uint8_t * const inbuf, const long insize )
|
||||
{
|
||||
int level;
|
||||
for( level = 0; level <= 9; ++level )
|
||||
{
|
||||
long midsize = 0, outsize = 0;
|
||||
uint8_t * outbuf;
|
||||
uint8_t * midbuf = bbcompressl( inbuf, insize, level, &midsize );
|
||||
if( !midbuf )
|
||||
{ fputs( "bbexample: full_test: Not enough memory or compress error.\n",
|
||||
stderr ); return 1; }
|
||||
|
||||
outbuf = bbdecompressl( midbuf, midsize, &outsize );
|
||||
free( midbuf );
|
||||
if( !outbuf )
|
||||
{ fputs( "bbexample: full_test: Not enough memory or decompress error.\n",
|
||||
stderr ); return 1; }
|
||||
|
||||
if( insize != outsize ||
|
||||
( insize > 0 && memcmp( inbuf, outbuf, insize ) != 0 ) )
|
||||
{ fputs( "bbexample: full_test: Decompressed data differs from original.\n",
|
||||
stderr ); free( outbuf ); return 1; }
|
||||
|
||||
free( outbuf );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Compresses 'insize' bytes from 'inbuf' to 'outbuf'.
|
||||
Returns the size of the compressed data in '*outlenp'.
|
||||
In case of error, or if 'outsize' is too small, returns false and does
|
||||
not modify '*outlenp'.
|
||||
*/
|
||||
bool bbcompress( const uint8_t * const inbuf, const int insize,
|
||||
const int dictionary_size, const int match_len_limit,
|
||||
uint8_t * const outbuf, const int outsize,
|
||||
int * const outlenp )
|
||||
{
|
||||
int inpos = 0, outpos = 0;
|
||||
bool error = false;
|
||||
struct LZ_Encoder * const encoder =
|
||||
LZ_compress_open( dictionary_size, match_len_limit, INT64_MAX );
|
||||
if( !encoder || LZ_compress_errno( encoder ) != LZ_ok )
|
||||
{ LZ_compress_close( encoder ); return false; }
|
||||
|
||||
while( true )
|
||||
{
|
||||
int ret = LZ_compress_write( encoder, inbuf + inpos, insize - inpos );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
inpos += ret;
|
||||
if( inpos >= insize ) LZ_compress_finish( encoder );
|
||||
ret = LZ_compress_read( encoder, outbuf + outpos, outsize - outpos );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
outpos += ret;
|
||||
if( LZ_compress_finished( encoder ) == 1 ) break;
|
||||
if( outpos >= outsize ) { error = true; break; }
|
||||
}
|
||||
|
||||
if( LZ_compress_close( encoder ) < 0 ) error = true;
|
||||
if( error ) return false;
|
||||
*outlenp = outpos;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Decompresses 'insize' bytes from 'inbuf' to 'outbuf'.
|
||||
Returns the size of the decompressed data in '*outlenp'.
|
||||
In case of error, or if 'outsize' is too small, returns false and does
|
||||
not modify '*outlenp'.
|
||||
*/
|
||||
bool bbdecompress( const uint8_t * const inbuf, const int insize,
|
||||
uint8_t * const outbuf, const int outsize,
|
||||
int * const outlenp )
|
||||
{
|
||||
int inpos = 0, outpos = 0;
|
||||
bool error = false;
|
||||
struct LZ_Decoder * const decoder = LZ_decompress_open();
|
||||
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok )
|
||||
{ LZ_decompress_close( decoder ); return false; }
|
||||
|
||||
while( true )
|
||||
{
|
||||
int ret = LZ_decompress_write( decoder, inbuf + inpos, insize - inpos );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
inpos += ret;
|
||||
if( inpos >= insize ) LZ_decompress_finish( decoder );
|
||||
ret = LZ_decompress_read( decoder, outbuf + outpos, outsize - outpos );
|
||||
if( ret < 0 ) { error = true; break; }
|
||||
outpos += ret;
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) break;
|
||||
if( outpos >= outsize ) { error = true; break; }
|
||||
}
|
||||
|
||||
if( LZ_decompress_close( decoder ) < 0 ) error = true;
|
||||
if( error ) return false;
|
||||
*outlenp = outpos;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Test at most INT_MAX bytes from the file with buffers of fixed size. */
|
||||
int fixed_test( const uint8_t * const inbuf, const int insize )
|
||||
{
|
||||
int dictionary_size = 65535; /* fast encoder */
|
||||
int midsize = min( INT_MAX, ( insize / 8 ) * 9LL + 44 ), outsize = insize;
|
||||
uint8_t * midbuf = (uint8_t *)malloc( midsize );
|
||||
uint8_t * outbuf = (uint8_t *)malloc( outsize );
|
||||
if( !midbuf || !outbuf )
|
||||
{ fputs( "bbexample: fixed_test: Not enough memory.\n", stderr );
|
||||
free( outbuf ); free( midbuf ); return 1; }
|
||||
|
||||
for( ; dictionary_size <= 8 << 20; dictionary_size += 8323073 )
|
||||
{
|
||||
int midlen, outlen;
|
||||
if( !bbcompress( inbuf, insize, dictionary_size, 16, midbuf, midsize, &midlen ) )
|
||||
{ fputs( "bbexample: fixed_test: Not enough memory or compress error.\n",
|
||||
stderr ); free( outbuf ); free( midbuf ); return 1; }
|
||||
|
||||
if( !bbdecompress( midbuf, midlen, outbuf, outsize, &outlen ) )
|
||||
{ fputs( "bbexample: fixed_test: Not enough memory or decompress error.\n",
|
||||
stderr ); free( outbuf ); free( midbuf ); return 1; }
|
||||
|
||||
if( insize != outlen ||
|
||||
( insize > 0 && memcmp( inbuf, outbuf, insize ) != 0 ) )
|
||||
{ fputs( "bbexample: fixed_test: Decompressed data differs from original.\n",
|
||||
stderr ); free( outbuf ); free( midbuf ); return 1; }
|
||||
|
||||
}
|
||||
free( outbuf );
|
||||
free( midbuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main( const int argc, const char * const argv[] )
|
||||
{
|
||||
uint8_t * in_buffer;
|
||||
long in_size = 0;
|
||||
int level;
|
||||
int retval = 0, i;
|
||||
int open_failures = 0;
|
||||
const bool verbose = ( argc > 2 );
|
||||
|
||||
if( argc < 2 )
|
||||
{
|
||||
|
@ -233,38 +348,20 @@ int main( const int argc, const char * const argv[] )
|
|||
return 1;
|
||||
}
|
||||
|
||||
in_buffer = read_file( argv[1], &in_size );
|
||||
if( !in_buffer ) return 1;
|
||||
|
||||
for( level = 0; level <= 9; ++level )
|
||||
for( i = 1; i < argc && retval == 0; ++i )
|
||||
{
|
||||
uint8_t * mid_buffer, * out_buffer;
|
||||
long mid_size = 0, out_size = 0;
|
||||
long insize;
|
||||
uint8_t * const inbuf = read_file( argv[i], &insize );
|
||||
if( !inbuf ) { ++open_failures; continue; }
|
||||
if( verbose ) fprintf( stderr, " Testing file '%s'\n", argv[i] );
|
||||
|
||||
mid_buffer = bbcompress( in_buffer, in_size, level, &mid_size );
|
||||
if( !mid_buffer )
|
||||
{
|
||||
fputs( "bbexample: Not enough memory or compress error.\n", stderr );
|
||||
return 1;
|
||||
retval = full_test( inbuf, insize );
|
||||
if( retval == 0 ) retval = fixed_test( inbuf, min( INT_MAX, insize ) );
|
||||
free( inbuf );
|
||||
}
|
||||
|
||||
out_buffer = bbdecompress( mid_buffer, mid_size, &out_size );
|
||||
if( !out_buffer )
|
||||
{
|
||||
fputs( "bbexample: Not enough memory or decompress error.\n", stderr );
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( in_size != out_size ||
|
||||
( in_size > 0 && memcmp( in_buffer, out_buffer, in_size ) != 0 ) )
|
||||
{
|
||||
fputs( "bbexample: Decompressed data differs from original.\n", stderr );
|
||||
return 1;
|
||||
}
|
||||
|
||||
free( out_buffer );
|
||||
free( mid_buffer );
|
||||
}
|
||||
free( in_buffer );
|
||||
return 0;
|
||||
if( open_failures > 0 && verbose )
|
||||
fprintf( stderr, "bbexample: warning: %d %s failed to open.\n",
|
||||
open_failures, ( open_failures == 1 ) ? "file" : "files" );
|
||||
if( retval == 0 && open_failures ) retval = 1;
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||
Copyright (C) 2006-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||
Copyright (C) 2006-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
/* Arg_parser reads the arguments in 'argv' and creates a number of
|
||||
option codes, option arguments and non-option arguments.
|
||||
option codes, option arguments, and non-option arguments.
|
||||
|
||||
In case of error, 'ap_error' returns a non-null pointer to an error
|
||||
message.
|
||||
|
@ -79,7 +79,7 @@ void ap_free( struct Arg_parser * const ap );
|
|||
|
||||
const char * ap_error( const struct Arg_parser * const ap );
|
||||
|
||||
/* The number of arguments parsed (may be different from argc) */
|
||||
/* The number of arguments parsed. May be different from argc. */
|
||||
int ap_arguments( const struct Arg_parser * const ap );
|
||||
|
||||
/* If ap_code( i ) is 0, ap_argument( i ) is a non-option.
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
|
25
configure
vendored
25
configure
vendored
|
@ -1,12 +1,12 @@
|
|||
#! /bin/sh
|
||||
# configure script for Lzlib - Compression library for the lzip format
|
||||
# Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
#
|
||||
# This configure script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
pkgname=lzlib
|
||||
pkgversion=1.11
|
||||
pkgversion=1.12
|
||||
soversion=1
|
||||
progname=minilzip
|
||||
progname_static=${progname}
|
||||
|
@ -34,11 +34,7 @@ CFLAGS='-Wall -W -O2'
|
|||
LDFLAGS=
|
||||
|
||||
# checking whether we are using GNU C.
|
||||
/bin/sh -c "${CC} --version" > /dev/null 2>&1 ||
|
||||
{
|
||||
CC=cc
|
||||
CFLAGS=-O2
|
||||
}
|
||||
/bin/sh -c "${CC} --version" > /dev/null 2>&1 || { CC=cc ; CFLAGS=-O2 ; }
|
||||
|
||||
# Loop over all args
|
||||
args=
|
||||
|
@ -50,11 +46,12 @@ while [ $# != 0 ] ; do
|
|||
shift
|
||||
|
||||
# Add the argument quoted to args
|
||||
args="${args} \"${option}\""
|
||||
if [ -z "${args}" ] ; then args="\"${option}\""
|
||||
else args="${args} \"${option}\"" ; fi
|
||||
|
||||
# Split out the argument for options that take them
|
||||
case ${option} in
|
||||
*=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
|
||||
*=*) optarg=`echo "${option}" | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
|
||||
esac
|
||||
|
||||
# Process the options
|
||||
|
@ -151,7 +148,7 @@ if [ -z "${srcdir}" ] ; then
|
|||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||
## the sed command below emulates the dirname command
|
||||
srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
srcdir=`echo "$0" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -174,7 +171,7 @@ if [ -z "${no_create}" ] ; then
|
|||
# Run this file to recreate the current configuration.
|
||||
#
|
||||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
exec /bin/sh $0 ${args} --no-create
|
||||
EOF
|
||||
|
@ -198,11 +195,11 @@ echo "LDFLAGS = ${LDFLAGS}"
|
|||
rm -f Makefile
|
||||
cat > Makefile << EOF
|
||||
# Makefile for Lzlib - Compression library for the lzip format
|
||||
# Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
# This file was generated automatically by configure. Don't edit.
|
||||
#
|
||||
# This Makefile is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
pkgname = ${pkgname}
|
||||
pkgversion = ${pkgversion}
|
||||
|
|
22
decoder.c
22
decoder.c
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -20,8 +20,8 @@
|
|||
static int LZd_try_verify_trailer( struct LZ_decoder * const d )
|
||||
{
|
||||
Lzip_trailer trailer;
|
||||
if( Rd_available_bytes( d->rdec ) < Lt_size && !d->rdec->at_stream_end )
|
||||
return 0;
|
||||
if( Rd_available_bytes( d->rdec ) < Lt_size )
|
||||
{ if( !d->rdec->at_stream_end ) return 0; else return 2; }
|
||||
d->verify_trailer_pending = false;
|
||||
d->member_finished = true;
|
||||
|
||||
|
@ -40,10 +40,10 @@ static int LZd_decode_member( struct LZ_decoder * const d )
|
|||
{
|
||||
struct Range_decoder * const rdec = d->rdec;
|
||||
State * const state = &d->state;
|
||||
/* unsigned old_mpos = d->rdec->member_position; */
|
||||
/* unsigned old_mpos = rdec->member_position; */
|
||||
|
||||
if( d->member_finished ) return 0;
|
||||
if( !Rd_try_reload( rdec, false ) )
|
||||
if( !Rd_try_reload( rdec ) )
|
||||
{ if( !rdec->at_stream_end ) return 0; else return 2; }
|
||||
if( d->verify_trailer_pending ) return LZd_try_verify_trailer( d );
|
||||
|
||||
|
@ -51,7 +51,7 @@ static int LZd_decode_member( struct LZ_decoder * const d )
|
|||
{
|
||||
int len;
|
||||
const int pos_state = LZd_data_position( d ) & pos_state_mask;
|
||||
/* const unsigned mpos = d->rdec->member_position;
|
||||
/* const unsigned mpos = rdec->member_position;
|
||||
if( mpos - old_mpos > rd_min_available_bytes ) return 5;
|
||||
old_mpos = mpos; */
|
||||
if( !Rd_enough_available_bytes( rdec ) ) /* check unexpected EOF */
|
||||
|
@ -123,6 +123,9 @@ static int LZd_decode_member( struct LZ_decoder * const d )
|
|||
if( distance == 0xFFFFFFFFU ) /* marker found */
|
||||
{
|
||||
Rd_normalize( rdec );
|
||||
/* const unsigned mpos = rdec->member_position;
|
||||
if( mpos - old_mpos > rd_min_available_bytes ) return 5;
|
||||
old_mpos = mpos; */
|
||||
if( len == min_match_len ) /* End Of Stream marker */
|
||||
{
|
||||
d->verify_trailer_pending = true;
|
||||
|
@ -130,7 +133,8 @@ static int LZd_decode_member( struct LZ_decoder * const d )
|
|||
}
|
||||
if( len == min_match_len + 1 ) /* Sync Flush marker */
|
||||
{
|
||||
if( Rd_try_reload( rdec, true ) ) { /*old_mpos += 5;*/ continue; }
|
||||
rdec->reload_pending = true;
|
||||
if( Rd_try_reload( rdec ) ) continue;
|
||||
else { if( !rdec->at_stream_end ) return 0; else break; }
|
||||
}
|
||||
return 4;
|
||||
|
|
38
decoder.h
38
decoder.h
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -17,7 +17,7 @@
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
enum { rd_min_available_bytes = 8 };
|
||||
enum { rd_min_available_bytes = 10 };
|
||||
|
||||
struct Range_decoder
|
||||
{
|
||||
|
@ -133,9 +133,8 @@ static inline bool Rd_unread_data( struct Range_decoder * const rdec,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool Rd_try_reload( struct Range_decoder * const rdec, const bool force )
|
||||
static bool Rd_try_reload( struct Range_decoder * const rdec )
|
||||
{
|
||||
if( force ) rdec->reload_pending = true;
|
||||
if( rdec->reload_pending && Rd_available_bytes( rdec ) >= 5 )
|
||||
{
|
||||
int i;
|
||||
|
@ -168,7 +167,7 @@ static inline unsigned Rd_decode( struct Range_decoder * const rdec,
|
|||
/* symbol <<= 1; */
|
||||
/* if( rdec->code >= rdec->range ) { rdec->code -= rdec->range; symbol |= 1; } */
|
||||
bit = ( rdec->code >= rdec->range );
|
||||
symbol = ( symbol << 1 ) + bit;
|
||||
symbol <<= 1; symbol += bit;
|
||||
rdec->code -= rdec->range & ( 0U - bit );
|
||||
}
|
||||
return symbol;
|
||||
|
@ -182,15 +181,15 @@ static inline unsigned Rd_decode_bit( struct Range_decoder * const rdec,
|
|||
bound = ( rdec->range >> bit_model_total_bits ) * *probability;
|
||||
if( rdec->code < bound )
|
||||
{
|
||||
rdec->range = bound;
|
||||
*probability += (bit_model_total - *probability) >> bit_model_move_bits;
|
||||
rdec->range = bound;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rdec->range -= bound;
|
||||
rdec->code -= bound;
|
||||
*probability -= *probability >> bit_model_move_bits;
|
||||
rdec->code -= bound;
|
||||
rdec->range -= bound;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -198,8 +197,7 @@ static inline unsigned Rd_decode_bit( struct Range_decoder * const rdec,
|
|||
static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec,
|
||||
Bit_model bm[] )
|
||||
{
|
||||
unsigned symbol = 1;
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
unsigned symbol = 2 | Rd_decode_bit( rdec, &bm[1] );
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
return symbol & 7;
|
||||
|
@ -208,8 +206,7 @@ static inline unsigned Rd_decode_tree3( struct Range_decoder * const rdec,
|
|||
static inline unsigned Rd_decode_tree6( struct Range_decoder * const rdec,
|
||||
Bit_model bm[] )
|
||||
{
|
||||
unsigned symbol = 1;
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
unsigned symbol = 2 | Rd_decode_bit( rdec, &bm[1] );
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
symbol = ( symbol << 1 ) | Rd_decode_bit( rdec, &bm[symbol] );
|
||||
|
@ -238,7 +235,7 @@ Rd_decode_tree_reversed( struct Range_decoder * const rdec,
|
|||
for( i = 0; i < num_bits; ++i )
|
||||
{
|
||||
const unsigned bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) + bit;
|
||||
model <<= 1; model += bit;
|
||||
symbol |= ( bit << i );
|
||||
}
|
||||
return symbol;
|
||||
|
@ -248,12 +245,9 @@ static inline unsigned
|
|||
Rd_decode_tree_reversed4( struct Range_decoder * const rdec, Bit_model bm[] )
|
||||
{
|
||||
unsigned symbol = Rd_decode_bit( rdec, &bm[1] );
|
||||
unsigned model = 2 + symbol;
|
||||
unsigned bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) + bit; symbol |= ( bit << 1 );
|
||||
bit = Rd_decode_bit( rdec, &bm[model] );
|
||||
model = ( model << 1 ) + bit; symbol |= ( bit << 2 );
|
||||
symbol |= ( Rd_decode_bit( rdec, &bm[model] ) << 3 );
|
||||
symbol += Rd_decode_bit( rdec, &bm[2+symbol] ) << 1;
|
||||
symbol += Rd_decode_bit( rdec, &bm[4+symbol] ) << 2;
|
||||
symbol += Rd_decode_bit( rdec, &bm[8+symbol] ) << 3;
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
@ -266,7 +260,7 @@ static inline unsigned Rd_decode_matched( struct Range_decoder * const rdec,
|
|||
{
|
||||
const unsigned match_bit = ( match_byte <<= 1 ) & mask;
|
||||
const unsigned bit = Rd_decode_bit( rdec, &bm[symbol+match_bit+mask] );
|
||||
symbol = ( symbol << 1 ) + bit;
|
||||
symbol <<= 1; symbol += bit;
|
||||
if( symbol > 0xFF ) return symbol & 0xFF;
|
||||
mask &= ~(match_bit ^ (bit << 8)); /* if( match_bit != bit ) mask = 0; */
|
||||
}
|
||||
|
|
1329
doc/lzlib.info
1329
doc/lzlib.info
File diff suppressed because it is too large
Load diff
908
doc/lzlib.texi
908
doc/lzlib.texi
File diff suppressed because it is too large
Load diff
|
@ -1,13 +1,23 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.1.
|
||||
.TH MINILZIP "1" "January 2019" "minilzip 1.11" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||
.TH MINILZIP "1" "January 2021" "minilzip 1.12" "User Commands"
|
||||
.SH NAME
|
||||
minilzip \- reduces the size of files
|
||||
.SH SYNOPSIS
|
||||
.B minilzip
|
||||
[\fI\,options\/\fR] [\fI\,files\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Minilzip is a test program for the lzlib compression library, fully
|
||||
Minilzip is a test program for the compression library lzlib, fully
|
||||
compatible with lzip 1.4 or newer.
|
||||
.PP
|
||||
Lzip is a lossless data compressor with a user interface similar to the one
|
||||
of gzip or bzip2. Lzip uses a simplified form of the 'Lempel\-Ziv\-Markov
|
||||
chain\-Algorithm' (LZMA) stream format, chosen to maximize safety and
|
||||
interoperability. Lzip can compress about as fast as gzip (lzip \fB\-0\fR) or
|
||||
compress most files more than bzip2 (lzip \fB\-9\fR). Decompression speed is
|
||||
intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 from
|
||||
a data recovery perspective. Lzip has been designed, written, and tested
|
||||
with great care to replace gzip and bzip2 as the standard general\-purpose
|
||||
compressed format for unix\-like systems.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
|
@ -41,7 +51,7 @@ keep (don't delete) input files
|
|||
set match length limit in bytes [36]
|
||||
.TP
|
||||
\fB\-o\fR, \fB\-\-output=\fR<file>
|
||||
if reading standard input, write to <file>
|
||||
write to <file>, keep input files
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
suppress all messages
|
||||
|
@ -69,6 +79,9 @@ alias for \fB\-9\fR
|
|||
.TP
|
||||
\fB\-\-loose\-trailing\fR
|
||||
allow trailing data seeming corrupt header
|
||||
.TP
|
||||
\fB\-\-check\-lib\fR
|
||||
compare version of lzlib.h with liblz.{a,so}
|
||||
.PP
|
||||
If no file names are given, or if a file is '\-', minilzip compresses or
|
||||
decompresses from standard input to standard output.
|
||||
|
@ -79,20 +92,29 @@ to 2^29 bytes.
|
|||
.PP
|
||||
The bidimensional parameter space of LZMA can't be mapped to a linear
|
||||
scale optimal for all files. If your files are large, very repetitive,
|
||||
etc, you may need to use the \fB\-\-dictionary\-size\fR and \fB\-\-match\-length\fR
|
||||
options directly to achieve optimal performance.
|
||||
etc, you may need to use the options \fB\-\-dictionary\-size\fR and \fB\-\-match\-length\fR
|
||||
directly to achieve optimal performance.
|
||||
.PP
|
||||
To extract all the files from archive 'foo.tar.lz', use the commands
|
||||
\&'tar \fB\-xf\fR foo.tar.lz' or 'minilzip \fB\-cd\fR foo.tar.lz | tar \fB\-xf\fR \-'.
|
||||
.PP
|
||||
Exit status: 0 for a normal exit, 1 for environmental problems (file
|
||||
not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or
|
||||
invalid input file, 3 for an internal consistency error (eg, bug) which
|
||||
caused minilzip to panic.
|
||||
.PP
|
||||
The ideas embodied in lzlib are due to (at least) the following people:
|
||||
Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the
|
||||
definition of Markov chains), G.N.N. Martin (for the definition of range
|
||||
encoding), Igor Pavlov (for putting all the above together in LZMA), and
|
||||
Julian Seward (for bzip2's CLI).
|
||||
.SH "REPORTING BUGS"
|
||||
Report bugs to lzip\-bug@nongnu.org
|
||||
.br
|
||||
Lzlib home page: http://www.nongnu.org/lzip/lzlib.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2019 Antonio Diaz Diaz.
|
||||
Using lzlib 1.11
|
||||
Copyright \(co 2021 Antonio Diaz Diaz.
|
||||
Using lzlib 1.12
|
||||
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>
|
||||
.br
|
||||
This is free software: you are free to change and redistribute it.
|
||||
|
|
20
encoder.c
20
encoder.c
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -23,7 +23,7 @@ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs
|
|||
int32_t * ptr1 = ptr0 + 1;
|
||||
int32_t * newptr;
|
||||
int len = 0, len0 = 0, len1 = 0;
|
||||
int maxlen = 0;
|
||||
int maxlen = 3; /* only used if pairs != 0 */
|
||||
int num_pairs = 0;
|
||||
const int pos1 = e->eb.mb.pos + 1;
|
||||
const int min_pos = ( e->eb.mb.pos > e->eb.mb.dictionary_size ) ?
|
||||
|
@ -49,8 +49,8 @@ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs
|
|||
|
||||
if( pairs )
|
||||
{
|
||||
int np2 = e->eb.mb.prev_positions[key2];
|
||||
int np3 = e->eb.mb.prev_positions[key3];
|
||||
const int np2 = e->eb.mb.prev_positions[key2];
|
||||
const int np3 = e->eb.mb.prev_positions[key3];
|
||||
if( np2 > min_pos && e->eb.mb.buffer[np2-1] == data[0] )
|
||||
{
|
||||
pairs[0].dis = e->eb.mb.pos - np2;
|
||||
|
@ -60,19 +60,17 @@ static int LZe_get_match_pairs( struct LZ_encoder * const e, struct Pair * pairs
|
|||
if( np2 != np3 && np3 > min_pos && e->eb.mb.buffer[np3-1] == data[0] )
|
||||
{
|
||||
maxlen = 3;
|
||||
np2 = np3;
|
||||
pairs[num_pairs].dis = e->eb.mb.pos - np2;
|
||||
++num_pairs;
|
||||
pairs[num_pairs++].dis = e->eb.mb.pos - np3;
|
||||
}
|
||||
if( num_pairs > 0 )
|
||||
{
|
||||
const int delta = pos1 - np2;
|
||||
const int delta = pairs[num_pairs-1].dis + 1;
|
||||
while( maxlen < len_limit && data[maxlen-delta] == data[maxlen] )
|
||||
++maxlen;
|
||||
pairs[num_pairs-1].len = maxlen;
|
||||
if( maxlen < 3 ) maxlen = 3;
|
||||
if( maxlen >= len_limit ) pairs = 0; /* done. now just skip */
|
||||
}
|
||||
if( maxlen < 3 ) maxlen = 3;
|
||||
}
|
||||
|
||||
e->eb.mb.prev_positions[key2] = pos1;
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -58,7 +58,7 @@ static bool Mb_init( struct Matchfinder_base * const mb, const int before_size,
|
|||
mb->stream_pos = 0;
|
||||
mb->num_prev_positions23 = num_prev_positions23;
|
||||
mb->at_stream_end = false;
|
||||
mb->flushing = false;
|
||||
mb->sync_flush_pending = false;
|
||||
|
||||
mb->buffer_size = max( 65536, buffer_size_limit );
|
||||
mb->buffer = (uint8_t *)malloc( mb->buffer_size );
|
||||
|
@ -69,7 +69,7 @@ static bool Mb_init( struct Matchfinder_base * const mb, const int before_size,
|
|||
size = 1 << max( 16, real_bits( mb->dictionary_size - 1 ) - 2 );
|
||||
if( mb->dictionary_size > 1 << 26 ) /* 64 MiB */
|
||||
size >>= 1;
|
||||
mb->key4_mask = size - 1;
|
||||
mb->key4_mask = size - 1; /* increases with dictionary size */
|
||||
size += num_prev_positions23;
|
||||
mb->num_prev_positions = size;
|
||||
|
||||
|
@ -118,7 +118,7 @@ static void Mb_reset( struct Matchfinder_base * const mb )
|
|||
mb->pos = 0;
|
||||
mb->cyclic_pos = 0;
|
||||
mb->at_stream_end = false;
|
||||
mb->flushing = false;
|
||||
mb->sync_flush_pending = false;
|
||||
mb->dictionary_size = mb->saved_dictionary_size;
|
||||
Mb_adjust_array( mb );
|
||||
mb->pos_limit = mb->buffer_size - mb->after_size;
|
||||
|
@ -126,7 +126,7 @@ static void Mb_reset( struct Matchfinder_base * const mb )
|
|||
}
|
||||
|
||||
|
||||
/* End Of Stream mark => (dis == 0xFFFFFFFFU, len == min_match_len) */
|
||||
/* End Of Stream marker => (dis == 0xFFFFFFFFU, len == min_match_len) */
|
||||
static void LZeb_try_full_flush( struct LZ_encoder_base * const eb )
|
||||
{
|
||||
int i;
|
||||
|
@ -149,33 +149,36 @@ static void LZeb_try_full_flush( struct LZ_encoder_base * const eb )
|
|||
}
|
||||
|
||||
|
||||
/* Sync Flush mark => (dis == 0xFFFFFFFFU, len == min_match_len + 1) */
|
||||
static bool LZeb_sync_flush( struct LZ_encoder_base * const eb )
|
||||
/* Sync Flush marker => (dis == 0xFFFFFFFFU, len == min_match_len + 1) */
|
||||
static void LZeb_try_sync_flush( struct LZ_encoder_base * const eb )
|
||||
{
|
||||
int i;
|
||||
const int pos_state = Mb_data_position( &eb->mb ) & pos_state_mask;
|
||||
const State state = eb->state;
|
||||
const unsigned min_size = eb->renc.ff_count + max_marker_size;
|
||||
if( eb->member_finished ||
|
||||
Cb_free_bytes( &eb->renc.cb ) < (2 * max_marker_size) + eb->renc.ff_count )
|
||||
return false;
|
||||
for( i = 0; i < 2; ++i ) /* 2 consecutive markers guarantee decoding */
|
||||
{
|
||||
Cb_free_bytes( &eb->renc.cb ) < min_size + max_marker_size ) return;
|
||||
eb->mb.sync_flush_pending = false;
|
||||
const unsigned long long old_mpos = Re_member_position( &eb->renc );
|
||||
do { /* size of markers must be >= rd_min_available_bytes + 5 */
|
||||
Re_encode_bit( &eb->renc, &eb->bm_match[state][pos_state], 1 );
|
||||
Re_encode_bit( &eb->renc, &eb->bm_rep[state], 0 );
|
||||
LZeb_encode_pair( eb, 0xFFFFFFFFU, min_match_len + 1, pos_state );
|
||||
Re_flush( &eb->renc );
|
||||
}
|
||||
return true;
|
||||
while( Re_member_position( &eb->renc ) - old_mpos < min_size );
|
||||
}
|
||||
|
||||
|
||||
static void LZeb_reset( struct LZ_encoder_base * const eb,
|
||||
const unsigned long long member_size )
|
||||
{
|
||||
const unsigned long long min_member_size = min_dictionary_size;
|
||||
const unsigned long long max_member_size = 0x0008000000000000ULL; /* 2 PiB */
|
||||
int i;
|
||||
Mb_reset( &eb->mb );
|
||||
eb->member_size_limit =
|
||||
min( member_size, 0x0008000000000000ULL ) - Lt_size - max_marker_size;
|
||||
min( max( min_member_size, member_size ), max_member_size ) -
|
||||
Lt_size - max_marker_size;
|
||||
eb->crc = 0xFFFFFFFFU;
|
||||
Bm_array_init( eb->bm_literal[0], (1 << literal_context_bits) * 0x300 );
|
||||
Bm_array_init( eb->bm_match[0], states * pos_states );
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -197,7 +197,7 @@ static inline int price_symbol_reversed( const Bit_model bm[], int symbol,
|
|||
const bool bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += price_bit( bm[model], bit );
|
||||
model = ( model << 1 ) | bit;
|
||||
model <<= 1; model |= bit;
|
||||
}
|
||||
return price;
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ struct Matchfinder_base
|
|||
int pos_array_size;
|
||||
int saved_dictionary_size; /* dictionary_size restored by Mb_reset */
|
||||
bool at_stream_end; /* stream_pos shows real end of file */
|
||||
bool flushing;
|
||||
bool sync_flush_pending;
|
||||
};
|
||||
|
||||
static bool Mb_normalize_pos( struct Matchfinder_base * const mb );
|
||||
|
@ -265,19 +265,20 @@ Mb_data_position( const struct Matchfinder_base * const mb )
|
|||
{ return mb->partial_data_pos + mb->pos; }
|
||||
|
||||
static inline void Mb_finish( struct Matchfinder_base * const mb )
|
||||
{ mb->at_stream_end = true; mb->flushing = false; }
|
||||
{ mb->at_stream_end = true; mb->sync_flush_pending = false; }
|
||||
|
||||
static inline bool Mb_data_finished( const struct Matchfinder_base * const mb )
|
||||
{ return mb->at_stream_end && !mb->flushing && mb->pos >= mb->stream_pos; }
|
||||
{ return mb->at_stream_end && mb->pos >= mb->stream_pos; }
|
||||
|
||||
static inline bool Mb_flushing_or_end( const struct Matchfinder_base * const mb )
|
||||
{ return mb->at_stream_end || mb->flushing; }
|
||||
{ return mb->at_stream_end || mb->sync_flush_pending; }
|
||||
|
||||
static inline int Mb_free_bytes( const struct Matchfinder_base * const mb )
|
||||
{ if( Mb_flushing_or_end( mb ) ) return 0;
|
||||
return mb->buffer_size - mb->stream_pos; }
|
||||
|
||||
static inline bool Mb_enough_available_bytes( const struct Matchfinder_base * const mb )
|
||||
static inline bool
|
||||
Mb_enough_available_bytes( const struct Matchfinder_base * const mb )
|
||||
{ return ( mb->pos + mb->after_size <= mb->stream_pos ||
|
||||
( Mb_flushing_or_end( mb ) && mb->pos < mb->stream_pos ) ); }
|
||||
|
||||
|
@ -426,28 +427,30 @@ static inline void Re_encode_bit( struct Range_encoder * const renc,
|
|||
static inline void Re_encode_tree3( struct Range_encoder * const renc,
|
||||
Bit_model bm[], const int symbol )
|
||||
{
|
||||
int model = 1;
|
||||
int model;
|
||||
bool bit = ( symbol >> 2 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[1], bit );
|
||||
model = 2 | bit;
|
||||
bit = ( symbol >> 1 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
|
||||
Re_encode_bit( renc, &bm[model], symbol & 1 );
|
||||
}
|
||||
|
||||
static inline void Re_encode_tree6( struct Range_encoder * const renc,
|
||||
Bit_model bm[], const unsigned symbol )
|
||||
{
|
||||
int model = 1;
|
||||
int model;
|
||||
bool bit = ( symbol >> 5 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[1], bit );
|
||||
model = 2 | bit;
|
||||
bit = ( symbol >> 4 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
|
||||
bit = ( symbol >> 3 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
|
||||
bit = ( symbol >> 2 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
|
||||
bit = ( symbol >> 1 ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model = ( model << 1 ) | bit;
|
||||
Re_encode_bit( renc, &bm[model], bit ); model <<= 1; model |= bit;
|
||||
Re_encode_bit( renc, &bm[model], symbol & 1 );
|
||||
}
|
||||
|
||||
|
@ -460,7 +463,7 @@ static inline void Re_encode_tree8( struct Range_encoder * const renc,
|
|||
{
|
||||
const bool bit = ( symbol >> i ) & 1;
|
||||
Re_encode_bit( renc, &bm[model], bit );
|
||||
model = ( model << 1 ) | bit;
|
||||
model <<= 1; model |= bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,7 +477,7 @@ static inline void Re_encode_tree_reversed( struct Range_encoder * const renc,
|
|||
const bool bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
Re_encode_bit( renc, &bm[model], bit );
|
||||
model = ( model << 1 ) | bit;
|
||||
model <<= 1; model |= bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,7 +564,7 @@ static inline bool LZeb_init( struct LZ_encoder_base * const eb,
|
|||
}
|
||||
|
||||
static inline bool LZeb_member_finished( const struct LZ_encoder_base * const eb )
|
||||
{ return ( eb->member_finished && !Cb_used_bytes( &eb->renc.cb ) ); }
|
||||
{ return ( eb->member_finished && Cb_empty( &eb->renc.cb ) ); }
|
||||
|
||||
static inline void LZeb_free( struct LZ_encoder_base * const eb )
|
||||
{ Re_free( &eb->renc ); Mb_free( &eb->mb ); }
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -17,7 +17,7 @@
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance )
|
||||
static int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance )
|
||||
{
|
||||
enum { len_limit = 16 };
|
||||
const uint8_t * const data = Mb_ptr_to_current_pos( &fe->eb.mb );
|
||||
|
@ -59,7 +59,7 @@ int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance
|
|||
}
|
||||
|
||||
|
||||
bool FLZe_encode_member( struct FLZ_encoder * const fe )
|
||||
static bool FLZe_encode_member( struct FLZ_encoder * const fe )
|
||||
{
|
||||
int rep = 0, i;
|
||||
State * const state = &fe->eb.state;
|
||||
|
@ -86,7 +86,7 @@ bool FLZe_encode_member( struct FLZ_encoder * const fe )
|
|||
while( !Mb_data_finished( &fe->eb.mb ) &&
|
||||
Re_member_position( &fe->eb.renc ) < fe->eb.member_size_limit )
|
||||
{
|
||||
int match_distance;
|
||||
int match_distance = 0; /* avoid warning from gcc 6.1.0 */
|
||||
int main_len, pos_state;
|
||||
int len = 0;
|
||||
if( !Mb_enough_available_bytes( &fe->eb.mb ) ||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -31,21 +31,19 @@ static inline void FLZe_reset_key4( struct FLZ_encoder * const fe )
|
|||
fe->key4 = ( fe->key4 << 4 ) ^ fe->eb.mb.buffer[i];
|
||||
}
|
||||
|
||||
int FLZe_longest_match_len( struct FLZ_encoder * const fe, int * const distance );
|
||||
|
||||
static inline bool FLZe_update_and_move( struct FLZ_encoder * const fe, int n )
|
||||
{
|
||||
struct Matchfinder_base * const mb = &fe->eb.mb;
|
||||
while( --n >= 0 )
|
||||
{
|
||||
if( Mb_available_bytes( &fe->eb.mb ) >= 4 )
|
||||
if( Mb_available_bytes( mb ) >= 4 )
|
||||
{
|
||||
fe->key4 = ( ( fe->key4 << 4 ) ^ fe->eb.mb.buffer[fe->eb.mb.pos+3] ) &
|
||||
fe->eb.mb.key4_mask;
|
||||
fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = fe->eb.mb.prev_positions[fe->key4];
|
||||
fe->eb.mb.prev_positions[fe->key4] = fe->eb.mb.pos + 1;
|
||||
fe->key4 = ( ( fe->key4 << 4 ) ^ mb->buffer[mb->pos+3] ) & mb->key4_mask;
|
||||
mb->pos_array[mb->cyclic_pos] = mb->prev_positions[fe->key4];
|
||||
mb->prev_positions[fe->key4] = mb->pos + 1;
|
||||
}
|
||||
else fe->eb.mb.pos_array[fe->eb.mb.cyclic_pos] = 0;
|
||||
if( !Mb_move_pos( &fe->eb.mb ) ) return false;
|
||||
else mb->pos_array[mb->cyclic_pos] = 0;
|
||||
if( !Mb_move_pos( mb ) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
300
ffexample.c
Normal file
300
ffexample.c
Normal file
|
@ -0,0 +1,300 @@
|
|||
/* File to file example - Test program for the library lzlib
|
||||
Copyright (C) 2010-2021 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you have unlimited permission
|
||||
to copy, distribute, and modify it.
|
||||
|
||||
Try 'ffexample -h' for usage information.
|
||||
|
||||
This program is an example of how file-to-file
|
||||
compression/decompression can be implemented using lzlib.
|
||||
*/
|
||||
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "lzlib.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
|
||||
static void show_help( void )
|
||||
{
|
||||
printf( "ffexample is an example program showing how file-to-file (de)compression can\n"
|
||||
"be implemented using lzlib. The content of infile is compressed,\n"
|
||||
"decompressed, or both, and then written to outfile.\n"
|
||||
"\nUsage: ffexample operation [infile [outfile]]\n" );
|
||||
printf( "\nOperation:\n"
|
||||
" -h display this help and exit\n"
|
||||
" -c compress infile to outfile\n"
|
||||
" -d decompress infile to outfile\n"
|
||||
" -b both (compress then decompress) infile to outfile\n"
|
||||
" -m compress (multimember) infile to outfile\n"
|
||||
" -l compress (1 member per line) infile to outfile\n"
|
||||
" -r decompress with resync if data error or leading garbage\n"
|
||||
"\nIf infile or outfile are omitted, or are specified as '-', standard input or\n"
|
||||
"standard output are used in their place respectively.\n"
|
||||
"\nReport bugs to lzip-bug@nongnu.org\n"
|
||||
"Lzlib home page: http://www.nongnu.org/lzip/lzlib.html\n" );
|
||||
}
|
||||
|
||||
|
||||
int ffcompress( struct LZ_Encoder * const encoder,
|
||||
FILE * const infile, FILE * const outfile )
|
||||
{
|
||||
enum { buffer_size = 16384 };
|
||||
uint8_t buffer[buffer_size];
|
||||
while( true )
|
||||
{
|
||||
int len, ret;
|
||||
int size = min( buffer_size, LZ_compress_write_size( encoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
len = fread( buffer, 1, size, infile );
|
||||
ret = LZ_compress_write( encoder, buffer, len );
|
||||
if( ret < 0 || ferror( infile ) ) break;
|
||||
if( feof( infile ) ) LZ_compress_finish( encoder );
|
||||
}
|
||||
ret = LZ_compress_read( encoder, buffer, buffer_size );
|
||||
if( ret < 0 ) break;
|
||||
len = fwrite( buffer, 1, ret, outfile );
|
||||
if( len < ret ) break;
|
||||
if( LZ_compress_finished( encoder ) == 1 ) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ffdecompress( struct LZ_Decoder * const decoder,
|
||||
FILE * const infile, FILE * const outfile )
|
||||
{
|
||||
enum { buffer_size = 16384 };
|
||||
uint8_t buffer[buffer_size];
|
||||
while( true )
|
||||
{
|
||||
int len, ret;
|
||||
int size = min( buffer_size, LZ_decompress_write_size( decoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
len = fread( buffer, 1, size, infile );
|
||||
ret = LZ_decompress_write( decoder, buffer, len );
|
||||
if( ret < 0 || ferror( infile ) ) break;
|
||||
if( feof( infile ) ) LZ_decompress_finish( decoder );
|
||||
}
|
||||
ret = LZ_decompress_read( decoder, buffer, buffer_size );
|
||||
if( ret < 0 ) break;
|
||||
len = fwrite( buffer, 1, ret, outfile );
|
||||
if( len < ret ) break;
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ffboth( struct LZ_Encoder * const encoder,
|
||||
struct LZ_Decoder * const decoder,
|
||||
FILE * const infile, FILE * const outfile )
|
||||
{
|
||||
enum { buffer_size = 16384 };
|
||||
uint8_t buffer[buffer_size];
|
||||
while( true )
|
||||
{
|
||||
int len, ret;
|
||||
int size = min( buffer_size, LZ_compress_write_size( encoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
len = fread( buffer, 1, size, infile );
|
||||
ret = LZ_compress_write( encoder, buffer, len );
|
||||
if( ret < 0 || ferror( infile ) ) break;
|
||||
if( feof( infile ) ) LZ_compress_finish( encoder );
|
||||
}
|
||||
size = min( buffer_size, LZ_decompress_write_size( decoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
ret = LZ_compress_read( encoder, buffer, size );
|
||||
if( ret < 0 ) break;
|
||||
ret = LZ_decompress_write( decoder, buffer, ret );
|
||||
if( ret < 0 ) break;
|
||||
if( LZ_compress_finished( encoder ) == 1 )
|
||||
LZ_decompress_finish( decoder );
|
||||
}
|
||||
ret = LZ_decompress_read( decoder, buffer, buffer_size );
|
||||
if( ret < 0 ) break;
|
||||
len = fwrite( buffer, 1, ret, outfile );
|
||||
if( len < ret ) break;
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ffmmcompress( FILE * const infile, FILE * const outfile )
|
||||
{
|
||||
enum { buffer_size = 16384, member_size = 4096 };
|
||||
uint8_t buffer[buffer_size];
|
||||
bool done = false;
|
||||
struct LZ_Encoder * const encoder =
|
||||
LZ_compress_open( 65535, 16, member_size );
|
||||
if( !encoder || LZ_compress_errno( encoder ) != LZ_ok )
|
||||
{ fputs( "ffexample: Not enough memory.\n", stderr );
|
||||
LZ_compress_close( encoder ); return 1; }
|
||||
while( true )
|
||||
{
|
||||
int len, ret;
|
||||
int size = min( buffer_size, LZ_compress_write_size( encoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
len = fread( buffer, 1, size, infile );
|
||||
ret = LZ_compress_write( encoder, buffer, len );
|
||||
if( ret < 0 || ferror( infile ) ) break;
|
||||
if( feof( infile ) ) LZ_compress_finish( encoder );
|
||||
}
|
||||
ret = LZ_compress_read( encoder, buffer, buffer_size );
|
||||
if( ret < 0 ) break;
|
||||
len = fwrite( buffer, 1, ret, outfile );
|
||||
if( len < ret ) break;
|
||||
if( LZ_compress_member_finished( encoder ) == 1 )
|
||||
{
|
||||
if( LZ_compress_finished( encoder ) == 1 ) { done = true; break; }
|
||||
if( LZ_compress_restart_member( encoder, member_size ) < 0 ) break;
|
||||
}
|
||||
}
|
||||
if( LZ_compress_close( encoder ) < 0 ) done = false;
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
/* Compresses 'infile' to 'outfile' as a multimember stream with one member
|
||||
for each line of text terminated by a newline character or by EOF.
|
||||
Returns 0 if success, 1 if error.
|
||||
*/
|
||||
int fflfcompress( struct LZ_Encoder * const encoder,
|
||||
FILE * const infile, FILE * const outfile )
|
||||
{
|
||||
enum { buffer_size = 16384 };
|
||||
uint8_t buffer[buffer_size];
|
||||
while( true )
|
||||
{
|
||||
int len, ret;
|
||||
int size = min( buffer_size, LZ_compress_write_size( encoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
for( len = 0; len < size; )
|
||||
{
|
||||
int ch = getc( infile );
|
||||
if( ch == EOF || ( buffer[len++] = ch ) == '\n' ) break;
|
||||
}
|
||||
/* avoid writing an empty member to outfile */
|
||||
if( len == 0 && LZ_compress_data_position( encoder ) == 0 ) return 0;
|
||||
ret = LZ_compress_write( encoder, buffer, len );
|
||||
if( ret < 0 || ferror( infile ) ) break;
|
||||
if( feof( infile ) || buffer[len-1] == '\n' )
|
||||
LZ_compress_finish( encoder );
|
||||
}
|
||||
ret = LZ_compress_read( encoder, buffer, buffer_size );
|
||||
if( ret < 0 ) break;
|
||||
len = fwrite( buffer, 1, ret, outfile );
|
||||
if( len < ret ) break;
|
||||
if( LZ_compress_member_finished( encoder ) == 1 )
|
||||
{
|
||||
if( feof( infile ) && LZ_compress_finished( encoder ) == 1 ) return 0;
|
||||
if( LZ_compress_restart_member( encoder, INT64_MAX ) < 0 ) break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Decompresses 'infile' to 'outfile' with automatic resynchronization to
|
||||
next member in case of data error, including the automatic removal of
|
||||
leading garbage.
|
||||
*/
|
||||
int ffrsdecompress( struct LZ_Decoder * const decoder,
|
||||
FILE * const infile, FILE * const outfile )
|
||||
{
|
||||
enum { buffer_size = 16384 };
|
||||
uint8_t buffer[buffer_size];
|
||||
while( true )
|
||||
{
|
||||
int len, ret;
|
||||
int size = min( buffer_size, LZ_decompress_write_size( decoder ) );
|
||||
if( size > 0 )
|
||||
{
|
||||
len = fread( buffer, 1, size, infile );
|
||||
ret = LZ_decompress_write( decoder, buffer, len );
|
||||
if( ret < 0 || ferror( infile ) ) break;
|
||||
if( feof( infile ) ) LZ_decompress_finish( decoder );
|
||||
}
|
||||
ret = LZ_decompress_read( decoder, buffer, buffer_size );
|
||||
if( ret < 0 )
|
||||
{
|
||||
if( LZ_decompress_errno( decoder ) == LZ_header_error ||
|
||||
LZ_decompress_errno( decoder ) == LZ_data_error )
|
||||
{ LZ_decompress_sync_to_member( decoder ); continue; }
|
||||
else break;
|
||||
}
|
||||
len = fwrite( buffer, 1, ret, outfile );
|
||||
if( len < ret ) break;
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main( const int argc, const char * const argv[] )
|
||||
{
|
||||
#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
|
||||
setmode( STDIN_FILENO, O_BINARY );
|
||||
setmode( STDOUT_FILENO, O_BINARY );
|
||||
#endif
|
||||
|
||||
struct LZ_Encoder * const encoder = LZ_compress_open( 65535, 16, INT64_MAX );
|
||||
struct LZ_Decoder * const decoder = LZ_decompress_open();
|
||||
FILE * const infile = ( argc >= 3 && strcmp( argv[2], "-" ) != 0 ) ?
|
||||
fopen( argv[2], "rb" ) : stdin;
|
||||
FILE * const outfile = ( argc >= 4 && strcmp( argv[3], "-" ) != 0 ) ?
|
||||
fopen( argv[3], "wb" ) : stdout;
|
||||
int retval;
|
||||
|
||||
if( argc < 2 || argc > 4 || strlen( argv[1] ) != 2 || argv[1][0] != '-' )
|
||||
{ show_help(); return 1; }
|
||||
if( !encoder || LZ_compress_errno( encoder ) != LZ_ok ||
|
||||
!decoder || LZ_decompress_errno( decoder ) != LZ_ok )
|
||||
{ fputs( "ffexample: Not enough memory.\n", stderr );
|
||||
LZ_compress_close( encoder ); LZ_decompress_close( decoder ); return 1; }
|
||||
if( !infile )
|
||||
{ fprintf( stderr, "ffexample: Can't open input file '%s': %s\n",
|
||||
argv[2], strerror( errno ) ); return 1; }
|
||||
if( !outfile )
|
||||
{ fprintf( stderr, "ffexample: Can't open output file '%s': %s\n",
|
||||
argv[3], strerror( errno ) ); return 1; }
|
||||
|
||||
switch( argv[1][1] )
|
||||
{
|
||||
case 'c': retval = ffcompress( encoder, infile, outfile ); break;
|
||||
case 'd': retval = ffdecompress( decoder, infile, outfile ); break;
|
||||
case 'b': retval = ffboth( encoder, decoder, infile, outfile ); break;
|
||||
case 'm': retval = ffmmcompress( infile, outfile ); break;
|
||||
case 'l': retval = fflfcompress( encoder, infile, outfile ); break;
|
||||
case 'r': retval = ffrsdecompress( decoder, infile, outfile ); break;
|
||||
default: show_help(); return ( argv[1][1] != 'h' );
|
||||
}
|
||||
|
||||
if( LZ_decompress_close( decoder ) < 0 || LZ_compress_close( encoder ) < 0 ||
|
||||
fclose( outfile ) != 0 || fclose( infile ) != 0 ) retval = 1;
|
||||
return retval;
|
||||
}
|
328
lzcheck.c
328
lzcheck.c
|
@ -1,13 +1,12 @@
|
|||
/* Lzcheck - Test program for the lzlib library
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
/* Lzcheck - Test program for the library lzlib
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you have unlimited permission
|
||||
to copy, distribute and modify it.
|
||||
to copy, distribute, and modify it.
|
||||
|
||||
Usage is:
|
||||
lzcheck filename.txt...
|
||||
Usage: lzcheck [-m|-s] filename.txt...
|
||||
|
||||
This program reads each specified text file and then compresses it,
|
||||
This program reads each text file specified and then compresses it,
|
||||
line by line, to test the flushing mechanism and the member
|
||||
restart/reset/sync functions.
|
||||
*/
|
||||
|
@ -21,21 +20,19 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "lzlib.h"
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
|
||||
const unsigned long long member_size = INT64_MAX;
|
||||
enum { buffer_size = 32768 };
|
||||
uint8_t in_buffer[buffer_size];
|
||||
uint8_t mid_buffer[buffer_size];
|
||||
uint8_t out_buffer[buffer_size];
|
||||
|
||||
|
||||
void show_line( const uint8_t * const buffer, const int size )
|
||||
static void show_line( const uint8_t * const buffer, const int size )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < size; ++i )
|
||||
|
@ -44,50 +41,147 @@ void show_line( const uint8_t * const buffer, const int size )
|
|||
}
|
||||
|
||||
|
||||
int lzcheck( FILE * const file, const int dictionary_size )
|
||||
static struct LZ_Encoder * xopen_encoder( const int dictionary_size )
|
||||
{
|
||||
const int match_len_limit = 16;
|
||||
const unsigned long long member_size = 0x7FFFFFFFFFFFFFFFULL; /* INT64_MAX */
|
||||
struct LZ_Encoder * encoder;
|
||||
struct LZ_Decoder * decoder;
|
||||
int retval = 0;
|
||||
|
||||
encoder = LZ_compress_open( dictionary_size, match_len_limit, member_size );
|
||||
struct LZ_Encoder * const encoder =
|
||||
LZ_compress_open( dictionary_size, match_len_limit, member_size );
|
||||
if( !encoder || LZ_compress_errno( encoder ) != LZ_ok )
|
||||
{
|
||||
const bool mem_error = ( LZ_compress_errno( encoder ) == LZ_mem_error );
|
||||
const bool bad_arg =
|
||||
encoder && ( LZ_compress_errno( encoder ) == LZ_bad_argument );
|
||||
LZ_compress_close( encoder );
|
||||
if( mem_error )
|
||||
if( bad_arg )
|
||||
{
|
||||
fputs( "lzcheck: Not enough memory.\n", stderr );
|
||||
return 1;
|
||||
}
|
||||
fputs( "lzcheck: internal error: Invalid argument to encoder.\n", stderr );
|
||||
return 3;
|
||||
exit( 3 );
|
||||
}
|
||||
fputs( "lzcheck: Not enough memory.\n", stderr );
|
||||
exit( 1 );
|
||||
}
|
||||
return encoder;
|
||||
}
|
||||
|
||||
decoder = LZ_decompress_open();
|
||||
static struct LZ_Decoder * xopen_decoder( void )
|
||||
{
|
||||
struct LZ_Decoder * const decoder = LZ_decompress_open();
|
||||
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok )
|
||||
{
|
||||
LZ_decompress_close( decoder );
|
||||
fputs( "lzcheck: Not enough memory.\n", stderr );
|
||||
return 1;
|
||||
exit( 1 );
|
||||
}
|
||||
return decoder;
|
||||
}
|
||||
|
||||
while( retval <= 1 )
|
||||
{
|
||||
int l, r;
|
||||
const int read_size = fread( in_buffer, 1, buffer_size, file );
|
||||
if( read_size <= 0 ) break; /* end of file */
|
||||
|
||||
for( l = 0, r = 1; r <= read_size; l = r, ++r )
|
||||
static void xclose_encoder( struct LZ_Encoder * const encoder,
|
||||
const bool finish )
|
||||
{
|
||||
if( finish )
|
||||
{
|
||||
unsigned long long size = 0;
|
||||
LZ_compress_finish( encoder );
|
||||
while( true )
|
||||
{
|
||||
const int rd = LZ_compress_read( encoder, mid_buffer, buffer_size );
|
||||
if( rd < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: xclose: LZ_compress_read error: %s\n",
|
||||
LZ_strerror( LZ_compress_errno( encoder ) ) );
|
||||
exit( 3 );
|
||||
}
|
||||
size += rd;
|
||||
if( LZ_compress_finished( encoder ) == 1 ) break;
|
||||
}
|
||||
if( size > 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: %lld bytes remain in encoder.\n", size );
|
||||
exit( 3 );
|
||||
}
|
||||
}
|
||||
if( LZ_compress_close( encoder ) < 0 ) exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
static void xclose_decoder( struct LZ_Decoder * const decoder,
|
||||
const bool finish )
|
||||
{
|
||||
if( finish )
|
||||
{
|
||||
unsigned long long size = 0;
|
||||
LZ_decompress_finish( decoder );
|
||||
while( true )
|
||||
{
|
||||
const int rd = LZ_decompress_read( decoder, out_buffer, buffer_size );
|
||||
if( rd < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: xclose: LZ_decompress_read error: %s\n",
|
||||
LZ_strerror( LZ_decompress_errno( decoder ) ) );
|
||||
exit( 3 );
|
||||
}
|
||||
size += rd;
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) break;
|
||||
}
|
||||
if( size > 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: %lld bytes remain in decoder.\n", size );
|
||||
exit( 3 );
|
||||
}
|
||||
}
|
||||
if( LZ_decompress_close( decoder ) < 0 ) exit( 1 );
|
||||
}
|
||||
|
||||
|
||||
/* Returns the next (usually newline-terminated) chunk of data from file.
|
||||
The size returned in *sizep is always <= buffer_size.
|
||||
If sizep is a null pointer, rewinds the file, resets state, and returns.
|
||||
If file is at EOF, returns an empty line. */
|
||||
static const uint8_t * next_line( FILE * const file, int * const sizep )
|
||||
{
|
||||
static int l = 0;
|
||||
static int read_size = 0;
|
||||
int r;
|
||||
|
||||
if( !sizep ) { rewind( file ); l = read_size = 0; return in_buffer; }
|
||||
if( l >= read_size )
|
||||
{
|
||||
l = 0; read_size = fread( in_buffer, 1, buffer_size, file );
|
||||
if( l >= read_size ) { *sizep = 0; return in_buffer; } /* end of file */
|
||||
}
|
||||
|
||||
for( r = l + 1; r < read_size && in_buffer[r-1] != '\n'; ++r );
|
||||
*sizep = r - l; l = r;
|
||||
return in_buffer + l - *sizep;
|
||||
}
|
||||
|
||||
|
||||
static int check_sync_flush( FILE * const file, const int dictionary_size )
|
||||
{
|
||||
struct LZ_Encoder * const encoder = xopen_encoder( dictionary_size );
|
||||
struct LZ_Decoder * const decoder = xopen_decoder();
|
||||
int retval = 0;
|
||||
|
||||
while( retval <= 1 ) /* test LZ_compress_sync_flush */
|
||||
{
|
||||
int in_size, mid_size, out_size;
|
||||
while( r < read_size && in_buffer[r-1] != '\n' ) ++r;
|
||||
in_size = LZ_compress_write( encoder, in_buffer + l, r - l );
|
||||
if( in_size < r - l ) r = l + in_size;
|
||||
int line_size;
|
||||
const uint8_t * const line_buf = next_line( file, &line_size );
|
||||
if( line_size <= 0 ) break; /* end of file */
|
||||
|
||||
in_size = LZ_compress_write( encoder, line_buf, line_size );
|
||||
if( in_size < line_size )
|
||||
fprintf( stderr, "lzcheck: sync: LZ_compress_write only accepted %d of %d bytes\n",
|
||||
in_size, line_size );
|
||||
LZ_compress_sync_flush( encoder );
|
||||
if( line_buf[0] & 1 ) /* read all data at once or byte by byte */
|
||||
mid_size = LZ_compress_read( encoder, mid_buffer, buffer_size );
|
||||
else for( mid_size = 0; mid_size < buffer_size; )
|
||||
{
|
||||
const int rd = LZ_compress_read( encoder, mid_buffer + mid_size, 1 );
|
||||
if( rd > 0 ) mid_size += rd;
|
||||
else { if( rd < 0 ) { mid_size = -1; } break; }
|
||||
}
|
||||
if( mid_size < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: LZ_compress_read error: %s\n",
|
||||
|
@ -103,118 +197,125 @@ int lzcheck( FILE * const file, const int dictionary_size )
|
|||
retval = 3; break;
|
||||
}
|
||||
|
||||
if( out_size != in_size || memcmp( in_buffer + l, out_buffer, out_size ) )
|
||||
if( out_size != in_size || memcmp( line_buf, out_buffer, out_size ) )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: Sync error at pos %d in_size = %d, "
|
||||
"out_size = %d\n",
|
||||
l, in_size, out_size );
|
||||
show_line( in_buffer + l, in_size );
|
||||
fprintf( stderr, "lzcheck: LZ_compress_sync_flush error: "
|
||||
"in_size = %d, out_size = %d\n", in_size, out_size );
|
||||
show_line( line_buf, in_size );
|
||||
show_line( out_buffer, out_size );
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( retval <= 1 )
|
||||
{
|
||||
rewind( file );
|
||||
int rd = 0;
|
||||
if( LZ_compress_finish( encoder ) < 0 ||
|
||||
LZ_compress_finish( encoder ) < 0 ||
|
||||
LZ_decompress_write( decoder, mid_buffer,
|
||||
LZ_compress_read( encoder, mid_buffer, buffer_size ) ) < 0 ||
|
||||
LZ_decompress_read( decoder, out_buffer, buffer_size ) != 0 ||
|
||||
LZ_compress_finish( encoder ) < 0 ||
|
||||
LZ_compress_restart_member( encoder, member_size ) < 0 )
|
||||
( rd = LZ_compress_read( encoder, mid_buffer, buffer_size ) ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: Can't finish member: %s\n",
|
||||
LZ_strerror( LZ_decompress_errno( decoder ) ) );
|
||||
fprintf( stderr, "lzcheck: Can't drain encoder: %s\n",
|
||||
LZ_strerror( LZ_compress_errno( encoder ) ) );
|
||||
retval = 3;
|
||||
}
|
||||
LZ_decompress_write( decoder, mid_buffer, rd );
|
||||
}
|
||||
|
||||
while( retval <= 1 )
|
||||
{
|
||||
int l, r, size;
|
||||
const int read_size = fread( in_buffer, 1, buffer_size / 2, file );
|
||||
if( read_size <= 0 ) break; /* end of file */
|
||||
xclose_decoder( decoder, retval == 0 );
|
||||
xclose_encoder( encoder, retval == 0 );
|
||||
return retval;
|
||||
}
|
||||
|
||||
for( l = 0, r = 1; r <= read_size; l = r, ++r )
|
||||
|
||||
/* Test member by member decompression without calling LZ_decompress_finish,
|
||||
inserting leading garbage before some members, and resetting the
|
||||
decompressor sometimes. Test that the increase in total_in_size when
|
||||
syncing to member is equal to the size of the leading garbage skipped.
|
||||
*/
|
||||
static int check_members( FILE * const file, const int dictionary_size )
|
||||
{
|
||||
struct LZ_Encoder * const encoder = xopen_encoder( dictionary_size );
|
||||
struct LZ_Decoder * const decoder = xopen_decoder();
|
||||
int retval = 0;
|
||||
|
||||
while( retval <= 1 ) /* test LZ_compress_restart_member */
|
||||
{
|
||||
unsigned long long garbage_begin = 0; /* avoid warning from gcc 3.3.6 */
|
||||
int leading_garbage, in_size, mid_size, out_size;
|
||||
while( r < read_size && in_buffer[r-1] != '\n' ) ++r;
|
||||
leading_garbage = (l == 0) ? min( r, read_size ) / 2 : 0;
|
||||
in_size = LZ_compress_write( encoder, in_buffer + l, r - l );
|
||||
if( in_size < r - l ) r = l + in_size;
|
||||
LZ_compress_sync_flush( encoder );
|
||||
if( leading_garbage )
|
||||
int line_size;
|
||||
const uint8_t * const line_buf = next_line( file, &line_size );
|
||||
if( line_size <= 0 && /* end of file, write at least 1 member */
|
||||
LZ_decompress_total_in_size( decoder ) != 0 ) break;
|
||||
|
||||
if( LZ_compress_finished( encoder ) == 1 )
|
||||
{
|
||||
if( LZ_compress_restart_member( encoder, member_size ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: Can't restart member: %s\n",
|
||||
LZ_strerror( LZ_compress_errno( encoder ) ) );
|
||||
retval = 3; break;
|
||||
}
|
||||
if( line_size >= 2 && line_buf[1] == 'h' )
|
||||
LZ_decompress_reset( decoder );
|
||||
}
|
||||
in_size = LZ_compress_write( encoder, line_buf, line_size );
|
||||
if( in_size < line_size )
|
||||
fprintf( stderr, "lzcheck: member: LZ_compress_write only accepted %d of %d bytes\n",
|
||||
in_size, line_size );
|
||||
LZ_compress_finish( encoder );
|
||||
if( line_size * 3 < buffer_size && line_buf[0] == 't' )
|
||||
{ leading_garbage = line_size;
|
||||
memset( mid_buffer, in_buffer[0], leading_garbage );
|
||||
garbage_begin = LZ_decompress_total_in_size( decoder ); }
|
||||
else leading_garbage = 0;
|
||||
mid_size = LZ_compress_read( encoder, mid_buffer + leading_garbage,
|
||||
buffer_size - leading_garbage );
|
||||
if( mid_size < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: LZ_compress_read error: %s\n",
|
||||
fprintf( stderr, "lzcheck: member: LZ_compress_read error: %s\n",
|
||||
LZ_strerror( LZ_compress_errno( encoder ) ) );
|
||||
retval = 3; break;
|
||||
}
|
||||
LZ_decompress_write( decoder, mid_buffer, mid_size + leading_garbage );
|
||||
LZ_decompress_write( decoder, mid_buffer, leading_garbage + mid_size );
|
||||
out_size = LZ_decompress_read( decoder, out_buffer, buffer_size );
|
||||
if( out_size < 0 )
|
||||
{
|
||||
if( LZ_decompress_errno( decoder ) == LZ_header_error ||
|
||||
LZ_decompress_errno( decoder ) == LZ_data_error )
|
||||
if( leading_garbage &&
|
||||
( LZ_decompress_errno( decoder ) == LZ_header_error ||
|
||||
LZ_decompress_errno( decoder ) == LZ_data_error ) )
|
||||
{
|
||||
LZ_decompress_sync_to_member( decoder ); /* remove leading garbage */
|
||||
LZ_decompress_sync_to_member( decoder ); /* skip leading garbage */
|
||||
const unsigned long long garbage_end =
|
||||
LZ_decompress_total_in_size( decoder );
|
||||
if( garbage_end - garbage_begin != (unsigned)leading_garbage )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: member: LZ_decompress_sync_to_member error:\n"
|
||||
" garbage_begin = %llu garbage_end = %llu "
|
||||
"difference = %llu expected = %d\n", garbage_begin,
|
||||
garbage_end, garbage_end - garbage_begin, leading_garbage );
|
||||
retval = 3; break;
|
||||
}
|
||||
out_size = LZ_decompress_read( decoder, out_buffer, buffer_size );
|
||||
}
|
||||
if( out_size < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: LZ_decompress_read error: %s\n",
|
||||
fprintf( stderr, "lzcheck: member: LZ_decompress_read error: %s\n",
|
||||
LZ_strerror( LZ_decompress_errno( decoder ) ) );
|
||||
retval = 3; break;
|
||||
}
|
||||
}
|
||||
|
||||
if( out_size != in_size || memcmp( in_buffer + l, out_buffer, out_size ) )
|
||||
if( out_size != in_size || memcmp( line_buf, out_buffer, out_size ) )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: Sync error at pos %d in_size = %d, "
|
||||
"out_size = %d, leading garbage = %d\n",
|
||||
l, in_size, out_size, leading_garbage );
|
||||
show_line( in_buffer + l, in_size );
|
||||
fprintf( stderr, "lzcheck: LZ_compress_restart_member error: "
|
||||
"in_size = %d, out_size = %d\n", in_size, out_size );
|
||||
show_line( line_buf, in_size );
|
||||
show_line( out_buffer, out_size );
|
||||
retval = 1;
|
||||
}
|
||||
}
|
||||
if( retval >= 3 ) break;
|
||||
|
||||
if( LZ_compress_finish( encoder ) < 0 ||
|
||||
LZ_decompress_write( decoder, mid_buffer,
|
||||
LZ_compress_read( encoder, mid_buffer, buffer_size ) ) < 0 ||
|
||||
LZ_decompress_read( decoder, out_buffer, buffer_size ) != 0 ||
|
||||
LZ_decompress_reset( decoder ) < 0 ||
|
||||
LZ_compress_restart_member( encoder, member_size ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: Can't restart member: %s\n",
|
||||
LZ_strerror( LZ_decompress_errno( decoder ) ) );
|
||||
retval = 3; break;
|
||||
}
|
||||
|
||||
size = min( 100, read_size );
|
||||
if( LZ_compress_write( encoder, in_buffer, size ) != size ||
|
||||
LZ_compress_finish( encoder ) < 0 ||
|
||||
LZ_decompress_write( decoder, mid_buffer,
|
||||
LZ_compress_read( encoder, mid_buffer, buffer_size ) ) < 0 ||
|
||||
LZ_decompress_read( decoder, out_buffer, 0 ) != 0 ||
|
||||
LZ_decompress_sync_to_member( decoder ) < 0 ||
|
||||
LZ_compress_restart_member( encoder, member_size ) < 0 )
|
||||
{
|
||||
fprintf( stderr, "lzcheck: Can't seek to next member: %s\n",
|
||||
LZ_strerror( LZ_decompress_errno( decoder ) ) );
|
||||
retval = 3; break;
|
||||
}
|
||||
}
|
||||
|
||||
LZ_decompress_close( decoder );
|
||||
LZ_compress_close( encoder );
|
||||
xclose_decoder( decoder, retval == 0 );
|
||||
xclose_encoder( encoder, retval == 0 );
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -223,7 +324,11 @@ int main( const int argc, const char * const argv[] )
|
|||
{
|
||||
int retval = 0, i;
|
||||
int open_failures = 0;
|
||||
const bool verbose = ( argc > 2 );
|
||||
const char opt = ( argc > 2 &&
|
||||
( strcmp( argv[1], "-m" ) == 0 || strcmp( argv[1], "-s" ) == 0 ) ) ?
|
||||
argv[1][1] : 0;
|
||||
const int first = opt ? 2 : 1;
|
||||
const bool verbose = ( opt != 0 || argc > first + 1 );
|
||||
|
||||
if( argc < 2 )
|
||||
{
|
||||
|
@ -231,8 +336,10 @@ int main( const int argc, const char * const argv[] )
|
|||
return 1;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc && retval == 0; ++ i )
|
||||
for( i = first; i < argc && retval == 0; ++i )
|
||||
{
|
||||
struct stat st;
|
||||
if( stat( argv[i], &st ) != 0 || !S_ISREG( st.st_mode ) ) continue;
|
||||
FILE * file = fopen( argv[i], "rb" );
|
||||
if( !file )
|
||||
{
|
||||
|
@ -241,9 +348,14 @@ int main( const int argc, const char * const argv[] )
|
|||
}
|
||||
if( verbose ) fprintf( stderr, " Testing file '%s'\n", argv[i] );
|
||||
|
||||
retval = lzcheck( file, 65535 ); /* 65535,16 chooses fast encoder */
|
||||
if( retval == 0 )
|
||||
{ rewind( file ); retval = lzcheck( file, 1 << 20 ); }
|
||||
/* 65535,16 chooses fast encoder */
|
||||
if( opt != 'm' ) retval = check_sync_flush( file, 65535 );
|
||||
if( retval == 0 && opt != 'm' )
|
||||
{ next_line( file, 0 ); retval = check_sync_flush( file, 1 << 20 ); }
|
||||
if( retval == 0 && opt != 's' )
|
||||
{ next_line( file, 0 ); retval = check_members( file, 65535 ); }
|
||||
if( retval == 0 && opt != 's' )
|
||||
{ next_line( file, 0 ); retval = check_members( file, 1 << 20 ); }
|
||||
fclose( file );
|
||||
}
|
||||
if( open_failures > 0 && verbose )
|
||||
|
|
15
lzip.h
15
lzip.h
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -83,7 +83,7 @@ static inline int get_len_state( const int len )
|
|||
{ return min( len - min_match_len, len_states - 1 ); }
|
||||
|
||||
static inline int get_lit_state( const uint8_t prev_byte )
|
||||
{ return ( prev_byte >> ( 8 - literal_context_bits ) ); }
|
||||
{ return prev_byte >> ( 8 - literal_context_bits ); }
|
||||
|
||||
|
||||
enum { bit_model_move_bits = 5,
|
||||
|
@ -197,7 +197,7 @@ static const uint8_t lzip_magic[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
|
|||
|
||||
typedef uint8_t Lzip_header[6]; /* 0-3 magic bytes */
|
||||
/* 4 version */
|
||||
/* 5 coded_dict_size */
|
||||
/* 5 coded dictionary size */
|
||||
enum { Lh_size = 6 };
|
||||
|
||||
static inline void Lh_set_magic( Lzip_header data )
|
||||
|
@ -255,9 +255,8 @@ static inline bool Lh_set_dictionary_size( Lzip_header data, const unsigned sz )
|
|||
|
||||
static inline bool Lh_verify( const Lzip_header data )
|
||||
{
|
||||
if( Lh_verify_magic( data ) && Lh_verify_version( data ) )
|
||||
return isvalid_ds( Lh_get_dictionary_size( data ) );
|
||||
return false;
|
||||
return Lh_verify_magic( data ) && Lh_verify_version( data ) &&
|
||||
isvalid_ds( Lh_get_dictionary_size( data ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
42
lzlib.c
42
lzlib.c
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -107,8 +107,9 @@ static bool verify_decoder( struct LZ_Decoder * const d )
|
|||
|
||||
/* ------------------------- Misc Functions ------------------------- */
|
||||
|
||||
const char * LZ_version( void ) { return LZ_version_string; }
|
||||
int LZ_api_version( void ) { return LZ_API_VERSION; }
|
||||
|
||||
const char * LZ_version( void ) { return LZ_version_string; }
|
||||
|
||||
const char * LZ_strerror( const enum LZ_Errno lz_errno )
|
||||
{
|
||||
|
@ -135,7 +136,7 @@ int LZ_min_match_len_limit( void ) { return min_match_len_limit; }
|
|||
int LZ_max_match_len_limit( void ) { return max_match_len; }
|
||||
|
||||
|
||||
/*---------------------- Compression Functions ----------------------*/
|
||||
/* --------------------- Compression Functions --------------------- */
|
||||
|
||||
struct LZ_Encoder * LZ_compress_open( const int dictionary_size,
|
||||
const int match_len_limit,
|
||||
|
@ -226,8 +227,8 @@ int LZ_compress_restart_member( struct LZ_Encoder * const e,
|
|||
int LZ_compress_sync_flush( struct LZ_Encoder * const e )
|
||||
{
|
||||
if( !verify_encoder( e ) || e->fatal ) return -1;
|
||||
if( !Mb_flushing_or_end( &e->lz_encoder_base->mb ) )
|
||||
e->lz_encoder_base->mb.flushing = true;
|
||||
if( !e->lz_encoder_base->mb.at_stream_end )
|
||||
e->lz_encoder_base->mb.sync_flush_pending = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -235,24 +236,22 @@ int LZ_compress_sync_flush( struct LZ_Encoder * const e )
|
|||
int LZ_compress_read( struct LZ_Encoder * const e,
|
||||
uint8_t * const buffer, const int size )
|
||||
{
|
||||
int out_size = 0;
|
||||
if( !verify_encoder( e ) || e->fatal ) return -1;
|
||||
if( size < 0 ) return 0;
|
||||
do {
|
||||
|
||||
{ struct LZ_encoder_base * const eb = e->lz_encoder_base;
|
||||
int out_size = Re_read_data( &eb->renc, buffer, size );
|
||||
/* minimize number of calls to encode_member */
|
||||
if( out_size < size || size == 0 )
|
||||
{
|
||||
if( ( e->flz_encoder && !FLZe_encode_member( e->flz_encoder ) ) ||
|
||||
( e->lz_encoder && !LZe_encode_member( e->lz_encoder ) ) )
|
||||
{ e->lz_errno = LZ_library_error; e->fatal = true; return -1; }
|
||||
if( e->lz_encoder_base->mb.flushing &&
|
||||
Mb_available_bytes( &e->lz_encoder_base->mb ) <= 0 &&
|
||||
LZeb_sync_flush( e->lz_encoder_base ) )
|
||||
e->lz_encoder_base->mb.flushing = false;
|
||||
out_size += Re_read_data( &e->lz_encoder_base->renc,
|
||||
buffer + out_size, size - out_size );
|
||||
if( eb->mb.sync_flush_pending && Mb_available_bytes( &eb->mb ) <= 0 )
|
||||
LZeb_try_sync_flush( eb );
|
||||
out_size += Re_read_data( &eb->renc, buffer + out_size, size - out_size );
|
||||
}
|
||||
while( e->lz_encoder_base->mb.flushing && out_size < size &&
|
||||
Mb_enough_available_bytes( &e->lz_encoder_base->mb ) &&
|
||||
Re_enough_free_bytes( &e->lz_encoder_base->renc ) );
|
||||
return out_size;
|
||||
return out_size; }
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,7 +320,7 @@ unsigned long long LZ_compress_total_out_size( struct LZ_Encoder * const e )
|
|||
}
|
||||
|
||||
|
||||
/*--------------------- Decompression Functions ---------------------*/
|
||||
/* -------------------- Decompression Functions -------------------- */
|
||||
|
||||
struct LZ_Decoder * LZ_decompress_open( void )
|
||||
{
|
||||
|
@ -401,10 +400,11 @@ int LZ_decompress_read( struct LZ_Decoder * const d,
|
|||
{
|
||||
int result;
|
||||
if( !verify_decoder( d ) ) return -1;
|
||||
if( size < 0 ) return 0;
|
||||
if( d->fatal ) /* don't return error until pending bytes are read */
|
||||
{ if( d->lz_decoder && !Cb_empty( &d->lz_decoder->cb ) ) goto get_data;
|
||||
return -1; }
|
||||
if( d->seeking || size < 0 ) return 0;
|
||||
if( d->seeking ) return 0;
|
||||
|
||||
if( d->lz_decoder && LZd_member_finished( d->lz_decoder ) )
|
||||
{
|
||||
|
|
18
lzlib.h
18
lzlib.h
|
@ -1,15 +1,15 @@
|
|||
/* Lzlib - Compression library for the lzip format
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
|
@ -21,15 +21,19 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LZ_API_VERSION 1
|
||||
/* LZ_API_VERSION was first defined in lzlib 1.8 to 1.
|
||||
Since lzlib 1.12, LZ_API_VERSION is defined as (major * 1000 + minor). */
|
||||
|
||||
static const char * const LZ_version_string = "1.11";
|
||||
#define LZ_API_VERSION 1012
|
||||
|
||||
static const char * const LZ_version_string = "1.12";
|
||||
|
||||
enum LZ_Errno { LZ_ok = 0, LZ_bad_argument, LZ_mem_error,
|
||||
LZ_sequence_error, LZ_header_error, LZ_unexpected_eof,
|
||||
LZ_data_error, LZ_library_error };
|
||||
|
||||
|
||||
int LZ_api_version( void ); /* new in 1.12 */
|
||||
const char * LZ_version( void );
|
||||
const char * LZ_strerror( const enum LZ_Errno lz_errno );
|
||||
|
||||
|
@ -41,7 +45,7 @@ int LZ_min_match_len_limit( void );
|
|||
int LZ_max_match_len_limit( void );
|
||||
|
||||
|
||||
/*---------------------- Compression Functions ----------------------*/
|
||||
/* --------------------- Compression Functions --------------------- */
|
||||
|
||||
struct LZ_Encoder;
|
||||
|
||||
|
@ -71,7 +75,7 @@ unsigned long long LZ_compress_total_in_size( struct LZ_Encoder * const encoder
|
|||
unsigned long long LZ_compress_total_out_size( struct LZ_Encoder * const encoder );
|
||||
|
||||
|
||||
/*--------------------- Decompression Functions ---------------------*/
|
||||
/* -------------------- Decompression Functions -------------------- */
|
||||
|
||||
struct LZ_Decoder;
|
||||
|
||||
|
|
360
main.c
360
main.c
|
@ -1,5 +1,5 @@
|
|||
/* Minilzip - Test program for the lzlib library
|
||||
Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
/* Minilzip - Test program for the library lzlib
|
||||
Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -74,19 +74,21 @@
|
|||
#define min(x,y) ((x) <= (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
void cleanup_and_fail( const int retval );
|
||||
void show_error( const char * const msg, const int errcode, const bool help );
|
||||
void show_file_error( const char * const filename, const char * const msg,
|
||||
const int errcode );
|
||||
void internal_error( const char * const msg );
|
||||
static void cleanup_and_fail( const int retval );
|
||||
static void show_error( const char * const msg, const int errcode,
|
||||
const bool help );
|
||||
static void show_file_error( const char * const filename,
|
||||
const char * const msg, const int errcode );
|
||||
static void internal_error( const char * const msg );
|
||||
static const char * const mem_msg = "Not enough memory.";
|
||||
|
||||
int verbosity = 0;
|
||||
|
||||
const char * const program_name = "minilzip";
|
||||
const char * const program_year = "2019";
|
||||
const char * invocation_name = 0;
|
||||
static const char * const program_name = "minilzip";
|
||||
static const char * const program_year = "2021";
|
||||
static const char * invocation_name = "minilzip"; /* default value */
|
||||
|
||||
const struct { const char * from; const char * to; } known_extensions[] = {
|
||||
static const struct { const char * from; const char * to; } known_extensions[] = {
|
||||
{ ".lz", "" },
|
||||
{ ".tlz", ".tar" },
|
||||
{ 0, 0 } };
|
||||
|
@ -101,15 +103,24 @@ enum Mode { m_compress, m_decompress, m_test };
|
|||
|
||||
/* Variables used in signal handler context.
|
||||
They are not declared volatile because the handler never returns. */
|
||||
char * output_filename = 0;
|
||||
int outfd = -1;
|
||||
bool delete_output_on_interrupt = false;
|
||||
static char * output_filename = 0;
|
||||
static int outfd = -1;
|
||||
static bool delete_output_on_interrupt = false;
|
||||
|
||||
|
||||
static void show_help( void )
|
||||
{
|
||||
printf( "Minilzip is a test program for the lzlib compression library, fully\n"
|
||||
printf( "Minilzip is a test program for the compression library lzlib, fully\n"
|
||||
"compatible with lzip 1.4 or newer.\n"
|
||||
"\nLzip is a lossless data compressor with a user interface similar to the one\n"
|
||||
"of gzip or bzip2. Lzip uses a simplified form of the 'Lempel-Ziv-Markov\n"
|
||||
"chain-Algorithm' (LZMA) stream format, chosen to maximize safety and\n"
|
||||
"interoperability. Lzip can compress about as fast as gzip (lzip -0) or\n"
|
||||
"compress most files more than bzip2 (lzip -9). Decompression speed is\n"
|
||||
"intermediate between gzip and bzip2. Lzip is better than gzip and bzip2 from\n"
|
||||
"a data recovery perspective. Lzip has been designed, written, and tested\n"
|
||||
"with great care to replace gzip and bzip2 as the standard general-purpose\n"
|
||||
"compressed format for unix-like systems.\n"
|
||||
"\nUsage: %s [options] [files]\n", invocation_name );
|
||||
printf( "\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
|
@ -122,7 +133,7 @@ static void show_help( void )
|
|||
" -F, --recompress force re-compression of compressed files\n"
|
||||
" -k, --keep keep (don't delete) input files\n"
|
||||
" -m, --match-length=<bytes> set match length limit in bytes [36]\n"
|
||||
" -o, --output=<file> if reading standard input, write to <file>\n"
|
||||
" -o, --output=<file> write to <file>, keep input files\n"
|
||||
" -q, --quiet suppress all messages\n"
|
||||
" -s, --dictionary-size=<bytes> set dictionary size limit in bytes [8 MiB]\n"
|
||||
" -S, --volume-size=<bytes> set volume size limit in bytes\n"
|
||||
|
@ -132,7 +143,8 @@ static void show_help( void )
|
|||
" --fast alias for -0\n"
|
||||
" --best alias for -9\n"
|
||||
" --loose-trailing allow trailing data seeming corrupt header\n"
|
||||
"If no file names are given, or if a file is '-', minilzip compresses or\n"
|
||||
" --check-lib compare version of lzlib.h with liblz.{a,so}\n"
|
||||
"\nIf no file names are given, or if a file is '-', minilzip compresses or\n"
|
||||
"decompresses from standard input to standard output.\n"
|
||||
"Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,\n"
|
||||
"Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...\n"
|
||||
|
@ -140,12 +152,19 @@ static void show_help( void )
|
|||
"to 2^29 bytes.\n"
|
||||
"\nThe bidimensional parameter space of LZMA can't be mapped to a linear\n"
|
||||
"scale optimal for all files. If your files are large, very repetitive,\n"
|
||||
"etc, you may need to use the --dictionary-size and --match-length\n"
|
||||
"options directly to achieve optimal performance.\n"
|
||||
"etc, you may need to use the options --dictionary-size and --match-length\n"
|
||||
"directly to achieve optimal performance.\n"
|
||||
"\nTo extract all the files from archive 'foo.tar.lz', use the commands\n"
|
||||
"'tar -xf foo.tar.lz' or 'minilzip -cd foo.tar.lz | tar -xf -'.\n"
|
||||
"\nExit status: 0 for a normal exit, 1 for environmental problems (file\n"
|
||||
"not found, invalid flags, I/O errors, etc), 2 to indicate a corrupt or\n"
|
||||
"invalid input file, 3 for an internal consistency error (eg, bug) which\n"
|
||||
"caused minilzip to panic.\n"
|
||||
"\nThe ideas embodied in lzlib are due to (at least) the following people:\n"
|
||||
"Abraham Lempel and Jacob Ziv (for the LZ algorithm), Andrey Markov (for the\n"
|
||||
"definition of Markov chains), G.N.N. Martin (for the definition of range\n"
|
||||
"encoding), Igor Pavlov (for putting all the above together in LZMA), and\n"
|
||||
"Julian Seward (for bzip2's CLI).\n"
|
||||
"\nReport bugs to lzip-bug@nongnu.org\n"
|
||||
"Lzlib home page: http://www.nongnu.org/lzip/lzlib.html\n" );
|
||||
}
|
||||
|
@ -162,16 +181,43 @@ static void show_version( void )
|
|||
}
|
||||
|
||||
|
||||
int check_lib()
|
||||
{
|
||||
bool warning = false;
|
||||
if( strcmp( LZ_version_string, LZ_version() ) != 0 )
|
||||
{ warning = true;
|
||||
if( verbosity >= 0 )
|
||||
printf( "warning: LZ_version_string != LZ_version() (%s vs %s)\n",
|
||||
LZ_version_string, LZ_version() ); }
|
||||
#if defined LZ_API_VERSION && LZ_API_VERSION >= 1012
|
||||
if( LZ_API_VERSION != LZ_api_version() )
|
||||
{ warning = true;
|
||||
if( verbosity >= 0 )
|
||||
printf( "warning: LZ_API_VERSION != LZ_api_version() (%u vs %u)\n",
|
||||
LZ_API_VERSION, LZ_api_version() ); }
|
||||
#endif
|
||||
if( verbosity >= 1 )
|
||||
{
|
||||
printf( "Using lzlib %s\n", LZ_version() );
|
||||
#if !defined LZ_API_VERSION
|
||||
fputs( "LZ_API_VERSION is not defined.\n", stdout );
|
||||
#elif LZ_API_VERSION >= 1012
|
||||
printf( "Using LZ_API_VERSION = %u\n", LZ_api_version() );
|
||||
#else
|
||||
printf( "Compiled with LZ_API_VERSION = %u. "
|
||||
"Using an unknown LZ_API_VERSION\n", LZ_API_VERSION );
|
||||
#endif
|
||||
}
|
||||
return warning;
|
||||
}
|
||||
|
||||
|
||||
/* assure at least a minimum size for buffer 'buf' */
|
||||
static void * resize_buffer( void * buf, const unsigned min_size )
|
||||
{
|
||||
if( buf ) buf = realloc( buf, min_size );
|
||||
else buf = malloc( min_size );
|
||||
if( !buf )
|
||||
{
|
||||
show_error( "Not enough memory.", 0, false );
|
||||
cleanup_and_fail( 1 );
|
||||
}
|
||||
if( !buf ) { show_error( mem_msg, 0, false ); cleanup_and_fail( 1 ); }
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -186,8 +232,7 @@ struct Pretty_print
|
|||
};
|
||||
|
||||
static void Pp_init( struct Pretty_print * const pp,
|
||||
const char * const filenames[],
|
||||
const int num_filenames )
|
||||
const char * const filenames[], const int num_filenames )
|
||||
{
|
||||
unsigned stdin_name_len;
|
||||
int i;
|
||||
|
@ -208,7 +253,7 @@ static void Pp_init( struct Pretty_print * const pp,
|
|||
if( pp->longest_name == 0 ) pp->longest_name = stdin_name_len;
|
||||
}
|
||||
|
||||
static inline void Pp_set_name( struct Pretty_print * const pp,
|
||||
static void Pp_set_name( struct Pretty_print * const pp,
|
||||
const char * const filename )
|
||||
{
|
||||
unsigned name_len, padded_name_len, i = 0;
|
||||
|
@ -227,7 +272,7 @@ static inline void Pp_set_name( struct Pretty_print * const pp,
|
|||
pp->first_post = true;
|
||||
}
|
||||
|
||||
static inline void Pp_reset( struct Pretty_print * const pp )
|
||||
static void Pp_reset( struct Pretty_print * const pp )
|
||||
{ if( pp->name && pp->name[0] ) pp->first_post = true; }
|
||||
|
||||
static void Pp_show_msg( struct Pretty_print * const pp, const char * const msg )
|
||||
|
@ -258,7 +303,7 @@ static void show_header( const unsigned dictionary_size )
|
|||
int i; for( i = 0; i < 8 && ( num > 9999 || ( exact && num >= factor ) ); ++i )
|
||||
{ num /= factor; if( num % factor != 0 ) exact = false;
|
||||
p = prefix[i]; np = ""; }
|
||||
fprintf( stderr, "dictionary %s%4u %sB, ", np, num, p );
|
||||
fprintf( stderr, "dict %s%4u %sB, ", np, num, p );
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,7 +366,7 @@ static int get_dict_size( const char * const arg )
|
|||
const long bits = strtol( arg, &tail, 0 );
|
||||
if( bits >= LZ_min_dictionary_bits() &&
|
||||
bits <= LZ_max_dictionary_bits() && *tail == 0 )
|
||||
return ( 1 << bits );
|
||||
return 1 << bits;
|
||||
dictionary_size = getnum( arg, LZ_min_dictionary_size(),
|
||||
LZ_max_dictionary_size() );
|
||||
if( dictionary_size == 65535 ) ++dictionary_size; /* no fast encoder */
|
||||
|
@ -329,7 +374,7 @@ static int get_dict_size( const char * const arg )
|
|||
}
|
||||
|
||||
|
||||
void set_mode( enum Mode * const program_modep, const enum Mode new_mode )
|
||||
static void set_mode( enum Mode * const program_modep, const enum Mode new_mode )
|
||||
{
|
||||
if( *program_modep != m_compress && *program_modep != new_mode )
|
||||
{
|
||||
|
@ -363,7 +408,7 @@ static void set_c_outname( const char * const name, const bool force_ext,
|
|||
strlen( known_extensions[0].from ) + 1 );
|
||||
strcpy( output_filename, name );
|
||||
if( multifile ) strcat( output_filename, "00001" );
|
||||
if( force_ext || multifile || extension_index( output_filename ) < 0 )
|
||||
if( force_ext || multifile )
|
||||
strcat( output_filename, known_extensions[0].from );
|
||||
}
|
||||
|
||||
|
@ -395,7 +440,7 @@ static void set_d_outname( const char * const name, const int eindex )
|
|||
|
||||
static int open_instream( const char * const name, struct stat * const in_statsp,
|
||||
const enum Mode program_mode, const int eindex,
|
||||
const bool recompress, const bool to_stdout )
|
||||
const bool one_to_one, const bool recompress )
|
||||
{
|
||||
int infd = -1;
|
||||
if( program_mode == m_compress && !recompress && eindex >= 0 )
|
||||
|
@ -416,14 +461,12 @@ static int open_instream( const char * const name, struct stat * const in_statsp
|
|||
const bool can_read = ( i == 0 &&
|
||||
( S_ISBLK( mode ) || S_ISCHR( mode ) ||
|
||||
S_ISFIFO( mode ) || S_ISSOCK( mode ) ) );
|
||||
const bool no_ofile = ( to_stdout || program_mode == m_test );
|
||||
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || !no_ofile ) ) )
|
||||
if( i != 0 || ( !S_ISREG( mode ) && ( !can_read || one_to_one ) ) )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
fprintf( stderr, "%s: Input file '%s' is not a regular file%s.\n",
|
||||
program_name, name,
|
||||
( can_read && !no_ofile ) ?
|
||||
",\n and '--stdout' was not specified" : "" );
|
||||
program_name, name, ( can_read && one_to_one ) ?
|
||||
",\n and neither '-c' nor '-o' were specified" : "" );
|
||||
close( infd );
|
||||
infd = -1;
|
||||
}
|
||||
|
@ -433,11 +476,11 @@ static int open_instream( const char * const name, struct stat * const in_statsp
|
|||
}
|
||||
|
||||
|
||||
static bool open_outstream( const bool force, const bool from_stdin )
|
||||
static bool open_outstream( const bool force, const bool protect )
|
||||
{
|
||||
const mode_t usr_rw = S_IRUSR | S_IWUSR;
|
||||
const mode_t all_rw = usr_rw | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
const mode_t outfd_mode = from_stdin ? all_rw : usr_rw;
|
||||
const mode_t outfd_mode = protect ? usr_rw : all_rw;
|
||||
int flags = O_CREAT | O_WRONLY | O_BINARY;
|
||||
if( force ) flags |= O_TRUNC; else flags |= O_EXCL;
|
||||
|
||||
|
@ -456,25 +499,6 @@ static bool open_outstream( const bool force, const bool from_stdin )
|
|||
}
|
||||
|
||||
|
||||
static bool check_tty( const char * const input_filename, const int infd,
|
||||
const enum Mode program_mode )
|
||||
{
|
||||
if( program_mode == m_compress && isatty( outfd ) )
|
||||
{
|
||||
show_error( "I won't write compressed data to a terminal.", 0, true );
|
||||
return false;
|
||||
}
|
||||
if( ( program_mode == m_decompress || program_mode == m_test ) &&
|
||||
isatty( infd ) )
|
||||
{
|
||||
show_file_error( input_filename,
|
||||
"I won't read compressed data from a terminal.", 0 );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void set_signals( void (*action)(int) )
|
||||
{
|
||||
signal( SIGHUP, action );
|
||||
|
@ -483,7 +507,7 @@ static void set_signals( void (*action)(int) )
|
|||
}
|
||||
|
||||
|
||||
void cleanup_and_fail( const int retval )
|
||||
static void cleanup_and_fail( const int retval )
|
||||
{
|
||||
set_signals( SIG_IGN ); /* ignore signals */
|
||||
if( delete_output_on_interrupt )
|
||||
|
@ -500,7 +524,7 @@ void cleanup_and_fail( const int retval )
|
|||
}
|
||||
|
||||
|
||||
void signal_handler( int sig )
|
||||
static void signal_handler( int sig )
|
||||
{
|
||||
if( sig ) {} /* keep compiler happy */
|
||||
show_error( "Control-C or similar caught, quitting.", 0, false );
|
||||
|
@ -508,7 +532,35 @@ void signal_handler( int sig )
|
|||
}
|
||||
|
||||
|
||||
/* Set permissions, owner and times. */
|
||||
static inline void set_retval( int * retval, const int new_val )
|
||||
{ if( *retval < new_val ) *retval = new_val; }
|
||||
|
||||
|
||||
static bool check_tty_in( const char * const input_filename, const int infd,
|
||||
const enum Mode program_mode, int * const retval )
|
||||
{
|
||||
if( ( program_mode == m_decompress || program_mode == m_test ) &&
|
||||
isatty( infd ) ) /* for example /dev/tty */
|
||||
{ show_file_error( input_filename,
|
||||
"I won't read compressed data from a terminal.", 0 );
|
||||
close( infd ); set_retval( retval, 1 );
|
||||
if( program_mode != m_test ) cleanup_and_fail( *retval );
|
||||
return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool check_tty_out( const enum Mode program_mode )
|
||||
{
|
||||
if( program_mode == m_compress && isatty( outfd ) )
|
||||
{ show_file_error( output_filename[0] ?
|
||||
output_filename : "(stdout)",
|
||||
"I won't write compressed data to a terminal.", 0 );
|
||||
return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Set permissions, owner, and times. */
|
||||
static void close_and_set_permissions( const struct stat * const in_statsp )
|
||||
{
|
||||
bool warning = false;
|
||||
|
@ -602,7 +654,7 @@ static int do_compress( struct LZ_Encoder * const encoder,
|
|||
{
|
||||
unsigned long long partial_volume_size = 0;
|
||||
enum { buffer_size = 65536 };
|
||||
uint8_t buffer[buffer_size];
|
||||
uint8_t buffer[buffer_size]; /* read/write buffer */
|
||||
if( verbosity >= 1 ) Pp_show_msg( pp, 0 );
|
||||
|
||||
while( true )
|
||||
|
@ -658,7 +710,7 @@ static int do_compress( struct LZ_Encoder * const encoder,
|
|||
close_and_set_permissions( in_statsp );
|
||||
if( !next_filename() )
|
||||
{ Pp_show_msg( pp, "Too many volume files." ); return 1; }
|
||||
if( !open_outstream( true, !in_statsp ) ) return 1;
|
||||
if( !open_outstream( true, in_statsp ) ) return 1;
|
||||
}
|
||||
}
|
||||
size = min( member_size, volume_size - partial_volume_size );
|
||||
|
@ -726,7 +778,8 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
|
|||
const bool loose_trailing, const bool testing )
|
||||
{
|
||||
enum { buffer_size = 65536 };
|
||||
uint8_t buffer[buffer_size];
|
||||
uint8_t buffer[buffer_size]; /* read/write buffer */
|
||||
unsigned long long total_in = 0; /* to detect library stall */
|
||||
bool first_member;
|
||||
|
||||
for( first_member = true; ; )
|
||||
|
@ -786,8 +839,7 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
|
|||
if( verbosity >= 4 )
|
||||
fprintf( stderr, "CRC %08X, ", LZ_decompress_data_crc( decoder ) );
|
||||
if( verbosity >= 3 )
|
||||
fprintf( stderr, "decompressed %9llu, compressed %8llu. ",
|
||||
data_size, member_size );
|
||||
fprintf( stderr, "%9llu out, %8llu in. ", data_size, member_size );
|
||||
fputs( testing ? "ok\n" : "done\n", stderr ); Pp_reset( pp );
|
||||
}
|
||||
}
|
||||
|
@ -840,8 +892,7 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
|
|||
else break; /* trailing data */
|
||||
return 2;
|
||||
}
|
||||
if( lz_errno == LZ_mem_error )
|
||||
{ Pp_show_msg( pp, "Not enough memory." ); return 1; }
|
||||
if( lz_errno == LZ_mem_error ) { Pp_show_msg( pp, mem_msg ); return 1; }
|
||||
if( verbosity >= 0 )
|
||||
{
|
||||
Pp_show_msg( pp, 0 );
|
||||
|
@ -853,7 +904,11 @@ static int do_decompress( struct LZ_Decoder * const decoder, const int infd,
|
|||
}
|
||||
if( LZ_decompress_finished( decoder ) == 1 ) break;
|
||||
if( in_size == 0 && out_size == 0 )
|
||||
internal_error( "library error (stalled)." );
|
||||
{
|
||||
const unsigned long long size = LZ_decompress_total_in_size( decoder );
|
||||
if( total_in == size ) internal_error( "library error (stalled)." );
|
||||
total_in = size;
|
||||
}
|
||||
}
|
||||
if( verbosity == 1 ) fputs( testing ? "ok\n" : "done\n", stderr );
|
||||
return 0;
|
||||
|
@ -868,7 +923,7 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
int retval;
|
||||
|
||||
if( !decoder || LZ_decompress_errno( decoder ) != LZ_ok )
|
||||
{ Pp_show_msg( pp, "Not enough memory." ); retval = 1; }
|
||||
{ Pp_show_msg( pp, mem_msg ); retval = 1; }
|
||||
else retval = do_decompress( decoder, infd, pp, ignore_trailing,
|
||||
loose_trailing, testing );
|
||||
LZ_decompress_close( decoder );
|
||||
|
@ -876,7 +931,8 @@ static int decompress( const int infd, struct Pretty_print * const pp,
|
|||
}
|
||||
|
||||
|
||||
void show_error( const char * const msg, const int errcode, const bool help )
|
||||
static void show_error( const char * const msg, const int errcode,
|
||||
const bool help )
|
||||
{
|
||||
if( verbosity < 0 ) return;
|
||||
if( msg && msg[0] )
|
||||
|
@ -889,8 +945,8 @@ void show_error( const char * const msg, const int errcode, const bool help )
|
|||
}
|
||||
|
||||
|
||||
void show_file_error( const char * const filename, const char * const msg,
|
||||
const int errcode )
|
||||
static void show_file_error( const char * const filename,
|
||||
const char * const msg, const int errcode )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
fprintf( stderr, "%s: %s: %s%s%s\n", program_name, filename, msg,
|
||||
|
@ -899,7 +955,7 @@ void show_file_error( const char * const filename, const char * const msg,
|
|||
}
|
||||
|
||||
|
||||
void internal_error( const char * const msg )
|
||||
static void internal_error( const char * const msg )
|
||||
{
|
||||
if( verbosity >= 0 )
|
||||
fprintf( stderr, "%s: internal error: %s\n", program_name, msg );
|
||||
|
@ -924,12 +980,14 @@ int main( const int argc, const char * const argv[] )
|
|||
{ 3 << 23, 132 }, /* -8 */
|
||||
{ 1 << 25, 273 } }; /* -9 */
|
||||
struct Lzma_options encoder_options = option_mapping[6]; /* default = "-6" */
|
||||
const unsigned long long max_member_size = 0x0008000000000000ULL;
|
||||
const unsigned long long max_volume_size = 0x4000000000000000ULL;
|
||||
const unsigned long long max_member_size = 0x0008000000000000ULL; /* 2 PiB */
|
||||
const unsigned long long max_volume_size = 0x4000000000000000ULL; /* 4 EiB */
|
||||
unsigned long long member_size = max_member_size;
|
||||
unsigned long long volume_size = 0;
|
||||
const char * default_output_filename = "";
|
||||
const char ** filenames = 0;
|
||||
static struct Arg_parser parser; /* static because valgrind complains */
|
||||
static struct Pretty_print pp; /* and memory management in C sucks */
|
||||
static const char ** filenames = 0;
|
||||
int num_filenames = 0;
|
||||
enum Mode program_mode = m_compress;
|
||||
int argind = 0;
|
||||
|
@ -944,9 +1002,8 @@ int main( const int argc, const char * const argv[] )
|
|||
bool recompress = false;
|
||||
bool stdin_used = false;
|
||||
bool to_stdout = false;
|
||||
struct Pretty_print pp;
|
||||
|
||||
enum { opt_lt = 256 };
|
||||
enum { opt_chk = 256, opt_lt };
|
||||
const struct ap_Option options[] =
|
||||
{
|
||||
{ '0', "fast", ap_no },
|
||||
|
@ -976,20 +1033,14 @@ int main( const int argc, const char * const argv[] )
|
|||
{ 't', "test", ap_no },
|
||||
{ 'v', "verbose", ap_no },
|
||||
{ 'V', "version", ap_no },
|
||||
{ opt_chk, "check-lib", ap_no },
|
||||
{ opt_lt, "loose-trailing", ap_no },
|
||||
{ 0, 0, ap_no } };
|
||||
|
||||
struct Arg_parser parser;
|
||||
|
||||
invocation_name = argv[0];
|
||||
|
||||
if( LZ_version()[0] != LZ_version_string[0] )
|
||||
internal_error( "bad library version." );
|
||||
if( strcmp( PROGVERSION, LZ_version_string ) != 0 )
|
||||
internal_error( "bad library version_string." );
|
||||
if( argc > 0 ) invocation_name = argv[0];
|
||||
|
||||
if( !ap_init( &parser, argc, argv, options, 0 ) )
|
||||
{ show_error( "Not enough memory.", 0, false ); return 1; }
|
||||
{ show_error( mem_msg, 0, false ); return 1; }
|
||||
if( ap_error( &parser ) ) /* bad option */
|
||||
{ show_error( ap_error( &parser ), 0, true ); return 1; }
|
||||
|
||||
|
@ -1015,7 +1066,8 @@ int main( const int argc, const char * const argv[] )
|
|||
getnum( arg, LZ_min_match_len_limit(),
|
||||
LZ_max_match_len_limit() ); break;
|
||||
case 'n': break;
|
||||
case 'o': default_output_filename = arg; break;
|
||||
case 'o': if( strcmp( arg, "-" ) == 0 ) to_stdout = true;
|
||||
else { default_output_filename = arg; } break;
|
||||
case 'q': verbosity = -1; break;
|
||||
case 's': encoder_options.dictionary_size = get_dict_size( arg );
|
||||
break;
|
||||
|
@ -1023,11 +1075,27 @@ int main( const int argc, const char * const argv[] )
|
|||
case 't': set_mode( &program_mode, m_test ); break;
|
||||
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||
case 'V': show_version(); return 0;
|
||||
case opt_chk: return check_lib();
|
||||
case opt_lt: loose_trailing = true; break;
|
||||
default : internal_error( "uncaught option." );
|
||||
}
|
||||
} /* end process options */
|
||||
|
||||
if( strcmp( PROGVERSION, LZ_version_string ) != 0 )
|
||||
internal_error( "wrong PROGVERSION." );
|
||||
#if !defined LZ_API_VERSION || LZ_API_VERSION < 1012
|
||||
#error "lzlib 1.12 or newer needed."
|
||||
#else
|
||||
if( LZ_api_version() < 1012 ) /* minilzip passes null to LZ_decompress_read */
|
||||
{ show_error( "lzlib 1.12 or newer needed. Try --check-lib.", 0, false );
|
||||
return 1; }
|
||||
if( LZ_api_version() != LZ_API_VERSION ) show_error(
|
||||
"warning: wrong library API version. Try --check-lib.", 0, false );
|
||||
else
|
||||
#endif
|
||||
if( strcmp( LZ_version_string, LZ_version() ) != 0 ) show_error(
|
||||
"warning: wrong library version_string. Try --check-lib.", 0, false );
|
||||
|
||||
#if defined(__MSVCRT__) || defined(__OS2__) || defined(__DJGPP__)
|
||||
setmode( STDIN_FILENO, O_BINARY );
|
||||
setmode( STDOUT_FILENO, O_BINARY );
|
||||
|
@ -1043,16 +1111,31 @@ int main( const int argc, const char * const argv[] )
|
|||
if( strcmp( filenames[i], "-" ) != 0 ) filenames_given = true;
|
||||
}
|
||||
|
||||
if( program_mode == m_test )
|
||||
outfd = -1;
|
||||
if( program_mode == m_compress )
|
||||
{
|
||||
if( volume_size > 0 && !to_stdout && default_output_filename[0] &&
|
||||
num_filenames > 1 )
|
||||
{ show_error( "Only can compress one file when using '-o' and '-S'.",
|
||||
0, true ); return 1; }
|
||||
}
|
||||
else volume_size = 0;
|
||||
if( program_mode == m_test ) to_stdout = false; /* apply overrides */
|
||||
if( program_mode == m_test || to_stdout ) default_output_filename = "";
|
||||
|
||||
if( !to_stdout && program_mode != m_test &&
|
||||
( filenames_given || default_output_filename[0] ) )
|
||||
output_filename = resize_buffer( output_filename, 1 );
|
||||
output_filename[0] = 0;
|
||||
if( to_stdout && program_mode != m_test ) /* check tty only once */
|
||||
{ outfd = STDOUT_FILENO; if( !check_tty_out( program_mode ) ) return 1; }
|
||||
else outfd = -1;
|
||||
|
||||
const bool to_file = !to_stdout && program_mode != m_test &&
|
||||
default_output_filename[0];
|
||||
if( !to_stdout && program_mode != m_test && ( filenames_given || to_file ) )
|
||||
set_signals( signal_handler );
|
||||
|
||||
Pp_init( &pp, filenames, num_filenames );
|
||||
|
||||
output_filename = resize_buffer( output_filename, 1 );
|
||||
const bool one_to_one = !to_stdout && program_mode != m_test && !to_file;
|
||||
for( i = 0; i < num_filenames; ++i )
|
||||
{
|
||||
const char * input_filename = "";
|
||||
|
@ -1060,68 +1143,48 @@ int main( const int argc, const char * const argv[] )
|
|||
int tmp;
|
||||
struct stat in_stats;
|
||||
const struct stat * in_statsp;
|
||||
output_filename[0] = 0;
|
||||
|
||||
if( !filenames[i][0] || strcmp( filenames[i], "-" ) == 0 )
|
||||
Pp_set_name( &pp, filenames[i] );
|
||||
if( strcmp( filenames[i], "-" ) == 0 )
|
||||
{
|
||||
if( stdin_used ) continue; else stdin_used = true;
|
||||
infd = STDIN_FILENO;
|
||||
if( program_mode != m_test )
|
||||
{
|
||||
if( to_stdout || !default_output_filename[0] )
|
||||
outfd = STDOUT_FILENO;
|
||||
else
|
||||
{
|
||||
if( program_mode == m_compress )
|
||||
set_c_outname( default_output_filename, false, volume_size > 0 );
|
||||
else
|
||||
{
|
||||
output_filename = resize_buffer( output_filename,
|
||||
strlen( default_output_filename ) + 1 );
|
||||
strcpy( output_filename, default_output_filename );
|
||||
}
|
||||
if( !open_outstream( force, true ) )
|
||||
{
|
||||
if( retval < 1 ) retval = 1;
|
||||
close( infd );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( !check_tty_in( pp.name, infd, program_mode, &retval ) ) continue;
|
||||
if( one_to_one ) { outfd = STDOUT_FILENO; output_filename[0] = 0; }
|
||||
}
|
||||
else
|
||||
{
|
||||
const int eindex = extension_index( input_filename = filenames[i] );
|
||||
infd = open_instream( input_filename, &in_stats, program_mode,
|
||||
eindex, recompress, to_stdout );
|
||||
if( infd < 0 ) { if( retval < 1 ) retval = 1; continue; }
|
||||
if( program_mode != m_test )
|
||||
{
|
||||
if( to_stdout ) outfd = STDOUT_FILENO;
|
||||
else
|
||||
eindex, one_to_one, recompress );
|
||||
if( infd < 0 ) { set_retval( &retval, 1 ); continue; }
|
||||
if( !check_tty_in( pp.name, infd, program_mode, &retval ) ) continue;
|
||||
if( one_to_one ) /* open outfd after verifying infd */
|
||||
{
|
||||
if( program_mode == m_compress )
|
||||
set_c_outname( input_filename, true, volume_size > 0 );
|
||||
else set_d_outname( input_filename, eindex );
|
||||
if( !open_outstream( force, false ) )
|
||||
{
|
||||
if( retval < 1 ) retval = 1;
|
||||
close( infd );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( !open_outstream( force, true ) )
|
||||
{ close( infd ); set_retval( &retval, 1 ); continue; }
|
||||
}
|
||||
}
|
||||
|
||||
Pp_set_name( &pp, input_filename );
|
||||
if( !check_tty( pp.name, infd, program_mode ) )
|
||||
if( one_to_one && !check_tty_out( program_mode ) )
|
||||
{ set_retval( &retval, 1 ); return retval; } /* don't delete a tty */
|
||||
|
||||
if( to_file && outfd < 0 ) /* open outfd after verifying infd */
|
||||
{
|
||||
if( retval < 1 ) retval = 1;
|
||||
if( program_mode == m_test ) { close( infd ); continue; }
|
||||
cleanup_and_fail( retval );
|
||||
if( program_mode == m_compress ) set_c_outname( default_output_filename,
|
||||
false, volume_size > 0 );
|
||||
else
|
||||
{ output_filename = resize_buffer( output_filename,
|
||||
strlen( default_output_filename ) + 1 );
|
||||
strcpy( output_filename, default_output_filename ); }
|
||||
if( !open_outstream( force, false ) || !check_tty_out( program_mode ) )
|
||||
return 1; /* check tty only once and don't try to delete a tty */
|
||||
}
|
||||
|
||||
in_statsp = input_filename[0] ? &in_stats : 0;
|
||||
in_statsp = ( input_filename[0] && one_to_one ) ? &in_stats : 0;
|
||||
if( program_mode == m_compress )
|
||||
tmp = compress( member_size, volume_size, infd, &encoder_options, &pp,
|
||||
in_statsp );
|
||||
|
@ -1129,29 +1192,24 @@ int main( const int argc, const char * const argv[] )
|
|||
tmp = decompress( infd, &pp, ignore_trailing,
|
||||
loose_trailing, program_mode == m_test );
|
||||
if( close( infd ) != 0 )
|
||||
{
|
||||
show_error( input_filename[0] ? "Error closing input file" :
|
||||
"Error closing stdin", errno, false );
|
||||
if( tmp < 1 ) tmp = 1;
|
||||
}
|
||||
if( tmp > retval ) retval = tmp;
|
||||
{ show_file_error( pp.name, "Error closing input file", errno );
|
||||
set_retval( &tmp, 1 ); }
|
||||
set_retval( &retval, tmp );
|
||||
if( tmp )
|
||||
{ if( program_mode != m_test ) cleanup_and_fail( retval );
|
||||
else ++failed_tests; }
|
||||
|
||||
if( delete_output_on_interrupt )
|
||||
if( delete_output_on_interrupt && one_to_one )
|
||||
close_and_set_permissions( in_statsp );
|
||||
if( input_filename[0] )
|
||||
{
|
||||
if( !keep_input_files && !to_stdout && program_mode != m_test &&
|
||||
if( input_filename[0] && !keep_input_files && one_to_one &&
|
||||
( program_mode != m_compress || volume_size == 0 ) )
|
||||
remove( input_filename );
|
||||
}
|
||||
}
|
||||
if( outfd >= 0 && close( outfd ) != 0 )
|
||||
if( delete_output_on_interrupt ) close_and_set_permissions( 0 ); /* -o */
|
||||
else if( outfd >= 0 && close( outfd ) != 0 ) /* -c */
|
||||
{
|
||||
show_error( "Error closing stdout", errno, false );
|
||||
if( retval < 1 ) retval = 1;
|
||||
set_retval( &retval, 1 );
|
||||
}
|
||||
if( failed_tests > 0 && verbosity >= 1 && num_filenames > 1 )
|
||||
fprintf( stderr, "%s: warning: %d %s failed the test.\n",
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#! /bin/sh
|
||||
# check script for Lzlib - Compression library for the lzip format
|
||||
# Copyright (C) 2009-2019 Antonio Diaz Diaz.
|
||||
# Copyright (C) 2009-2021 Antonio Diaz Diaz.
|
||||
#
|
||||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute and modify it.
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
@ -11,6 +11,7 @@ objdir=`pwd`
|
|||
testdir=`cd "$1" ; pwd`
|
||||
LZIP="${objdir}"/minilzip
|
||||
BBEXAMPLE="${objdir}"/bbexample
|
||||
FFEXAMPLE="${objdir}"/ffexample
|
||||
LZCHECK="${objdir}"/lzcheck
|
||||
framework_failure() { echo "failure in testing framework" ; exit 1 ; }
|
||||
|
||||
|
@ -32,10 +33,13 @@ cd "${objdir}"/tmp || framework_failure
|
|||
|
||||
cat "${testdir}"/test.txt > in || framework_failure
|
||||
in_lz="${testdir}"/test.txt.lz
|
||||
test2="${testdir}"/test2.txt
|
||||
in_em="${testdir}"/test_em.txt.lz
|
||||
fox_lf="${testdir}"/fox_lf
|
||||
fox_lz="${testdir}"/fox.lz
|
||||
fail=0
|
||||
test_failed() { fail=1 ; printf " $1" ; [ -z "$2" ] || printf "($2)" ; }
|
||||
|
||||
"${LZIP}" --check-lib # just print warning
|
||||
printf "testing lzlib-%s..." "$2"
|
||||
|
||||
"${LZIP}" -fkqm4 in
|
||||
|
@ -59,10 +63,22 @@ done
|
|||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -dq -o in < "${in_lz}"
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -dq -o in "${in_lz}"
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -dq -o out nx_file.lz
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
[ ! -e out ] || test_failed $LINENO
|
||||
"${LZIP}" -q -o out.lz nx_file
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
[ ! -e out.lz ] || test_failed $LINENO
|
||||
"${LZIP}" -qf -S100k -o out in in
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
# these are for code coverage
|
||||
"${LZIP}" -cdt "${in_lz}" > out 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -t -- nx_file 2> /dev/null
|
||||
"${LZIP}" -t -- nx_file.lz 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -t "" < /dev/null 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" --help > /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -n1 -V > /dev/null || test_failed $LINENO
|
||||
|
@ -86,15 +102,22 @@ printf "LZIP\001+.............................." | "${LZIP}" -t 2> /dev/null
|
|||
|
||||
printf "\ntesting decompression..."
|
||||
|
||||
"${LZIP}" -t "${in_lz}" || test_failed $LINENO
|
||||
"${LZIP}" -cd "${in_lz}" > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
|
||||
"${LZIP}" -t "${testdir}"/test_sync.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd "${testdir}"/test_sync.lz > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
|
||||
for i in "${in_lz}" "${in_em}" "${testdir}"/test_sync.lz ; do
|
||||
"${LZIP}" -t "$i" || test_failed $LINENO "$i"
|
||||
"${LZIP}" -d "$i" -o copy || test_failed $LINENO "$i"
|
||||
cmp in copy || test_failed $LINENO "$i"
|
||||
"${LZIP}" -cd "$i" > copy || test_failed $LINENO "$i"
|
||||
cmp in copy || test_failed $LINENO "$i"
|
||||
"${LZIP}" -d "$i" -o - > copy || test_failed $LINENO "$i"
|
||||
cmp in copy || test_failed $LINENO "$i"
|
||||
"${LZIP}" -d < "$i" > copy || test_failed $LINENO "$i"
|
||||
cmp in copy || test_failed $LINENO "$i"
|
||||
rm -f copy || framework_failure
|
||||
done
|
||||
|
||||
lines=$("${LZIP}" -tvv "${in_em}" 2>&1 | wc -l) || test_failed $LINENO
|
||||
[ "${lines}" -eq 8 ] || test_failed $LINENO "${lines}"
|
||||
|
||||
cat "${in_lz}" > copy.lz || framework_failure
|
||||
"${LZIP}" -dk copy.lz || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
|
@ -112,12 +135,20 @@ cat "${in_lz}" > copy.lz || framework_failure
|
|||
cmp in copy || test_failed $LINENO
|
||||
|
||||
printf "to be overwritten" > copy || framework_failure
|
||||
"${LZIP}" -d -o copy < "${in_lz}" 2> /dev/null
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -df -o copy < "${in_lz}" || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
rm -f out copy || framework_failure
|
||||
"${LZIP}" -d -o ./- "${in_lz}" || test_failed $LINENO
|
||||
cmp in ./- || test_failed $LINENO
|
||||
rm -f ./- || framework_failure
|
||||
"${LZIP}" -d -o ./- < "${in_lz}" || test_failed $LINENO
|
||||
cmp in ./- || test_failed $LINENO
|
||||
rm -f ./- || framework_failure
|
||||
|
||||
rm -f copy || framework_failure
|
||||
"${LZIP}" -s16 < in > anyothername || test_failed $LINENO
|
||||
"${LZIP}" -dv --output copy - anyothername - < "${in_lz}" 2> /dev/null ||
|
||||
cat "${in_lz}" > anyothername || framework_failure
|
||||
"${LZIP}" -dv - anyothername - < "${in_lz}" > copy 2> /dev/null ||
|
||||
test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
cmp in anyothername.out || test_failed $LINENO
|
||||
|
@ -152,19 +183,18 @@ done
|
|||
cmp in copy || test_failed $LINENO
|
||||
|
||||
cat in in > in2 || framework_failure
|
||||
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
|
||||
"${LZIP}" -t in2.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd in2.lz > copy2 || test_failed $LINENO
|
||||
"${LZIP}" -t "${in_lz}" "${in_lz}" || test_failed $LINENO
|
||||
"${LZIP}" -cd "${in_lz}" "${in_lz}" -o out > copy2 || test_failed $LINENO
|
||||
[ ! -e out ] || test_failed $LINENO # override -o
|
||||
cmp in2 copy2 || test_failed $LINENO
|
||||
|
||||
"${LZIP}" -s16 --output=copy2.lz < in2 || test_failed $LINENO
|
||||
"${LZIP}" -t copy2.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd copy2.lz > copy2 || test_failed $LINENO
|
||||
rm -f copy2 || framework_failure
|
||||
"${LZIP}" -d "${in_lz}" "${in_lz}" -o copy2 || test_failed $LINENO
|
||||
cmp in2 copy2 || test_failed $LINENO
|
||||
rm -f copy2 || framework_failure
|
||||
|
||||
cat "${in_lz}" "${in_lz}" > copy2.lz || framework_failure
|
||||
printf "\ngarbage" >> copy2.lz || framework_failure
|
||||
"${LZIP}" -tvvvv copy2.lz 2> /dev/null || test_failed $LINENO
|
||||
rm -f copy2 || framework_failure
|
||||
"${LZIP}" -atq copy2.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -atq < copy2.lz
|
||||
|
@ -178,68 +208,91 @@ rm -f copy2 || framework_failure
|
|||
printf "to be overwritten" > copy2 || framework_failure
|
||||
"${LZIP}" -df copy2.lz || test_failed $LINENO
|
||||
cmp in2 copy2 || test_failed $LINENO
|
||||
rm -f in2 copy2 || framework_failure
|
||||
rm -f copy2 || framework_failure
|
||||
|
||||
printf "\ntesting compression..."
|
||||
|
||||
"${LZIP}" -c -0 in in in -S100k -o out3.lz > copy2.lz || test_failed $LINENO
|
||||
[ ! -e out3.lz ] || test_failed $LINENO # override -o and -S
|
||||
"${LZIP}" -0f in in --output=copy2.lz || test_failed $LINENO
|
||||
"${LZIP}" -d copy2.lz -o out2 || test_failed $LINENO
|
||||
cmp in2 out2 || test_failed $LINENO
|
||||
rm -f out2 copy2.lz || framework_failure
|
||||
|
||||
"${LZIP}" -cf "${in_lz}" > out 2> /dev/null # /dev/null is a tty on OS/2
|
||||
[ $? = 1 ] || test_failed $LINENO
|
||||
"${LZIP}" -cFvvm36 -s16 "${in_lz}" > out 2> /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -Fvvm36 -o - -s16 "${in_lz}" > out 2> /dev/null || test_failed $LINENO
|
||||
"${LZIP}" -cd out | "${LZIP}" -d > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
|
||||
"${LZIP}" -0 -o ./- in || test_failed $LINENO
|
||||
"${LZIP}" -cd ./- | cmp in - || test_failed $LINENO
|
||||
rm -f ./- || framework_failure
|
||||
"${LZIP}" -0 -o ./- < in || test_failed $LINENO # don't add .lz
|
||||
[ ! -e ./-.lz ] || test_failed $LINENO
|
||||
"${LZIP}" -cd ./- | cmp in - || test_failed $LINENO
|
||||
rm -f ./- || framework_failure
|
||||
|
||||
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||
"${LZIP}" -k -$i -s16 in || test_failed $LINENO $i
|
||||
mv -f in.lz copy.lz || test_failed $LINENO $i
|
||||
printf "garbage" >> copy.lz || framework_failure
|
||||
"${LZIP}" -df copy.lz || test_failed $LINENO $i
|
||||
cmp in copy || test_failed $LINENO $i
|
||||
done
|
||||
|
||||
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||
"${LZIP}" -c -$i -s16 in > out || test_failed $LINENO $i
|
||||
"${LZIP}" -$i -s16 in -c > out || test_failed $LINENO $i
|
||||
"${LZIP}" -$i -s16 in -o o_out || test_failed $LINENO $i # don't add .lz
|
||||
[ ! -e o_out.lz ] || test_failed $LINENO
|
||||
cmp out o_out || test_failed $LINENO $i
|
||||
rm -f o_out || framework_failure
|
||||
printf "g" >> out || framework_failure
|
||||
"${LZIP}" -cd out > copy || test_failed $LINENO $i
|
||||
cmp in copy || test_failed $LINENO $i
|
||||
done
|
||||
|
||||
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||
"${LZIP}" -$i -s16 < in > out || test_failed $LINENO $i
|
||||
"${LZIP}" -d < out > copy || test_failed $LINENO $i
|
||||
cmp in copy || test_failed $LINENO $i
|
||||
done
|
||||
|
||||
for i in s4Ki 0 1 2 3 4 5 6 7 8 9 ; do
|
||||
rm -f out.lz || framework_failure
|
||||
printf "to be overwritten" > out || framework_failure # don't add .lz
|
||||
"${LZIP}" -f -$i -s16 -o out < in || test_failed $LINENO $i
|
||||
"${LZIP}" -df -o copy < out.lz || test_failed $LINENO $i
|
||||
[ ! -e out.lz ] || test_failed $LINENO
|
||||
"${LZIP}" -df -o copy < out || test_failed $LINENO $i
|
||||
cmp in copy || test_failed $LINENO $i
|
||||
done
|
||||
rm -f out.lz || framework_failure
|
||||
rm -f out out.lz || framework_failure
|
||||
|
||||
cat in in in in in in in in > in8 || framework_failure
|
||||
"${LZIP}" -1s12 -S100k in8 || test_failed $LINENO
|
||||
"${LZIP}" -t in800001.lz in800002.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd in800001.lz in800002.lz | cmp in8 - || test_failed $LINENO
|
||||
[ ! -e in800003.lz ] || test_failed $LINENO
|
||||
rm -f in800001.lz in800002.lz || framework_failure
|
||||
"${LZIP}" -1s12 -S100k -o out.lz < in8 || test_failed $LINENO
|
||||
"${LZIP}" -1s12 -S100k -o out.lz in8 || test_failed $LINENO
|
||||
# ignore -S
|
||||
"${LZIP}" -d out.lz00001.lz out.lz00002.lz -S100k -o out || test_failed $LINENO
|
||||
cmp in8 out || test_failed $LINENO
|
||||
"${LZIP}" -t out.lz00001.lz out.lz00002.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd out.lz00001.lz out.lz00002.lz | cmp in8 - || test_failed $LINENO
|
||||
rm -f out.lz00001.lz out.lz00002.lz || framework_failure
|
||||
[ ! -e out.lz00003.lz ] || test_failed $LINENO
|
||||
rm -f out out.lz00001.lz out.lz00002.lz || framework_failure
|
||||
"${LZIP}" -1ks4Ki -b100000 in8 || test_failed $LINENO
|
||||
"${LZIP}" -t in8.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd in8.lz | cmp in8 - || test_failed $LINENO
|
||||
rm -f in8 || framework_failure
|
||||
"${LZIP}" -cd in8.lz -o out | cmp in8 - || test_failed $LINENO # override -o
|
||||
[ ! -e out ] || test_failed $LINENO
|
||||
"${LZIP}" -0 -S100k -o out < in8.lz || test_failed $LINENO
|
||||
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
|
||||
[ ! -e out00003.lz ] || test_failed $LINENO
|
||||
rm -f out00001.lz || framework_failure
|
||||
"${LZIP}" -1 -S100k -o out < in8.lz || test_failed $LINENO
|
||||
"${LZIP}" -t out00001.lz out00002.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd out00001.lz out00002.lz | cmp in8.lz - || test_failed $LINENO
|
||||
[ ! -e out00003.lz ] || test_failed $LINENO
|
||||
rm -f out00001.lz out00002.lz || framework_failure
|
||||
"${LZIP}" -0 -F -S100k in8.lz || test_failed $LINENO
|
||||
"${LZIP}" -t in8.lz00001.lz in8.lz00002.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd in8.lz00001.lz in8.lz00002.lz | cmp in8.lz - || test_failed $LINENO
|
||||
[ ! -e in8.lz00003.lz ] || test_failed $LINENO
|
||||
rm -f in8.lz00001.lz in8.lz00002.lz || framework_failure
|
||||
"${LZIP}" -0kF -b100k in8.lz || test_failed $LINENO
|
||||
"${LZIP}" -t in8.lz.lz || test_failed $LINENO
|
||||
|
@ -247,12 +300,33 @@ rm -f in8.lz00001.lz in8.lz00002.lz || framework_failure
|
|||
rm -f in8.lz in8.lz.lz || framework_failure
|
||||
|
||||
"${BBEXAMPLE}" in || test_failed $LINENO
|
||||
"${BBEXAMPLE}" out || test_failed $LINENO
|
||||
"${BBEXAMPLE}" ${test2} || test_failed $LINENO
|
||||
"${BBEXAMPLE}" "${in_lz}" || test_failed $LINENO
|
||||
"${BBEXAMPLE}" "${fox_lf}" || test_failed $LINENO
|
||||
|
||||
"${FFEXAMPLE}" -h > /dev/null || test_failed $LINENO
|
||||
"${FFEXAMPLE}" > /dev/null && test_failed $LINENO
|
||||
rm -f out || framework_failure
|
||||
"${FFEXAMPLE}" -b in out || test_failed $LINENO
|
||||
cmp in out || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -b in | cmp in - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -b in8 | cmp in8 - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -b "${fox_lf}" | cmp "${fox_lf}" - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -d "${in_lz}" - | cmp in - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -d "${in_em}" - | cmp in - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -c in | "${FFEXAMPLE}" -d | cmp in - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -m in | "${FFEXAMPLE}" -d | cmp in - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -l in | "${FFEXAMPLE}" -d | cmp in - || test_failed $LINENO
|
||||
cat "${fox_lf}" "${in_lz}" | "${FFEXAMPLE}" -r | cmp in - || test_failed $LINENO
|
||||
cat in8 "${in_lz}" | "${FFEXAMPLE}" -r | cmp in - || test_failed $LINENO
|
||||
cat "${in_lz}" "${fox_lf}" "${in_lz}" | "${FFEXAMPLE}" -r - | cmp in2 - ||
|
||||
test_failed $LINENO
|
||||
cat "${in_lz}" in8 "${in_lz}" | "${FFEXAMPLE}" -r - - | cmp in2 - ||
|
||||
test_failed $LINENO
|
||||
|
||||
"${LZCHECK}" in || test_failed $LINENO
|
||||
"${LZCHECK}" out || test_failed $LINENO
|
||||
"${LZCHECK}" ${test2} || test_failed $LINENO
|
||||
"${LZCHECK}" "${in_lz}" || test_failed $LINENO
|
||||
"${LZCHECK}" "${fox_lf}" || test_failed $LINENO
|
||||
rm -f in8 || framework_failure
|
||||
|
||||
printf "\ntesting bad input..."
|
||||
|
||||
|
@ -301,6 +375,21 @@ else
|
|||
fi
|
||||
rm -f int.lz || framework_failure
|
||||
|
||||
for i in fox_v2.lz fox_s11.lz fox_de20.lz \
|
||||
fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
|
||||
"${LZIP}" -tq "${testdir}"/$i
|
||||
[ $? = 2 ] || test_failed $LINENO $i
|
||||
done
|
||||
|
||||
"${LZIP}" -cd "${fox_lz}" > fox || test_failed $LINENO
|
||||
for i in fox_bcrc.lz fox_crc0.lz fox_das46.lz fox_mes81.lz ; do
|
||||
"${LZIP}" -cdq "${testdir}"/$i > out
|
||||
[ $? = 2 ] || test_failed $LINENO $i
|
||||
cmp fox out || test_failed $LINENO $i
|
||||
done
|
||||
rm -f fox out || framework_failure
|
||||
|
||||
cat "${in_lz}" "${in_lz}" > in2.lz || framework_failure
|
||||
cat "${in_lz}" "${in_lz}" "${in_lz}" > in3.lz || framework_failure
|
||||
if dd if=in3.lz of=trunc.lz bs=14752 count=1 2> /dev/null &&
|
||||
[ -e trunc.lz ] && cmp in2.lz trunc.lz > /dev/null 2>&1 ; then
|
||||
|
@ -323,13 +412,23 @@ rm -f in2.lz in3.lz trunc.lz out || framework_failure
|
|||
cat "${in_lz}" > ingin.lz || framework_failure
|
||||
printf "g" >> ingin.lz || framework_failure
|
||||
cat "${in_lz}" >> ingin.lz || framework_failure
|
||||
"${LZIP}" -atq ingin.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -atq < ingin.lz
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -acdq ingin.lz > out
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -adq < ingin.lz > out
|
||||
[ $? = 2 ] || test_failed $LINENO
|
||||
"${LZIP}" -t ingin.lz || test_failed $LINENO
|
||||
"${LZIP}" -t < ingin.lz || test_failed $LINENO
|
||||
"${LZIP}" -cd ingin.lz > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
"${LZIP}" -t < ingin.lz || test_failed $LINENO
|
||||
"${LZIP}" -d < ingin.lz > copy || test_failed $LINENO
|
||||
cmp in copy || test_failed $LINENO
|
||||
rm -f copy ingin.lz || framework_failure
|
||||
"${FFEXAMPLE}" -d ingin.lz | cmp in - || test_failed $LINENO
|
||||
"${FFEXAMPLE}" -r ingin.lz | cmp in2 - || test_failed $LINENO
|
||||
rm -f copy ingin.lz in2 out || framework_failure
|
||||
|
||||
echo
|
||||
if [ ${fail} = 0 ] ; then
|
||||
|
|
BIN
testsuite/fox.lz
Normal file
BIN
testsuite/fox.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_bcrc.lz
Normal file
BIN
testsuite/fox_bcrc.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_crc0.lz
Normal file
BIN
testsuite/fox_crc0.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_das46.lz
Normal file
BIN
testsuite/fox_das46.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_de20.lz
Normal file
BIN
testsuite/fox_de20.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_mes81.lz
Normal file
BIN
testsuite/fox_mes81.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_s11.lz
Normal file
BIN
testsuite/fox_s11.lz
Normal file
Binary file not shown.
BIN
testsuite/fox_v2.lz
Normal file
BIN
testsuite/fox_v2.lz
Normal file
Binary file not shown.
BIN
testsuite/test_em.txt.lz
Normal file
BIN
testsuite/test_em.txt.lz
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue