mirror of
https://github.com/PCSX2/xz.git
synced 2026-02-09 05:41:17 +01:00
Compare commits
148 Commits
v4.42.2alp
...
v4.999.3al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
beeb810608 | ||
|
|
c324325f9f | ||
|
|
d3ba30243c | ||
|
|
8f804c29aa | ||
|
|
c99037ea10 | ||
|
|
22ba3b0b50 | ||
|
|
17c36422d4 | ||
|
|
283f939974 | ||
|
|
eb348a60b6 | ||
|
|
6c5306e312 | ||
|
|
712cfe3ebf | ||
|
|
bc04486e36 | ||
|
|
7ab493924e | ||
|
|
641998c3e1 | ||
|
|
ad999efd27 | ||
|
|
03e0e8a0d7 | ||
|
|
7521bbdc83 | ||
|
|
63b74d000e | ||
|
|
e6eb0a2675 | ||
|
|
7d516f5129 | ||
|
|
748d6e4274 | ||
|
|
bfde3b24a5 | ||
|
|
f310c50286 | ||
|
|
5ead36cf7f | ||
|
|
d4d7feb83d | ||
|
|
0541c5ea63 | ||
|
|
596fa1fac7 | ||
|
|
45e43e1695 | ||
|
|
c0e19e0662 | ||
|
|
de74858062 | ||
|
|
1a3b218598 | ||
|
|
7e796e312b | ||
|
|
7dd48578a3 | ||
|
|
b596fac963 | ||
|
|
e9f6e9c075 | ||
|
|
4c7ad179c7 | ||
|
|
288b232f54 | ||
|
|
c467b0defc | ||
|
|
f9842f7127 | ||
|
|
e988ea1d1a | ||
|
|
4441e00418 | ||
|
|
bf4200c818 | ||
|
|
7b8fc7e6b5 | ||
|
|
e0c3d0043d | ||
|
|
1fd76d4881 | ||
|
|
6e27b1098a | ||
|
|
db9df0a960 | ||
|
|
765f0b05f6 | ||
|
|
3a7cc5c3de | ||
|
|
e5fdec93e2 | ||
|
|
ed40dc5a2c | ||
|
|
ae0cd09a66 | ||
|
|
0e80ded13d | ||
|
|
8c8eb14055 | ||
|
|
980f65a9a1 | ||
|
|
99e12af4e2 | ||
|
|
58b78ab20c | ||
|
|
4d8cdbdab4 | ||
|
|
67321de963 | ||
|
|
863028cb7a | ||
|
|
cf49f42a6b | ||
|
|
1747b85a43 | ||
|
|
0ed6f1adce | ||
|
|
305afa38f6 | ||
|
|
d53e9b7705 | ||
|
|
107259e306 | ||
|
|
e141fe1895 | ||
|
|
23c227a864 | ||
|
|
61dc82f3e3 | ||
|
|
0ae3208db9 | ||
|
|
ab5feaf1fc | ||
|
|
079c4f7fc2 | ||
|
|
61d1784d8f | ||
|
|
c9cba97691 | ||
|
|
33be3c0e24 | ||
|
|
b254bd97b1 | ||
|
|
8f5794c8f1 | ||
|
|
f88590e001 | ||
|
|
bc0b945ca3 | ||
|
|
7599bb7064 | ||
|
|
0b58153931 | ||
|
|
5b5b13c7bb | ||
|
|
19389f2b82 | ||
|
|
9bc33a54cb | ||
|
|
01d71d60b7 | ||
|
|
8235e6e5b2 | ||
|
|
f10fc6a69d | ||
|
|
e5728142a2 | ||
|
|
10437b5b56 | ||
|
|
f3c88e8b8d | ||
|
|
54ec204f58 | ||
|
|
01b4b19f49 | ||
|
|
19bd7f3cf2 | ||
|
|
9f9b198301 | ||
|
|
78e85cb1a7 | ||
|
|
949d4346e2 | ||
|
|
d13d693155 | ||
|
|
362dc3843b | ||
|
|
e22b37968d | ||
|
|
b59ef39737 | ||
|
|
9547e734a0 | ||
|
|
3e09e1c058 | ||
|
|
a670fec802 | ||
|
|
3599dba957 | ||
|
|
f73c2ab607 | ||
|
|
382808514a | ||
|
|
0e70fbe403 | ||
|
|
379fbbe84d | ||
|
|
97d5fa8207 | ||
|
|
3bb9bb3109 | ||
|
|
7054c5f588 | ||
|
|
753e4d95cd | ||
|
|
faeac7b7ac | ||
|
|
a751126dbb | ||
|
|
9080267603 | ||
|
|
b4943ccf73 | ||
|
|
e2417b2b91 | ||
|
|
5d227e51c2 | ||
|
|
c7189d981a | ||
|
|
3dbbea82b7 | ||
|
|
2fd2d18154 | ||
|
|
9a71d57310 | ||
|
|
47f48fe993 | ||
|
|
3502b3e1d0 | ||
|
|
908b2ac604 | ||
|
|
ecb2a6548f | ||
|
|
eacb805043 | ||
|
|
1239649f96 | ||
|
|
88ee301ec2 | ||
|
|
c15a7abf66 | ||
|
|
4e7e54c4c5 | ||
|
|
a71864f77d | ||
|
|
072927905a | ||
|
|
d160ee3259 | ||
|
|
fc67f79f60 | ||
|
|
0029cbbabe | ||
|
|
bbfd1f6ab0 | ||
|
|
5db745cd2a | ||
|
|
44b333d461 | ||
|
|
ec1c82b2e8 | ||
|
|
2881570df6 | ||
|
|
698470b8f3 | ||
|
|
918bcb0e07 | ||
|
|
3e16d51dd6 | ||
|
|
5286723e0d | ||
|
|
ce8b036a6c | ||
|
|
7c1ad41eb6 | ||
|
|
ce64df7162 |
3
COPYING
3
COPYING
@@ -5,7 +5,8 @@ LZMA Utils Licenses
|
||||
Different licenses apply to different files in this package. Here
|
||||
is a rough summary of which license apply to which parts of this
|
||||
package (but check the individual files to be sure!):
|
||||
- Everything under src/liblzma/check is public domain.
|
||||
- Everything under src/liblzma/check and tests/files is public
|
||||
domain.
|
||||
- Everything else under the src directory is under the GNU LGPL
|
||||
2.1 or (at your opinion) any later version.
|
||||
- Outside the src directory, there are some files that are under
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
## Lesser General Public License for more details.
|
||||
##
|
||||
|
||||
DIST_SUBDIRS = lib src po tests debug
|
||||
SUBDIRS =
|
||||
|
||||
if COND_GNULIB
|
||||
@@ -20,7 +21,6 @@ endif
|
||||
|
||||
SUBDIRS += src po tests
|
||||
|
||||
|
||||
EXTRA_DIST = \
|
||||
m4 \
|
||||
config.rpath \
|
||||
@@ -32,4 +32,8 @@ EXTRA_DIST = \
|
||||
COPYING.LGPLv2.1
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
# This works with GNU tar and gives cleaner package than normal 'make dist'.
|
||||
mydist:
|
||||
TAR_OPTIONS='--owner=0 --group=0 --numeric-owner --mode=u+rw,go+r-w' \
|
||||
$(MAKE) dist-gzip
|
||||
|
||||
35
README
35
README
@@ -59,6 +59,35 @@ Supported platforms
|
||||
in C89 or C++.
|
||||
|
||||
|
||||
Version numbering
|
||||
|
||||
Starting from LZMA Utils 5, the version number of LZMA Utils has
|
||||
absolutely nothing to do with the version number of LZMA SDK or
|
||||
7-Zip. The new version number format of LZMA Utils is X.Y.ZS:
|
||||
|
||||
- X is the major version. When this is incremented, the library
|
||||
API and ABI break.
|
||||
|
||||
- Y is the minor version. It is incremented when new features are
|
||||
added without breaking existing API or ABI. Even Y indicates
|
||||
stable release and odd Y indicates unstable (alpha or beta
|
||||
version).
|
||||
|
||||
- Z is the revision. This has different meaning for stable and
|
||||
unstable releases:
|
||||
* Stable: Z is incremented when bugs get fixed without adding
|
||||
any new features.
|
||||
* Unstable: Z is just a counter. API or ABI of features added
|
||||
in earlier unstable releases having the same X.Y may break.
|
||||
|
||||
- S indicates stability of the release. It is missing from the
|
||||
stable releases where Y is an even number. When Y is odd, S
|
||||
is either "alpha" or "beta" to make it very clear that such
|
||||
versions are not stable releases. The same X.Y.Z combination is
|
||||
not used for more than one stability level i.e. after X.Y.Zalpha,
|
||||
the next version can be X.Y.(Z+1)beta but not X.Y.Zbeta.
|
||||
|
||||
|
||||
configure options
|
||||
|
||||
If you are not familiar with `configure' scripts, read the file
|
||||
@@ -113,7 +142,11 @@ configure options
|
||||
|
||||
All the assembler code in liblzma is position-independent
|
||||
code, which is suitable for use in shared libraries and
|
||||
position-independent executables.
|
||||
position-independent executables. So far only i386
|
||||
instructions are used, but the code is optimized for i686
|
||||
class CPUs. If you are compiling liblzma exclusively for
|
||||
pre-i686 systems, you may want to disable the assembler
|
||||
code.
|
||||
|
||||
--enable-small
|
||||
Omits precomputed tables. This makes liblzma a few KiB
|
||||
|
||||
3
THANKS
3
THANKS
@@ -6,17 +6,20 @@ Some people have helped more, some less, some don't even know they have
|
||||
been helpful, but nevertheless everyone's help has been important. :-)
|
||||
In alphabetical order:
|
||||
- Mark Adler
|
||||
- Nelson H. F. Beebe
|
||||
- Anders F. Björklund
|
||||
- İsmail Dönmez
|
||||
- Jean-loup Gailly
|
||||
- Per Øyvind Karlsen
|
||||
- Ville Koskinen
|
||||
- Stephan Kulow
|
||||
- Jim Meyering
|
||||
- Igor Pavlov
|
||||
- Mikko Pouru
|
||||
- Alexandre Sauvé
|
||||
- Julian Seward
|
||||
- Mohammed Adnène Trojette
|
||||
- Andreas Zieringer
|
||||
|
||||
Also thanks to all the people who have participated the Tukaani project
|
||||
and others who I have forgot.
|
||||
|
||||
86
configure.ac
86
configure.ac
@@ -26,7 +26,7 @@ AC_PREREQ(2.61)
|
||||
|
||||
# [LZMA] instead of [LZMA utils] since I prefer to have lzma-version.tar.gz
|
||||
# instead of lzma-utils-version.tar.gz.
|
||||
AC_INIT([LZMA], [4.42.2alpha], [lasse.collin@tukaani.org])
|
||||
AC_INIT([LZMA], [4.999.3alpha], [lasse.collin@tukaani.org])
|
||||
|
||||
AC_CONFIG_SRCDIR([src/liblzma/common/common.h])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
@@ -47,7 +47,6 @@ AC_MSG_CHECKING([if debugging code should be compiled])
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [Enable debugging code.]),
|
||||
[], enable_debug=no)
|
||||
if test "x$enable_debug" = xyes; then
|
||||
CFLAGS="-g $CFLAGS"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_DEFINE(NDEBUG, 1, [Define to disable debugging code.])
|
||||
@@ -299,11 +298,27 @@ AC_ARG_ENABLE(assembler, AC_HELP_STRING([--disable-assembler],
|
||||
if test "x$enable_assembler" = xyes; then
|
||||
case $host_cpu in
|
||||
i?86) enable_assembler=x86 ;;
|
||||
x86_64) enable_assembler=x86_64 ;;
|
||||
*) enable_assembler=no ;;
|
||||
esac
|
||||
# Darwin has different ABI than GNU+Linux and Solaris,
|
||||
# and the assembler code doesn't assemble.
|
||||
case $host_os in
|
||||
darwin*) enable_assembler=no ;;
|
||||
*) ;;
|
||||
esac
|
||||
fi
|
||||
case $enable_assembler in
|
||||
x86|no) ;;
|
||||
x86)
|
||||
AC_DEFINE([HAVE_ASM_X86], 1,
|
||||
[Define to 1 if using x86 assembler optimizations.])
|
||||
;;
|
||||
x86_64)
|
||||
AC_DEFINE([HAVE_ASM_X86_64], 1,
|
||||
[Define to 1 if using x86_64 assembler optimizations.])
|
||||
;;
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_ERROR([--enable-assembler accepts only \`yes', \`no', or \`x86'.])
|
||||
@@ -328,6 +343,10 @@ fi
|
||||
AC_MSG_RESULT([$enable_small])
|
||||
AM_CONDITIONAL(COND_SMALL, test "x$enable_small" = xyes)
|
||||
|
||||
###############################################################################
|
||||
# Checks for programs.
|
||||
###############################################################################
|
||||
|
||||
echo
|
||||
echo "Initializing Automake:"
|
||||
|
||||
@@ -335,17 +354,11 @@ echo "Initializing Automake:"
|
||||
CXX=no
|
||||
F77=no
|
||||
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
###############################################################################
|
||||
# Checks for programs.
|
||||
###############################################################################
|
||||
|
||||
AM_INIT_AUTOMAKE([1.10 foreign tar-v7 filename-length-max=99])
|
||||
AC_PROG_LN_S
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_AS
|
||||
AC_PROG_LN_S
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
echo
|
||||
echo "Threading support:"
|
||||
@@ -392,10 +405,21 @@ AC_CHECK_HEADERS([assert.h errno.h byteswap.h sys/param.h sys/sysctl.h],
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
###############################################################################
|
||||
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_INLINE
|
||||
AC_C_RESTRICT
|
||||
|
||||
AC_HEADER_STDBOOL
|
||||
|
||||
AC_TYPE_UINT8_T
|
||||
AC_TYPE_INT32_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_INT64_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINTPTR_T
|
||||
|
||||
AC_CHECK_SIZEOF([unsigned long])
|
||||
AC_CHECK_SIZEOF([size_t])
|
||||
|
||||
# The command line tool can copy high resolution timestamps if such
|
||||
# information is availabe in struct stat. Otherwise one second accuracy
|
||||
# is used. Most systems seem to have st_xtim but BSDs have st_xtimespec.
|
||||
@@ -516,7 +540,7 @@ main()
|
||||
|
||||
Wno_uninitialized=no
|
||||
|
||||
if test -n "$GCC" ; then
|
||||
if test "x$GCC" = xyes ; then
|
||||
echo
|
||||
echo "GCC extensions:"
|
||||
gl_VISIBILITY
|
||||
@@ -545,13 +569,29 @@ if test -n "$GCC" ; then
|
||||
# * -Winline, -Wdisabled-optimization, -Wunsafe-loop-optimizations
|
||||
# don't seem so useful here; at least the last one gives some
|
||||
# warnings which are not bugs.
|
||||
for NEW_FLAG in -Wextra -Wformat=2 -Winit-self -Wstrict-aliasing=2 \
|
||||
-Wfloat-equal -Wshadow -Wpointer-arith \
|
||||
-Wbad-function-cast -Wwrite-strings \
|
||||
-Waggregate-return -Wstrict-prototypes \
|
||||
-Wold-style-definition -Wmissing-prototypes \
|
||||
-Wmissing-declarations -Wmissing-noreturn \
|
||||
-Wredundant-decls
|
||||
#
|
||||
# The flags are in reverse order below so they end up in "beautiful"
|
||||
# order on the actual command line.
|
||||
for NEW_FLAG in \
|
||||
-Wredundant-decls \
|
||||
-Wmissing-noreturn \
|
||||
-Wmissing-declarations \
|
||||
-Wmissing-prototypes \
|
||||
-Wold-style-definition \
|
||||
-Wstrict-prototypes \
|
||||
-Waggregate-return \
|
||||
-Wwrite-strings \
|
||||
-Wbad-function-cast \
|
||||
-Wpointer-arith \
|
||||
-Wshadow \
|
||||
-Wfloat-equal \
|
||||
-Wstrict-aliasing=2 \
|
||||
-Winit-self \
|
||||
-Wformat=2 \
|
||||
-Wextra \
|
||||
-Wall \
|
||||
-pedantic \
|
||||
-std=c99
|
||||
do
|
||||
AC_MSG_CHECKING([if $CC accepts $NEW_FLAG])
|
||||
OLD_CFLAGS="$CFLAGS"
|
||||
@@ -571,9 +611,6 @@ if test -n "$GCC" ; then
|
||||
if test "x$enable_werror" = "xyes"; then
|
||||
CFLAGS="-Werror $CFLAGS"
|
||||
fi
|
||||
|
||||
# IIRC these work with all GCC versions that support -std=c99:
|
||||
CFLAGS="-std=c99 -pedantic -Wall $CFLAGS"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL([COND_WNO_UNINITIALIZED], test "x$Wno_uninitialized" = "xyes")
|
||||
@@ -609,6 +646,7 @@ AC_CONFIG_FILES([
|
||||
src/lzmadec/Makefile
|
||||
src/scripts/Makefile
|
||||
tests/Makefile
|
||||
debug/Makefile
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
33
debug/Makefile.am
Normal file
33
debug/Makefile.am
Normal file
@@ -0,0 +1,33 @@
|
||||
##
|
||||
## Copyright (C) 2008 Lasse Collin
|
||||
##
|
||||
## This library is free software; you can redistribute it and/or
|
||||
## modify it under the terms of the GNU Lesser General Public
|
||||
## License as published by the Free Software Foundation; either
|
||||
## version 2.1 of the License, or (at your option) any later version.
|
||||
##
|
||||
## This library is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
## Lesser General Public License for more details.
|
||||
##
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
repeat \
|
||||
sync_flush \
|
||||
full_flush \
|
||||
memusage
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I@top_srcdir@/src/common \
|
||||
-I@top_srcdir@/src/liblzma/api
|
||||
|
||||
AM_LDFLAGS = -static
|
||||
|
||||
LDADD = \
|
||||
@top_builddir@/src/liblzma/liblzma.la \
|
||||
@LTLIBINTL@
|
||||
|
||||
if COND_GNULIB
|
||||
LDADD += @top_builddir@/lib/libgnu.a
|
||||
endif
|
||||
17
debug/README
Normal file
17
debug/README
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
Debug tools
|
||||
-----------
|
||||
|
||||
This directory contains a few tiny programs that may be helpful when
|
||||
debugging LZMA Utils.
|
||||
|
||||
These tools are not meant to be installed. Often one needs to edit
|
||||
the source code a little to make the programs do the wanted things.
|
||||
If you don't know how these programs could help you, it is likely
|
||||
that they really are useless to you.
|
||||
|
||||
These aren't intended to be used as example programs. They take some
|
||||
shortcuts here and there, which correct programs should not do. Many
|
||||
possible errors (especially I/O errors) are ignored. Don't report
|
||||
bugs or send patches to fix this kind of bugs.
|
||||
|
||||
105
debug/full_flush.c
Normal file
105
debug/full_flush.c
Normal file
@@ -0,0 +1,105 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file full_flush.c
|
||||
/// \brief Encode files using LZMA_FULL_FLUSH
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "sysdefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static lzma_stream strm = LZMA_STREAM_INIT;
|
||||
static FILE *file_in;
|
||||
|
||||
|
||||
static void
|
||||
encode(size_t size, lzma_action action)
|
||||
{
|
||||
static const size_t CHUNK = 64;
|
||||
uint8_t in[CHUNK];
|
||||
uint8_t out[CHUNK];
|
||||
lzma_ret ret;
|
||||
|
||||
do {
|
||||
if (strm.avail_in == 0 && size > 0) {
|
||||
const size_t amount = MIN(size, CHUNK);
|
||||
strm.avail_in = fread(in, 1, amount, file_in);
|
||||
strm.next_in = in;
|
||||
size -= amount; // Intentionally not using avail_in.
|
||||
}
|
||||
|
||||
strm.next_out = out;
|
||||
strm.avail_out = CHUNK;
|
||||
|
||||
ret = lzma_code(&strm, size == 0 ? action : LZMA_RUN);
|
||||
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
|
||||
fprintf(stderr, "%s:%u: %s: ret == %d\n",
|
||||
__FILE__, __LINE__, __func__, ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fwrite(out, 1, CHUNK - strm.avail_out, stdout);
|
||||
|
||||
} while (size > 0 || strm.avail_out == 0);
|
||||
|
||||
if ((action == LZMA_RUN && ret != LZMA_OK)
|
||||
|| (action != LZMA_RUN && ret != LZMA_STREAM_END)) {
|
||||
fprintf(stderr, "%s:%u: %s: ret == %d\n",
|
||||
__FILE__, __LINE__, __func__, ret);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
lzma_init_encoder();
|
||||
|
||||
file_in = argc > 1 ? fopen(argv[1], "rb") : stdin;
|
||||
|
||||
// Config
|
||||
lzma_options_stream opt_stream = {
|
||||
.check = LZMA_CHECK_CRC32,
|
||||
.has_crc32 = true,
|
||||
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
|
||||
.alignment = 0,
|
||||
};
|
||||
opt_stream.filters[0].id = LZMA_VLI_VALUE_UNKNOWN;
|
||||
opt_stream.metadata_filters[0].id = LZMA_VLI_VALUE_UNKNOWN;
|
||||
opt_stream.header = NULL;
|
||||
opt_stream.footer = NULL;
|
||||
|
||||
// Init
|
||||
if (lzma_stream_encoder_multi(&strm, &opt_stream) != LZMA_OK) {
|
||||
fprintf(stderr, "init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Encoding
|
||||
encode(0, LZMA_FULL_FLUSH);
|
||||
encode(6, LZMA_FULL_FLUSH);
|
||||
encode(0, LZMA_FULL_FLUSH);
|
||||
encode(7, LZMA_FULL_FLUSH);
|
||||
encode(0, LZMA_FULL_FLUSH);
|
||||
encode(0, LZMA_FINISH);
|
||||
|
||||
// Clean up
|
||||
lzma_end(&strm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
55
debug/memusage.c
Normal file
55
debug/memusage.c
Normal file
@@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file memusage.c
|
||||
/// \brief Calculates memory usage using lzma_memory_usage()
|
||||
///
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "sysdefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
||||
lzma_options_lzma lzma = {
|
||||
.dictionary_size = (1 << 27) + (1 << 26),
|
||||
.literal_context_bits = 3,
|
||||
.literal_pos_bits = 0,
|
||||
.pos_bits = 2,
|
||||
.preset_dictionary = NULL,
|
||||
.preset_dictionary_size = 0,
|
||||
.mode = LZMA_MODE_BEST,
|
||||
.fast_bytes = 48,
|
||||
.match_finder = LZMA_MF_BT4,
|
||||
.match_finder_cycles = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
lzma_options_filter filters[] = {
|
||||
{ LZMA_FILTER_LZMA,
|
||||
(lzma_options_lzma *)&lzma_preset_lzma[6 - 1] },
|
||||
{ UINT64_MAX, NULL }
|
||||
};
|
||||
*/
|
||||
lzma_options_filter filters[] = {
|
||||
{ LZMA_FILTER_LZMA, &lzma },
|
||||
{ UINT64_MAX, NULL }
|
||||
};
|
||||
|
||||
printf("%u MiB\n", lzma_memory_usage(filters, true));
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
debug/repeat.c
Normal file
43
debug/repeat.c
Normal file
@@ -0,0 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file repeat.c
|
||||
/// \brief Repeats given string given times
|
||||
///
|
||||
/// This program can be useful when debugging run-length encoder in
|
||||
/// the Subblock filter, especially the condition when repeat count
|
||||
/// doesn't fit into 28-bit integer.
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "sysdefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s COUNT STRING\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
unsigned long long count = strtoull(argv[1], NULL, 10);
|
||||
const size_t size = strlen(argv[2]);
|
||||
|
||||
while (count-- != 0)
|
||||
fwrite(argv[2], 1, size, stdout);
|
||||
|
||||
return !!(ferror(stdout) || fclose(stdout));
|
||||
}
|
||||
138
debug/sync_flush.c
Normal file
138
debug/sync_flush.c
Normal file
@@ -0,0 +1,138 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file sync_flush.c
|
||||
/// \brief Encode files using LZMA_SYNC_FLUSH
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "sysdefs.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static lzma_stream strm = LZMA_STREAM_INIT;
|
||||
static FILE *file_in;
|
||||
|
||||
|
||||
static void
|
||||
encode(size_t size, lzma_action action)
|
||||
{
|
||||
static const size_t CHUNK = 64;
|
||||
uint8_t in[CHUNK];
|
||||
uint8_t out[CHUNK];
|
||||
lzma_ret ret;
|
||||
|
||||
do {
|
||||
if (strm.avail_in == 0 && size > 0) {
|
||||
const size_t amount = MIN(size, CHUNK);
|
||||
strm.avail_in = fread(in, 1, amount, file_in);
|
||||
strm.next_in = in;
|
||||
size -= amount; // Intentionally not using avail_in.
|
||||
}
|
||||
|
||||
strm.next_out = out;
|
||||
strm.avail_out = CHUNK;
|
||||
|
||||
ret = lzma_code(&strm, size == 0 ? action : LZMA_RUN);
|
||||
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
|
||||
fprintf(stderr, "%s:%u: %s: ret == %d\n",
|
||||
__FILE__, __LINE__, __func__, ret);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fwrite(out, 1, CHUNK - strm.avail_out, stdout);
|
||||
|
||||
} while (size > 0 || strm.avail_out == 0);
|
||||
|
||||
if ((action == LZMA_RUN && ret != LZMA_OK)
|
||||
|| (action != LZMA_RUN && ret != LZMA_STREAM_END)) {
|
||||
fprintf(stderr, "%s:%u: %s: ret == %d\n",
|
||||
__FILE__, __LINE__, __func__, ret);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
lzma_init_encoder();
|
||||
|
||||
file_in = argc > 1 ? fopen(argv[1], "rb") : stdin;
|
||||
|
||||
// Config
|
||||
lzma_options_lzma opt_lzma = {
|
||||
.dictionary_size = 1 << 16,
|
||||
.literal_context_bits = LZMA_LITERAL_CONTEXT_BITS_DEFAULT,
|
||||
.literal_pos_bits = LZMA_LITERAL_POS_BITS_DEFAULT,
|
||||
.pos_bits = LZMA_POS_BITS_DEFAULT,
|
||||
.preset_dictionary = NULL,
|
||||
.mode = LZMA_MODE_BEST,
|
||||
.fast_bytes = 32,
|
||||
.match_finder = LZMA_MF_BT3,
|
||||
.match_finder_cycles = 0,
|
||||
};
|
||||
|
||||
lzma_options_delta opt_delta = {
|
||||
.distance = 16
|
||||
};
|
||||
|
||||
lzma_options_subblock opt_subblock = {
|
||||
.allow_subfilters = true,
|
||||
.alignment = 8, // LZMA_SUBBLOCK_ALIGNMENT_DEFAULT,
|
||||
.subblock_data_size = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT,
|
||||
.rle = 1, // LZMA_SUBBLOCK_RLE_OFF,
|
||||
.subfilter_mode = LZMA_SUBFILTER_SET,
|
||||
};
|
||||
opt_subblock.subfilter_options.id = LZMA_FILTER_LZMA;
|
||||
opt_subblock.subfilter_options.options = &opt_lzma;
|
||||
opt_subblock.subfilter_options.id = LZMA_FILTER_DELTA;
|
||||
opt_subblock.subfilter_options.options = &opt_delta;
|
||||
|
||||
lzma_options_stream opt_stream = {
|
||||
.check = LZMA_CHECK_NONE,
|
||||
.has_crc32 = false,
|
||||
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
|
||||
.alignment = 0,
|
||||
};
|
||||
opt_stream.filters[0].id = LZMA_FILTER_SUBBLOCK;
|
||||
opt_stream.filters[0].options = &opt_subblock;
|
||||
opt_stream.filters[1].id = LZMA_VLI_VALUE_UNKNOWN;
|
||||
|
||||
// Init
|
||||
if (lzma_stream_encoder_single(&strm, &opt_stream) != LZMA_OK) {
|
||||
fprintf(stderr, "init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Encoding
|
||||
encode(0, LZMA_SYNC_FLUSH);
|
||||
encode(6, LZMA_SYNC_FLUSH);
|
||||
encode(0, LZMA_SYNC_FLUSH);
|
||||
encode(6, LZMA_SYNC_FLUSH);
|
||||
encode(0, LZMA_SYNC_FLUSH);
|
||||
encode(0, LZMA_FINISH);
|
||||
|
||||
// Clean up
|
||||
lzma_end(&strm);
|
||||
|
||||
return 0;
|
||||
|
||||
// Prevent useless warnings so we don't need to have special CFLAGS
|
||||
// to disable -Werror.
|
||||
(void)opt_lzma;
|
||||
(void)opt_subblock;
|
||||
(void)opt_delta;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ The .lzma File Format
|
||||
This document describes the .lzma file format (filename suffix
|
||||
`.lzma', MIME type `application/x-lzma'). It is intended that
|
||||
this format replace the format used by the LZMA_Alone tool
|
||||
included in LZMA SDK up to and including version 4.43.
|
||||
included in LZMA SDK up to and including version 4.57.
|
||||
|
||||
IMPORTANT: The version described in this document is a
|
||||
draft, NOT a final, official version. Changes
|
||||
@@ -112,7 +112,7 @@ The .lzma File Format
|
||||
|
||||
0.2. Changes
|
||||
|
||||
Last modified: 2007-12-02 22:40+0200
|
||||
Last modified: 2008-02-01 19:25+0200
|
||||
|
||||
(A changelog will be kept once the first official version
|
||||
is made.)
|
||||
@@ -812,8 +812,8 @@ The .lzma File Format
|
||||
When a filter that cannot embed End of Payload Marker is the
|
||||
last filter in the chain, Subblock filter is appended to the
|
||||
chain as an implicit filter. In the simplest case, this occurs
|
||||
when no filters are specified, and Uncompressed Size is unknown
|
||||
or the End of Payload Marker bit is set in Block Flags.
|
||||
when no filters are specified, and the End of Payload Marker
|
||||
bit is set in Block Flags.
|
||||
|
||||
|
||||
4.1.3. With End of Payload Marker
|
||||
@@ -1197,7 +1197,7 @@ The .lzma File Format
|
||||
|
||||
4.3.4.1. LZMA Properties
|
||||
|
||||
The LZMA Properties bits contain three properties. An
|
||||
The LZMA Properties field contains three properties. An
|
||||
abbreviation is given in parentheses, followed by the value
|
||||
range of the property. The field consists of
|
||||
|
||||
|
||||
@@ -5,8 +5,14 @@ Introduction to liblzma
|
||||
Writing applications to work with liblzma
|
||||
|
||||
liblzma API is split in several subheaders to improve readability and
|
||||
maintainance. The subheaders must not be #included directly; simply
|
||||
use `#include <lzma.h>' instead.
|
||||
maintainance. The subheaders must not be #included directly. lzma.h
|
||||
requires that certain integer types and macros are available when
|
||||
the header is #included. On systems that have inttypes.h that conforms
|
||||
to C99, the following will work:
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
#include <lzma.h>
|
||||
|
||||
Those who have used zlib should find liblzma's API easy to use.
|
||||
To developers who haven't used zlib before, I recommend learning
|
||||
|
||||
@@ -15,19 +15,11 @@
|
||||
|
||||
## Not using gnulib-tool, at least for now. Less mess this way.
|
||||
|
||||
## We need two builds of libgnu: one with NLS and one without.
|
||||
## This is because lzma uses NLS but lzmadec doesn't, while
|
||||
## both need GNU getopt_long().
|
||||
noinst_LIBRARIES = libgnu.a libgnu_nls.a
|
||||
noinst_LIBRARIES = libgnu.a
|
||||
|
||||
libgnu_a_SOURCES =
|
||||
libgnu_a_DEPENDENCIES = $(LIBOBJS)
|
||||
libgnu_a_LIBADD = $(LIBOBJS)
|
||||
libgnu_a_CPPFLAGS = -DDISABLE_NLS=1
|
||||
|
||||
libgnu_nls_a_SOURCES =
|
||||
libgnu_nls_a_DEPENDENCIES = $(LIBOBJS)
|
||||
libgnu_nls_a_LIBADD = $(LIBOBJS)
|
||||
|
||||
EXTRA_DIST = gettext.h getopt_.h getopt.c getopt1.c getopt_int.h
|
||||
BUILT_SOURCES = $(GETOPT_H)
|
||||
|
||||
12
po/fi.po
12
po/fi.po
@@ -5,7 +5,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: fi\n"
|
||||
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
|
||||
"POT-Creation-Date: 2007-12-10 14:34+0200\n"
|
||||
"POT-Creation-Date: 2008-01-07 21:30+0200\n"
|
||||
"PO-Revision-Date: 2007-08-09 22:14+0300\n"
|
||||
"Last-Translator: Lasse Collin <lasse.collin@tukaani.org>\n"
|
||||
"Language-Team: Finnish\n"
|
||||
@@ -124,14 +124,14 @@ msgstr ""
|
||||
msgid "With no FILE, or when FILE is -, read standard input.\n"
|
||||
msgstr "Jos TIEDOSTOa ei ole annettu, tai se on \"-\", luetaan vakiosyötettä.\n"
|
||||
|
||||
#: src/lzma/help.c:143
|
||||
#: src/lzma/help.c:144
|
||||
msgid "On this system and configuration, the tool will use"
|
||||
msgstr "Tässä järjestelmässä näillä asetuksilla, tämä työkalu käyttää"
|
||||
|
||||
#: src/lzma/help.c:144
|
||||
#: src/lzma/help.c:145
|
||||
#, c-format
|
||||
msgid " * roughly %zu MiB of memory at maximum; and\n"
|
||||
msgstr " * korkeintaan %zu MiB keskusmuistia (suurpiirteinen rajoitus); ja\n"
|
||||
msgid " * roughly %<PRIu64> MiB of memory at maximum; and\n"
|
||||
msgstr " * korkeintaan %<PRIu64> MiB keskusmuistia (suurpiirteinen rajoitus); ja\n"
|
||||
|
||||
#: src/lzma/help.c:147
|
||||
msgid ""
|
||||
@@ -141,7 +141,7 @@ msgstr ""
|
||||
" * korkeintaan yhtä säiettä pakkaukseen tai purkuun.\n"
|
||||
"\n"
|
||||
|
||||
#: src/lzma/help.c:151
|
||||
#: src/lzma/help.c:152
|
||||
#, c-format
|
||||
msgid "Report bugs to <%s> (in English or Finnish).\n"
|
||||
msgstr ""
|
||||
|
||||
@@ -14,17 +14,6 @@
|
||||
#ifndef PHYSMEM_H
|
||||
#define PHYSMEM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PHYSMEM_SYSCTL) || defined(HAVE_NCPU_SYSCTL)
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
|
||||
@@ -31,7 +31,62 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "lzma.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
// Be more compatible with systems that have non-conforming inttypes.h.
|
||||
// We assume that int is 32-bit and that long is either 32-bit or 64-bit.
|
||||
// Full Autoconf test could be more correct, but this should work well enough.
|
||||
#ifndef UINT32_C
|
||||
# define UINT32_C(n) n ## U
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX UINT32_C(4294967295)
|
||||
#endif
|
||||
#ifndef PRIu32
|
||||
# define PRIu32 "u"
|
||||
#endif
|
||||
#ifndef PRIX32
|
||||
# define PRIX32 "X"
|
||||
#endif
|
||||
#if SIZEOF_UNSIGNED_LONG == 4
|
||||
# ifndef UINT64_C
|
||||
# define UINT64_C(n) n ## ULL
|
||||
# endif
|
||||
# ifndef PRIu64
|
||||
# define PRIu64 "llu"
|
||||
# endif
|
||||
# ifndef PRIX64
|
||||
# define PRIX64 "llX"
|
||||
# endif
|
||||
#else
|
||||
# ifndef UINT64_C
|
||||
# define UINT64_C(n) n ## UL
|
||||
# endif
|
||||
# ifndef PRIu64
|
||||
# define PRIu64 "lu"
|
||||
# endif
|
||||
# ifndef PRIX64
|
||||
# define PRIX64 "lX"
|
||||
# endif
|
||||
#endif
|
||||
#ifndef UINT64_MAX
|
||||
# define UINT64_MAX UINT64_C(18446744073709551615)
|
||||
#endif
|
||||
#ifndef SIZE_MAX
|
||||
# if SIZEOF_SIZE_T == 4
|
||||
# define SIZE_MAX UINT32_MAX
|
||||
# else
|
||||
# define SIZE_MAX UINT64_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -70,6 +125,8 @@ typedef unsigned char _Bool;
|
||||
# include <memory.h>
|
||||
#endif
|
||||
|
||||
#include "lzma.h"
|
||||
|
||||
|
||||
////////////
|
||||
// Macros //
|
||||
@@ -97,4 +154,8 @@ typedef unsigned char _Bool;
|
||||
# define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@ nobase_include_HEADERS = \
|
||||
lzma/check.h \
|
||||
lzma/copy.h \
|
||||
lzma/delta.h \
|
||||
lzma/easy.h \
|
||||
lzma/extra.h \
|
||||
lzma/filter.h \
|
||||
lzma/index.h \
|
||||
|
||||
@@ -17,25 +17,37 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Before #including this file, you must make the following types available:
|
||||
* - size_t
|
||||
* - uint8_t
|
||||
* - int32_t
|
||||
* - uint32_t
|
||||
* - int64_t
|
||||
* - uint64_t
|
||||
*
|
||||
* Before #including this file, you must make the following macros available:
|
||||
* - UINT32_C(n)
|
||||
* - UINT64_C(n)
|
||||
* - UINT32_MAX
|
||||
* - UINT64_MAX
|
||||
*
|
||||
* Easiest way to achieve the above is to #include sys/types.h and inttypes.h
|
||||
* before #including lzma.h. However, some pre-C99 libc headers don't provide
|
||||
* all the required types in inttypes.h (that file may even be missing).
|
||||
* Portable applications need to provide these types themselves. This way
|
||||
* liblzma API can use the standard types instead of defining its own
|
||||
* (e.g. lzma_uint32).
|
||||
*
|
||||
* Note that the API still has lzma_bool, because using stdbool.h would
|
||||
* break C89 and C++ programs on many systems.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H
|
||||
#define LZMA_H
|
||||
|
||||
/********************
|
||||
* External headers *
|
||||
********************/
|
||||
|
||||
/* size_t */
|
||||
#include <sys/types.h>
|
||||
|
||||
/* NULL */
|
||||
#include <stddef.h>
|
||||
|
||||
/* uint8_t, uint32_t, uint64_t, UINT32_C, UINT64_C, UINT64_MAX. */
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
/******************
|
||||
* GCC extensions *
|
||||
******************/
|
||||
@@ -99,6 +111,7 @@ extern "C" {
|
||||
#include "lzma/alone.h"
|
||||
#include "lzma/raw.h"
|
||||
#include "lzma/auto.h"
|
||||
#include "lzma/easy.h"
|
||||
|
||||
/* Advanced features */
|
||||
#include "lzma/info.h"
|
||||
|
||||
@@ -315,7 +315,7 @@ typedef struct lzma_internal_s lzma_internal;
|
||||
* Application must not touch the `internal' pointer.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *next_in; /**< Pointer to the next input byte. */
|
||||
const uint8_t *next_in; /**< Pointer to the next input byte. */
|
||||
size_t avail_in; /**< Number of available input bytes in next_in. */
|
||||
uint64_t total_in; /**< Total number of bytes read by liblzma. */
|
||||
|
||||
|
||||
174
src/liblzma/api/lzma/easy.h
Normal file
174
src/liblzma/api/lzma/easy.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* \file lzma/easy.h
|
||||
* \brief Easy to use encoder initialization
|
||||
*
|
||||
* \author Copyright (C) 1999-2006 Igor Pavlov
|
||||
* \author Copyright (C) 2008 Lasse Collin
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Compression level names for lzma_easy_* functions
|
||||
*
|
||||
* At the moment, all the compression levels support LZMA_SYNC_FLUSH.
|
||||
* In future there may be levels that don't support LZMA_SYNC_FLUSH.
|
||||
* However, the LZMA_SYNC_FLUSH support won't be removed from the
|
||||
* existing compression levels.
|
||||
*
|
||||
* \note If liblzma is built without encoder support, or with some
|
||||
* filters disabled, some of the compression levels may be
|
||||
* unsupported. In that case, the initialization functions
|
||||
* will return LZMA_HEADER_ERROR.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_EASY_COPY,
|
||||
/**<
|
||||
* No compression; the data is just wrapped into .lzma
|
||||
* container.
|
||||
*/
|
||||
|
||||
LZMA_EASY_LZMA_1,
|
||||
/**<
|
||||
* LZMA filter with fast compression (fast in terms of LZMA).
|
||||
* If you are interested in the exact options used, see
|
||||
* lzma_preset_lzma[0]. Note that the exact options may
|
||||
* change between liblzma versions.
|
||||
*
|
||||
* At the moment, the command line tool uses these settings
|
||||
* when `lzma -1' is used. In future, the command line tool
|
||||
* may default to some more complex way to determine the
|
||||
* settings used e.g. the type of files being compressed.
|
||||
*
|
||||
* LZMA_EASY_LZMA_2 is equivalent to lzma_preset_lzma[1]
|
||||
* and so on.
|
||||
*/
|
||||
|
||||
LZMA_EASY_LZMA_2,
|
||||
LZMA_EASY_LZMA_3,
|
||||
LZMA_EASY_LZMA_4,
|
||||
LZMA_EASY_LZMA_5,
|
||||
LZMA_EASY_LZMA_6,
|
||||
LZMA_EASY_LZMA_7,
|
||||
LZMA_EASY_LZMA_8,
|
||||
LZMA_EASY_LZMA_9,
|
||||
} lzma_easy_level;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Default compression level for Data Blocks
|
||||
*
|
||||
* Data Blocks contain the actual compressed data. It's not straightforward
|
||||
* to recommend a default level, because in some cases keeping the resource
|
||||
* usage relatively low is more important that getting the maximum
|
||||
* compression ratio.
|
||||
*/
|
||||
#define LZMA_EASY_DEFAULT LZMA_EASY_LZMA_7
|
||||
|
||||
|
||||
/**
|
||||
* \brief Default compression level for Metadata Blocks
|
||||
*
|
||||
* Metadata Blocks are present only in Multi-Block Streams. Metadata Blocks
|
||||
* contain the Extra Records (if any) and some book-keeping data that is
|
||||
* used by decoders.
|
||||
*/
|
||||
#define LZMA_EASY_METADATA_DEFAULT LZMA_EASY_LZMA_3
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculates rough memory requirements of a compression level
|
||||
*
|
||||
* This function is a wrapper for lzma_memory_usage(), which is declared
|
||||
* in lzma/filter.h.
|
||||
*
|
||||
* \return Approximate memory usage of the encoder with the given
|
||||
* compression level in mebibytes (value * 1024 * 1024 bytes).
|
||||
* On error (e.g. compression level is not supported),
|
||||
* UINT32_MAX is returned.
|
||||
*/
|
||||
extern uint32_t lzma_easy_memory_usage(lzma_easy_level level);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initializes Single-Block .lzma Stream encoder
|
||||
*
|
||||
* This function is intended for those who just want to use the basic LZMA
|
||||
* features (that is, most developers out there). Lots of assumptions are
|
||||
* made, which are correct for most situations or at least good enough.
|
||||
*
|
||||
* \param strm Pointer to lzma_stream that is at least initialized
|
||||
* with LZMA_STREAM_INIT.
|
||||
* \param level Compression level to use. This selects a set of
|
||||
* compression settings from a list of compression
|
||||
* presets.
|
||||
*
|
||||
* \return - LZMA_OK: Initialization succeeded. Use lzma_code() to
|
||||
* encode your data.
|
||||
* - LZMA_MEM_ERROR: Memory allocation failed. All memory
|
||||
* previously allocated for *strm is now freed.
|
||||
* - LZMA_HEADER_ERROR: The given compression level is not
|
||||
* supported by this build of liblzma.
|
||||
*
|
||||
* If initialization succeeds, use lzma_code() to do the actual encoding.
|
||||
* Valid values for `action' (the second argument of lzma_code()) are
|
||||
* LZMA_RUN, LZMA_SYNC_FLUSH, and LZMA_FINISH. In future, there may be
|
||||
* compression levels that don't support LZMA_SYNC_FLUSH.
|
||||
*/
|
||||
extern lzma_ret lzma_easy_encoder_single(
|
||||
lzma_stream *strm, lzma_easy_level level);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initializes Multi-Block .lzma Stream encoder
|
||||
*
|
||||
* If you want to be able to store Extra Records or want to be able to use
|
||||
* LZMA_FULL_FLUSH, you need to create a Multi-Block Stream.
|
||||
*
|
||||
* \param strm Pointer to lzma_stream that is at least initialized
|
||||
* with LZMA_STREAM_INIT.
|
||||
* \param level Compression level to use for the data being encoded.
|
||||
* \param metadata_level
|
||||
* Compression level to use for Metadata Blocks.
|
||||
* Metadata Blocks contain the Extra Records (if any)
|
||||
* and some book-keeping data that is used by decoders.
|
||||
* \param header Pointer to a list of Extra Records to be stored to
|
||||
* the Header Metadata Block. Set this to NULL to omit
|
||||
* Header Metadata Block completely. The list must be
|
||||
* kept available until the encoding has finished.
|
||||
* \param footer Pointer to a list of Extra Records to be stored to
|
||||
* the Footer Metadata Block. Set this to NULL if you
|
||||
* don't want to store any Extra Records (the Footer
|
||||
* Metadata Block will still be written for other
|
||||
* reasons.) The list must be kept available until
|
||||
* the encoding has finished.
|
||||
*
|
||||
* \return - LZMA_OK: Initialization succeeded. Use lzma_code() to
|
||||
* encode your data.
|
||||
* - LZMA_MEM_ERROR: Memory allocation failed. All memory
|
||||
* previously allocated for *strm is now freed.
|
||||
* - LZMA_HEADER_ERROR: The given compression level is not
|
||||
* supported by this build of liblzma.
|
||||
*
|
||||
* If initialization succeeds, use lzma_code() to do the actual encoding.
|
||||
* Valid values for `action' (the second argument of lzma_code()) are
|
||||
* LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future,
|
||||
* there may be compression levels that don't support LZMA_SYNC_FLUSH.
|
||||
* LZMA_FULL_FLUSH will always work with all compression levels.
|
||||
*/
|
||||
extern lzma_ret lzma_easy_encoder_multi(lzma_stream *strm,
|
||||
lzma_easy_level level, lzma_easy_level metadata_level,
|
||||
const lzma_extra *header, const lzma_extra *footer);
|
||||
@@ -302,7 +302,7 @@ extern const lzma_match_finder *const lzma_available_match_finders;
|
||||
/**
|
||||
* \brief Table of presets for the LZMA filter
|
||||
*
|
||||
* lzma_presets[0] is the fastest and lzma_preset_lzma[8] is the slowest.
|
||||
* lzma_preset_lzma[0] is the fastest and lzma_preset_lzma[8] is the slowest.
|
||||
* These presets match the switches -1 .. -9 of the lzma command line tool
|
||||
*
|
||||
* The preset values are subject to changes between liblzma versions.
|
||||
|
||||
@@ -92,6 +92,51 @@ extern size_t lzma_memlimit_get(const lzma_memlimit *mem);
|
||||
extern size_t lzma_memlimit_used(const lzma_memlimit *mem);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Gets the maximum amount of memory required in total
|
||||
*
|
||||
* Returns how much memory was or would have been allocated at the same time.
|
||||
* If lzma_memlimit_alloc() was requested so much memory that the limit
|
||||
* would have been exceeded or malloc() simply ran out of memory, the
|
||||
* requested amount is still included to the value returned by
|
||||
* lzma_memlimit_max(). This may be used as a hint how much bigger memory
|
||||
* limit would have been needed.
|
||||
*
|
||||
* If the clear flag is set, the internal variable holding the maximum
|
||||
* value is set to the current memory usage (the same value as returned
|
||||
* by lzma_memlimit_used()).
|
||||
*
|
||||
* \note Usually liblzma needs to allocate many chunks of memory, and
|
||||
* displaying a message like "memory usage limit reached, at
|
||||
* least 1024 bytes would have been needed" may be confusing,
|
||||
* because the next allocation could have been e.g. 8 MiB.
|
||||
*
|
||||
* \todo The description of this function is unclear.
|
||||
*/
|
||||
extern size_t lzma_memlimit_max(lzma_memlimit *mem, lzma_bool clear);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Checks if memory limit was reached at some point
|
||||
*
|
||||
* This function is useful to find out if the reason for LZMA_MEM_ERROR
|
||||
* was running out of memory or hitting the memory usage limit imposed
|
||||
* by lzma_memlimit_alloc(). If the clear argument is true, the internal
|
||||
* flag, that indicates that limit was reached, is cleared.
|
||||
*/
|
||||
extern lzma_bool lzma_memlimit_reached(lzma_memlimit *mem, lzma_bool clear);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Gets the number of allocations owned by the memory limitter
|
||||
*
|
||||
* The count does not include the helper structures; if no memory has
|
||||
* been allocated with lzma_memlimit_alloc() or all memory allocated
|
||||
* has been freed or detached, this will return zero.
|
||||
*/
|
||||
extern size_t lzma_memlimit_count(const lzma_memlimit *mem);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Allocates memory with malloc() if memory limit allows
|
||||
*
|
||||
|
||||
@@ -64,6 +64,15 @@
|
||||
*
|
||||
* If options with non-default values have been specified when encoding,
|
||||
* the same options must also be specified when decoding.
|
||||
*
|
||||
* \note At the moment, none of the simple filters support
|
||||
* LZMA_SYNC_FLUSH. If LZMA_SYNC_FLUSH is specified,
|
||||
* LZMA_HEADER_ERROR will be returned. If there is need,
|
||||
* partial support for LZMA_SYNC_FLUSH can be added in future.
|
||||
* Partial means that flushing would be possible only at
|
||||
* offsets that are multiple of 2, 4, or 16 depending on
|
||||
* the filter, except x86 which cannot be made to support
|
||||
* LZMA_SYNC_FLUSH predictably.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
|
||||
@@ -111,7 +111,7 @@ typedef struct {
|
||||
/**
|
||||
* \brief Extra information in the Header Metadata Block
|
||||
*/
|
||||
lzma_extra *header;
|
||||
const lzma_extra *header;
|
||||
|
||||
/**
|
||||
* \brief Extra information in the Footer Metadata Block
|
||||
@@ -119,7 +119,7 @@ typedef struct {
|
||||
* It is enough to set this pointer any time before calling
|
||||
* lzma_code() with LZMA_FINISH as the second argument.
|
||||
*/
|
||||
lzma_extra *footer;
|
||||
const lzma_extra *footer;
|
||||
|
||||
} lzma_options_stream;
|
||||
|
||||
|
||||
@@ -95,9 +95,10 @@ typedef struct {
|
||||
* input_offset % alignment == output_offset % alignment
|
||||
*
|
||||
* The Subblock filter assumes that the first output byte will be
|
||||
* written to a position in the output stream that is properly aligned.
|
||||
*
|
||||
* FIXME desc
|
||||
* written to a position in the output stream that is properly
|
||||
* aligned. This requirement is automatically met when the start
|
||||
* offset of the Stream or Block is correctly told to Block or
|
||||
* Stream encoder.
|
||||
*/
|
||||
uint32_t alignment;
|
||||
# define LZMA_SUBBLOCK_ALIGNMENT_MIN 1
|
||||
@@ -161,16 +162,17 @@ typedef struct {
|
||||
*
|
||||
* When subfilter_mode is LZMA_SUBFILTER_NONE, the application may
|
||||
* put Subfilter options to subfilter_options structure, and then
|
||||
* set subfilter_mode to LZMA_SUBFILTER_SET. This implies setting
|
||||
* flush to true. No new input data will be read until the Subfilter
|
||||
* has been enabled. Once the Subfilter has been enabled, liblzma
|
||||
* will set subfilter_mode to LZMA_SUBFILTER_RUN.
|
||||
* set subfilter_mode to LZMA_SUBFILTER_SET. No new input data will
|
||||
* be read until the Subfilter has been enabled. Once the Subfilter
|
||||
* has been enabled, liblzma will set subfilter_mode to
|
||||
* LZMA_SUBFILTER_RUN.
|
||||
*
|
||||
* When subfilter_mode is LZMA_SUBFILTER_RUN, the application may
|
||||
* set subfilter_mode to LZMA_SUBFILTER_FINISH. No new input data
|
||||
* will be read until the Subfilter has been finished. Once the
|
||||
* Subfilter has been finished, liblzma will set subfilter_mode
|
||||
* to LZMA_SUBFILTER_NONE.
|
||||
* set subfilter_mode to LZMA_SUBFILTER_FINISH. All the input
|
||||
* currently available will be encoded before unsetting the
|
||||
* Subfilter. Application must not change the amount of available
|
||||
* input until the Subfilter has finished. Once the Subfilter has
|
||||
* finished, liblzma will set subfilter_mode to LZMA_SUBFILTER_NONE.
|
||||
*
|
||||
* If the intent is to have Subfilter enabled to the very end of
|
||||
* the data, it is not needed to separately disable Subfilter with
|
||||
@@ -178,6 +180,11 @@ typedef struct {
|
||||
* of lzma_code() will make the Subblock encoder to disable the
|
||||
* Subfilter once all the data has been ran through the Subfilter.
|
||||
*
|
||||
* After the first call with LZMA_SYNC_FLUSH or LZMA_FINISH, the
|
||||
* application must not change subfilter_mode until LZMA_STREAM_END.
|
||||
* Setting LZMA_SUBFILTER_SET/LZMA_SUBFILTER_FINISH and
|
||||
* LZMA_SYNC_FLUSH/LZMA_FINISH _at the same time_ is fine.
|
||||
*
|
||||
* \note This variable is ignored if allow_subfilters is false.
|
||||
*/
|
||||
lzma_subfilter_mode subfilter_mode;
|
||||
|
||||
@@ -24,14 +24,18 @@
|
||||
/**
|
||||
* \brief Compile-time version number
|
||||
*
|
||||
* The version number is of format xyyyuuus where
|
||||
* - x is the major LZMA SDK version
|
||||
* - yyy is the minor LZMA SDK version
|
||||
* - uuu is LZMA Utils version (reset to zero every time SDK version
|
||||
* is incremented)
|
||||
* The version number is of format xyyyzzzs where
|
||||
* - x = major
|
||||
* - yyy = minor
|
||||
* - zzz = revision
|
||||
* - s indicates stability: 0 = alpha, 1 = beta, 2 = stable
|
||||
*
|
||||
* See the README file for details about the version numbering.
|
||||
*
|
||||
* \note The version number of LZMA Utils (and thus liblzma)
|
||||
* has nothing to with the version number of LZMA SDK.
|
||||
*/
|
||||
#define LZMA_VERSION UINT32_C(40420010)
|
||||
#define LZMA_VERSION UINT32_C(49990030)
|
||||
|
||||
|
||||
/**
|
||||
@@ -49,11 +53,5 @@ extern const uint32_t lzma_version_number;
|
||||
*
|
||||
* This function may be useful if you want to display which version of
|
||||
* libilzma your application is currently using.
|
||||
*
|
||||
* \return Returns a pointer to a statically allocated string constant,
|
||||
* which contains the version number of liblzma. The format of
|
||||
* the version string is usually (but not necessarily) x.y.z
|
||||
* e.g. "4.42.1". Alpha and beta versions contain a suffix
|
||||
* ("4.42.0alpha").
|
||||
*/
|
||||
extern const char *const lzma_version_string;
|
||||
|
||||
@@ -154,7 +154,7 @@ typedef uint64_t lzma_vli;
|
||||
* The encoding scheme encodes seven bits to every byte, using minimum
|
||||
* number of bytes required to represent the given value. In other words,
|
||||
* it puts 7-63 bits into 1-9 bytes. This implementation limits the number
|
||||
* of bits used to 63, thus num must be at maximum of INT64_MAX / 2. You
|
||||
* of bits used to 63, thus num must be at maximum of UINT64_MAX / 2. You
|
||||
* may use LZMA_VLI_VALUE_MAX for clarity.
|
||||
*
|
||||
* \param vli Integer to be encoded
|
||||
|
||||
@@ -23,7 +23,7 @@ libcheck_la_CPPFLAGS = \
|
||||
if COND_CHECK_CRC32
|
||||
|
||||
if COND_ASM_X86
|
||||
libcheck_la_SOURCES += crc32_x86.s
|
||||
libcheck_la_SOURCES += crc32_x86.S
|
||||
else
|
||||
libcheck_la_SOURCES += crc32.c
|
||||
endif
|
||||
@@ -40,7 +40,7 @@ endif
|
||||
if COND_CHECK_CRC64
|
||||
|
||||
if COND_ASM_X86
|
||||
libcheck_la_SOURCES += crc64_x86.s
|
||||
libcheck_la_SOURCES += crc64_x86.S
|
||||
else
|
||||
libcheck_la_SOURCES += crc64.c
|
||||
endif
|
||||
|
||||
@@ -13,12 +13,9 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include "check.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# include "check_byteswap.h"
|
||||
#endif
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# include "crc32_table_be.h"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* This file has been automatically generated by crc32_tablegen.c. */
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
const uint32_t lzma_crc32_table[8][256] = {
|
||||
{
|
||||
0x00000000, 0x96300777, 0x2C610EEE, 0xBA510999,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* This file has been automatically generated by crc32_tablegen.c. */
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
const uint32_t lzma_crc32_table[8][256] = {
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// \file crc32_tablegen.c
|
||||
/// \brief Generates CRC32 crc32_table.c
|
||||
///
|
||||
/// Compiling: gcc -std=c99 -o crc32_tablegen crc32_tablegen.c crc32_init.c
|
||||
/// Compiling: gcc -std=c99 -o crc32_tablegen crc32_tablegen.c
|
||||
/// Add -DWORDS_BIGENDIAN to generate big endian table.
|
||||
//
|
||||
// This code has been put into the public domain.
|
||||
@@ -18,10 +18,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern void lzma_crc32_init(void);
|
||||
|
||||
extern uint32_t lzma_crc32_table[8][256];
|
||||
#include "crc32_init.c"
|
||||
|
||||
|
||||
int
|
||||
@@ -31,7 +28,6 @@ main()
|
||||
|
||||
printf("/* This file has been automatically generated by "
|
||||
"crc32_tablegen.c. */\n\n"
|
||||
"#include <inttypes.h>\n\n"
|
||||
"const uint32_t lzma_crc32_table[8][256] = {\n\t{");
|
||||
|
||||
for (size_t s = 0; s < 8; ++s) {
|
||||
|
||||
@@ -45,7 +45,7 @@ init_table(void)
|
||||
*/
|
||||
|
||||
.text
|
||||
.global lzma_crc32
|
||||
.globl lzma_crc32
|
||||
.type lzma_crc32, @function
|
||||
|
||||
.align 16
|
||||
@@ -215,3 +215,12 @@ lzma_crc32:
|
||||
ret
|
||||
|
||||
.size lzma_crc32, .-lzma_crc32
|
||||
|
||||
/*
|
||||
* This is needed to support non-executable stack. It's ugly to
|
||||
* use __linux__ here, but I don't know a way to detect when
|
||||
* we are using GNU assembler.
|
||||
*/
|
||||
#if defined(__ELF__) && defined(__linux__)
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#endif
|
||||
@@ -13,12 +13,9 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include "check.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# include "check_byteswap.h"
|
||||
#endif
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "common.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# include "crc64_table_be.h"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* This file has been automatically generated by crc64_tablegen.c. */
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
const uint64_t lzma_crc64_table[4][256] = {
|
||||
{
|
||||
UINT64_C(0x0000000000000000), UINT64_C(0x6F5FA703BE4C2EB3),
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* This file has been automatically generated by crc64_tablegen.c. */
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
const uint64_t lzma_crc64_table[4][256] = {
|
||||
{
|
||||
UINT64_C(0x0000000000000000), UINT64_C(0xB32E4CBE03A75F6F),
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/// \file crc64_tablegen.c
|
||||
/// \brief Generates CRC64 crc64_table.c
|
||||
///
|
||||
/// Compiling: gcc -std=c99 -o crc64_tablegen crc64_tablegen.c crc64_init.c
|
||||
/// Compiling: gcc -std=c99 -o crc64_tablegen crc64_tablegen.c
|
||||
/// Add -DWORDS_BIGENDIAN to generate big endian table.
|
||||
//
|
||||
// This code has been put into the public domain.
|
||||
@@ -18,10 +18,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
extern void lzma_crc64_init(void);
|
||||
|
||||
extern uint64_t lzma_crc64_table[4][256];
|
||||
#include "crc64_init.c"
|
||||
|
||||
|
||||
int
|
||||
@@ -31,7 +28,6 @@ main()
|
||||
|
||||
printf("/* This file has been automatically generated by "
|
||||
"crc64_tablegen.c. */\n\n"
|
||||
"#include <inttypes.h>\n\n"
|
||||
"const uint64_t lzma_crc64_table[4][256] = {\n\t{");
|
||||
|
||||
for (size_t s = 0; s < 4; ++s) {
|
||||
|
||||
@@ -38,7 +38,7 @@ init_table(void)
|
||||
*/
|
||||
|
||||
.text
|
||||
.global lzma_crc64
|
||||
.globl lzma_crc64
|
||||
.type lzma_crc64, @function
|
||||
|
||||
.align 16
|
||||
@@ -200,4 +200,13 @@ lzma_crc64:
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.size lzma_crc32, .-lzma_crc32
|
||||
.size lzma_crc64, .-lzma_crc64
|
||||
|
||||
/*
|
||||
* This is needed to support non-executable stack. It's ugly to
|
||||
* use __linux__ here, but I don't know a way to detect when
|
||||
* we are using GNU assembler.
|
||||
*/
|
||||
#if defined(__ELF__) && defined(__linux__)
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#endif
|
||||
@@ -23,7 +23,7 @@ libcommon_la_CPPFLAGS = \
|
||||
-I@top_srcdir@/src/liblzma/rangecoder
|
||||
libcommon_la_SOURCES = \
|
||||
common.h \
|
||||
sysdefs.h \
|
||||
bsr.h \
|
||||
allocator.c \
|
||||
block_private.h \
|
||||
extra.c \
|
||||
@@ -47,8 +47,18 @@ endif
|
||||
|
||||
if COND_FILTER_DELTA
|
||||
libcommon_la_SOURCES += \
|
||||
delta_coder.c \
|
||||
delta_coder.h
|
||||
delta_common.c \
|
||||
delta_common.h
|
||||
if COND_MAIN_ENCODER
|
||||
libcommon_la_SOURCES += \
|
||||
delta_encoder.c \
|
||||
delta_encoder.h
|
||||
endif
|
||||
if COND_MAIN_DECODER
|
||||
libcommon_la_SOURCES += \
|
||||
delta_decoder.c \
|
||||
delta_decoder.h
|
||||
endif
|
||||
endif
|
||||
|
||||
if COND_MAIN_ENCODER
|
||||
@@ -59,6 +69,10 @@ libcommon_la_SOURCES += \
|
||||
block_encoder.c \
|
||||
block_encoder.h \
|
||||
block_header_encoder.c \
|
||||
easy_common.c \
|
||||
easy_common.h \
|
||||
easy_single.c \
|
||||
easy_multi.c \
|
||||
filter_flags_encoder.c \
|
||||
init_encoder.c \
|
||||
metadata_encoder.c \
|
||||
@@ -69,6 +83,7 @@ libcommon_la_SOURCES += \
|
||||
stream_common.h \
|
||||
stream_encoder_single.c \
|
||||
stream_encoder_multi.c \
|
||||
stream_encoder_multi.h \
|
||||
stream_flags_encoder.c \
|
||||
vli_encoder.c
|
||||
endif
|
||||
|
||||
@@ -36,9 +36,10 @@ lzma_alloc(size_t size, lzma_allocator *allocator)
|
||||
ptr = malloc(size);
|
||||
|
||||
#if !defined(NDEBUG) && defined(HAVE_MEMSET)
|
||||
// This helps to catch some stupid mistakes.
|
||||
if (ptr != NULL)
|
||||
memset(ptr, 0xFD, size);
|
||||
// This helps to catch some stupid mistakes, but also hides them from
|
||||
// Valgrind. Uncomment when useful.
|
||||
// if (ptr != NULL)
|
||||
// memset(ptr, 0xFD, size);
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
|
||||
@@ -75,7 +75,8 @@ alone_decode(lzma_coder *coder,
|
||||
& (UINT32_C(1) << i))
|
||||
++count;
|
||||
|
||||
if (count > 1)
|
||||
if (count != 1 || coder->options.lzma.dictionary_size
|
||||
> LZMA_DICTIONARY_SIZE_MAX)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
coder->pos = 0;
|
||||
|
||||
@@ -152,7 +152,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
const size_t in_start = *in_pos;
|
||||
const size_t out_start = *out_pos;
|
||||
|
||||
lzma_ret ret = coder->next.code(coder->next.coder,
|
||||
const lzma_ret ret = coder->next.code(coder->next.coder,
|
||||
allocator, in, in_pos, in_size,
|
||||
out, out_pos, out_size, action);
|
||||
|
||||
@@ -174,9 +174,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
if (ret != LZMA_STREAM_END)
|
||||
return ret;
|
||||
|
||||
ret = update_sequence(coder);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
return_if_error(update_sequence(coder));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -213,10 +211,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
++*in_pos;
|
||||
|
||||
if (++coder->pos == lzma_check_sizes[coder->options->check]) {
|
||||
const lzma_ret ret = update_sequence(coder);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
|
||||
return_if_error(update_sequence(coder));
|
||||
coder->pos = 0;
|
||||
}
|
||||
|
||||
@@ -225,7 +220,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
case SEQ_UNCOMPRESSED_SIZE: {
|
||||
const size_t in_start = *in_pos;
|
||||
|
||||
lzma_ret ret = lzma_vli_decode(&coder->tmp,
|
||||
const lzma_ret ret = lzma_vli_decode(&coder->tmp,
|
||||
&coder->pos, in, in_pos, in_size);
|
||||
|
||||
if (update_size(&coder->total_size, *in_pos - in_start,
|
||||
@@ -241,9 +236,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
coder->pos = 0;
|
||||
coder->tmp = 0;
|
||||
|
||||
ret = update_sequence(coder);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
return_if_error(update_sequence(coder));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -251,7 +244,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
case SEQ_BACKWARD_SIZE: {
|
||||
const size_t in_start = *in_pos;
|
||||
|
||||
lzma_ret ret = lzma_vli_decode(&coder->tmp,
|
||||
const lzma_ret ret = lzma_vli_decode(&coder->tmp,
|
||||
&coder->pos, in, in_pos, in_size);
|
||||
|
||||
const size_t in_used = *in_pos - in_start;
|
||||
@@ -269,9 +262,7 @@ block_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
- coder->size_of_backward_size)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
ret = update_sequence(coder);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
return_if_error(update_sequence(coder));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -305,8 +296,8 @@ block_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
static lzma_ret
|
||||
block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_options_block *options)
|
||||
{
|
||||
// This is pretty similar to lzma_block_encoder_init().
|
||||
@@ -322,51 +313,15 @@ lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
next->coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
if (!lzma_vli_is_valid(options->total_size)
|
||||
|| !lzma_vli_is_valid(options->compressed_size)
|
||||
|| !lzma_vli_is_valid(options->uncompressed_size)
|
||||
|| !lzma_vli_is_valid(options->total_size)
|
||||
|| !lzma_vli_is_valid(options->total_limit)
|
||||
|| !lzma_vli_is_valid(options->uncompressed_limit)
|
||||
|| (options->uncompressed_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN
|
||||
&& options->uncompressed_size
|
||||
> options->uncompressed_limit)
|
||||
|| (options->total_size != LZMA_VLI_VALUE_UNKNOWN
|
||||
&& options->total_size
|
||||
> options->total_limit)
|
||||
|| (!options->has_eopm && options->uncompressed_size
|
||||
== LZMA_VLI_VALUE_UNKNOWN)
|
||||
|| options->header_size > options->total_size
|
||||
|| (options->handle_padding
|
||||
&& (options->has_uncompressed_size_in_footer
|
||||
|| options->has_backward_size)))
|
||||
if (validate_options_1(options))
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (validate_options_2(options))
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
return_if_error(lzma_check_init(&next->coder->check, options->check));
|
||||
|
||||
if (!options->has_eopm && options->uncompressed_size == 0) {
|
||||
if (!is_size_valid(0, options->compressed_size))
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (options->check != LZMA_CHECK_NONE) {
|
||||
lzma_check_finish(&next->coder->check, options->check);
|
||||
next->coder->sequence = SEQ_CHECK;
|
||||
} else if (options->handle_padding) {
|
||||
next->coder->sequence = SEQ_PADDING;
|
||||
} else {
|
||||
next->coder->sequence = SEQ_END;
|
||||
}
|
||||
} else {
|
||||
next->coder->sequence = SEQ_CODE;
|
||||
}
|
||||
|
||||
return_if_error(lzma_raw_decoder_init(&next->coder->next, allocator,
|
||||
options->filters, options->has_eopm
|
||||
? LZMA_VLI_VALUE_UNKNOWN
|
||||
: options->uncompressed_size,
|
||||
true));
|
||||
|
||||
next->coder->sequence = SEQ_CODE;
|
||||
next->coder->options = options;
|
||||
next->coder->pos = 0;
|
||||
next->coder->total_size = options->header_size;
|
||||
@@ -379,14 +334,34 @@ lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
next->coder->tmp = 0;
|
||||
next->coder->size_of_backward_size = 0;
|
||||
|
||||
return LZMA_OK;
|
||||
if (!options->has_eopm && options->uncompressed_size == 0) {
|
||||
// The Compressed Data field is empty, thus we skip SEQ_CODE
|
||||
// phase completely.
|
||||
const lzma_ret ret = update_sequence(next->coder);
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||
return LZMA_PROG_ERROR;
|
||||
}
|
||||
|
||||
return lzma_raw_decoder_init(&next->coder->next, allocator,
|
||||
options->filters, options->has_eopm
|
||||
? LZMA_VLI_VALUE_UNKNOWN
|
||||
: options->uncompressed_size,
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_block_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_options_block *options)
|
||||
{
|
||||
lzma_next_coder_init(block_decoder_init, next, allocator, options);
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API lzma_ret
|
||||
lzma_block_decoder(lzma_stream *strm, lzma_options_block *options)
|
||||
{
|
||||
lzma_next_strm_init(strm, lzma_block_decoder_init, options);
|
||||
lzma_next_strm_init(strm, block_decoder_init, options);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
|
||||
|
||||
@@ -94,7 +94,7 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
// Main loop
|
||||
while (*out_pos < out_size
|
||||
&& (*in_pos < in_size || action == LZMA_FINISH))
|
||||
&& (*in_pos < in_size || action != LZMA_RUN))
|
||||
switch (coder->sequence) {
|
||||
case SEQ_CODE: {
|
||||
const size_t in_start = *in_pos;
|
||||
@@ -121,7 +121,7 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
lzma_check_update(&coder->check, coder->options->check,
|
||||
in + in_start, in_used);
|
||||
|
||||
if (ret != LZMA_STREAM_END)
|
||||
if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
|
||||
return ret;
|
||||
|
||||
assert(*in_pos == in_size);
|
||||
@@ -232,10 +232,8 @@ block_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
|
||||
case SEQ_PADDING:
|
||||
if (coder->options->handle_padding) {
|
||||
assert(!coder->options
|
||||
->has_uncompressed_size_in_footer);
|
||||
assert(!coder->options->has_backward_size);
|
||||
assert(coder->options->total_size != LZMA_VLI_VALUE_UNKNOWN);
|
||||
assert(coder->options->total_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN);
|
||||
|
||||
if (coder->total_size < coder->options->total_size) {
|
||||
out[*out_pos] = 0x00;
|
||||
@@ -284,27 +282,9 @@ block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_options_block *options)
|
||||
{
|
||||
// Validate some options.
|
||||
if (options == NULL
|
||||
|| !lzma_vli_is_valid(options->total_size)
|
||||
|| !lzma_vli_is_valid(options->compressed_size)
|
||||
|| !lzma_vli_is_valid(options->uncompressed_size)
|
||||
|| !lzma_vli_is_valid(options->total_size)
|
||||
|| !lzma_vli_is_valid(options->total_limit)
|
||||
|| !lzma_vli_is_valid(options->uncompressed_limit)
|
||||
|| (options->uncompressed_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN
|
||||
&& options->uncompressed_size
|
||||
> options->uncompressed_limit)
|
||||
|| (options->total_size != LZMA_VLI_VALUE_UNKNOWN
|
||||
&& options->total_size
|
||||
> options->total_limit)
|
||||
|| (!options->has_eopm && options->uncompressed_size
|
||||
== LZMA_VLI_VALUE_UNKNOWN)
|
||||
|| (options->handle_padding && (options->total_size
|
||||
== LZMA_VLI_VALUE_UNKNOWN
|
||||
|| options->has_uncompressed_size_in_footer
|
||||
|| options->has_backward_size))
|
||||
|| options->header_size > options->total_size)
|
||||
if (validate_options_1(options) || validate_options_2(options)
|
||||
|| (options->handle_padding && options->total_size
|
||||
== LZMA_VLI_VALUE_UNKNOWN))
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
// Allocate and initialize *next->coder if needed.
|
||||
@@ -325,9 +305,9 @@ block_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
// Compressed Data is empty. That is, we don't call the encoder at all.
|
||||
// We initialize it though; it allows detecting invalid options.
|
||||
if (!options->has_eopm && options->uncompressed_size == 0) {
|
||||
// Also Compressed Size must also be zero if it has been
|
||||
// Also Compressed Size must be zero if it has been
|
||||
// given to us.
|
||||
if (!is_size_valid(options->compressed_size, 0))
|
||||
if (!is_size_valid(0, options->compressed_size))
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
next->coder->sequence = SEQ_CHECK_FINISH;
|
||||
|
||||
@@ -43,4 +43,54 @@ is_size_valid(lzma_vli size, lzma_vli reference)
|
||||
return reference == LZMA_VLI_VALUE_UNKNOWN || reference == size;
|
||||
}
|
||||
|
||||
|
||||
/// If any of these tests fail, the caller has to return LZMA_PROG_ERROR.
|
||||
static inline bool
|
||||
validate_options_1(const lzma_options_block *options)
|
||||
{
|
||||
return options == NULL
|
||||
|| !lzma_vli_is_valid(options->compressed_size)
|
||||
|| !lzma_vli_is_valid(options->uncompressed_size)
|
||||
|| !lzma_vli_is_valid(options->total_size)
|
||||
|| !lzma_vli_is_valid(options->total_limit)
|
||||
|| !lzma_vli_is_valid(options->uncompressed_limit);
|
||||
}
|
||||
|
||||
|
||||
/// If any of these tests fail, the encoder has to return LZMA_PROG_ERROR
|
||||
/// because something is going horribly wrong if such values get passed
|
||||
/// to the encoder. In contrast, the decoder has to return LZMA_DATA_ERROR,
|
||||
/// since these tests failing indicate that something is wrong in the Stream.
|
||||
static inline bool
|
||||
validate_options_2(const lzma_options_block *options)
|
||||
{
|
||||
if ((options->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN
|
||||
&& options->uncompressed_size
|
||||
> options->uncompressed_limit)
|
||||
|| (options->total_size != LZMA_VLI_VALUE_UNKNOWN
|
||||
&& options->total_size
|
||||
> options->total_limit)
|
||||
|| (!options->has_eopm && options->uncompressed_size
|
||||
== LZMA_VLI_VALUE_UNKNOWN)
|
||||
|| options->header_size > options->total_size)
|
||||
return true;
|
||||
|
||||
if (options->compressed_size != LZMA_VLI_VALUE_UNKNOWN) {
|
||||
// Calculate a rough minimum possible valid Total Size of
|
||||
// this Block, and check that total_size and total_limit
|
||||
// are big enough. Note that the real minimum size can be
|
||||
// bigger due to the Check, Uncompressed Size, Backwards
|
||||
// Size, pr Padding being present. A rough check here is
|
||||
// enough for us to catch the most obvious errors as early
|
||||
// as possible.
|
||||
const lzma_vli total_min = options->compressed_size
|
||||
+ (lzma_vli)(options->header_size);
|
||||
if (total_min > options->total_size
|
||||
|| total_min > options->total_limit)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
61
src/liblzma/common/bsr.h
Normal file
61
src/liblzma/common/bsr.h
Normal file
@@ -0,0 +1,61 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file bsr.h
|
||||
/// \brief Bit scan reverse
|
||||
//
|
||||
// This code has been put into the public domain.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_BSR_H
|
||||
#define LZMA_BSR_H
|
||||
|
||||
// NOTE: Both input and output variables for lzma_bsr must be uint32_t.
|
||||
|
||||
#if defined(__GNUC__) && (defined (HAVE_ASM_X86) || defined(HAVE_ASM_X86_64))
|
||||
# define lzma_bsr(dest, n) \
|
||||
__asm__("bsrl %1, %0" : "=r" (dest) : "rm" (n))
|
||||
|
||||
#else
|
||||
# define lzma_bsr(dest, n) dest = lzma_bsr_helper(n)
|
||||
|
||||
static inline uint32_t
|
||||
lzma_bsr_helper(uint32_t n)
|
||||
{
|
||||
assert(n != 0);
|
||||
|
||||
uint32_t i = 31;
|
||||
|
||||
if ((n & UINT32_C(0xFFFF0000)) == 0) {
|
||||
n <<= 16;
|
||||
i = 15;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xFF000000)) == 0) {
|
||||
n <<= 8;
|
||||
i -= 8;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xF0000000)) == 0) {
|
||||
n <<= 4;
|
||||
i -= 4;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xC0000000)) == 0) {
|
||||
n <<= 2;
|
||||
i -= 2;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x80000000)) == 0)
|
||||
--i;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef LZMA_COMMON_H
|
||||
#define LZMA_COMMON_H
|
||||
|
||||
#include "sysdefs.h"
|
||||
#include "../../common/sysdefs.h"
|
||||
|
||||
// Don't use ifdef...
|
||||
#if HAVE_VISIBILITY
|
||||
|
||||
@@ -42,33 +42,12 @@ copy_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
in, in_pos, in_size, out, out_pos, out_size,
|
||||
action);
|
||||
|
||||
// If we get here, we are the last filter in the chain.
|
||||
assert(coder->uncompressed_size <= LZMA_VLI_VALUE_MAX);
|
||||
|
||||
const size_t in_avail = in_size - *in_pos;
|
||||
|
||||
// Check that we don't have too much input.
|
||||
if ((lzma_vli)(in_avail) > coder->uncompressed_size)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
// Check that once LZMA_FINISH has been given, the amount of input
|
||||
// matches uncompressed_size, which is always known.
|
||||
if (action == LZMA_FINISH
|
||||
&& coder->uncompressed_size != (lzma_vli)(in_avail))
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
// We are the last coder in the chain.
|
||||
// Just copy as much data as possible.
|
||||
const size_t in_used = bufcpy(
|
||||
in, in_pos, in_size, out, out_pos, out_size);
|
||||
|
||||
// Update uncompressed_size if it is known.
|
||||
if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
coder->uncompressed_size -= in_used;
|
||||
bufcpy(in, in_pos, in_size, out, out_pos, out_size);
|
||||
|
||||
// LZMA_SYNC_FLUSH and LZMA_FINISH are the same thing for us.
|
||||
if ((action != LZMA_RUN && *in_pos == in_size)
|
||||
|| coder->uncompressed_size == 0)
|
||||
if (action != LZMA_RUN && *in_pos == in_size)
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
return LZMA_OK;
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_coder.c
|
||||
/// \brief Encoder and decoder for the Delta filter
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "delta_coder.h"
|
||||
|
||||
|
||||
struct lzma_coder_s {
|
||||
/// Next coder in the chain
|
||||
lzma_next_coder next;
|
||||
|
||||
/// Uncompressed size - This is needed when we are the last
|
||||
/// filter in the chain.
|
||||
lzma_vli uncompressed_size;
|
||||
|
||||
/// Delta distance
|
||||
size_t distance;
|
||||
|
||||
/// True if we are encoding; false if decoding
|
||||
bool is_encoder;
|
||||
|
||||
/// Position in history[]
|
||||
uint8_t pos;
|
||||
|
||||
/// Buffer to hold history of the original data
|
||||
uint8_t history[LZMA_DELTA_DISTANCE_MAX];
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
encode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
{
|
||||
const size_t distance = coder->distance;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
const uint8_t tmp = coder->history[
|
||||
(distance + coder->pos) & 0xFF];
|
||||
coder->history[coder->pos--] = buffer[i];
|
||||
buffer[i] -= tmp;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
{
|
||||
const size_t distance = coder->distance;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
buffer[i] += coder->history[(distance + coder->pos) & 0xFF];
|
||||
coder->history[coder->pos--] = buffer[i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_code(lzma_coder *coder, lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
{
|
||||
const size_t out_start = *out_pos;
|
||||
size_t size;
|
||||
lzma_ret ret;
|
||||
|
||||
if (coder->next.code == NULL) {
|
||||
const size_t in_avail = in_size - *in_pos;
|
||||
|
||||
if (coder->is_encoder) {
|
||||
// Check that we don't have too much input.
|
||||
if ((lzma_vli)(in_avail) > coder->uncompressed_size)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
// Check that once LZMA_FINISH has been given, the
|
||||
// amount of input matches uncompressed_size if it
|
||||
// is known.
|
||||
if (action == LZMA_FINISH && coder->uncompressed_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN
|
||||
&& coder->uncompressed_size
|
||||
!= (lzma_vli)(in_avail))
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
} else {
|
||||
// Limit in_size so that we don't copy too much.
|
||||
if ((lzma_vli)(in_avail) > coder->uncompressed_size)
|
||||
in_size = *in_pos + (size_t)(
|
||||
coder->uncompressed_size);
|
||||
}
|
||||
|
||||
size = bufcpy(in, in_pos, in_size, out, out_pos, out_size);
|
||||
|
||||
if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
coder->uncompressed_size -= size;
|
||||
|
||||
// action can be LZMA_FINISH only in the encoder.
|
||||
ret = (action == LZMA_FINISH && *in_pos == in_size)
|
||||
|| coder->uncompressed_size == 0
|
||||
? LZMA_STREAM_END : LZMA_OK;
|
||||
|
||||
} else {
|
||||
ret = coder->next.code(coder->next.coder, allocator,
|
||||
in, in_pos, in_size, out, out_pos, out_size,
|
||||
action);
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||
return ret;
|
||||
|
||||
size = *out_pos - out_start;
|
||||
}
|
||||
|
||||
if (coder->is_encoder)
|
||||
encode_buffer(coder, out + out_start, size);
|
||||
else
|
||||
decode_buffer(coder, out + out_start, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_coder_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
// Allocate memory for the decoder if needed.
|
||||
if (next->coder == NULL) {
|
||||
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||
if (next->coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->code = &delta_code;
|
||||
next->end = &delta_coder_end;
|
||||
next->coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
// Copy Uncompressed Size which is used to limit the output size.
|
||||
next->coder->uncompressed_size = filters[0].uncompressed_size;
|
||||
|
||||
// The coder acts slightly differently as encoder and decoder.
|
||||
next->coder->is_encoder = is_encoder;
|
||||
|
||||
// Set the delta distance.
|
||||
if (filters[0].options == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
next->coder->distance = ((lzma_options_delta *)(filters[0].options))
|
||||
->distance;
|
||||
if (next->coder->distance < LZMA_DELTA_DISTANCE_MIN
|
||||
|| next->coder->distance > LZMA_DELTA_DISTANCE_MAX)
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
// Initialize the rest of the variables.
|
||||
next->coder->pos = 0;
|
||||
memzero(next->coder->history, LZMA_DELTA_DISTANCE_MAX);
|
||||
|
||||
// Initialize the next decoder in the chain, if any.
|
||||
return lzma_next_filter_init(&next->coder->next,
|
||||
allocator, filters + 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ENCODER
|
||||
extern lzma_ret
|
||||
lzma_delta_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return delta_coder_init(next, allocator, filters, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_DECODER
|
||||
extern lzma_ret
|
||||
lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return delta_coder_init(next, allocator, filters, false);
|
||||
}
|
||||
#endif
|
||||
70
src/liblzma/common/delta_common.c
Normal file
70
src/liblzma/common/delta_common.c
Normal file
@@ -0,0 +1,70 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_common.c
|
||||
/// \brief Common stuff for Delta encoder and decoder
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "delta_common.h"
|
||||
|
||||
|
||||
static void
|
||||
delta_coder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_coder_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, lzma_code_function code)
|
||||
{
|
||||
// Allocate memory for the decoder if needed.
|
||||
if (next->coder == NULL) {
|
||||
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||
if (next->coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
// End function is the same for encoder and decoder.
|
||||
next->end = &delta_coder_end;
|
||||
next->coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
// Coding function is different for encoder and decoder.
|
||||
next->code = code;
|
||||
|
||||
// Copy Uncompressed Size which is used to limit the output size
|
||||
// in the Delta decoder.
|
||||
next->coder->uncompressed_size = filters[0].uncompressed_size;
|
||||
|
||||
// Set the delta distance.
|
||||
if (filters[0].options == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
next->coder->distance = ((lzma_options_delta *)(filters[0].options))
|
||||
->distance;
|
||||
if (next->coder->distance < LZMA_DELTA_DISTANCE_MIN
|
||||
|| next->coder->distance > LZMA_DELTA_DISTANCE_MAX)
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
// Initialize the rest of the variables.
|
||||
next->coder->pos = 0;
|
||||
memzero(next->coder->history, LZMA_DELTA_DISTANCE_MAX);
|
||||
|
||||
// Initialize the next decoder in the chain, if any.
|
||||
return lzma_next_filter_init(&next->coder->next,
|
||||
allocator, filters + 1);
|
||||
}
|
||||
48
src/liblzma/common/delta_common.h
Normal file
48
src/liblzma/common/delta_common.h
Normal file
@@ -0,0 +1,48 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_common.h
|
||||
/// \brief Common stuff for Delta encoder and decoder
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_DELTA_COMMON_H
|
||||
#define LZMA_DELTA_COMMON_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
struct lzma_coder_s {
|
||||
/// Next coder in the chain
|
||||
lzma_next_coder next;
|
||||
|
||||
/// Uncompressed size - This is needed when we are the last
|
||||
/// filter in the chain.
|
||||
lzma_vli uncompressed_size;
|
||||
|
||||
/// Delta distance
|
||||
size_t distance;
|
||||
|
||||
/// Position in history[]
|
||||
uint8_t pos;
|
||||
|
||||
/// Buffer to hold history of the original data
|
||||
uint8_t history[LZMA_DELTA_DISTANCE_MAX];
|
||||
};
|
||||
|
||||
|
||||
extern lzma_ret lzma_delta_coder_init(
|
||||
lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, lzma_code_function code);
|
||||
|
||||
#endif
|
||||
102
src/liblzma/common/delta_decoder.c
Normal file
102
src/liblzma/common/delta_decoder.c
Normal file
@@ -0,0 +1,102 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_decoder.c
|
||||
/// \brief Delta filter decoder
|
||||
//
|
||||
// Copyright (C) 2007, 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "delta_decoder.h"
|
||||
#include "delta_common.h"
|
||||
|
||||
|
||||
/// Copies and decodes the data at the same time. This is used when Delta
|
||||
/// is the last filter in the chain.
|
||||
static void
|
||||
copy_and_decode(lzma_coder *coder,
|
||||
const uint8_t *restrict in, uint8_t *restrict out, size_t size)
|
||||
{
|
||||
const size_t distance = coder->distance;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
out[i] = in[i] + coder->history[
|
||||
(distance + coder->pos) & 0xFF];
|
||||
coder->history[coder->pos-- & 0xFF] = out[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Decodes the data in place. This is used when we are not the last filter
|
||||
/// in the chain.
|
||||
static void
|
||||
decode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
{
|
||||
const size_t distance = coder->distance;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
buffer[i] += coder->history[(distance + coder->pos) & 0xFF];
|
||||
coder->history[coder->pos-- & 0xFF] = buffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
{
|
||||
lzma_ret ret;
|
||||
|
||||
if (coder->next.code == NULL) {
|
||||
// Limit in_size so that we don't copy too much.
|
||||
if ((lzma_vli)(in_size - *in_pos) > coder->uncompressed_size)
|
||||
in_size = *in_pos + (size_t)(coder->uncompressed_size);
|
||||
|
||||
const size_t in_avail = in_size - *in_pos;
|
||||
const size_t out_avail = out_size - *out_pos;
|
||||
const size_t size = MIN(in_avail, out_avail);
|
||||
|
||||
copy_and_decode(coder, in + *in_pos, out + *out_pos, size);
|
||||
|
||||
*in_pos += size;
|
||||
*out_pos += size;
|
||||
|
||||
assert(coder->uncompressed_size <= LZMA_VLI_VALUE_MAX);
|
||||
coder->uncompressed_size -= size;
|
||||
|
||||
ret = coder->uncompressed_size == 0
|
||||
? LZMA_STREAM_END : LZMA_OK;
|
||||
|
||||
} else {
|
||||
const size_t out_start = *out_pos;
|
||||
|
||||
ret = coder->next.code(coder->next.coder, allocator,
|
||||
in, in_pos, in_size, out, out_pos, out_size,
|
||||
action);
|
||||
|
||||
decode_in_place(coder, out + out_start, *out_pos - out_start);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return lzma_delta_coder_init(next, allocator, filters, &delta_decode);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_coder.h
|
||||
/// \brief The Delta filter encoder and decoder
|
||||
/// \file delta_decoder.h
|
||||
/// \brief Delta filter decoder
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
@@ -17,14 +17,11 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_DELTA_CODER_H
|
||||
#define LZMA_DELTA_CODER_H
|
||||
#ifndef LZMA_DELTA_DECODER_H
|
||||
#define LZMA_DELTA_DECODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern lzma_ret lzma_delta_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
|
||||
extern lzma_ret lzma_delta_decoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
|
||||
97
src/liblzma/common/delta_encoder.c
Normal file
97
src/liblzma/common/delta_encoder.c
Normal file
@@ -0,0 +1,97 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_encoder.c
|
||||
/// \brief Delta filter encoder
|
||||
//
|
||||
// Copyright (C) 2007, 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "delta_encoder.h"
|
||||
#include "delta_common.h"
|
||||
|
||||
|
||||
/// Copies and encodes the data at the same time. This is used when Delta
|
||||
/// is the last filter in the chain.
|
||||
static void
|
||||
copy_and_encode(lzma_coder *coder,
|
||||
const uint8_t *restrict in, uint8_t *restrict out, size_t size)
|
||||
{
|
||||
const size_t distance = coder->distance;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
const uint8_t tmp = coder->history[
|
||||
(distance + coder->pos) & 0xFF];
|
||||
coder->history[coder->pos-- & 0xFF] = in[i];
|
||||
out[i] = in[i] - tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Encodes the data in place. This is used when we are not the last filter
|
||||
/// in the chain.
|
||||
static void
|
||||
encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size)
|
||||
{
|
||||
const size_t distance = coder->distance;
|
||||
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
const uint8_t tmp = coder->history[
|
||||
(distance + coder->pos) & 0xFF];
|
||||
coder->history[coder->pos-- & 0xFF] = buffer[i];
|
||||
buffer[i] -= tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
delta_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
{
|
||||
lzma_ret ret;
|
||||
|
||||
if (coder->next.code == NULL) {
|
||||
const size_t in_avail = in_size - *in_pos;
|
||||
const size_t out_avail = out_size - *out_pos;
|
||||
const size_t size = MIN(in_avail, out_avail);
|
||||
|
||||
copy_and_encode(coder, in + *in_pos, out + *out_pos, size);
|
||||
|
||||
*in_pos += size;
|
||||
*out_pos += size;
|
||||
|
||||
ret = action != LZMA_RUN && *in_pos == in_size
|
||||
? LZMA_STREAM_END : LZMA_OK;
|
||||
|
||||
} else {
|
||||
const size_t out_start = *out_pos;
|
||||
|
||||
ret = coder->next.code(coder->next.coder, allocator,
|
||||
in, in_pos, in_size, out, out_pos, out_size,
|
||||
action);
|
||||
|
||||
encode_in_place(coder, out + out_start, *out_pos - out_start);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_delta_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return lzma_delta_coder_init(next, allocator, filters, &delta_encode);
|
||||
}
|
||||
28
src/liblzma/common/delta_encoder.h
Normal file
28
src/liblzma/common/delta_encoder.h
Normal file
@@ -0,0 +1,28 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file delta_encoder.h
|
||||
/// \brief Delta filter encoder
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_DELTA_ENCODER_H
|
||||
#define LZMA_DELTA_ENCODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern lzma_ret lzma_delta_encoder_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_filter_info *filters);
|
||||
|
||||
#endif
|
||||
54
src/liblzma/common/easy_common.c
Normal file
54
src/liblzma/common/easy_common.c
Normal file
@@ -0,0 +1,54 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file easy_common.c
|
||||
/// \brief Shared stuff for easy encoder initialization functions
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "easy_common.h"
|
||||
|
||||
|
||||
extern bool
|
||||
lzma_easy_set_filters(lzma_options_filter *filters, uint32_t level)
|
||||
{
|
||||
bool error = false;
|
||||
|
||||
if (level == 0) {
|
||||
filters[0].id = LZMA_VLI_VALUE_UNKNOWN;
|
||||
|
||||
#ifdef HAVE_FILTER_LZMA
|
||||
} else if (level <= 9) {
|
||||
filters[0].id = LZMA_FILTER_LZMA;
|
||||
filters[0].options = (void *)(&lzma_preset_lzma[level - 1]);
|
||||
filters[1].id = LZMA_VLI_VALUE_UNKNOWN;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
error = true;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API uint32_t
|
||||
lzma_easy_memory_usage(lzma_easy_level level)
|
||||
{
|
||||
lzma_options_filter filters[8];
|
||||
if (lzma_easy_set_filters(filters, level))
|
||||
return UINT32_MAX;
|
||||
|
||||
return lzma_memory_usage(filters, true);
|
||||
}
|
||||
28
src/liblzma/common/easy_common.h
Normal file
28
src/liblzma/common/easy_common.h
Normal file
@@ -0,0 +1,28 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file easy_common.c
|
||||
/// \brief Shared stuff for easy encoder initialization functions
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifndef LZMA_EASY_COMMON_H
|
||||
#define LZMA_EASY_COMMON_H
|
||||
|
||||
extern bool lzma_easy_set_filters(
|
||||
lzma_options_filter *filters, uint32_t level);
|
||||
|
||||
#endif
|
||||
103
src/liblzma/common/easy_multi.c
Normal file
103
src/liblzma/common/easy_multi.c
Normal file
@@ -0,0 +1,103 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file easy_multi.c
|
||||
/// \brief Easy Multi-Block Stream encoder initialization
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "easy_common.h"
|
||||
#include "stream_encoder_multi.h"
|
||||
|
||||
|
||||
struct lzma_coder_s {
|
||||
lzma_next_coder encoder;
|
||||
lzma_options_stream options;
|
||||
};
|
||||
|
||||
|
||||
static lzma_ret
|
||||
easy_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
{
|
||||
return coder->encoder.code(coder->encoder.coder, allocator,
|
||||
in, in_pos, in_size, out, out_pos, out_size, action);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
easy_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_coder_end(&coder->encoder, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
easy_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
lzma_easy_level level, lzma_easy_level metadata_level,
|
||||
const lzma_extra *header, const lzma_extra *footer)
|
||||
{
|
||||
if (next->coder == NULL) {
|
||||
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||
if (next->coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->code = &easy_encode;
|
||||
next->end = &easy_encoder_end;
|
||||
|
||||
next->coder->encoder = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
next->coder->options = (lzma_options_stream){
|
||||
.check = LZMA_CHECK_CRC32,
|
||||
.has_crc32 = true,
|
||||
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
|
||||
.alignment = 0,
|
||||
.header = header,
|
||||
.footer = footer,
|
||||
};
|
||||
|
||||
if (lzma_easy_set_filters(next->coder->options.filters, level)
|
||||
|| lzma_easy_set_filters(
|
||||
next->coder->options.metadata_filters,
|
||||
metadata_level))
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
return lzma_stream_encoder_multi_init(&next->coder->encoder,
|
||||
allocator, &next->coder->options);
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API lzma_ret
|
||||
lzma_easy_encoder_multi(lzma_stream *strm,
|
||||
lzma_easy_level level, lzma_easy_level metadata_level,
|
||||
const lzma_extra *header, const lzma_extra *footer)
|
||||
{
|
||||
// This is more complicated than lzma_easy_encoder_single(),
|
||||
// because lzma_stream_encoder_multi() wants that the options
|
||||
// structure is available until the encoding is finished.
|
||||
lzma_next_strm_init(strm, easy_encoder_init,
|
||||
level, metadata_level, header, footer);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FULL_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
37
src/liblzma/common/easy_single.c
Normal file
37
src/liblzma/common/easy_single.c
Normal file
@@ -0,0 +1,37 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file easy_single.c
|
||||
/// \brief Easy Single-Block Stream encoder initialization
|
||||
//
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "easy_common.h"
|
||||
|
||||
|
||||
extern LZMA_API lzma_ret
|
||||
lzma_easy_encoder_single(lzma_stream *strm, lzma_easy_level level)
|
||||
{
|
||||
lzma_options_stream opt_stream = {
|
||||
.check = LZMA_CHECK_CRC32,
|
||||
.has_crc32 = true,
|
||||
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
|
||||
.alignment = 0,
|
||||
};
|
||||
|
||||
if (lzma_easy_set_filters(opt_stream.filters, level))
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
return lzma_stream_encoder_single(strm, &opt_stream);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ lzma_extra_free(lzma_extra *extra, lzma_allocator *allocator)
|
||||
{
|
||||
while (extra != NULL) {
|
||||
lzma_extra *tmp = extra->next;
|
||||
lzma_free(extra->data, allocator);
|
||||
lzma_free(extra, allocator);
|
||||
extra = tmp;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "lzma_encoder.h"
|
||||
#include "fastpos.h"
|
||||
|
||||
|
||||
/// \brief Calculates the size of the Filter Properties field
|
||||
@@ -204,35 +205,32 @@ properties_lzma(uint8_t *out, size_t *out_pos, size_t out_size,
|
||||
|
||||
// Dictionary flags
|
||||
//
|
||||
// Dictionary size is encoded using six bits of
|
||||
// which one is mantissa and five are exponent.
|
||||
// Dictionary size is encoded using similar encoding that is used
|
||||
// internally by LZMA.
|
||||
//
|
||||
// There are some limits that must hold to keep
|
||||
// this coding working.
|
||||
# if LZMA_DICTIONARY_SIZE_MAX > UINT32_MAX / 2
|
||||
# error LZMA_DICTIONARY_SIZE_MAX is too big.
|
||||
# endif
|
||||
// This won't work if dictionary size can be zero:
|
||||
# if LZMA_DICTIONARY_SIZE_MIN < 1
|
||||
# error LZMA_DICTIONARY_SIZE_MIN cannot be zero.
|
||||
# endif
|
||||
|
||||
uint32_t d = options->dictionary_size;
|
||||
|
||||
// Validate it:
|
||||
if (options->dictionary_size < LZMA_DICTIONARY_SIZE_MIN
|
||||
|| options->dictionary_size > LZMA_DICTIONARY_SIZE_MAX)
|
||||
if (d < LZMA_DICTIONARY_SIZE_MIN || d > LZMA_DICTIONARY_SIZE_MAX)
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
if (options->dictionary_size == 1) {
|
||||
// Special case
|
||||
out[*out_pos] = 0x00;
|
||||
} else {
|
||||
// TODO This could be more elegant.
|
||||
uint32_t i = 1;
|
||||
while (((2 | ((i + 1) & 1)) << ((i - 1) / 2))
|
||||
< options->dictionary_size)
|
||||
++i;
|
||||
out[*out_pos] = i;
|
||||
}
|
||||
// Round up to to the next 2^n or 2^n + 2^(n - 1) depending on which
|
||||
// one is the next:
|
||||
--d;
|
||||
d |= d >> 2;
|
||||
d |= d >> 3;
|
||||
d |= d >> 4;
|
||||
d |= d >> 8;
|
||||
d |= d >> 16;
|
||||
++d;
|
||||
|
||||
// Get the highest two bits using the proper encoding:
|
||||
out[*out_pos] = get_pos_slot(d) - 1;
|
||||
++*out_pos;
|
||||
|
||||
return LZMA_OK;
|
||||
|
||||
@@ -367,7 +367,7 @@ lzma_info_metadata_set(lzma_info *info, lzma_allocator *allocator,
|
||||
lzma_bool eat_index)
|
||||
{
|
||||
// Validate *metadata.
|
||||
if (!lzma_vli_is_valid(metadata->header_metadata_size)
|
||||
if (metadata->header_metadata_size > LZMA_VLI_VALUE_MAX
|
||||
|| !lzma_vli_is_valid(metadata->total_size)
|
||||
|| !lzma_vli_is_valid(metadata->uncompressed_size)) {
|
||||
if (eat_index) {
|
||||
@@ -385,6 +385,10 @@ lzma_info_metadata_set(lzma_info *info, lzma_allocator *allocator,
|
||||
|
||||
const lzma_ret ret = lzma_info_index_set(
|
||||
info, allocator, metadata->index, eat_index);
|
||||
|
||||
if (eat_index)
|
||||
metadata->index = NULL;
|
||||
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
|
||||
@@ -399,34 +403,21 @@ lzma_info_metadata_set(lzma_info *info, lzma_allocator *allocator,
|
||||
}
|
||||
|
||||
// Size of Header Metadata
|
||||
if (!is_header_metadata) {
|
||||
// If it is marked unknown in Metadata, it means that
|
||||
// it's not present.
|
||||
const lzma_vli size = metadata->header_metadata_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN
|
||||
? metadata->header_metadata_size : 0;
|
||||
const lzma_ret ret = lzma_info_size_set(
|
||||
info, LZMA_INFO_HEADER_METADATA, size);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
}
|
||||
if (!is_header_metadata)
|
||||
return_if_error(lzma_info_size_set(
|
||||
info, LZMA_INFO_HEADER_METADATA,
|
||||
metadata->header_metadata_size));
|
||||
|
||||
// Total Size
|
||||
if (metadata->total_size != LZMA_VLI_VALUE_UNKNOWN) {
|
||||
const lzma_ret ret = lzma_info_size_set(info,
|
||||
LZMA_INFO_TOTAL, metadata->total_size);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
}
|
||||
if (metadata->total_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
return_if_error(lzma_info_size_set(info,
|
||||
LZMA_INFO_TOTAL, metadata->total_size));
|
||||
|
||||
// Uncompressed Size
|
||||
if (metadata->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
|
||||
const lzma_ret ret = lzma_info_size_set(info,
|
||||
if (metadata->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
return_if_error(lzma_info_size_set(info,
|
||||
LZMA_INFO_UNCOMPRESSED,
|
||||
metadata->uncompressed_size);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
}
|
||||
metadata->uncompressed_size));
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
@@ -25,9 +25,7 @@ lzma_init_decoder(void)
|
||||
{
|
||||
// So far there's no decoder-specific stuff to initialize.
|
||||
|
||||
#ifdef HAVE_CHECK
|
||||
lzma_init_check();
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,14 +29,10 @@ lzma_init_encoder(void)
|
||||
if (already_initialized)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_CHECK
|
||||
lzma_init_check();
|
||||
#endif
|
||||
|
||||
// FIXME TODO Create precalculated tables.
|
||||
#if defined(HAVE_ENCODER) && defined(HAVE_FILTER_LZMA)
|
||||
#if defined(HAVE_SMALL) && defined(HAVE_ENCODER) && defined(HAVE_FILTER_LZMA)
|
||||
lzma_rc_init();
|
||||
lzma_fastpos_init();
|
||||
#endif
|
||||
|
||||
already_initialized = true;
|
||||
|
||||
@@ -25,9 +25,16 @@
|
||||
((num) + (((multiple) - ((num) % (multiple))) % (multiple)))
|
||||
|
||||
|
||||
/// Rounds upwards to the next multiple of 2 * sizeof(void*).
|
||||
/// malloc() tends to align allocations this way.
|
||||
#define malloc_ceil(num) my_ceil(num, 2 * sizeof(void *))
|
||||
/// Add approximated overhead of malloc() to size and round upwards to the
|
||||
/// next multiple of 2 * sizeof(size_t). I suppose that most malloc()
|
||||
/// implementations align small allocations this way, but the overhead
|
||||
/// varies due to several reasons (free lists, mmap() usage etc.).
|
||||
///
|
||||
/// This doesn't need to be exact at all. It's enough to take into account
|
||||
/// that there is some overhead. That way our memory usage count won't be
|
||||
/// horribly wrong if we are used to allocate lots of small memory chunks.
|
||||
#define malloc_ceil(size) \
|
||||
my_ceil((size) + 2 * sizeof(void *), 2 * sizeof(size_t))
|
||||
|
||||
|
||||
typedef struct lzma_memlimit_list_s lzma_memlimit_list;
|
||||
@@ -39,24 +46,44 @@ struct lzma_memlimit_list_s {
|
||||
|
||||
|
||||
struct lzma_memlimit_s {
|
||||
size_t used;
|
||||
size_t limit;
|
||||
/// List of allocated memory chunks
|
||||
lzma_memlimit_list *list;
|
||||
|
||||
/// Number of bytes currently allocated; this includes the memory
|
||||
/// needed for the helper structures.
|
||||
size_t used;
|
||||
|
||||
/// Memory usage limit
|
||||
size_t limit;
|
||||
|
||||
/// Maximum amount of memory that have been or would have been needed.
|
||||
/// That is, this is updated also if memory allocation fails, letting
|
||||
/// the application check how much memory was tried to be allocated
|
||||
/// in total.
|
||||
size_t max;
|
||||
|
||||
/// True if lzma_memlimit_alloc() has returned NULL due to memory
|
||||
/// usage limit.
|
||||
bool limit_reached;
|
||||
};
|
||||
|
||||
|
||||
extern LZMA_API lzma_memlimit *
|
||||
lzma_memlimit_create(size_t limit)
|
||||
{
|
||||
if (limit < sizeof(lzma_memlimit))
|
||||
const size_t base_size = malloc_ceil(sizeof(lzma_memlimit));
|
||||
|
||||
if (limit < base_size)
|
||||
return NULL;
|
||||
|
||||
lzma_memlimit *mem = malloc(sizeof(lzma_memlimit));
|
||||
|
||||
if (mem != NULL) {
|
||||
mem->used = sizeof(lzma_memlimit);
|
||||
mem->limit = limit;
|
||||
mem->list = NULL;
|
||||
mem->used = base_size;
|
||||
mem->limit = limit;
|
||||
mem->max = base_size;
|
||||
mem->limit_reached = false;
|
||||
}
|
||||
|
||||
return mem;
|
||||
@@ -85,6 +112,49 @@ lzma_memlimit_used(const lzma_memlimit *mem)
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API size_t
|
||||
lzma_memlimit_max(lzma_memlimit *mem, lzma_bool clear)
|
||||
{
|
||||
const size_t ret = mem->max;
|
||||
|
||||
if (clear)
|
||||
mem->max = mem->used;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API lzma_bool
|
||||
lzma_memlimit_reached(lzma_memlimit *mem, lzma_bool clear)
|
||||
{
|
||||
const bool ret = mem->limit_reached;
|
||||
|
||||
if (clear)
|
||||
mem->limit_reached = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API size_t
|
||||
lzma_memlimit_count(const lzma_memlimit *mem)
|
||||
{
|
||||
// This is slow; we could have a counter in lzma_memlimit
|
||||
// for fast version. I expect the primary use of this
|
||||
// function to be limited to easy checking of memory leaks,
|
||||
// in which this implementation is just fine.
|
||||
size_t count = 0;
|
||||
const lzma_memlimit_list *record = mem->list;
|
||||
|
||||
while (record != NULL) {
|
||||
++count;
|
||||
record = record->next;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API void
|
||||
lzma_memlimit_end(lzma_memlimit *mem, lzma_bool free_allocated)
|
||||
{
|
||||
@@ -121,18 +191,36 @@ lzma_memlimit_alloc(lzma_memlimit *mem, size_t nmemb, size_t size)
|
||||
size = 1;
|
||||
|
||||
// Calculate how much memory we are going to allocate in reality.
|
||||
// TODO: We should add some rough estimate how much malloc() needs
|
||||
// for its internal structures.
|
||||
const size_t total_size = malloc_ceil(size)
|
||||
+ malloc_ceil(sizeof(lzma_memlimit_list));
|
||||
|
||||
// Integer overflow protection
|
||||
if (SIZE_MAX - size <= total_size)
|
||||
// Integer overflow protection for total_size and mem->used.
|
||||
if (total_size <= size || SIZE_MAX - total_size < mem->used) {
|
||||
mem->max = SIZE_MAX;
|
||||
mem->limit_reached = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mem->limit < mem->used || mem->limit - mem->used < total_size)
|
||||
// Update the maximum memory requirement counter if needed. This
|
||||
// is updated even if memory allocation would fail or limit would
|
||||
// be reached.
|
||||
if (mem->used + total_size > mem->max)
|
||||
mem->max = mem->used + total_size;
|
||||
|
||||
// Check if we would stay in the memory usage limits. We need to
|
||||
// check also that the current usage is in the limits, because
|
||||
// the application could have decreased the limit between calls
|
||||
// to this function.
|
||||
if (mem->limit < mem->used || mem->limit - mem->used < total_size) {
|
||||
mem->limit_reached = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Allocate separate memory chunks for lzma_memlimit_list and the
|
||||
// actual requested memory. Optimizing this to use only one
|
||||
// allocation is not a good idea, because applications may want to
|
||||
// detach lzma_extra structures that have been allocated with
|
||||
// lzma_memlimit_alloc().
|
||||
lzma_memlimit_list *record = malloc(sizeof(lzma_memlimit_list));
|
||||
void *ptr = malloc(size);
|
||||
|
||||
|
||||
@@ -127,6 +127,8 @@ process(lzma_coder *coder, lzma_allocator *allocator)
|
||||
if (coder->buffer[coder->buffer_pos] & 0x70)
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
coder->todo_count = 0;
|
||||
|
||||
// If Size of Header Metadata is present, prepare the
|
||||
// variable for variable-length integer decoding. Otherwise
|
||||
// set it to LZMA_VLI_VALUE_UNKNOWN to indicate that the
|
||||
@@ -350,7 +352,18 @@ process(lzma_coder *coder, lzma_allocator *allocator)
|
||||
case SEQ_EXTRA_SIZE:
|
||||
case SEQ_EXTRA_DUMMY_SIZE:
|
||||
read_vli(coder->tmp);
|
||||
++coder->sequence;
|
||||
|
||||
if (coder->tmp == 0) {
|
||||
// We have no Data in the Extra Record. Don't
|
||||
// allocate any memory for it. Go back to
|
||||
// SEQ_EXTRA_ALLOC or SEQ_EXTRA_DUMMY_ALLOC.
|
||||
coder->tmp = 0;
|
||||
coder->sequence -= 2;
|
||||
coder->todo_count = 0;
|
||||
} else {
|
||||
++coder->sequence;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SEQ_EXTRA_DATA_ALLOC: {
|
||||
@@ -360,7 +373,8 @@ process(lzma_coder *coder, lzma_allocator *allocator)
|
||||
coder->extra_tail->size = (size_t)(coder->tmp);
|
||||
coder->tmp = 0;
|
||||
|
||||
uint8_t *d = lzma_alloc((size_t)(coder->extra_tail->size),
|
||||
// We reserve space for the trailing '\0' too.
|
||||
uint8_t *d = lzma_alloc((size_t)(coder->extra_tail->size) + 1,
|
||||
allocator);
|
||||
if (d == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
@@ -377,6 +391,7 @@ process(lzma_coder *coder, lzma_allocator *allocator)
|
||||
(size_t)(coder->extra_tail->size));
|
||||
|
||||
if ((size_t)(coder->extra_tail->size) == coder->pos) {
|
||||
coder->extra_tail->data[coder->pos] = '\0';
|
||||
coder->pos = 0;
|
||||
coder->todo_count = 0;
|
||||
coder->sequence = SEQ_EXTRA_ALLOC;
|
||||
@@ -475,6 +490,13 @@ metadata_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
if (coder->todo_count != 0)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
// If Size of Header Metadata Block was not
|
||||
// present, we use zero as its size instead
|
||||
// of LZMA_VLI_VALUE_UNKNOWN.
|
||||
if (coder->metadata->header_metadata_size
|
||||
== LZMA_VLI_VALUE_UNKNOWN)
|
||||
coder->metadata->header_metadata_size = 0;
|
||||
|
||||
return LZMA_STREAM_END;
|
||||
}
|
||||
}
|
||||
@@ -484,6 +506,7 @@ metadata_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
static void
|
||||
metadata_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_coder_end(&coder->block_decoder, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
@@ -514,7 +537,7 @@ metadata_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
metadata->extra = NULL;
|
||||
|
||||
next->coder->sequence = SEQ_FLAGS;
|
||||
next->coder->todo_count = 0;
|
||||
next->coder->todo_count = 1;
|
||||
next->coder->pos = 0;
|
||||
next->coder->tmp = 0;
|
||||
next->coder->metadata = metadata;
|
||||
|
||||
@@ -87,8 +87,7 @@ process(lzma_coder *coder)
|
||||
case SEQ_FLAGS:
|
||||
coder->buffer[coder->buffer_size] = 0;
|
||||
|
||||
if (coder->metadata.header_metadata_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN)
|
||||
if (coder->metadata.header_metadata_size != 0)
|
||||
coder->buffer[coder->buffer_size] |= 0x01;
|
||||
|
||||
if (coder->metadata.total_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
@@ -109,8 +108,7 @@ process(lzma_coder *coder)
|
||||
break;
|
||||
|
||||
case SEQ_HEADER_METADATA_SIZE:
|
||||
if (coder->metadata.header_metadata_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN)
|
||||
if (coder->metadata.header_metadata_size != 0)
|
||||
write_vli(coder->metadata.header_metadata_size);
|
||||
|
||||
coder->sequence = SEQ_TOTAL_SIZE;
|
||||
@@ -373,13 +371,14 @@ lzma_metadata_size(const lzma_metadata *metadata)
|
||||
lzma_vli size = 1; // Metadata Flags
|
||||
|
||||
// Validate header_metadata_size, total_size, and uncompressed_size.
|
||||
if (!lzma_vli_is_valid(metadata->header_metadata_size)
|
||||
if (metadata->header_metadata_size > LZMA_VLI_VALUE_MAX
|
||||
|| !lzma_vli_is_valid(metadata->total_size)
|
||||
|| metadata->total_size == 0
|
||||
|| !lzma_vli_is_valid(metadata->uncompressed_size))
|
||||
return 0;
|
||||
|
||||
// Add the sizes of these three fields.
|
||||
if (metadata->header_metadata_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
if (metadata->header_metadata_size != 0)
|
||||
size += lzma_vli_size(metadata->header_metadata_size);
|
||||
|
||||
if (metadata->total_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/// \return true if error occurred, false on success.
|
||||
///
|
||||
static bool
|
||||
prepare(lzma_vli *id, lzma_vli *uncompressed_size, bool implicit)
|
||||
prepare(lzma_vli *id, lzma_vli *uncompressed_size, bool allow_implicit)
|
||||
{
|
||||
bool needs_end_of_input = false;
|
||||
|
||||
@@ -62,17 +62,19 @@ prepare(lzma_vli *id, lzma_vli *uncompressed_size, bool implicit)
|
||||
|
||||
// Is this the last filter in the chain?
|
||||
if (id[1] == LZMA_VLI_VALUE_UNKNOWN) {
|
||||
if (!needs_end_of_input || !implicit || uncompressed_size[0]
|
||||
!= LZMA_VLI_VALUE_UNKNOWN)
|
||||
return false;
|
||||
if (needs_end_of_input && allow_implicit
|
||||
&& uncompressed_size[0]
|
||||
== LZMA_VLI_VALUE_UNKNOWN) {
|
||||
// Add implicit Subblock filter.
|
||||
id[1] = LZMA_FILTER_SUBBLOCK;
|
||||
uncompressed_size[1] = LZMA_VLI_VALUE_UNKNOWN;
|
||||
id[2] = LZMA_VLI_VALUE_UNKNOWN;
|
||||
}
|
||||
|
||||
// Add implicit Subblock filter.
|
||||
id[1] = LZMA_FILTER_SUBBLOCK;
|
||||
uncompressed_size[1] = LZMA_VLI_VALUE_UNKNOWN;
|
||||
id[2] = LZMA_VLI_VALUE_UNKNOWN;
|
||||
return false;
|
||||
}
|
||||
|
||||
return prepare(id + 1, uncompressed_size + 1, implicit);
|
||||
return prepare(id + 1, uncompressed_size + 1, allow_implicit);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "simple_coder.h"
|
||||
#include "subblock_decoder.h"
|
||||
#include "subblock_decoder_helper.h"
|
||||
#include "delta_coder.h"
|
||||
#include "delta_decoder.h"
|
||||
#include "lzma_decoder.h"
|
||||
#include "metadata_decoder.h"
|
||||
|
||||
|
||||
@@ -21,10 +21,16 @@
|
||||
#include "copy_coder.h"
|
||||
#include "simple_coder.h"
|
||||
#include "subblock_encoder.h"
|
||||
#include "delta_coder.h"
|
||||
#include "delta_encoder.h"
|
||||
#include "lzma_encoder.h"
|
||||
|
||||
|
||||
struct lzma_coder_s {
|
||||
lzma_next_coder next;
|
||||
lzma_vli uncompressed_size;
|
||||
};
|
||||
|
||||
|
||||
static lzma_init_function
|
||||
get_function(lzma_vli id)
|
||||
{
|
||||
@@ -84,22 +90,78 @@ get_function(lzma_vli id)
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
raw_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
{
|
||||
// Check that our amount of input stays in proper limits.
|
||||
if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN) {
|
||||
if (action == LZMA_FINISH) {
|
||||
if (coder->uncompressed_size != in_size - *in_pos)
|
||||
return LZMA_PROG_ERROR;
|
||||
} else {
|
||||
if (coder->uncompressed_size < in_size - *in_pos)
|
||||
return LZMA_PROG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t in_start = *in_pos;
|
||||
|
||||
const lzma_ret ret = coder->next.code(coder->next.coder, allocator,
|
||||
in, in_pos, in_size, out, out_pos, out_size, action);
|
||||
|
||||
if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
coder->uncompressed_size -= *in_pos - in_start;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
raw_encoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_coder_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
raw_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_options_filter *options,
|
||||
lzma_vli uncompressed_size, bool allow_implicit)
|
||||
{
|
||||
if (next->coder == NULL) {
|
||||
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||
if (next->coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->code = &raw_encode;
|
||||
next->end = &raw_encoder_end;
|
||||
|
||||
next->coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
next->coder->uncompressed_size = uncompressed_size;
|
||||
|
||||
// lzma_raw_coder_init() accesses get_function() via function pointer,
|
||||
// because this way linker doesn't statically link both encoder and
|
||||
// decoder functions if user needs only encoder or decoder.
|
||||
return lzma_raw_coder_init(&next->coder->next, allocator,
|
||||
options, uncompressed_size,
|
||||
&get_function, allow_implicit, true);
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_raw_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_options_filter *options,
|
||||
lzma_vli uncompressed_size, bool allow_implicit)
|
||||
{
|
||||
// lzma_raw_coder_init() accesses get_function() via function pointer,
|
||||
// because this way linker doesn't statically link both encoder and
|
||||
// decoder functions if user needs only encoder or decoder.
|
||||
const lzma_ret ret = lzma_raw_coder_init(next, allocator,
|
||||
options, uncompressed_size, &get_function,
|
||||
allow_implicit, true);
|
||||
|
||||
if (ret != LZMA_OK)
|
||||
lzma_next_coder_end(next, allocator);
|
||||
|
||||
return ret;
|
||||
lzma_next_coder_init(raw_encoder_init, next, allocator,
|
||||
options, uncompressed_size, allow_implicit);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,18 +169,12 @@ extern LZMA_API lzma_ret
|
||||
lzma_raw_encoder(lzma_stream *strm, const lzma_options_filter *options,
|
||||
lzma_vli uncompressed_size, lzma_bool allow_implicit)
|
||||
{
|
||||
return_if_error(lzma_strm_init(strm));
|
||||
lzma_next_strm_init(strm, raw_encoder_init,
|
||||
options, uncompressed_size, allow_implicit);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
const lzma_ret ret = lzma_raw_coder_init(&strm->internal->next,
|
||||
strm->allocator, options, uncompressed_size,
|
||||
&get_function, allow_implicit, true);
|
||||
|
||||
if (ret != LZMA_OK)
|
||||
lzma_end(strm);
|
||||
|
||||
return ret;
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
@@ -204,6 +204,14 @@ stream_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
coder->block_options.check = coder->header_flags.check;
|
||||
coder->block_options.has_crc32 = coder->header_flags.has_crc32;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < ARRAY_SIZE(coder->block_options.filters);
|
||||
++i) {
|
||||
lzma_free(coder->block_options.filters[i].options,
|
||||
allocator);
|
||||
coder->block_options.filters[i].options = NULL;
|
||||
}
|
||||
|
||||
return_if_error(lzma_block_header_decoder_init(
|
||||
&coder->block_header_decoder, allocator,
|
||||
&coder->block_options));
|
||||
@@ -359,6 +367,9 @@ stream_decode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
static void
|
||||
stream_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(coder->block_options.filters); ++i)
|
||||
lzma_free(coder->block_options.filters[i].options, allocator);
|
||||
|
||||
lzma_next_coder_end(&coder->block_decoder, allocator);
|
||||
lzma_next_coder_end(&coder->block_header_decoder, allocator);
|
||||
lzma_next_coder_end(&coder->flags_decoder, allocator);
|
||||
@@ -389,6 +400,11 @@ stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
next->coder->metadata.index = NULL;
|
||||
next->coder->metadata.extra = NULL;
|
||||
} else {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(
|
||||
next->coder->block_options.filters); ++i)
|
||||
lzma_free(next->coder->block_options
|
||||
.filters[i].options, allocator);
|
||||
|
||||
lzma_index_free(next->coder->metadata.index, allocator);
|
||||
next->coder->metadata.index = NULL;
|
||||
|
||||
@@ -396,6 +412,10 @@ stream_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
next->coder->metadata.extra = NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(next->coder->block_options.filters);
|
||||
++i)
|
||||
next->coder->block_options.filters[i].options = NULL;
|
||||
|
||||
next->coder->info = lzma_info_init(next->coder->info, allocator);
|
||||
if (next->coder->info == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "stream_common.h"
|
||||
#include "stream_encoder_multi.h"
|
||||
#include "block_encoder.h"
|
||||
#include "metadata_encoder.h"
|
||||
|
||||
@@ -79,7 +80,7 @@ block_header_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
coder->block_options = (lzma_options_block){
|
||||
.check = coder->stream_options->check,
|
||||
.has_crc32 = coder->stream_options->has_crc32,
|
||||
.has_eopm = true,
|
||||
.has_eopm = uncompressed_size == LZMA_VLI_VALUE_UNKNOWN,
|
||||
.is_metadata = type != BLOCK_DATA,
|
||||
.has_uncompressed_size_in_footer = false,
|
||||
.has_backward_size = type == BLOCK_FOOTER_METADATA,
|
||||
@@ -220,7 +221,11 @@ stream_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
.uncompressed_size = coder->stream_options
|
||||
->uncompressed_size,
|
||||
.index = NULL,
|
||||
.extra = coder->stream_options->header,
|
||||
// Metadata encoder doesn't modify this, but since
|
||||
// the lzma_extra structure is used also when decoding
|
||||
// Metadata, the pointer is not const, and we need
|
||||
// to cast the constness away in the encoder.
|
||||
.extra = (lzma_extra *)(coder->stream_options->header),
|
||||
};
|
||||
|
||||
return_if_error(metadata_encoder_init(coder, allocator,
|
||||
@@ -238,7 +243,7 @@ stream_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
.total_size = LZMA_VLI_VALUE_UNKNOWN,
|
||||
.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN,
|
||||
.index = lzma_info_index_get(coder->info, false),
|
||||
.extra = coder->stream_options->footer,
|
||||
.extra = (lzma_extra *)(coder->stream_options->footer),
|
||||
};
|
||||
|
||||
return_if_error(metadata_encoder_init(coder, allocator,
|
||||
@@ -271,8 +276,12 @@ stream_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
// Don't create an empty Block unless it would be
|
||||
// the only Data Block.
|
||||
if (*in_pos == in_size) {
|
||||
// If we are LZMA_SYNC_FLUSHing or LZMA_FULL_FLUSHing,
|
||||
// return LZMA_STREAM_END since there's nothing to
|
||||
// flush.
|
||||
if (action != LZMA_FINISH)
|
||||
return LZMA_OK;
|
||||
return action == LZMA_RUN
|
||||
? LZMA_OK : LZMA_STREAM_END;
|
||||
|
||||
if (lzma_info_index_count_get(coder->info) != 0) {
|
||||
if (lzma_info_index_finish(coder->info))
|
||||
@@ -413,14 +422,12 @@ stream_encoder_init(lzma_next_coder *next,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
extern lzma_ret
|
||||
lzma_stream_encoder_multi_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_options_stream *options)
|
||||
{
|
||||
lzma_next_coder_init(stream_encoder_init, next, allocator, options);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
extern LZMA_API lzma_ret
|
||||
|
||||
26
src/liblzma/common/stream_encoder_multi.h
Normal file
26
src/liblzma/common/stream_encoder_multi.h
Normal file
@@ -0,0 +1,26 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file stream_encoder_multi.h
|
||||
/// \brief Encodes Multi-Block .lzma files
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_STREAM_ENCODER_MULTI_H
|
||||
#define LZMA_STREAM_ENCODER_MULTI_H
|
||||
|
||||
extern lzma_ret lzma_stream_encoder_multi_init(lzma_next_coder *next,
|
||||
lzma_allocator *allocator, const lzma_options_stream *options);
|
||||
|
||||
#endif
|
||||
@@ -212,6 +212,7 @@ lzma_stream_encoder_single(
|
||||
lzma_next_strm_init(strm, stream_encoder_init, options);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
return LZMA_OK;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../common/sysdefs.h
|
||||
@@ -429,20 +429,21 @@ lzma_lz_decoder_reset(lzma_lz_decoder *lz, lzma_allocator *allocator,
|
||||
return LZMA_MEM_ERROR;
|
||||
}
|
||||
|
||||
// Clean up the buffers to make it very sure that there are
|
||||
// no information leaks when multiple steams are decoded
|
||||
// with the same decoder structures.
|
||||
memzero(lz->dict, dict_real_size);
|
||||
memzero(lz->temp, LZMA_BUFFER_SIZE);
|
||||
|
||||
// Reset the variables so that lz_get_byte(lz, 0) will return '\0'.
|
||||
lz->pos = 0;
|
||||
lz->start = 0;
|
||||
lz->end = dict_real_size;
|
||||
lz->dict[dict_real_size - 1] = 0;
|
||||
lz->is_full = false;
|
||||
lz->eopm_detected = false;
|
||||
lz->next_finished = false;
|
||||
lz->this_finished = false;
|
||||
lz->temp_size = 0;
|
||||
|
||||
// Clean up the temporary buffer to make it very sure that there are
|
||||
// no information leaks when multiple steams are decoded with the
|
||||
// same decoder structures.
|
||||
memzero(lz->temp, LZMA_BUFFER_SIZE);
|
||||
|
||||
// Set the process function pointer.
|
||||
lz->process = process;
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
/// Calculate certain match finder properties and validate the calculated
|
||||
/// values. This is as its own function, because *num_items is needed to
|
||||
/// calculate memory requirements in common/memory.c.
|
||||
extern uint32_t
|
||||
extern bool
|
||||
lzma_lz_encoder_hash_properties(lzma_match_finder match_finder,
|
||||
uint32_t history_size, uint32_t *restrict hash_mask,
|
||||
uint32_t *restrict hash_size_sum, uint32_t *restrict num_items)
|
||||
@@ -141,8 +141,9 @@ lzma_lz_encoder_reset(lzma_lz_encoder *lz, lzma_allocator *allocator,
|
||||
const uint8_t *preset_dictionary,
|
||||
size_t preset_dictionary_size)
|
||||
{
|
||||
// Set uncompressed size.
|
||||
lz->sequence = SEQ_START;
|
||||
lz->uncompressed_size = uncompressed_size;
|
||||
lz->temp_size = 0;
|
||||
|
||||
///////////////
|
||||
// In Window //
|
||||
@@ -179,17 +180,15 @@ lzma_lz_encoder_reset(lzma_lz_encoder *lz, lzma_allocator *allocator,
|
||||
}
|
||||
}
|
||||
|
||||
// Allocation successful. Store the new size and calculate
|
||||
// must_move_pos.
|
||||
// Allocation successful. Store the new size.
|
||||
lz->size = buffer_size;
|
||||
lz->must_move_pos = lz->size - lz->keep_size_after;
|
||||
|
||||
// Reset in window variables.
|
||||
lz->offset = 0;
|
||||
lz->read_pos = 0;
|
||||
lz->read_limit = 0;
|
||||
lz->write_pos = 0;
|
||||
lz->stream_end_was_reached = false;
|
||||
lz->pending = 0;
|
||||
|
||||
|
||||
//////////////////
|
||||
@@ -370,35 +369,59 @@ fill_window(lzma_coder *coder, lzma_allocator *allocator, const uint8_t *in,
|
||||
size_t *in_pos, size_t in_size, lzma_action action)
|
||||
{
|
||||
assert(coder->lz.read_pos <= coder->lz.write_pos);
|
||||
lzma_ret ret;
|
||||
|
||||
// Move the sliding window if needed.
|
||||
if (coder->lz.read_pos >= coder->lz.must_move_pos)
|
||||
if (coder->lz.read_pos >= coder->lz.size - coder->lz.keep_size_after)
|
||||
move_window(&coder->lz);
|
||||
|
||||
size_t in_used;
|
||||
lzma_ret ret;
|
||||
if (coder->next.code == NULL) {
|
||||
// Not using a filter, simply memcpy() as much as possible.
|
||||
bufcpy(in, in_pos, in_size, coder->lz.buffer,
|
||||
in_used = bufcpy(in, in_pos, in_size, coder->lz.buffer,
|
||||
&coder->lz.write_pos, coder->lz.size);
|
||||
|
||||
if (action == LZMA_FINISH && *in_pos == in_size)
|
||||
if (action != LZMA_RUN && *in_pos == in_size)
|
||||
ret = LZMA_STREAM_END;
|
||||
else
|
||||
ret = LZMA_OK;
|
||||
|
||||
} else {
|
||||
const size_t in_start = *in_pos;
|
||||
ret = coder->next.code(coder->next.coder, allocator,
|
||||
in, in_pos, in_size,
|
||||
coder->lz.buffer, &coder->lz.write_pos,
|
||||
coder->lz.size, action);
|
||||
in_used = *in_pos - in_start;
|
||||
}
|
||||
|
||||
// If end of stream has been reached, we allow the encoder to process
|
||||
// all the input (that is, read_pos is allowed to reach write_pos).
|
||||
// Otherwise we keep keep_size_after bytes available as prebuffer.
|
||||
assert(coder->lz.uncompressed_size >= in_used);
|
||||
if (coder->lz.uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
coder->lz.uncompressed_size -= in_used;
|
||||
|
||||
// If end of stream has been reached or flushing completed, we allow
|
||||
// the encoder to process all the input (that is, read_pos is allowed
|
||||
// to reach write_pos). Otherwise we keep keep_size_after bytes
|
||||
// available as prebuffer.
|
||||
if (ret == LZMA_STREAM_END) {
|
||||
coder->lz.stream_end_was_reached = true;
|
||||
assert(*in_pos == in_size);
|
||||
coder->lz.read_limit = coder->lz.write_pos;
|
||||
ret = LZMA_OK;
|
||||
|
||||
switch (action) {
|
||||
case LZMA_SYNC_FLUSH:
|
||||
coder->lz.sequence = SEQ_FLUSH;
|
||||
break;
|
||||
|
||||
case LZMA_FINISH:
|
||||
coder->lz.sequence = SEQ_FINISH;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
ret = LZMA_PROG_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (coder->lz.write_pos > coder->lz.keep_size_after) {
|
||||
// This needs to be done conditionally, because if we got
|
||||
@@ -408,6 +431,39 @@ fill_window(lzma_coder *coder, lzma_allocator *allocator, const uint8_t *in,
|
||||
- coder->lz.keep_size_after;
|
||||
}
|
||||
|
||||
// Switch to finishing mode if we have got all the input data.
|
||||
// lzma_lz_encode() won't return LZMA_STREAM_END until LZMA_FINISH
|
||||
// is used.
|
||||
//
|
||||
// NOTE: When LZMA is used together with other filters, it is possible
|
||||
// that coder->lz.sequence gets set to SEQ_FINISH before the next
|
||||
// encoder has returned LZMA_STREAM_END. This is somewhat ugly, but
|
||||
// works correctly, because the next encoder cannot have any more
|
||||
// output left to be produced. If it had, then our known Uncompressed
|
||||
// Size would be invalid, which would mean that we have a bad bug.
|
||||
// if (ret == LZMA_OK && coder->lz.uncompressed_size == 0)
|
||||
// coder->lz.sequence = SEQ_FINISH;
|
||||
// The above breaks normal encoding with known uncompressed size
|
||||
// if input chunk size is a multiple of uncompressed size. Commenting
|
||||
// the above out breaks LZMA_SYNC_FLUSH at end of stream whose
|
||||
// uncompressed size is known. Support for encoding with known
|
||||
// uncompressed may get dropped completely so I won't fix this now.
|
||||
|
||||
// Restart the match finder after finished LZMA_SYNC_FLUSH.
|
||||
if (coder->lz.pending > 0
|
||||
&& coder->lz.read_pos < coder->lz.read_limit) {
|
||||
// Match finder may update coder->pending and expects it to
|
||||
// start from zero, so use a temporary variable.
|
||||
const size_t pending = coder->lz.pending;
|
||||
coder->lz.pending = 0;
|
||||
|
||||
// Rewind read_pos so that the match finder can hash
|
||||
// the pending bytes.
|
||||
assert(coder->lz.read_pos >= pending);
|
||||
coder->lz.read_pos -= pending;
|
||||
coder->lz.skip(&coder->lz, pending);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -419,20 +475,99 @@ lzma_lz_encode(lzma_coder *coder, lzma_allocator *allocator,
|
||||
uint8_t *restrict out, size_t *restrict out_pos,
|
||||
size_t out_size, lzma_action action)
|
||||
{
|
||||
while (*out_pos < out_size
|
||||
&& (*in_pos < in_size || action == LZMA_FINISH)) {
|
||||
// Fill the input window if there is no more usable data.
|
||||
if (!coder->lz.stream_end_was_reached && coder->lz.read_pos
|
||||
>= coder->lz.read_limit) {
|
||||
const lzma_ret ret = fill_window(coder, allocator,
|
||||
in, in_pos, in_size, action);
|
||||
if (ret != LZMA_OK && ret != LZMA_STREAM_END)
|
||||
return ret;
|
||||
// Flush the temporary output buffer, which may be used when the
|
||||
// encoder runs of out of space in primary output buffer (the out,
|
||||
// *out_pos, and out_size variables).
|
||||
if (coder->lz.temp_size > 0) {
|
||||
const size_t out_avail = out_size - *out_pos;
|
||||
if (out_avail < coder->lz.temp_size) {
|
||||
// Cannot copy everything. Copy as much as possible
|
||||
// and move the data in lz.temp to the beginning of
|
||||
// that buffer.
|
||||
memcpy(out + *out_pos, coder->lz.temp, out_avail);
|
||||
*out_pos += out_avail;
|
||||
memmove(coder->lz.temp, coder->lz.temp + out_avail,
|
||||
coder->lz.temp_size - out_avail);
|
||||
coder->lz.temp_size -= out_avail;
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
// Encode
|
||||
if (coder->lz.process(coder, out, out_pos, out_size))
|
||||
// We can copy everything from coder->lz.temp to out.
|
||||
memcpy(out + *out_pos, coder->lz.temp, coder->lz.temp_size);
|
||||
*out_pos += coder->lz.temp_size;
|
||||
coder->lz.temp_size = 0;
|
||||
}
|
||||
|
||||
switch (coder->lz.sequence) {
|
||||
case SEQ_START:
|
||||
assert(coder->lz.read_pos == coder->lz.write_pos);
|
||||
|
||||
// If there is no new input data and LZMA_SYNC_FLUSH is used
|
||||
// immediatelly after previous LZMA_SYNC_FLUSH finished or
|
||||
// at the very beginning of the input stream, we return
|
||||
// LZMA_STREAM_END immediatelly. Writing a flush marker
|
||||
// to the very beginning of the stream or right after previous
|
||||
// flush marker is not allowed by the LZMA stream format.
|
||||
if (*in_pos == in_size && action == LZMA_SYNC_FLUSH)
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
coder->lz.sequence = SEQ_RUN;
|
||||
break;
|
||||
|
||||
case SEQ_FLUSH_END:
|
||||
// During an earlier call to this function, flushing was
|
||||
// otherwise finished except some data was left pending
|
||||
// in coder->lz.buffer. Now we have copied all that data
|
||||
// to the output buffer and can return LZMA_STREAM_END.
|
||||
coder->lz.sequence = SEQ_START;
|
||||
assert(action == LZMA_SYNC_FLUSH);
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
case SEQ_END:
|
||||
// This is like the above flushing case, but for finishing
|
||||
// the encoding.
|
||||
//
|
||||
// NOTE: action is not necesarily LZMA_FINISH; it can
|
||||
// be LZMA_RUN or LZMA_SYNC_FLUSH too in case it is used
|
||||
// at the end of the stream with known Uncompressed Size.
|
||||
return action != LZMA_RUN ? LZMA_STREAM_END : LZMA_OK;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
while (*out_pos < out_size
|
||||
&& (*in_pos < in_size || action != LZMA_RUN)) {
|
||||
// Read more data to coder->lz.buffer if needed.
|
||||
if (coder->lz.sequence == SEQ_RUN
|
||||
&& coder->lz.read_pos >= coder->lz.read_limit)
|
||||
return_if_error(fill_window(coder, allocator,
|
||||
in, in_pos, in_size, action));
|
||||
|
||||
// Encode
|
||||
if (coder->lz.process(coder, out, out_pos, out_size)) {
|
||||
if (coder->lz.sequence == SEQ_FLUSH) {
|
||||
assert(action == LZMA_SYNC_FLUSH);
|
||||
if (coder->lz.temp_size == 0) {
|
||||
// Flushing was finished successfully.
|
||||
coder->lz.sequence = SEQ_START;
|
||||
} else {
|
||||
// Flushing was otherwise finished,
|
||||
// except that some data was left
|
||||
// into coder->lz.buffer.
|
||||
coder->lz.sequence = SEQ_FLUSH_END;
|
||||
}
|
||||
} else {
|
||||
// NOTE: action may be LZMA_RUN here in case
|
||||
// Uncompressed Size is known and we have
|
||||
// processed all the data already.
|
||||
assert(coder->lz.sequence == SEQ_FINISH);
|
||||
coder->lz.sequence = SEQ_END;
|
||||
}
|
||||
|
||||
return action != LZMA_RUN && coder->lz.temp_size == 0
|
||||
? LZMA_STREAM_END : LZMA_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
|
||||
@@ -24,11 +24,16 @@
|
||||
#include "common.h"
|
||||
|
||||
|
||||
#define LZMA_LZ_TEMP_SIZE 64
|
||||
|
||||
|
||||
typedef struct lzma_lz_encoder_s lzma_lz_encoder;
|
||||
struct lzma_lz_encoder_s {
|
||||
enum {
|
||||
SEQ_INIT,
|
||||
SEQ_START,
|
||||
SEQ_RUN,
|
||||
SEQ_FLUSH,
|
||||
SEQ_FLUSH_END,
|
||||
SEQ_FINISH,
|
||||
SEQ_END
|
||||
} sequence;
|
||||
@@ -36,8 +41,15 @@ struct lzma_lz_encoder_s {
|
||||
bool (*process)(lzma_coder *coder, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size);
|
||||
|
||||
/// Uncompressed Size or LZMA_VLI_VALUE_UNKNOWN if using EOPM. We need
|
||||
/// to track Uncompressed Size to prevent writing flush marker to the
|
||||
/// very end of stream that doesn't use EOPM.
|
||||
lzma_vli uncompressed_size;
|
||||
|
||||
/// Temporary buffer for range encoder.
|
||||
uint8_t temp[LZMA_LZ_TEMP_SIZE];
|
||||
size_t temp_size;
|
||||
|
||||
///////////////
|
||||
// In Window //
|
||||
///////////////
|
||||
@@ -72,9 +84,9 @@ struct lzma_lz_encoder_s {
|
||||
/// to buffer[write_pos].
|
||||
size_t write_pos;
|
||||
|
||||
/// When read_pos >= must_move_pos, move_window() must be called
|
||||
/// to make more space for the input data.
|
||||
size_t must_move_pos;
|
||||
/// Number of bytes not hashed before read_pos. This is needed to
|
||||
/// restart the match finder after LZMA_SYNC_FLUSH.
|
||||
size_t pending;
|
||||
|
||||
/// Number of bytes that must be kept available in our input history.
|
||||
/// That is, once keep_size_before bytes have been processed,
|
||||
@@ -88,10 +100,6 @@ struct lzma_lz_encoder_s {
|
||||
/// is allowed to reach write_pos).
|
||||
size_t keep_size_after;
|
||||
|
||||
/// This is set to true once the last byte of the input data has
|
||||
/// been copied to buffer.
|
||||
bool stream_end_was_reached;
|
||||
|
||||
//////////////////
|
||||
// Match Finder //
|
||||
//////////////////
|
||||
@@ -124,7 +132,7 @@ struct lzma_lz_encoder_s {
|
||||
|
||||
|
||||
/// Calculates
|
||||
extern uint32_t lzma_lz_encoder_hash_properties(lzma_match_finder match_finder,
|
||||
extern bool lzma_lz_encoder_hash_properties(lzma_match_finder match_finder,
|
||||
uint32_t history_size, uint32_t *restrict hash_mask,
|
||||
uint32_t *restrict hash_size_sum,
|
||||
uint32_t *restrict num_items);
|
||||
|
||||
@@ -104,6 +104,14 @@ do { \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define move_pending() \
|
||||
do { \
|
||||
++lz->read_pos; \
|
||||
assert(lz->read_pos <= lz->write_pos); \
|
||||
++lz->pending; \
|
||||
} while (0)
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Global constants //
|
||||
//////////////////////
|
||||
@@ -122,15 +130,16 @@ LZMA_GET_MATCHES(LZMA_MATCH_FINDER_NAME_LOWER)
|
||||
if (lz->read_pos + lz->match_max_len <= lz->write_pos) {
|
||||
len_limit = lz->match_max_len;
|
||||
} else {
|
||||
assert(lz->stream_end_was_reached);
|
||||
len_limit = lz->write_pos - lz->read_pos;
|
||||
if (len_limit < MIN_MATCH_CHECK) {
|
||||
if (len_limit < MIN_MATCH_CHECK || lz->sequence == SEQ_FLUSH) {
|
||||
distances[0] = 0;
|
||||
move_pos();
|
||||
move_pending();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(lz->pending == 0);
|
||||
|
||||
int32_t offset = 1;
|
||||
const uint32_t match_min_pos
|
||||
= lz->read_pos + lz->offset > lz->cyclic_buffer_size
|
||||
@@ -292,7 +301,7 @@ LZMA_SKIP(LZMA_MATCH_FINDER_NAME_LOWER)
|
||||
do {
|
||||
#ifdef IS_HASH_CHAIN
|
||||
if (lz->write_pos - lz->read_pos < NUM_HASH_BYTES) {
|
||||
move_pos();
|
||||
move_pending();
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
@@ -300,10 +309,10 @@ LZMA_SKIP(LZMA_MATCH_FINDER_NAME_LOWER)
|
||||
if (lz->read_pos + lz->match_max_len <= lz->write_pos) {
|
||||
len_limit = lz->match_max_len;
|
||||
} else {
|
||||
assert(lz->stream_end_was_reached == true);
|
||||
len_limit = lz->write_pos - lz->read_pos;
|
||||
if (len_limit < MIN_MATCH_CHECK) {
|
||||
move_pos();
|
||||
if (len_limit < MIN_MATCH_CHECK
|
||||
|| lz->sequence == SEQ_FLUSH) {
|
||||
move_pending();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -313,6 +322,8 @@ LZMA_SKIP(LZMA_MATCH_FINDER_NAME_LOWER)
|
||||
: 0;
|
||||
#endif
|
||||
|
||||
assert(lz->pending == 0);
|
||||
|
||||
const uint8_t *cur = lz->buffer + lz->read_pos;
|
||||
|
||||
#ifdef HASH_ARRAY_2
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
## Lesser General Public License for more details.
|
||||
##
|
||||
|
||||
EXTRA_DIST = fastpos_tablegen.c
|
||||
|
||||
noinst_LTLIBRARIES = liblzma4.la
|
||||
liblzma4_la_CPPFLAGS = \
|
||||
-I@top_srcdir@/src/liblzma/api \
|
||||
@@ -26,6 +28,7 @@ liblzma4_la_SOURCES = \
|
||||
|
||||
if COND_MAIN_ENCODER
|
||||
liblzma4_la_SOURCES += \
|
||||
fastpos.h \
|
||||
lzma_encoder.h \
|
||||
lzma_encoder.c \
|
||||
lzma_encoder_presets.c \
|
||||
@@ -34,6 +37,10 @@ liblzma4_la_SOURCES += \
|
||||
lzma_encoder_features.c \
|
||||
lzma_encoder_getoptimum.c \
|
||||
lzma_encoder_getoptimumfast.c
|
||||
|
||||
if !COND_SMALL
|
||||
liblzma4_la_SOURCES += fastpos_table.c
|
||||
endif
|
||||
endif
|
||||
|
||||
if COND_MAIN_DECODER
|
||||
|
||||
156
src/liblzma/lzma/fastpos.h
Normal file
156
src/liblzma/lzma/fastpos.h
Normal file
@@ -0,0 +1,156 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file fastpos.h
|
||||
/// \brief Kind of two-bit version of bit scan reverse
|
||||
//
|
||||
// Copyright (C) 1999-2007 Igor Pavlov
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_FASTPOS_H
|
||||
#define LZMA_FASTPOS_H
|
||||
|
||||
// LZMA encodes match distances (positions) by storing the highest two
|
||||
// bits using a six-bit value [0, 63], and then the missing lower bits.
|
||||
// Dictionary size is also stored using this encoding in the new .lzma
|
||||
// file format header.
|
||||
//
|
||||
// fastpos.h provides a way to quickly find out the correct six-bit
|
||||
// values. The following table gives some examples of this encoding:
|
||||
//
|
||||
// pos return
|
||||
// 0 0
|
||||
// 1 1
|
||||
// 2 2
|
||||
// 3 3
|
||||
// 4 4
|
||||
// 5 4
|
||||
// 6 5
|
||||
// 7 5
|
||||
// 8 6
|
||||
// 11 6
|
||||
// 12 7
|
||||
// ... ...
|
||||
// 15 7
|
||||
// 16 8
|
||||
// 17 8
|
||||
// ... ...
|
||||
// 23 8
|
||||
// 24 9
|
||||
// 25 9
|
||||
// ... ...
|
||||
//
|
||||
//
|
||||
// Provided functions or macros
|
||||
// ----------------------------
|
||||
//
|
||||
// get_pos_slot(pos) is the basic version. get_pos_slot_2(pos)
|
||||
// assumes that pos >= FULL_DISTANCES, thus the result is at least
|
||||
// FULL_DISTANCES_BITS * 2. Using get_pos_slot(pos) instead of
|
||||
// get_pos_slot_2(pos) would give the same result, but get_pos_slot_2(pos)
|
||||
// should be tiny bit faster due to the assumption being made.
|
||||
//
|
||||
//
|
||||
// Size vs. speed
|
||||
// --------------
|
||||
//
|
||||
// With some CPUs that have fast BSR (bit scan reverse) instruction, the
|
||||
// size optimized version is slightly faster than the bigger table based
|
||||
// approach. Such CPUs include Intel Pentium Pro, Pentium II, Pentium III
|
||||
// and Core 2 (possibly others). AMD K7 seems to have slower BSR, but that
|
||||
// would still have speed roughly comparable to the table version. Older
|
||||
// x86 CPUs like the original Pentium have very slow BSR; on those systems
|
||||
// the table version is a lot faster.
|
||||
//
|
||||
// On some CPUs, the table version is a lot faster when using position
|
||||
// dependent code, but with position independent code the size optimized
|
||||
// version is slightly faster. This occurs at least on 32-bit SPARC (no
|
||||
// ASM optimizations).
|
||||
//
|
||||
// I'm making the table version the default, because that has good speed
|
||||
// on all systems I have tried. The size optimized version is sometimes
|
||||
// slightly faster, but sometimes it is a lot slower.
|
||||
//
|
||||
// Finally, this code isn't a major bottle neck in LZMA encoding anyway.
|
||||
|
||||
#ifdef HAVE_SMALL
|
||||
# include "bsr.h"
|
||||
|
||||
# define get_pos_slot(pos) ((pos) <= 4 ? (pos) : get_pos_slot_2(pos))
|
||||
|
||||
static inline uint32_t
|
||||
get_pos_slot_2(uint32_t pos)
|
||||
{
|
||||
uint32_t i;
|
||||
lzma_bsr(i, pos);
|
||||
return (i + i) + ((pos >> (i - 1)) & 1);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define FASTPOS_BITS 13
|
||||
|
||||
extern const uint8_t lzma_fastpos[1 << FASTPOS_BITS];
|
||||
|
||||
|
||||
#define fastpos_shift(extra, n) \
|
||||
((extra) + (n) * (FASTPOS_BITS - 1))
|
||||
|
||||
#define fastpos_limit(extra, n) \
|
||||
(UINT32_C(1) << (FASTPOS_BITS + fastpos_shift(extra, n)))
|
||||
|
||||
#define fastpos_result(pos, extra, n) \
|
||||
lzma_fastpos[(pos) >> fastpos_shift(extra, n)] \
|
||||
+ 2 * fastpos_shift(extra, n)
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_pos_slot(uint32_t pos)
|
||||
{
|
||||
// If it is small enough, we can pick the result directly from
|
||||
// the precalculated table.
|
||||
if (pos < fastpos_limit(0, 0))
|
||||
return lzma_fastpos[pos];
|
||||
|
||||
if (pos < fastpos_limit(0, 1))
|
||||
return fastpos_result(pos, 0, 1);
|
||||
|
||||
return fastpos_result(pos, 0, 2);
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_DISTANCES_BITS
|
||||
static inline uint32_t
|
||||
get_pos_slot_2(uint32_t pos)
|
||||
{
|
||||
// FIXME: This assert() cannot be enabled at the moment, because
|
||||
// lzma_getoptimum.c calls this function so that this assertion
|
||||
// fails; however, it ignores the result of this function when
|
||||
// this assert() would have failed.
|
||||
// assert(pos >= FULL_DISTANCES);
|
||||
|
||||
if (pos < fastpos_limit(FULL_DISTANCES_BITS - 1, 0))
|
||||
return fastpos_result(pos, FULL_DISTANCES_BITS - 1, 0);
|
||||
|
||||
if (pos < fastpos_limit(FULL_DISTANCES_BITS - 1, 1))
|
||||
return fastpos_result(pos, FULL_DISTANCES_BITS - 1, 1);
|
||||
|
||||
return fastpos_result(pos, FULL_DISTANCES_BITS - 1, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
519
src/liblzma/lzma/fastpos_table.c
Normal file
519
src/liblzma/lzma/fastpos_table.c
Normal file
@@ -0,0 +1,519 @@
|
||||
/* This file has been automatically generated by fastpos_tablegen.c. */
|
||||
|
||||
#include "common.h"
|
||||
#include "fastpos.h"
|
||||
|
||||
const uint8_t lzma_fastpos[1 << FASTPOS_BITS] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25
|
||||
};
|
||||
63
src/liblzma/lzma/fastpos_tablegen.c
Normal file
63
src/liblzma/lzma/fastpos_tablegen.c
Normal file
@@ -0,0 +1,63 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file fastpos_tablegen.c
|
||||
/// \brief Generates the lzma_fastpos[] lookup table
|
||||
//
|
||||
// Copyright (C) 1999-2007 Igor Pavlov
|
||||
// Copyright (C) 2008 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include "fastpos.h"
|
||||
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
uint8_t fastpos[1 << FASTPOS_BITS];
|
||||
|
||||
const uint8_t fast_slots = 2 * FASTPOS_BITS;
|
||||
uint32_t c = 2;
|
||||
|
||||
fastpos[0] = 0;
|
||||
fastpos[1] = 1;
|
||||
|
||||
for (uint8_t slot_fast = 2; slot_fast < fast_slots; ++slot_fast) {
|
||||
const uint32_t k = 1 << ((slot_fast >> 1) - 1);
|
||||
for (uint32_t j = 0; j < k; ++j, ++c)
|
||||
fastpos[c] = slot_fast;
|
||||
}
|
||||
|
||||
printf("/* This file has been automatically generated "
|
||||
"by fastpos_tablegen.c. */\n\n"
|
||||
"#include \"common.h\"\n"
|
||||
"#include \"fastpos.h\"\n\n"
|
||||
"const uint8_t lzma_fastpos[1 << FASTPOS_BITS] = {");
|
||||
|
||||
for (size_t i = 0; i < (1 << FASTPOS_BITS); ++i) {
|
||||
if (i % 16 == 0)
|
||||
printf("\n\t");
|
||||
|
||||
printf("%3u", (unsigned int)(fastpos[i]));
|
||||
|
||||
if (i != (1 << FASTPOS_BITS) - 1)
|
||||
printf(",");
|
||||
}
|
||||
|
||||
printf("\n};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -31,8 +31,6 @@
|
||||
///////////////
|
||||
|
||||
#define REP_DISTANCES 4
|
||||
#define STATES 12
|
||||
#define LIT_STATES 7
|
||||
|
||||
#define POS_SLOT_BITS 6
|
||||
#define DICT_LOG_SIZE_MAX 30
|
||||
@@ -55,13 +53,10 @@
|
||||
#define END_POS_MODEL_INDEX 14
|
||||
#define POS_MODELS (END_POS_MODEL_INDEX - START_POS_MODEL_INDEX)
|
||||
|
||||
#define FULL_DISTANCES (1 << (END_POS_MODEL_INDEX / 2))
|
||||
#define FULL_DISTANCES_BITS (END_POS_MODEL_INDEX / 2)
|
||||
#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
|
||||
|
||||
#define LIT_POS_STATES_BITS_MAX LZMA_LITERAL_POS_BITS_MAX
|
||||
#define LIT_CONTEXT_BITS_MAX LZMA_LITERAL_CONTEXT_BITS_MAX
|
||||
|
||||
#define POS_STATES_BITS_MAX LZMA_POS_BITS_MAX
|
||||
#define POS_STATES_MAX (1 << POS_STATES_BITS_MAX)
|
||||
#define POS_STATES_MAX (1 << LZMA_POS_BITS_MAX)
|
||||
|
||||
|
||||
// Length coder & Length price table encoder
|
||||
@@ -79,7 +74,11 @@
|
||||
#define LEN_CODER_TOTAL_PROBS (LEN_HIGH_CODER + LEN_HIGH_SYMBOLS)
|
||||
|
||||
// Price table size of Len Encoder
|
||||
#define LEN_PRICES (LEN_SYMBOLS << POS_STATES_BITS_MAX)
|
||||
#define LEN_PRICES (LEN_SYMBOLS << LZMA_POS_BITS_MAX)
|
||||
|
||||
// Special lengths used together with distance == UINT32_MAX
|
||||
#define LEN_SPECIAL_EOPM MATCH_MIN_LEN
|
||||
#define LEN_SPECIAL_FLUSH (LEN_SPECIAL_EOPM + 1)
|
||||
|
||||
|
||||
// Optimal - Number of entries in the optimum array.
|
||||
@@ -104,25 +103,62 @@
|
||||
// State //
|
||||
///////////
|
||||
|
||||
// Used for updating strm->data->state in both encoder and decoder.
|
||||
/// This enum is used to track which events have occurred most recently and
|
||||
/// in which order. This information is used to predict the next event.
|
||||
///
|
||||
/// Events:
|
||||
/// - Literal: One 8-bit byte
|
||||
/// - Match: Repeat a chunk of data at some distance
|
||||
/// - Long repeat: Multi-byte match at a recently seen distance
|
||||
/// - Short repeat: One-byte repeat at a recently seen distance
|
||||
///
|
||||
/// The event names are in from STATE_oldest_older_previous. REP means
|
||||
/// either short or long repeated match, and NONLIT means any non-literal.
|
||||
typedef enum {
|
||||
STATE_LIT_LIT,
|
||||
STATE_MATCH_LIT_LIT,
|
||||
STATE_REP_LIT_LIT,
|
||||
STATE_SHORTREP_LIT_LIT,
|
||||
STATE_MATCH_LIT,
|
||||
STATE_REP_LIT,
|
||||
STATE_SHORTREP_LIT,
|
||||
STATE_LIT_MATCH,
|
||||
STATE_LIT_LONGREP,
|
||||
STATE_LIT_SHORTREP,
|
||||
STATE_NONLIT_MATCH,
|
||||
STATE_NONLIT_REP,
|
||||
} lzma_lzma_state;
|
||||
|
||||
#define update_char(index) \
|
||||
index = ((index) < 4 \
|
||||
? 0 \
|
||||
: ((index) < 10 \
|
||||
? (index) - 3 \
|
||||
: (index) - 6))
|
||||
|
||||
#define update_match(index) \
|
||||
index = ((index) < LIT_STATES ? 7 : 10)
|
||||
/// Total number of states
|
||||
#define STATES 12
|
||||
|
||||
#define update_rep(index) \
|
||||
index = ((index) < LIT_STATES ? 8 : 11)
|
||||
/// The lowest 7 states indicate that the previous state was a literal.
|
||||
#define LIT_STATES 7
|
||||
|
||||
#define update_short_rep(index) \
|
||||
index = ((index) < LIT_STATES ? 9 : 11)
|
||||
|
||||
#define is_char_state(index) \
|
||||
((index) < LIT_STATES)
|
||||
/// Indicate that the latest state was a literal.
|
||||
#define update_literal(state) \
|
||||
state = ((state) <= STATE_SHORTREP_LIT_LIT \
|
||||
? STATE_LIT_LIT \
|
||||
: ((state) <= STATE_LIT_SHORTREP \
|
||||
? (state) - 3 \
|
||||
: (state) - 6))
|
||||
|
||||
/// Indicate that the latest state was a match.
|
||||
#define update_match(state) \
|
||||
state = ((state) < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH)
|
||||
|
||||
/// Indicate that the latest state was a long repeated match.
|
||||
#define update_long_rep(state) \
|
||||
state = ((state) < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP)
|
||||
|
||||
/// Indicate that the latest state was a short match.
|
||||
#define update_short_rep(state) \
|
||||
state = ((state) < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP)
|
||||
|
||||
/// Test if the previous state was a literal.
|
||||
#define is_literal_state(state) \
|
||||
((state) < LIT_STATES)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// NOTE: If you want to keep the line length in 80 characters, set
|
||||
// tab width to 4 or less in your editor when editing this file.
|
||||
|
||||
#include "lzma_common.h"
|
||||
#include "lzma_decoder.h"
|
||||
#include "lz_decoder.h"
|
||||
@@ -44,21 +47,17 @@ do { \
|
||||
if_bit_0(len_decoder.choice) { \
|
||||
update_bit_0(len_decoder.choice); \
|
||||
target = MATCH_MIN_LEN; \
|
||||
bittree_decode(target, \
|
||||
len_decoder.low[pos_state], LEN_LOW_BITS); \
|
||||
bittree_decode(target, len_decoder.low[pos_state], LEN_LOW_BITS); \
|
||||
} else { \
|
||||
update_bit_1(len_decoder.choice); \
|
||||
if_bit_0(len_decoder.choice2) { \
|
||||
update_bit_0(len_decoder.choice2); \
|
||||
target = MATCH_MIN_LEN + LEN_LOW_SYMBOLS; \
|
||||
bittree_decode(target, len_decoder.mid[pos_state], \
|
||||
LEN_MID_BITS); \
|
||||
bittree_decode(target, len_decoder.mid[pos_state], LEN_MID_BITS); \
|
||||
} else { \
|
||||
update_bit_1(len_decoder.choice2); \
|
||||
target = MATCH_MIN_LEN + LEN_LOW_SYMBOLS \
|
||||
+ LEN_MID_SYMBOLS; \
|
||||
bittree_decode(target, len_decoder.high, \
|
||||
LEN_HIGH_BITS); \
|
||||
target = MATCH_MIN_LEN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; \
|
||||
bittree_decode(target, len_decoder.high, LEN_HIGH_BITS); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -76,15 +75,12 @@ do { \
|
||||
if_bit_0(len_decoder.choice2) { \
|
||||
update_bit_0_dummy(); \
|
||||
target = MATCH_MIN_LEN + LEN_LOW_SYMBOLS; \
|
||||
bittree_decode_dummy(target, \
|
||||
len_decoder.mid[pos_state], \
|
||||
bittree_decode_dummy(target, len_decoder.mid[pos_state], \
|
||||
LEN_MID_BITS); \
|
||||
} else { \
|
||||
update_bit_1_dummy(); \
|
||||
target = MATCH_MIN_LEN + LEN_LOW_SYMBOLS \
|
||||
+ LEN_MID_SYMBOLS; \
|
||||
bittree_decode_dummy(target, len_decoder.high, \
|
||||
LEN_HIGH_BITS); \
|
||||
target = MATCH_MIN_LEN + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; \
|
||||
bittree_decode_dummy(target, len_decoder.high, LEN_HIGH_BITS); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -110,7 +106,7 @@ struct lzma_coder_s {
|
||||
lzma_range_decoder rc;
|
||||
|
||||
// State
|
||||
uint32_t state;
|
||||
lzma_lzma_state state;
|
||||
uint32_t rep0; ///< Distance of the latest match
|
||||
uint32_t rep1; ///< Distance of second latest match
|
||||
uint32_t rep2; ///< Distance of third latest match
|
||||
@@ -139,7 +135,7 @@ struct lzma_coder_s {
|
||||
probability is_rep2[STATES];
|
||||
|
||||
/// If 1, the repeated match has length of one byte. Otherwise
|
||||
/// the length is decoded from rep_match_len_decoder.
|
||||
/// the length is decoded from rep_len_decoder.
|
||||
probability is_rep0_long[STATES][POS_STATES_MAX];
|
||||
|
||||
probability pos_slot_decoder[LEN_TO_POS_STATES][1 << POS_SLOT_BITS];
|
||||
@@ -147,14 +143,14 @@ struct lzma_coder_s {
|
||||
probability pos_align_decoder[1 << ALIGN_BITS];
|
||||
|
||||
/// Length of a match
|
||||
lzma_length_decoder len_decoder;
|
||||
lzma_length_decoder match_len_decoder;
|
||||
|
||||
/// Length of a repeated match.
|
||||
lzma_length_decoder rep_match_len_decoder;
|
||||
lzma_length_decoder rep_len_decoder;
|
||||
|
||||
/// The first five bytes of LZMA compressed data are treated
|
||||
/// specially. Once they are read, this stays at zero.
|
||||
size_t init_bytes_left;
|
||||
/// True when we have produced at least one byte of output since the
|
||||
/// beginning of the stream or the latest flush marker.
|
||||
bool has_produced_output;
|
||||
};
|
||||
|
||||
|
||||
@@ -166,7 +162,7 @@ struct lzma_coder_s {
|
||||
static bool lzma_attribute((pure))
|
||||
decode_dummy(const lzma_coder *restrict coder,
|
||||
const uint8_t *restrict in, size_t in_pos_local,
|
||||
const size_t in_size, uint32_t rc_range, uint32_t rc_code,
|
||||
const size_t in_size, lzma_range_decoder rc,
|
||||
uint32_t state, uint32_t rep0, const uint32_t now_pos)
|
||||
{
|
||||
uint32_t rc_bound;
|
||||
@@ -180,50 +176,44 @@ decode_dummy(const lzma_coder *restrict coder,
|
||||
update_bit_0_dummy();
|
||||
|
||||
const probability *subcoder = literal_get_subcoder(
|
||||
coder->literal_coder,
|
||||
now_pos, lz_get_byte(coder->lz, 0));
|
||||
coder->literal_coder, now_pos, lz_get_byte(coder->lz, 0));
|
||||
uint32_t symbol = 1;
|
||||
|
||||
if (!is_char_state(state)) {
|
||||
// Decode literal with match byte.
|
||||
if (is_literal_state(state)) {
|
||||
// Decode literal without match byte.
|
||||
do {
|
||||
if_bit_0(subcoder[symbol]) {
|
||||
update_bit_0_dummy();
|
||||
symbol <<= 1;
|
||||
} else {
|
||||
update_bit_1_dummy();
|
||||
symbol = (symbol << 1) | 1;
|
||||
}
|
||||
} while (symbol < 0x100);
|
||||
|
||||
assert(rep0 != UINT32_MAX);
|
||||
uint32_t match_byte
|
||||
= lz_get_byte(coder->lz, rep0);
|
||||
} else {
|
||||
// Decode literal with match byte.
|
||||
uint32_t match_byte = lz_get_byte(coder->lz, rep0);
|
||||
uint32_t subcoder_offset = 0x100;
|
||||
|
||||
do {
|
||||
match_byte <<= 1;
|
||||
const uint32_t match_bit
|
||||
= match_byte & 0x100;
|
||||
const uint32_t subcoder_index = 0x100
|
||||
+ match_bit + symbol;
|
||||
const uint32_t match_bit = match_byte & subcoder_offset;
|
||||
const uint32_t subcoder_index
|
||||
= subcoder_offset + match_bit + symbol;
|
||||
|
||||
if_bit_0(subcoder[subcoder_index]) {
|
||||
update_bit_0_dummy();
|
||||
symbol <<= 1;
|
||||
if (match_bit != 0)
|
||||
break;
|
||||
subcoder_offset &= ~match_bit;
|
||||
} else {
|
||||
update_bit_1_dummy();
|
||||
symbol = (symbol << 1) | 1;
|
||||
if (match_bit == 0)
|
||||
break;
|
||||
subcoder_offset &= match_bit;
|
||||
}
|
||||
} while (symbol < 0x100);
|
||||
}
|
||||
|
||||
// Decode literal without match byte. This is also
|
||||
// the tail of the with-match-byte function.
|
||||
while (symbol < 0x100) {
|
||||
if_bit_0(subcoder[symbol]) {
|
||||
update_bit_0_dummy();
|
||||
symbol <<= 1;
|
||||
} else {
|
||||
update_bit_1_dummy();
|
||||
symbol = (symbol << 1) | 1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -232,14 +222,12 @@ decode_dummy(const lzma_coder *restrict coder,
|
||||
|
||||
if_bit_0(coder->is_rep[state]) {
|
||||
update_bit_0_dummy();
|
||||
length_decode_dummy(len, coder->len_decoder, pos_state);
|
||||
update_match(state);
|
||||
length_decode_dummy(len, coder->match_len_decoder, pos_state);
|
||||
|
||||
const uint32_t len_to_pos_state
|
||||
= get_len_to_pos_state(len);
|
||||
const uint32_t len_to_pos_state = get_len_to_pos_state(len);
|
||||
uint32_t pos_slot = 0;
|
||||
bittree_decode_dummy(pos_slot, coder->pos_slot_decoder[
|
||||
len_to_pos_state], POS_SLOT_BITS);
|
||||
bittree_decode_dummy(pos_slot,
|
||||
coder->pos_slot_decoder[len_to_pos_state], POS_SLOT_BITS);
|
||||
assert(pos_slot <= 63);
|
||||
|
||||
if (pos_slot >= START_POS_MODEL_INDEX) {
|
||||
@@ -251,41 +239,25 @@ decode_dummy(const lzma_coder *restrict coder,
|
||||
assert(direct_bits <= 5);
|
||||
rep0 <<= direct_bits;
|
||||
assert(rep0 <= 96);
|
||||
// -1 is fine, because
|
||||
// bittree_reverse_decode()
|
||||
// starts from table index [1]
|
||||
// (not [0]).
|
||||
assert((int32_t)(rep0 - pos_slot - 1)
|
||||
>= -1);
|
||||
assert((int32_t)(rep0 - pos_slot - 1)
|
||||
<= 82);
|
||||
// -1 is fine, because bittree_reverse_decode()
|
||||
// starts from table index [1] (not [0]).
|
||||
assert((int32_t)(rep0 - pos_slot - 1) >= -1);
|
||||
assert((int32_t)(rep0 - pos_slot - 1) <= 82);
|
||||
// We add the result to rep0, so rep0
|
||||
// must not be part of second argument
|
||||
// of the macro.
|
||||
const int32_t offset
|
||||
= rep0 - pos_slot - 1;
|
||||
bittree_reverse_decode_dummy(
|
||||
coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
const int32_t offset = rep0 - pos_slot - 1;
|
||||
bittree_reverse_decode_dummy(coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
} else {
|
||||
// Decode direct bits
|
||||
assert(pos_slot >= 14);
|
||||
assert(direct_bits >= 6);
|
||||
direct_bits -= ALIGN_BITS;
|
||||
assert(direct_bits >= 2);
|
||||
do {
|
||||
rc_normalize();
|
||||
rc_range >>= 1;
|
||||
const uint32_t t
|
||||
= (rc_code - rc_range)
|
||||
>> 31;
|
||||
rc_code -= rc_range & (t - 1);
|
||||
} while (--direct_bits > 0);
|
||||
rep0 <<= ALIGN_BITS;
|
||||
rc_decode_direct_dummy(direct_bits);
|
||||
|
||||
bittree_reverse_decode_dummy(
|
||||
coder->pos_align_decoder,
|
||||
ALIGN_BITS);
|
||||
bittree_reverse_decode_dummy(coder->pos_align_decoder,
|
||||
ALIGN_BITS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,8 +267,7 @@ decode_dummy(const lzma_coder *restrict coder,
|
||||
if_bit_0(coder->is_rep0[state]) {
|
||||
update_bit_0_dummy();
|
||||
|
||||
if_bit_0(coder->is_rep0_long[state][
|
||||
pos_state]) {
|
||||
if_bit_0(coder->is_rep0_long[state][pos_state]) {
|
||||
update_bit_0_dummy();
|
||||
break;
|
||||
} else {
|
||||
@@ -319,18 +290,13 @@ decode_dummy(const lzma_coder *restrict coder,
|
||||
}
|
||||
}
|
||||
|
||||
length_decode_dummy(len, coder->rep_match_len_decoder,
|
||||
pos_state);
|
||||
length_decode_dummy(len, coder->rep_len_decoder, pos_state);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
rc_normalize();
|
||||
|
||||
// Validate the buffer position.
|
||||
if (in_pos_local > in_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return in_pos_local <= in_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -342,15 +308,8 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
// Initialization //
|
||||
////////////////////
|
||||
|
||||
while (coder->init_bytes_left > 0) {
|
||||
if (*in_pos == in_size)
|
||||
return false;
|
||||
|
||||
coder->rc.code = (coder->rc.code << 8) | in[*in_pos];
|
||||
++*in_pos;
|
||||
--coder->init_bytes_left;
|
||||
}
|
||||
|
||||
if (!rc_read_init(&coder->rc, in, in_pos, in_size))
|
||||
return false;
|
||||
|
||||
///////////////
|
||||
// Variables //
|
||||
@@ -371,6 +330,7 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
|
||||
// Misc
|
||||
uint32_t now_pos = coder->now_pos;
|
||||
bool has_produced_output = coder->has_produced_output;
|
||||
|
||||
// Variables derived from decoder settings
|
||||
const uint32_t pos_mask = coder->pos_mask;
|
||||
@@ -383,10 +343,10 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
in_limit = in_size - REQUIRED_IN_BUFFER_SIZE;
|
||||
|
||||
|
||||
while (coder->lz.pos < coder->lz.limit && (in_pos_local < in_limit
|
||||
|| (has_safe_buffer && decode_dummy(
|
||||
coder, in, in_pos_local, in_size,
|
||||
rc_range, rc_code, state, rep0, now_pos)))) {
|
||||
while (coder->lz.pos < coder->lz.limit
|
||||
&& (in_pos_local < in_limit || (has_safe_buffer
|
||||
&& decode_dummy(coder, in, in_pos_local, in_size,
|
||||
rc, state, rep0, now_pos)))) {
|
||||
|
||||
/////////////////////
|
||||
// Actual decoding //
|
||||
@@ -399,58 +359,56 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
|
||||
// It's a literal i.e. a single 8-bit byte.
|
||||
|
||||
probability *subcoder = literal_get_subcoder(
|
||||
coder->literal_coder,
|
||||
probability *subcoder = literal_get_subcoder(coder->literal_coder,
|
||||
now_pos, lz_get_byte(coder->lz, 0));
|
||||
uint32_t symbol = 1;
|
||||
|
||||
if (!is_char_state(state)) {
|
||||
// Decode literal with match byte.
|
||||
if (is_literal_state(state)) {
|
||||
// Decode literal without match byte.
|
||||
do {
|
||||
if_bit_0(subcoder[symbol]) {
|
||||
update_bit_0(subcoder[symbol]);
|
||||
symbol <<= 1;
|
||||
} else {
|
||||
update_bit_1(subcoder[symbol]);
|
||||
symbol = (symbol << 1) | 1;
|
||||
}
|
||||
} while (symbol < 0x100);
|
||||
|
||||
assert(rep0 != UINT32_MAX);
|
||||
uint32_t match_byte
|
||||
= lz_get_byte(coder->lz, rep0);
|
||||
} else {
|
||||
// Decode literal with match byte.
|
||||
//
|
||||
// The usage of subcoder_offset allows omitting some
|
||||
// branches, which should give tiny speed improvement on
|
||||
// some CPUs. subcoder_offset gets set to zero if match_bit
|
||||
// didn't match.
|
||||
uint32_t match_byte = lz_get_byte(coder->lz, rep0);
|
||||
uint32_t subcoder_offset = 0x100;
|
||||
|
||||
do {
|
||||
match_byte <<= 1;
|
||||
const uint32_t match_bit
|
||||
= match_byte & 0x100;
|
||||
const uint32_t subcoder_index = 0x100
|
||||
+ match_bit + symbol;
|
||||
const uint32_t match_bit = match_byte & subcoder_offset;
|
||||
const uint32_t subcoder_index
|
||||
= subcoder_offset + match_bit + symbol;
|
||||
|
||||
if_bit_0(subcoder[subcoder_index]) {
|
||||
update_bit_0(subcoder[
|
||||
subcoder_index]);
|
||||
update_bit_0(subcoder[subcoder_index]);
|
||||
symbol <<= 1;
|
||||
if (match_bit != 0)
|
||||
break;
|
||||
subcoder_offset &= ~match_bit;
|
||||
} else {
|
||||
update_bit_1(subcoder[
|
||||
subcoder_index]);
|
||||
update_bit_1(subcoder[subcoder_index]);
|
||||
symbol = (symbol << 1) | 1;
|
||||
if (match_bit == 0)
|
||||
break;
|
||||
subcoder_offset &= match_bit;
|
||||
}
|
||||
} while (symbol < 0x100);
|
||||
}
|
||||
|
||||
// Decode literal without match byte. This is also
|
||||
// the tail of the with-match-byte function.
|
||||
while (symbol < 0x100) {
|
||||
if_bit_0(subcoder[symbol]) {
|
||||
update_bit_0(subcoder[symbol]);
|
||||
symbol <<= 1;
|
||||
} else {
|
||||
update_bit_1(subcoder[symbol]);
|
||||
symbol = (symbol << 1) | 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Put the decoded byte to the dictionary, update the
|
||||
// decoder state, and start a new decoding loop.
|
||||
coder->lz.dict[coder->lz.pos++] = (uint8_t)(symbol);
|
||||
++now_pos;
|
||||
update_char(state);
|
||||
update_literal(state);
|
||||
has_produced_output = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -467,79 +425,101 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
// Not a repeated match
|
||||
//
|
||||
// We will decode a new distance and store
|
||||
// the value to rep0.
|
||||
|
||||
// The latest three match distances are kept in
|
||||
// memory in case there are repeated matches.
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
// the value to distance.
|
||||
|
||||
// Decode the length of the match.
|
||||
length_decode(len, coder->len_decoder, pos_state);
|
||||
length_decode(len, coder->match_len_decoder, pos_state);
|
||||
|
||||
update_match(state);
|
||||
|
||||
const uint32_t len_to_pos_state
|
||||
= get_len_to_pos_state(len);
|
||||
const uint32_t len_to_pos_state = get_len_to_pos_state(len);
|
||||
uint32_t pos_slot = 0;
|
||||
bittree_decode(pos_slot, coder->pos_slot_decoder[
|
||||
len_to_pos_state], POS_SLOT_BITS);
|
||||
bittree_decode(pos_slot,
|
||||
coder->pos_slot_decoder[len_to_pos_state], POS_SLOT_BITS);
|
||||
assert(pos_slot <= 63);
|
||||
|
||||
if (pos_slot >= START_POS_MODEL_INDEX) {
|
||||
uint32_t direct_bits = (pos_slot >> 1) - 1;
|
||||
assert(direct_bits >= 1 && direct_bits <= 30);
|
||||
rep0 = 2 | (pos_slot & 1);
|
||||
uint32_t distance = 2 | (pos_slot & 1);
|
||||
|
||||
if (pos_slot < END_POS_MODEL_INDEX) {
|
||||
assert(direct_bits <= 5);
|
||||
rep0 <<= direct_bits;
|
||||
assert(rep0 <= 96);
|
||||
distance <<= direct_bits;
|
||||
assert(distance <= 96);
|
||||
// -1 is fine, because
|
||||
// bittree_reverse_decode()
|
||||
// starts from table index [1]
|
||||
// (not [0]).
|
||||
assert((int32_t)(rep0 - pos_slot - 1)
|
||||
>= -1);
|
||||
assert((int32_t)(rep0 - pos_slot - 1)
|
||||
<= 82);
|
||||
// We add the result to rep0, so rep0
|
||||
assert((int32_t)(distance - pos_slot - 1) >= -1);
|
||||
assert((int32_t)(distance - pos_slot - 1) <= 82);
|
||||
// We add the result to distance, so distance
|
||||
// must not be part of second argument
|
||||
// of the macro.
|
||||
const int32_t offset
|
||||
= rep0 - pos_slot - 1;
|
||||
bittree_reverse_decode(rep0,
|
||||
coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
const int32_t offset = distance - pos_slot - 1;
|
||||
bittree_reverse_decode(distance, coder->pos_decoders + offset,
|
||||
direct_bits);
|
||||
} else {
|
||||
// Decode direct bits
|
||||
assert(pos_slot >= 14);
|
||||
assert(direct_bits >= 6);
|
||||
direct_bits -= ALIGN_BITS;
|
||||
assert(direct_bits >= 2);
|
||||
do {
|
||||
rc_normalize();
|
||||
rc_range >>= 1;
|
||||
const uint32_t t
|
||||
= (rc_code - rc_range)
|
||||
>> 31;
|
||||
rc_code -= rc_range & (t - 1);
|
||||
rep0 = (rep0 << 1) | (1 - t);
|
||||
} while (--direct_bits > 0);
|
||||
rep0 <<= ALIGN_BITS;
|
||||
rc_decode_direct(distance, direct_bits);
|
||||
distance <<= ALIGN_BITS;
|
||||
|
||||
bittree_reverse_decode(rep0,
|
||||
coder->pos_align_decoder,
|
||||
ALIGN_BITS);
|
||||
bittree_reverse_decode(distance, coder->pos_align_decoder,
|
||||
ALIGN_BITS);
|
||||
|
||||
if (rep0 == UINT32_MAX) {
|
||||
// End of Payload Marker found.
|
||||
coder->lz.eopm_detected = true;
|
||||
break;
|
||||
if (distance == UINT32_MAX) {
|
||||
if (len == LEN_SPECIAL_EOPM) {
|
||||
// End of Payload Marker found.
|
||||
coder->lz.eopm_detected = true;
|
||||
break;
|
||||
|
||||
} else if (len == LEN_SPECIAL_FLUSH) {
|
||||
// Flush marker detected. We must have produced
|
||||
// at least one byte of output since the previous
|
||||
// flush marker or the beginning of the stream.
|
||||
// This is to prevent hanging the decoder with
|
||||
// malicious input files.
|
||||
if (!has_produced_output)
|
||||
return true;
|
||||
|
||||
has_produced_output = false;
|
||||
|
||||
// We know that we have enough input to call
|
||||
// this macro, because it is tested at the
|
||||
// end of decode_dummy().
|
||||
rc_normalize();
|
||||
|
||||
rc_reset(rc);
|
||||
|
||||
// If we don't have enough input here, we jump
|
||||
// out of the loop. Note that while there is a
|
||||
// useless call to rc_normalize(), it does nothing
|
||||
// since we have just reset the range decoder.
|
||||
if (!rc_read_init(&rc, in, &in_pos_local, in_size))
|
||||
break;
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The latest three match distances are kept in
|
||||
// memory in case there are repeated matches.
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
|
||||
} else {
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
rep0 = pos_slot;
|
||||
}
|
||||
|
||||
@@ -558,39 +538,24 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
|
||||
// The distance is rep0.
|
||||
|
||||
if_bit_0(coder->is_rep0_long[state][
|
||||
pos_state]) {
|
||||
update_bit_0(coder->is_rep0_long[
|
||||
state][pos_state]);
|
||||
|
||||
// Repeating exactly one byte. For
|
||||
// simplicity, it is done here inline
|
||||
// instead of at the end of the main
|
||||
// loop.
|
||||
if_bit_0(coder->is_rep0_long[state][pos_state]) {
|
||||
update_bit_0(coder->is_rep0_long[state][pos_state]);
|
||||
|
||||
update_short_rep(state);
|
||||
|
||||
// Security/sanity checks. See the end
|
||||
// of the main loop for explanation
|
||||
// of these.
|
||||
if ((rep0 >= coder->lz.pos
|
||||
&& !coder->lz.is_full)
|
||||
|| in_pos_local
|
||||
> in_size)
|
||||
goto error;
|
||||
|
||||
// Repeat one byte and start a new
|
||||
// decoding loop.
|
||||
// Repeat exactly one byte and start a new decoding loop.
|
||||
// Note that rep0 is known to have a safe value, thus we
|
||||
// don't need to check if we are wrapping the dictionary
|
||||
// when it isn't full yet.
|
||||
coder->lz.dict[coder->lz.pos]
|
||||
= lz_get_byte(
|
||||
coder->lz, rep0);
|
||||
= lz_get_byte(coder->lz, rep0);
|
||||
++coder->lz.pos;
|
||||
++now_pos;
|
||||
has_produced_output = true;
|
||||
continue;
|
||||
|
||||
} else {
|
||||
update_bit_1(coder->is_rep0_long[
|
||||
state][pos_state]);
|
||||
update_bit_1(coder->is_rep0_long[state][pos_state]);
|
||||
|
||||
// Repeating more than one byte at
|
||||
// distance of rep0.
|
||||
@@ -613,12 +578,10 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
update_bit_1(coder->is_rep1[state]);
|
||||
|
||||
if_bit_0(coder->is_rep2[state]) {
|
||||
update_bit_0(coder->is_rep2[
|
||||
state]);
|
||||
update_bit_0(coder->is_rep2[state]);
|
||||
distance = rep2;
|
||||
} else {
|
||||
update_bit_1(coder->is_rep2[
|
||||
state]);
|
||||
update_bit_1(coder->is_rep2[state]);
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
@@ -630,11 +593,10 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
rep0 = distance;
|
||||
}
|
||||
|
||||
// Decode the length of the repeated match.
|
||||
length_decode(len, coder->rep_match_len_decoder,
|
||||
pos_state);
|
||||
update_long_rep(state);
|
||||
|
||||
update_rep(state);
|
||||
// Decode the length of the repeated match.
|
||||
length_decode(len, coder->rep_len_decoder, pos_state);
|
||||
}
|
||||
|
||||
|
||||
@@ -648,15 +610,11 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
assert(len <= MATCH_MAX_LEN);
|
||||
|
||||
now_pos += len;
|
||||
|
||||
// Validate the buffer position to avoid buffer overflows
|
||||
// on corrupted input data.
|
||||
if (in_pos_local > in_size)
|
||||
goto error;
|
||||
has_produced_output = true;
|
||||
|
||||
// Repeat len bytes from distance of rep0.
|
||||
if (!lzma_lz_out_repeat(&coder->lz, rep0, len))
|
||||
goto error;
|
||||
return true;
|
||||
}
|
||||
|
||||
rc_normalize();
|
||||
@@ -678,12 +636,10 @@ decode_real(lzma_coder *restrict coder, const uint8_t *restrict in,
|
||||
|
||||
// Misc
|
||||
coder->now_pos = now_pos;
|
||||
coder->has_produced_output = has_produced_output;
|
||||
*in_pos = in_pos_local;
|
||||
|
||||
return false;
|
||||
|
||||
error:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -762,7 +718,6 @@ lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
next->coder->pos_bits = options->pos_bits;
|
||||
next->coder->pos_mask = (1 << next->coder->pos_bits) - 1;
|
||||
next->coder->now_pos = 0;
|
||||
next->coder->init_bytes_left = 5;
|
||||
|
||||
// Range decoder
|
||||
rc_reset(next->coder->rc);
|
||||
@@ -790,25 +745,27 @@ lzma_lzma_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
|
||||
// Len decoders (also bit/bittree)
|
||||
const uint32_t num_pos_states = 1 << next->coder->pos_bits;
|
||||
bit_reset(next->coder->len_decoder.choice);
|
||||
bit_reset(next->coder->len_decoder.choice2);
|
||||
bit_reset(next->coder->rep_match_len_decoder.choice);
|
||||
bit_reset(next->coder->rep_match_len_decoder.choice2);
|
||||
bit_reset(next->coder->match_len_decoder.choice);
|
||||
bit_reset(next->coder->match_len_decoder.choice2);
|
||||
bit_reset(next->coder->rep_len_decoder.choice);
|
||||
bit_reset(next->coder->rep_len_decoder.choice2);
|
||||
|
||||
for (uint32_t pos_state = 0; pos_state < num_pos_states; ++pos_state) {
|
||||
bittree_reset(next->coder->len_decoder.low[pos_state],
|
||||
bittree_reset(next->coder->match_len_decoder.low[pos_state],
|
||||
LEN_LOW_BITS);
|
||||
bittree_reset(next->coder->len_decoder.mid[pos_state],
|
||||
bittree_reset(next->coder->match_len_decoder.mid[pos_state],
|
||||
LEN_MID_BITS);
|
||||
|
||||
bittree_reset(next->coder->rep_match_len_decoder.low[
|
||||
pos_state], LEN_LOW_BITS);
|
||||
bittree_reset(next->coder->rep_match_len_decoder.mid[
|
||||
pos_state], LEN_MID_BITS);
|
||||
bittree_reset(next->coder->rep_len_decoder.low[pos_state],
|
||||
LEN_LOW_BITS);
|
||||
bittree_reset(next->coder->rep_len_decoder.mid[pos_state],
|
||||
LEN_MID_BITS);
|
||||
}
|
||||
|
||||
bittree_reset(next->coder->len_decoder.high, LEN_HIGH_BITS);
|
||||
bittree_reset(next->coder->rep_match_len_decoder.high, LEN_HIGH_BITS);
|
||||
bittree_reset(next->coder->match_len_decoder.high, LEN_HIGH_BITS);
|
||||
bittree_reset(next->coder->rep_len_decoder.high, LEN_HIGH_BITS);
|
||||
|
||||
next->coder->has_produced_output = false;
|
||||
|
||||
// Initialize the next decoder in the chain, if any.
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "fastpos.h"
|
||||
|
||||
|
||||
////////////
|
||||
@@ -70,7 +71,7 @@ do { \
|
||||
|
||||
#define length_encode(length_encoder, symbol, pos_state, update_price) \
|
||||
do { \
|
||||
\
|
||||
assert((symbol) <= MATCH_MAX_LEN); \
|
||||
if ((symbol) < LEN_LOW_SYMBOLS) { \
|
||||
bit_encode_0((length_encoder).choice); \
|
||||
bittree_encode((length_encoder).low[pos_state], \
|
||||
@@ -101,7 +102,7 @@ do { \
|
||||
|
||||
/// \brief Updates price table of the length encoder
|
||||
///
|
||||
/// All all the other prices in LZMA, these are used by lzma_get_optimum().
|
||||
/// Like all the other prices in LZMA, these are used by lzma_get_optimum().
|
||||
///
|
||||
extern void
|
||||
lzma_length_encoder_update_table(lzma_length_encoder *lencoder,
|
||||
@@ -116,23 +117,18 @@ lzma_length_encoder_update_table(lzma_length_encoder *lencoder,
|
||||
uint32_t *prices = lencoder->prices[pos_state];
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < num_symbols && i < LEN_LOW_SYMBOLS; ++i) {
|
||||
prices[i] = a0;
|
||||
bittree_get_price(prices[i], lencoder->low[pos_state],
|
||||
for (i = 0; i < num_symbols && i < LEN_LOW_SYMBOLS; ++i)
|
||||
prices[i] = a0 + bittree_get_price(lencoder->low[pos_state],
|
||||
LEN_LOW_BITS, i);
|
||||
}
|
||||
|
||||
for (; i < num_symbols && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i) {
|
||||
prices[i] = b0;
|
||||
bittree_get_price(prices[i], lencoder->mid[pos_state],
|
||||
for (; i < num_symbols && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i)
|
||||
prices[i] = b0 + bittree_get_price(lencoder->mid[pos_state],
|
||||
LEN_MID_BITS, i - LEN_LOW_SYMBOLS);
|
||||
}
|
||||
|
||||
for (; i < num_symbols; ++i) {
|
||||
prices[i] = b1;
|
||||
bittree_get_price(prices[i], lencoder->high, LEN_HIGH_BITS,
|
||||
for (; i < num_symbols; ++i)
|
||||
prices[i] = b1 + bittree_get_price(
|
||||
lencoder->high, LEN_HIGH_BITS,
|
||||
i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS);
|
||||
}
|
||||
|
||||
lencoder->counters[pos_state] = num_symbols;
|
||||
|
||||
@@ -149,20 +145,11 @@ extern bool
|
||||
lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size)
|
||||
{
|
||||
// Flush the range encoder's temporary buffer to out[].
|
||||
// Return immediatelly if not everything could be flushed.
|
||||
if (rc_flush_buffer(&coder->rc, out, out_pos, out_size))
|
||||
return false;
|
||||
|
||||
// Return immediatelly if we have already finished our work.
|
||||
if (coder->lz.stream_end_was_reached
|
||||
&& coder->is_initialized
|
||||
&& coder->lz.read_pos == coder->lz.write_pos
|
||||
&& coder->additional_offset == 0)
|
||||
return true;
|
||||
#define rc_buffer coder->lz.temp
|
||||
#define rc_buffer_size coder->lz.temp_size
|
||||
|
||||
// Local copies
|
||||
rc_to_local(coder->rc);
|
||||
lzma_range_encoder rc = coder->rc;
|
||||
size_t out_pos_local = *out_pos;
|
||||
const uint32_t pos_mask = coder->pos_mask;
|
||||
const bool best_compression = coder->best_compression;
|
||||
@@ -170,14 +157,12 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
// Initialize the stream if no data has been encoded yet.
|
||||
if (!coder->is_initialized) {
|
||||
if (coder->lz.read_pos == coder->lz.read_limit) {
|
||||
// Cannot initialize, because there is no input data.
|
||||
if (!coder->lz.stream_end_was_reached)
|
||||
return false;
|
||||
if (coder->lz.sequence == SEQ_RUN)
|
||||
return false; // We cannot do anything.
|
||||
|
||||
// If we get here, we are encoding an empty file.
|
||||
// Initialization is skipped completely.
|
||||
// We are finishing (we cannot get here when flushing).
|
||||
assert(coder->lz.write_pos == coder->lz.read_pos);
|
||||
|
||||
assert(coder->lz.sequence == SEQ_FINISH);
|
||||
} else {
|
||||
// Do the actual initialization.
|
||||
uint32_t len;
|
||||
@@ -185,7 +170,7 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
lzma_read_match_distances(coder, &len, &num_distance_pairs);
|
||||
|
||||
bit_encode_0(coder->is_match[coder->state][0]);
|
||||
update_char(coder->state);
|
||||
update_literal(coder->state);
|
||||
|
||||
const uint8_t cur_byte = coder->lz.buffer[
|
||||
coder->lz.read_pos - coder->additional_offset];
|
||||
@@ -214,9 +199,10 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
|
||||
// Check that there is some input to process.
|
||||
if (coder->lz.read_pos >= coder->lz.read_limit) {
|
||||
// If end of input has been reached, we must keep
|
||||
// encoding until additional_offset becomes zero.
|
||||
if (!coder->lz.stream_end_was_reached
|
||||
// If flushing or finishing, we must keep encoding
|
||||
// until additional_offset becomes zero to make
|
||||
// all the input available at output.
|
||||
if (coder->lz.sequence == SEQ_RUN
|
||||
|| coder->additional_offset == 0)
|
||||
break;
|
||||
}
|
||||
@@ -224,7 +210,7 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
assert(coder->lz.read_pos <= coder->lz.write_pos);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (coder->lz.stream_end_was_reached) {
|
||||
if (coder->lz.sequence != SEQ_RUN) {
|
||||
assert(coder->lz.read_limit == coder->lz.write_pos);
|
||||
} else {
|
||||
assert(coder->lz.read_limit + coder->lz.keep_size_after
|
||||
@@ -258,7 +244,7 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
probability *subcoder = literal_get_subcoder(coder->literal_coder,
|
||||
coder->now_pos, coder->previous_byte);
|
||||
|
||||
if (is_char_state(coder->state)) {
|
||||
if (is_literal_state(coder->state)) {
|
||||
literal_encode(subcoder, cur_byte);
|
||||
} else {
|
||||
const uint8_t match_byte = coder->lz.buffer[
|
||||
@@ -268,7 +254,7 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
literal_encode_matched(subcoder, match_byte, cur_byte);
|
||||
}
|
||||
|
||||
update_char(coder->state);
|
||||
update_literal(coder->state);
|
||||
coder->previous_byte = cur_byte;
|
||||
|
||||
} else {
|
||||
@@ -308,16 +294,16 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
if (len == 1) {
|
||||
update_short_rep(coder->state);
|
||||
} else {
|
||||
length_encode(coder->rep_match_len_encoder,
|
||||
length_encode(coder->rep_len_encoder,
|
||||
len - MATCH_MIN_LEN, pos_state,
|
||||
best_compression);
|
||||
update_rep(coder->state);
|
||||
update_long_rep(coder->state);
|
||||
}
|
||||
|
||||
} else {
|
||||
bit_encode_0(coder->is_rep[coder->state]);
|
||||
update_match(coder->state);
|
||||
length_encode(coder->len_encoder, len - MATCH_MIN_LEN,
|
||||
length_encode(coder->match_len_encoder, len - MATCH_MIN_LEN,
|
||||
pos_state, best_compression);
|
||||
pos -= REP_DISTANCES;
|
||||
|
||||
@@ -363,20 +349,24 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
|
||||
// Check if everything is done.
|
||||
bool all_done = false;
|
||||
if (coder->lz.stream_end_was_reached
|
||||
if (coder->lz.sequence != SEQ_RUN
|
||||
&& coder->lz.read_pos == coder->lz.write_pos
|
||||
&& coder->additional_offset == 0) {
|
||||
// Write end of stream marker. It is encoded as a match with
|
||||
// distance of UINT32_MAX. Match length is needed but it is
|
||||
// ignored by the decoder.
|
||||
if (coder->lz.uncompressed_size == LZMA_VLI_VALUE_UNKNOWN) {
|
||||
assert(coder->longest_match_was_found == false);
|
||||
|
||||
if (coder->lz.uncompressed_size == LZMA_VLI_VALUE_UNKNOWN
|
||||
|| coder->lz.sequence == SEQ_FLUSH) {
|
||||
// Write special marker: flush marker or end of payload
|
||||
// marker. Both are encoded as a match with distance of
|
||||
// UINT32_MAX. The match length codes the type of the marker.
|
||||
const uint32_t pos_state = coder->now_pos & pos_mask;
|
||||
bit_encode_1(coder->is_match[coder->state][pos_state]);
|
||||
bit_encode_0(coder->is_rep[coder->state]);
|
||||
update_match(coder->state);
|
||||
|
||||
const uint32_t len = MATCH_MIN_LEN; // MATCH_MAX_LEN;
|
||||
length_encode(coder->len_encoder, len - MATCH_MIN_LEN,
|
||||
const uint32_t len = coder->lz.sequence == SEQ_FLUSH
|
||||
? LEN_SPECIAL_FLUSH : LEN_SPECIAL_EOPM;
|
||||
length_encode(coder->match_len_encoder, len - MATCH_MIN_LEN,
|
||||
pos_state, best_compression);
|
||||
|
||||
const uint32_t pos_slot = (1 << POS_SLOT_BITS) - 1;
|
||||
@@ -398,15 +388,16 @@ lzma_lzma_encode(lzma_coder *coder, uint8_t *restrict out,
|
||||
// the range coder to the output buffer.
|
||||
rc_flush();
|
||||
|
||||
rc_reset(rc);
|
||||
|
||||
// All done. Note that some output bytes might be
|
||||
// pending in coder->buffer. lzma_encode() will
|
||||
// pending in coder->lz.temp. lzma_lz_encode() will
|
||||
// take care of those bytes.
|
||||
if (rc_buffer_size == 0)
|
||||
all_done = true;
|
||||
all_done = true;
|
||||
}
|
||||
|
||||
// Store local variables back to *coder.
|
||||
rc_from_local(coder->rc);
|
||||
coder->rc = rc;
|
||||
*out_pos = out_pos_local;
|
||||
|
||||
return all_done;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "fastpos.h"
|
||||
|
||||
|
||||
#define length_get_price(length_encoder, symbol, pos_state) \
|
||||
@@ -62,7 +63,7 @@ do { \
|
||||
#define get_rep_price(price_target, rep_index, len, state, pos_state) \
|
||||
do { \
|
||||
get_pure_rep_price(price_target, rep_index, state, pos_state); \
|
||||
price_target += length_get_price(coder->rep_match_len_encoder, \
|
||||
price_target += length_get_price(coder->rep_len_encoder, \
|
||||
(len) - MATCH_MIN_LEN, pos_state); \
|
||||
} while (0)
|
||||
|
||||
@@ -79,7 +80,7 @@ do { \
|
||||
+ align_prices[(pos) & ALIGN_MASK]; \
|
||||
} \
|
||||
price_target += length_get_price( \
|
||||
coder->len_encoder, (len) - MATCH_MIN_LEN, pos_state); \
|
||||
coder->match_len_encoder, (len) - MATCH_MIN_LEN, pos_state); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -111,8 +112,7 @@ fill_distances_prices(lzma_coder *coder)
|
||||
const uint32_t pos_slot = get_pos_slot(i);
|
||||
const uint32_t footer_bits = ((pos_slot >> 1) - 1);
|
||||
const uint32_t base = (2 | (pos_slot & 1)) << footer_bits;
|
||||
temp_prices[i] = 0;
|
||||
bittree_reverse_get_price(temp_prices[i],
|
||||
temp_prices[i] = bittree_reverse_get_price(
|
||||
coder->pos_encoders + base - pos_slot - 1,
|
||||
footer_bits, i - base);
|
||||
}
|
||||
@@ -129,8 +129,7 @@ fill_distances_prices(lzma_coder *coder)
|
||||
for (uint32_t pos_slot = 0;
|
||||
pos_slot < dist_table_size;
|
||||
++pos_slot) {
|
||||
pos_slot_prices[pos_slot] = 0;
|
||||
bittree_get_price(pos_slot_prices[pos_slot], encoder,
|
||||
pos_slot_prices[pos_slot] = bittree_get_price(encoder,
|
||||
POS_SLOT_BITS, pos_slot);
|
||||
}
|
||||
|
||||
@@ -162,14 +161,12 @@ fill_distances_prices(lzma_coder *coder)
|
||||
static void
|
||||
fill_align_prices(lzma_coder *coder)
|
||||
{
|
||||
for (uint32_t i = 0; i < ALIGN_TABLE_SIZE; ++i) {
|
||||
uint32_t tmp = 0;
|
||||
bittree_reverse_get_price(tmp, coder->pos_align_encoder,
|
||||
ALIGN_BITS, i);
|
||||
coder->align_prices[i] = tmp;
|
||||
}
|
||||
for (uint32_t i = 0; i < ALIGN_TABLE_SIZE; ++i)
|
||||
coder->align_prices[i] = bittree_reverse_get_price(
|
||||
coder->pos_align_encoder, ALIGN_BITS, i);
|
||||
|
||||
coder->align_price_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -371,7 +368,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
+ literal_get_price(
|
||||
literal_get_subcoder(coder->literal_coder,
|
||||
position, coder->previous_byte),
|
||||
!is_char_state(coder->state), match_byte, current_byte);
|
||||
!is_literal_state(coder->state), match_byte, current_byte);
|
||||
|
||||
make_as_char(coder->optimum[1]);
|
||||
|
||||
@@ -427,7 +424,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
do {
|
||||
const uint32_t cur_and_len_price = price
|
||||
+ length_get_price(
|
||||
coder->rep_match_len_encoder,
|
||||
coder->rep_len_encoder,
|
||||
rep_len - 2, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->optimum[rep_len].price) {
|
||||
@@ -516,7 +513,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
state = coder->optimum[coder->optimum[cur].pos_prev_2].state;
|
||||
|
||||
if (coder->optimum[cur].back_prev_2 < REP_DISTANCES)
|
||||
update_rep(state);
|
||||
update_long_rep(state);
|
||||
else
|
||||
update_match(state);
|
||||
|
||||
@@ -524,7 +521,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
state = coder->optimum[pos_prev].state;
|
||||
}
|
||||
|
||||
update_char(state);
|
||||
update_literal(state);
|
||||
|
||||
} else {
|
||||
state = coder->optimum[pos_prev].state;
|
||||
@@ -534,17 +531,17 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
if (is_short_rep(coder->optimum[cur]))
|
||||
update_short_rep(state);
|
||||
else
|
||||
update_char(state);
|
||||
update_literal(state);
|
||||
} else {
|
||||
uint32_t pos;
|
||||
if (coder->optimum[cur].prev_1_is_char && coder->optimum[cur].prev_2) {
|
||||
pos_prev = coder->optimum[cur].pos_prev_2;
|
||||
pos = coder->optimum[cur].back_prev_2;
|
||||
update_rep(state);
|
||||
update_long_rep(state);
|
||||
} else {
|
||||
pos = coder->optimum[cur].back_prev;
|
||||
if (pos < REP_DISTANCES)
|
||||
update_rep(state);
|
||||
update_long_rep(state);
|
||||
else
|
||||
update_match(state);
|
||||
}
|
||||
@@ -585,7 +582,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
+ literal_get_price(
|
||||
literal_get_subcoder(coder->literal_coder,
|
||||
position, buf[-1]),
|
||||
!is_char_state(state), match_byte, current_byte);
|
||||
!is_literal_state(state), match_byte, current_byte);
|
||||
|
||||
bool next_is_char = false;
|
||||
|
||||
@@ -641,7 +638,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
|
||||
if (len_test_2 >= 2) {
|
||||
uint32_t state_2 = state;
|
||||
update_char(state_2);
|
||||
update_literal(state_2);
|
||||
|
||||
const uint32_t pos_state_next = (position + 1) & pos_mask;
|
||||
const uint32_t next_rep_match_price = cur_and_1_price
|
||||
@@ -692,7 +689,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
|
||||
do {
|
||||
const uint32_t cur_and_len_price = price
|
||||
+ length_get_price(coder->rep_match_len_encoder,
|
||||
+ length_get_price(coder->rep_len_encoder,
|
||||
len_test - 2, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->optimum[cur + len_test].price) {
|
||||
@@ -720,12 +717,12 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
|
||||
if (len_test_2 >= 2) {
|
||||
uint32_t state_2 = state;
|
||||
update_rep(state_2);
|
||||
update_long_rep(state_2);
|
||||
|
||||
uint32_t pos_state_next = (position + len_test) & pos_mask;
|
||||
|
||||
const uint32_t cur_and_len_char_price = price
|
||||
+ length_get_price(coder->rep_match_len_encoder,
|
||||
+ length_get_price(coder->rep_len_encoder,
|
||||
len_test - 2, pos_state)
|
||||
+ bit_get_price_0(coder->is_match[state_2][pos_state_next])
|
||||
+ literal_get_price(
|
||||
@@ -733,7 +730,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
position + len_test, buf[len_test - 1]),
|
||||
true, *(buf + len_test - back_offset), buf[len_test]);
|
||||
|
||||
update_char(state_2);
|
||||
update_literal(state_2);
|
||||
|
||||
pos_state_next = (position + len_test + 1) & pos_mask;
|
||||
|
||||
@@ -804,7 +801,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
len_to_pos_state][pos_slot]
|
||||
+ align_prices[cur_back & ALIGN_MASK];
|
||||
|
||||
cur_and_len_price += length_get_price(coder->len_encoder,
|
||||
cur_and_len_price += length_get_price(coder->match_len_encoder,
|
||||
len_test - MATCH_MIN_LEN, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->optimum[cur + len_test].price) {
|
||||
@@ -846,7 +843,7 @@ lzma_get_optimum(lzma_coder *restrict coder,
|
||||
*(buf + len_test - back_offset),
|
||||
buf[len_test]);
|
||||
|
||||
update_char(state_2);
|
||||
update_literal(state_2);
|
||||
pos_state_next = (pos_state_next + 1) & pos_mask;
|
||||
|
||||
const uint32_t next_rep_match_price
|
||||
|
||||
@@ -21,28 +21,6 @@
|
||||
#include "lzma_encoder_private.h"
|
||||
|
||||
|
||||
uint8_t lzma_fastpos[1 << 11];
|
||||
|
||||
extern void
|
||||
lzma_fastpos_init(void)
|
||||
{
|
||||
static const uint8_t fast_slots = 22;
|
||||
|
||||
int c = 2;
|
||||
lzma_fastpos[0] = 0;
|
||||
lzma_fastpos[1] = 1;
|
||||
|
||||
for (uint8_t slot_fast = 2; slot_fast < fast_slots; ++slot_fast) {
|
||||
const uint32_t k = (1 << ((slot_fast >> 1) - 1));
|
||||
|
||||
for (uint32_t j = 0; j < k; ++j, ++c)
|
||||
lzma_fastpos[c] = slot_fast;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Initializes the length encoder
|
||||
static void
|
||||
length_encoder_reset(lzma_length_encoder *lencoder,
|
||||
@@ -158,6 +136,8 @@ lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
}
|
||||
|
||||
// Misc FIXME desc
|
||||
next->coder->align_price_count = UINT32_MAX;
|
||||
next->coder->match_price_count = UINT32_MAX;
|
||||
next->coder->dictionary_size = options->dictionary_size;
|
||||
next->coder->pos_mask = (1U << options->pos_bits) - 1;
|
||||
next->coder->fast_bytes = options->fast_bytes;
|
||||
@@ -194,10 +174,11 @@ lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
bittree_reset(next->coder->pos_align_encoder, ALIGN_BITS);
|
||||
|
||||
// Length encoders
|
||||
length_encoder_reset(&next->coder->len_encoder, 1U << options->pos_bits,
|
||||
length_encoder_reset(&next->coder->match_len_encoder,
|
||||
1U << options->pos_bits,
|
||||
options->fast_bytes + 1 - MATCH_MIN_LEN);
|
||||
|
||||
length_encoder_reset(&next->coder->rep_match_len_encoder,
|
||||
length_encoder_reset(&next->coder->rep_len_encoder,
|
||||
1U << options->pos_bits,
|
||||
next->coder->fast_bytes + 1 - MATCH_MIN_LEN);
|
||||
|
||||
|
||||
@@ -24,13 +24,15 @@
|
||||
#include "lzma_encoder.h"
|
||||
#include "lzma_common.h"
|
||||
#include "lz_encoder.h"
|
||||
#include "range_encoder.h"
|
||||
|
||||
// We need space for about two encoding loops, because there is no check
|
||||
// for available buffer space before end of payload marker gets written.
|
||||
// 2*26 bytes should be enough for this... but Lasse isn't very sure about
|
||||
// the exact value. 64 bytes certainly is enough. :-)
|
||||
#define RC_BUFFER_SIZE 64
|
||||
#include "range_encoder.h"
|
||||
#if LZMA_LZ_TEMP_SIZE < 64
|
||||
# error LZMA_LZ_TEMP_SIZE is too small.
|
||||
#endif
|
||||
|
||||
|
||||
#define move_pos(num) \
|
||||
@@ -43,27 +45,6 @@ do { \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define get_pos_slot(pos) \
|
||||
((pos) < (1 << 11) \
|
||||
? lzma_fastpos[pos] \
|
||||
: ((pos) < (1 << 21) \
|
||||
? lzma_fastpos[(pos) >> 10] + 20 \
|
||||
: lzma_fastpos[(pos) >> 20] + 40))
|
||||
|
||||
|
||||
#define get_pos_slot_2(pos) \
|
||||
((pos) < (1 << 17) \
|
||||
? lzma_fastpos[(pos) >> 6] + 12 \
|
||||
: ((pos) < (1 << 27) \
|
||||
? lzma_fastpos[(pos) >> 16] + 32 \
|
||||
: lzma_fastpos[(pos) >> 26] + 52))
|
||||
|
||||
|
||||
/// This isn't modified once its contents have been
|
||||
/// initialized by lzma_fastpos_init().
|
||||
extern uint8_t lzma_fastpos[1 << 11];
|
||||
|
||||
|
||||
typedef struct {
|
||||
probability choice;
|
||||
probability choice2;
|
||||
@@ -79,7 +60,7 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t state;
|
||||
lzma_lzma_state state;
|
||||
|
||||
bool prev_1_is_char;
|
||||
bool prev_2;
|
||||
@@ -107,7 +88,7 @@ struct lzma_coder_s {
|
||||
lzma_range_encoder rc;
|
||||
|
||||
// State
|
||||
uint32_t state;
|
||||
lzma_lzma_state state;
|
||||
uint8_t previous_byte;
|
||||
uint32_t rep_distances[REP_DISTANCES];
|
||||
|
||||
@@ -136,8 +117,8 @@ struct lzma_coder_s {
|
||||
probability pos_align_encoder[1 << ALIGN_BITS];
|
||||
|
||||
// Length encoders
|
||||
lzma_length_encoder len_encoder;
|
||||
lzma_length_encoder rep_match_len_encoder;
|
||||
lzma_length_encoder match_len_encoder;
|
||||
lzma_length_encoder rep_len_encoder;
|
||||
|
||||
// Optimal
|
||||
lzma_optimal optimum[OPTS];
|
||||
@@ -197,12 +178,12 @@ lzma_read_match_distances(lzma_coder *coder,
|
||||
uint32_t limit = MATCH_MAX_LEN - *len_res;
|
||||
|
||||
assert(offset + limit < coder->lz.keep_size_after);
|
||||
assert(coder->lz.read_pos <= coder->lz.write_pos);
|
||||
|
||||
// If we are close to end of the stream, we may need
|
||||
// to limit the length of the match.
|
||||
if (coder->lz.stream_end_was_reached
|
||||
&& coder->lz.write_pos
|
||||
< coder->lz.read_pos + offset + limit)
|
||||
if (coder->lz.write_pos - coder->lz.read_pos
|
||||
< offset + limit)
|
||||
limit = coder->lz.write_pos
|
||||
- (coder->lz.read_pos + offset);
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
## Lesser General Public License for more details.
|
||||
##
|
||||
|
||||
EXTRA_DIST = price_table_gen.c
|
||||
|
||||
noinst_LTLIBRARIES = librangecoder.la
|
||||
|
||||
librangecoder_la_SOURCES = range_common.h
|
||||
@@ -20,7 +22,12 @@ librangecoder_la_CPPFLAGS = \
|
||||
-I@top_srcdir@/src/liblzma/common
|
||||
|
||||
if COND_MAIN_ENCODER
|
||||
librangecoder_la_SOURCES += range_encoder.c range_encoder.h
|
||||
librangecoder_la_SOURCES += range_encoder.h
|
||||
if COND_SMALL
|
||||
librangecoder_la_SOURCES += price_table_init.c
|
||||
else
|
||||
librangecoder_la_SOURCES += price_table.c
|
||||
endif
|
||||
endif
|
||||
|
||||
if COND_MAIN_DECODER
|
||||
|
||||
70
src/liblzma/rangecoder/price_table.c
Normal file
70
src/liblzma/rangecoder/price_table.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* This file has been automatically generated by price_table_gen.c. */
|
||||
|
||||
#include "range_encoder.h"
|
||||
|
||||
const uint32_t lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS] = {
|
||||
0, 576, 512, 480, 448, 432, 416, 400,
|
||||
384, 376, 368, 360, 352, 344, 336, 328,
|
||||
320, 316, 312, 308, 304, 300, 296, 292,
|
||||
288, 284, 280, 276, 272, 268, 264, 260,
|
||||
256, 254, 252, 250, 248, 246, 244, 242,
|
||||
240, 238, 236, 234, 232, 230, 228, 226,
|
||||
224, 222, 220, 218, 216, 214, 212, 210,
|
||||
208, 206, 204, 202, 200, 198, 196, 194,
|
||||
192, 191, 190, 189, 188, 187, 186, 185,
|
||||
184, 183, 182, 181, 180, 179, 178, 177,
|
||||
176, 175, 174, 173, 172, 171, 170, 169,
|
||||
168, 167, 166, 165, 164, 163, 162, 161,
|
||||
160, 159, 158, 157, 156, 155, 154, 153,
|
||||
152, 151, 150, 149, 148, 147, 146, 145,
|
||||
144, 143, 142, 141, 140, 139, 138, 137,
|
||||
136, 135, 134, 133, 132, 131, 130, 129,
|
||||
128, 127, 127, 126, 126, 125, 125, 124,
|
||||
124, 123, 123, 122, 122, 121, 121, 120,
|
||||
120, 119, 119, 118, 118, 117, 117, 116,
|
||||
116, 115, 115, 114, 114, 113, 113, 112,
|
||||
112, 111, 111, 110, 110, 109, 109, 108,
|
||||
108, 107, 107, 106, 106, 105, 105, 104,
|
||||
104, 103, 103, 102, 102, 101, 101, 100,
|
||||
100, 99, 99, 98, 98, 97, 97, 96,
|
||||
96, 95, 95, 94, 94, 93, 93, 92,
|
||||
92, 91, 91, 90, 90, 89, 89, 88,
|
||||
88, 87, 87, 86, 86, 85, 85, 84,
|
||||
84, 83, 83, 82, 82, 81, 81, 80,
|
||||
80, 79, 79, 78, 78, 77, 77, 76,
|
||||
76, 75, 75, 74, 74, 73, 73, 72,
|
||||
72, 71, 71, 70, 70, 69, 69, 68,
|
||||
68, 67, 67, 66, 66, 65, 65, 64,
|
||||
64, 63, 63, 63, 63, 62, 62, 62,
|
||||
62, 61, 61, 61, 61, 60, 60, 60,
|
||||
60, 59, 59, 59, 59, 58, 58, 58,
|
||||
58, 57, 57, 57, 57, 56, 56, 56,
|
||||
56, 55, 55, 55, 55, 54, 54, 54,
|
||||
54, 53, 53, 53, 53, 52, 52, 52,
|
||||
52, 51, 51, 51, 51, 50, 50, 50,
|
||||
50, 49, 49, 49, 49, 48, 48, 48,
|
||||
48, 47, 47, 47, 47, 46, 46, 46,
|
||||
46, 45, 45, 45, 45, 44, 44, 44,
|
||||
44, 43, 43, 43, 43, 42, 42, 42,
|
||||
42, 41, 41, 41, 41, 40, 40, 40,
|
||||
40, 39, 39, 39, 39, 38, 38, 38,
|
||||
38, 37, 37, 37, 37, 36, 36, 36,
|
||||
36, 35, 35, 35, 35, 34, 34, 34,
|
||||
34, 33, 33, 33, 33, 32, 32, 32,
|
||||
32, 31, 31, 31, 31, 30, 30, 30,
|
||||
30, 29, 29, 29, 29, 28, 28, 28,
|
||||
28, 27, 27, 27, 27, 26, 26, 26,
|
||||
26, 25, 25, 25, 25, 24, 24, 24,
|
||||
24, 23, 23, 23, 23, 22, 22, 22,
|
||||
22, 21, 21, 21, 21, 20, 20, 20,
|
||||
20, 19, 19, 19, 19, 18, 18, 18,
|
||||
18, 17, 17, 17, 17, 16, 16, 16,
|
||||
16, 15, 15, 15, 15, 14, 14, 14,
|
||||
14, 13, 13, 13, 13, 12, 12, 12,
|
||||
12, 11, 11, 11, 11, 10, 10, 10,
|
||||
10, 9, 9, 9, 9, 8, 8, 8,
|
||||
8, 7, 7, 7, 7, 6, 6, 6,
|
||||
6, 5, 5, 5, 5, 4, 4, 4,
|
||||
4, 3, 3, 3, 3, 2, 2, 2,
|
||||
2, 1, 1, 1, 1, 0, 0, 0
|
||||
};
|
||||
55
src/liblzma/rangecoder/price_table_gen.c
Normal file
55
src/liblzma/rangecoder/price_table_gen.c
Normal file
@@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file price_table_gen.c
|
||||
/// \brief Probability price table generator
|
||||
///
|
||||
/// Compiling: gcc -std=c99 -o price_table_gen price_table_gen.c
|
||||
//
|
||||
// Copyright (C) 2007 Lasse Collin
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include "range_common.h"
|
||||
#include "price_table_init.c"
|
||||
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
lzma_rc_init();
|
||||
|
||||
printf("/* This file has been automatically generated by "
|
||||
"price_table_gen.c. */\n\n"
|
||||
"#include \"range_encoder.h\"\n\n"
|
||||
"const uint32_t lzma_rc_prob_prices["
|
||||
"BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS] = {");
|
||||
|
||||
const size_t array_size = sizeof(lzma_rc_prob_prices)
|
||||
/ sizeof(lzma_rc_prob_prices[0]);
|
||||
for (size_t i = 0; i < array_size; ++i) {
|
||||
if (i % 8 == 0)
|
||||
printf("\n\t");
|
||||
|
||||
printf("%4" PRIu32, lzma_rc_prob_prices[i]);
|
||||
|
||||
if (i != array_size - 1)
|
||||
printf(",");
|
||||
}
|
||||
|
||||
printf("\n};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file range_encoder.c
|
||||
/// \file price_table_init.c
|
||||
/// \brief Static initializations for the range encoder's prices array
|
||||
//
|
||||
// Copyright (C) 1999-2006 Igor Pavlov
|
||||
@@ -18,7 +18,9 @@
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "range_encoder.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "range_encoder.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define NUM_BITS (BIT_MODEL_TOTAL_BITS - MOVE_REDUCING_BITS)
|
||||
@@ -21,7 +21,9 @@
|
||||
#ifndef LZMA_RANGE_COMMON_H
|
||||
#define LZMA_RANGE_COMMON_H
|
||||
|
||||
#include "common.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "common.h"
|
||||
#endif
|
||||
|
||||
|
||||
///////////////
|
||||
@@ -58,11 +60,24 @@
|
||||
// Type definitions //
|
||||
//////////////////////
|
||||
|
||||
// Bit coder speed optimization
|
||||
// uint16_t is enough for probability, but usually uint32_t is faster and it
|
||||
// doesn't waste too much memory. If uint64_t is fastest on 64-bit CPU, you
|
||||
// probably want to use that instead of uint32_t. With uint64_t you will
|
||||
// waste RAM _at maximum_ of 4.5 MiB (same for both encoding and decoding).
|
||||
typedef uint32_t probability;
|
||||
/// \brief Type of probabilities used with range coder
|
||||
///
|
||||
/// This needs to be at least 12-bit integer, so uint16_t is a logical choice.
|
||||
/// However, on some architecture and compiler combinations, a bigger type
|
||||
/// may give better speed, because the probability variables are accessed
|
||||
/// a lot. On the other hand, bigger probability type increases cache
|
||||
/// footprint, since there are 2 to 14 thousand probability variables in
|
||||
/// LZMA (assuming the limit of lc + lp <= 4; with lc + lp <= 12 there
|
||||
/// would be about 1.5 million variables).
|
||||
///
|
||||
/// With malicious files, the initialization speed of the LZMA decoder can
|
||||
/// become important. In that case, smaller probability variables mean that
|
||||
/// there is less bytes to write to RAM, which makes initialization faster.
|
||||
/// With big probability type, the initialization can become so slow that it
|
||||
/// can be a problem e.g. for email servers doing virus scanning.
|
||||
///
|
||||
/// I will be sticking to uint16_t unless some specific architectures
|
||||
/// are *much* faster (20-50 %) with uint32_t.
|
||||
typedef uint16_t probability;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,36 +27,50 @@
|
||||
typedef struct {
|
||||
uint32_t range;
|
||||
uint32_t code;
|
||||
uint32_t init_bytes_left;
|
||||
} lzma_range_decoder;
|
||||
|
||||
|
||||
static inline bool
|
||||
rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in,
|
||||
size_t *restrict in_pos, size_t in_size)
|
||||
{
|
||||
while (rc->init_bytes_left > 0) {
|
||||
if (*in_pos == in_size)
|
||||
return false;
|
||||
|
||||
rc->code = (rc->code << 8) | in[*in_pos];
|
||||
++*in_pos;
|
||||
--rc->init_bytes_left;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Makes local copies of range decoder variables.
|
||||
#define rc_to_local(rc) \
|
||||
uint32_t rc_range = (rc).range; \
|
||||
uint32_t rc_code = (rc).code; \
|
||||
#define rc_to_local(range_decoder) \
|
||||
lzma_range_decoder rc = range_decoder; \
|
||||
uint32_t rc_bound
|
||||
|
||||
/// Stores the local copes back to the range decoder structure.
|
||||
#define rc_from_local(rc) \
|
||||
do {\
|
||||
(rc).range = rc_range; \
|
||||
(rc).code = rc_code; \
|
||||
} while (0)
|
||||
#define rc_from_local(range_decoder) \
|
||||
range_decoder = rc
|
||||
|
||||
/// Resets the range decoder structure.
|
||||
#define rc_reset(rc) \
|
||||
#define rc_reset(range_decoder) \
|
||||
do { \
|
||||
(rc).range = UINT32_MAX; \
|
||||
(rc).code = 0; \
|
||||
(range_decoder).range = UINT32_MAX; \
|
||||
(range_decoder).code = 0; \
|
||||
(range_decoder).init_bytes_left = 5; \
|
||||
} while (0)
|
||||
|
||||
|
||||
// All of the macros in this file expect the following variables being defined:
|
||||
// - uint32_t rc_range;
|
||||
// - uint32_t rc_code;
|
||||
// - lzma_range_decoder range_decoder;
|
||||
// - uint32_t rc_bound; // Temporary variable
|
||||
// - uint8_t *in;
|
||||
// - size_t in_pos_local; // Local alias for *in_pos
|
||||
// - uint8_t *in;
|
||||
// - size_t in_pos_local; // Local alias for *in_pos
|
||||
|
||||
|
||||
//////////////////
|
||||
@@ -66,9 +80,9 @@ do { \
|
||||
// Read the next byte of compressed data from buffer_in, if needed.
|
||||
#define rc_normalize() \
|
||||
do { \
|
||||
if (rc_range < TOP_VALUE) { \
|
||||
rc_range <<= SHIFT_BITS; \
|
||||
rc_code = (rc_code << SHIFT_BITS) | in[in_pos_local++]; \
|
||||
if (rc.range < TOP_VALUE) { \
|
||||
rc.range <<= SHIFT_BITS; \
|
||||
rc.code = (rc.code << SHIFT_BITS) | in[in_pos_local++]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -88,37 +102,57 @@ do { \
|
||||
|
||||
#define if_bit_0(prob) \
|
||||
rc_normalize(); \
|
||||
rc_bound = (rc_range >> BIT_MODEL_TOTAL_BITS) * (prob); \
|
||||
if (rc_code < rc_bound)
|
||||
rc_bound = (rc.range >> BIT_MODEL_TOTAL_BITS) * (prob); \
|
||||
if (rc.code < rc_bound)
|
||||
|
||||
|
||||
#define update_bit_0(prob) \
|
||||
do { \
|
||||
rc_range = rc_bound; \
|
||||
rc.range = rc_bound; \
|
||||
prob += (BIT_MODEL_TOTAL - (prob)) >> MOVE_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define update_bit_1(prob) \
|
||||
do { \
|
||||
rc_range -= rc_bound; \
|
||||
rc_code -= rc_bound; \
|
||||
rc.range -= rc_bound; \
|
||||
rc.code -= rc_bound; \
|
||||
prob -= (prob) >> MOVE_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Dummy versions don't update prob.
|
||||
#define rc_decode_direct(dest, count) \
|
||||
do { \
|
||||
rc_normalize(); \
|
||||
rc.range >>= 1; \
|
||||
rc.code -= rc.range; \
|
||||
rc_bound = UINT32_C(0) - (rc.code >> 31); \
|
||||
rc.code += rc.range & rc_bound; \
|
||||
dest = (dest << 1) + (rc_bound + 1); \
|
||||
} while (--count > 0)
|
||||
|
||||
|
||||
// Dummy versions don't update prob or dest.
|
||||
#define update_bit_0_dummy() \
|
||||
rc_range = rc_bound
|
||||
rc.range = rc_bound
|
||||
|
||||
|
||||
#define update_bit_1_dummy() \
|
||||
do { \
|
||||
rc_range -= rc_bound; \
|
||||
rc_code -= rc_bound; \
|
||||
rc.range -= rc_bound; \
|
||||
rc.code -= rc_bound; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define rc_decode_direct_dummy(count) \
|
||||
do { \
|
||||
rc_normalize(); \
|
||||
rc.range >>= 1; \
|
||||
rc.code -= rc.range; \
|
||||
rc.code += rc.range & (UINT32_C(0) - (rc.code >> 31)); \
|
||||
} while (--count > 0)
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Bit tree decoding //
|
||||
///////////////////////
|
||||
|
||||
@@ -24,46 +24,38 @@
|
||||
#include "range_common.h"
|
||||
|
||||
|
||||
// Allow #including this file even if RC_TEMP_BUFFER_SIZE isn't defined.
|
||||
#ifdef RC_BUFFER_SIZE
|
||||
typedef struct {
|
||||
uint64_t low;
|
||||
uint64_t cache_size;
|
||||
uint32_t range;
|
||||
uint32_t cache_size;
|
||||
uint8_t cache;
|
||||
uint8_t buffer[RC_BUFFER_SIZE];
|
||||
size_t buffer_size;
|
||||
} lzma_range_encoder;
|
||||
|
||||
|
||||
#ifdef HAVE_SMALL
|
||||
/// Probability prices used by *_get_price() macros. This is initialized
|
||||
/// by lzma_rc_init() and is not modified later.
|
||||
extern uint32_t lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
|
||||
|
||||
/// Initializes lzma_rc_prob_prices[]. This needs to be called only once.
|
||||
extern void lzma_rc_init(void);
|
||||
|
||||
#else
|
||||
// Not building a size optimized version, so we use a precomputed
|
||||
// constant table.
|
||||
extern const uint32_t
|
||||
lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/// Makes local copies of range encoder variables.
|
||||
#define rc_to_local(rc) \
|
||||
uint64_t rc_low = (rc).low; \
|
||||
uint32_t rc_range = (rc).range; \
|
||||
uint32_t rc_cache_size = (rc).cache_size; \
|
||||
uint8_t rc_cache = (rc).cache; \
|
||||
uint8_t *rc_buffer = (rc).buffer; \
|
||||
size_t rc_buffer_size = (rc).buffer_size
|
||||
|
||||
/// Stores the local copes back to the range encoder structure.
|
||||
#define rc_from_local(rc) \
|
||||
do { \
|
||||
(rc).low = rc_low; \
|
||||
(rc).range = rc_range; \
|
||||
(rc).cache_size = rc_cache_size; \
|
||||
(rc).cache = rc_cache; \
|
||||
(rc).buffer_size = rc_buffer_size; \
|
||||
} while (0)
|
||||
|
||||
/// Resets the range encoder structure.
|
||||
#define rc_reset(rc) \
|
||||
do { \
|
||||
(rc).low = 0; \
|
||||
(rc).range = 0xFFFFFFFF; \
|
||||
(rc).range = UINT32_MAX; \
|
||||
(rc).cache_size = 1; \
|
||||
(rc).cache = 0; \
|
||||
(rc).buffer_size = 0; \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -72,13 +64,14 @@ do { \
|
||||
//////////////////
|
||||
|
||||
// These macros expect that the following variables are defined:
|
||||
// - uint64_t rc_low;
|
||||
// - uint32_t rc_range;
|
||||
// - uint8_t rc_cache;
|
||||
// - uint32_t rc_cache_size;
|
||||
// - uint8_t *out;
|
||||
// - size_t out_pos_local; // Local copy of *out_pos
|
||||
// - size_t size_out;
|
||||
// - lzma_range_encoder rc;
|
||||
// - uint8_t *out;
|
||||
// - size_t out_pos_local; // Local copy of *out_pos
|
||||
// - size_t size_out;
|
||||
//
|
||||
// Macros pointing to these variables are also needed:
|
||||
// - uint8_t rc_buffer[]; // Don't use a pointer, must be real array!
|
||||
// - size_t rc_buffer_size;
|
||||
|
||||
|
||||
// Combined from NRangeCoder::CEncoder::Encode()
|
||||
@@ -87,13 +80,13 @@ do { \
|
||||
do { \
|
||||
probability rc_prob = prob; \
|
||||
const uint32_t rc_bound \
|
||||
= (rc_range >> BIT_MODEL_TOTAL_BITS) * rc_prob; \
|
||||
= (rc.range >> BIT_MODEL_TOTAL_BITS) * rc_prob; \
|
||||
if ((symbol) == 0) { \
|
||||
rc_range = rc_bound; \
|
||||
rc.range = rc_bound; \
|
||||
rc_prob += (BIT_MODEL_TOTAL - rc_prob) >> MOVE_BITS; \
|
||||
} else { \
|
||||
rc_low += rc_bound; \
|
||||
rc_range -= rc_bound; \
|
||||
rc.low += rc_bound; \
|
||||
rc.range -= rc_bound; \
|
||||
rc_prob -= rc_prob >> MOVE_BITS; \
|
||||
} \
|
||||
prob = rc_prob; \
|
||||
@@ -105,7 +98,7 @@ do { \
|
||||
#define bit_encode_0(prob) \
|
||||
do { \
|
||||
probability rc_prob = prob; \
|
||||
rc_range = (rc_range >> BIT_MODEL_TOTAL_BITS) * rc_prob; \
|
||||
rc.range = (rc.range >> BIT_MODEL_TOTAL_BITS) * rc_prob; \
|
||||
rc_prob += (BIT_MODEL_TOTAL - rc_prob) >> MOVE_BITS; \
|
||||
prob = rc_prob; \
|
||||
rc_normalize(); \
|
||||
@@ -116,10 +109,10 @@ do { \
|
||||
#define bit_encode_1(prob) \
|
||||
do { \
|
||||
probability rc_prob = prob; \
|
||||
const uint32_t rc_bound = (rc_range >> BIT_MODEL_TOTAL_BITS) \
|
||||
const uint32_t rc_bound = (rc.range >> BIT_MODEL_TOTAL_BITS) \
|
||||
* rc_prob; \
|
||||
rc_low += rc_bound; \
|
||||
rc_range -= rc_bound; \
|
||||
rc.low += rc_bound; \
|
||||
rc.range -= rc_bound; \
|
||||
rc_prob -= rc_prob >> MOVE_BITS; \
|
||||
prob = rc_prob; \
|
||||
rc_normalize(); \
|
||||
@@ -160,9 +153,9 @@ do { \
|
||||
#define rc_encode_direct_bits(value, num_total_bits) \
|
||||
do { \
|
||||
for (int32_t rc_i = (num_total_bits) - 1; rc_i >= 0; --rc_i) { \
|
||||
rc_range >>= 1; \
|
||||
rc.range >>= 1; \
|
||||
if ((((value) >> rc_i) & 1) == 1) \
|
||||
rc_low += rc_range; \
|
||||
rc.low += rc.range; \
|
||||
rc_normalize(); \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -175,8 +168,8 @@ do { \
|
||||
// Calls rc_shift_low() to write out a byte if needed.
|
||||
#define rc_normalize() \
|
||||
do { \
|
||||
if (rc_range < TOP_VALUE) { \
|
||||
rc_range <<= SHIFT_BITS; \
|
||||
if (rc.range < TOP_VALUE) { \
|
||||
rc.range <<= SHIFT_BITS; \
|
||||
rc_shift_low(); \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -192,23 +185,23 @@ do { \
|
||||
// TODO: Notation change?
|
||||
// (uint32_t)(0xFF000000) => ((uint32_t)(0xFF) << TOP_BITS)
|
||||
// TODO: Another notation change?
|
||||
// rc_low = (uint32_t)(rc_low) << SHIFT_BITS;
|
||||
// rc.low = (uint32_t)(rc.low) << SHIFT_BITS;
|
||||
// =>
|
||||
// rc_low &= TOP_VALUE - 1;
|
||||
// rc_low <<= SHIFT_BITS;
|
||||
// rc.low &= TOP_VALUE - 1;
|
||||
// rc.low <<= SHIFT_BITS;
|
||||
#define rc_shift_low() \
|
||||
do { \
|
||||
if ((uint32_t)(rc_low) < (uint32_t)(0xFF000000) \
|
||||
|| (uint32_t)(rc_low >> 32) != 0) { \
|
||||
uint8_t rc_temp = rc_cache; \
|
||||
if ((uint32_t)(rc.low) < (uint32_t)(0xFF000000) \
|
||||
|| (uint32_t)(rc.low >> 32) != 0) { \
|
||||
uint8_t rc_temp = rc.cache; \
|
||||
do { \
|
||||
rc_write_byte(rc_temp + (uint8_t)(rc_low >> 32)); \
|
||||
rc_write_byte(rc_temp + (uint8_t)(rc.low >> 32)); \
|
||||
rc_temp = 0xFF; \
|
||||
} while(--rc_cache_size != 0); \
|
||||
rc_cache = (uint8_t)((uint32_t)(rc_low) >> 24); \
|
||||
} while(--rc.cache_size != 0); \
|
||||
rc.cache = (uint8_t)((uint32_t)(rc.low) >> 24); \
|
||||
} \
|
||||
++rc_cache_size; \
|
||||
rc_low = (uint32_t)(rc_low) << SHIFT_BITS; \
|
||||
++rc.cache_size; \
|
||||
rc.low = (uint32_t)(rc.low) << SHIFT_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -218,7 +211,7 @@ do { \
|
||||
do { \
|
||||
if (out_pos_local == out_size) { \
|
||||
rc_buffer[rc_buffer_size++] = (uint8_t)(b); \
|
||||
assert(rc_buffer_size < RC_BUFFER_SIZE); \
|
||||
assert(rc_buffer_size < sizeof(rc_buffer)); \
|
||||
} else { \
|
||||
assert(rc_buffer_size == 0); \
|
||||
out[out_pos_local++] = (uint8_t)(b); \
|
||||
@@ -246,72 +239,37 @@ do { \
|
||||
lzma_rc_prob_prices[(BIT_MODEL_TOTAL - (prob)) >> MOVE_REDUCING_BITS]
|
||||
|
||||
|
||||
// Adds price to price_target. TODO Optimize/Cleanup?
|
||||
#define bittree_get_price(price_target, probs, bit_levels, symbol) \
|
||||
do { \
|
||||
uint32_t bittree_symbol = (symbol) | (UINT32_C(1) << bit_levels); \
|
||||
while (bittree_symbol != 1) { \
|
||||
price_target += bit_get_price((probs)[bittree_symbol >> 1], \
|
||||
bittree_symbol & 1); \
|
||||
bittree_symbol >>= 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
// Adds price to price_target.
|
||||
#define bittree_reverse_get_price(price_target, probs, bit_levels, symbol) \
|
||||
do { \
|
||||
uint32_t model_index = 1; \
|
||||
for (uint32_t bit_index = 0; bit_index < bit_levels; ++bit_index) { \
|
||||
const uint32_t bit = ((symbol) >> bit_index) & 1; \
|
||||
price_target += bit_get_price((probs)[model_index], bit); \
|
||||
model_index = (model_index << 1) | bit; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Global variables //
|
||||
//////////////////////
|
||||
|
||||
// Probability prices used by *_get_price() macros. This is initialized
|
||||
// by lzma_rc_init() and is not modified later.
|
||||
extern uint32_t lzma_rc_prob_prices[BIT_MODEL_TOTAL >> MOVE_REDUCING_BITS];
|
||||
|
||||
|
||||
///////////////
|
||||
// Functions //
|
||||
///////////////
|
||||
|
||||
/// Initializes lzma_rc_prob_prices[]. This needs to be called only once.
|
||||
extern void lzma_rc_init(void);
|
||||
|
||||
|
||||
#ifdef RC_BUFFER_SIZE
|
||||
/// Flushes data from rc->temp[] to out[] as much as possible. If everything
|
||||
/// cannot be flushed, returns true; false otherwise.
|
||||
static inline bool
|
||||
rc_flush_buffer(lzma_range_encoder *rc,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
static inline uint32_t
|
||||
bittree_get_price(const probability *probs,
|
||||
uint32_t bit_levels, uint32_t symbol)
|
||||
{
|
||||
if (rc->buffer_size > 0) {
|
||||
const size_t out_avail = out_size - *out_pos;
|
||||
if (rc->buffer_size > out_avail) {
|
||||
memcpy(out + *out_pos, rc->buffer, out_avail);
|
||||
*out_pos += out_avail;
|
||||
rc->buffer_size -= out_avail;
|
||||
memmove(rc->buffer, rc->buffer + out_avail,
|
||||
rc->buffer_size);
|
||||
return true;
|
||||
}
|
||||
uint32_t price = 0;
|
||||
symbol |= UINT32_C(1) << bit_levels;
|
||||
|
||||
memcpy(out + *out_pos, rc->buffer, rc->buffer_size);
|
||||
*out_pos += rc->buffer_size;
|
||||
rc->buffer_size = 0;
|
||||
}
|
||||
do {
|
||||
price += bit_get_price(probs[symbol >> 1], symbol & 1);
|
||||
symbol >>= 1;
|
||||
} while (symbol != 1);
|
||||
|
||||
return false;
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
bittree_reverse_get_price(const probability *probs,
|
||||
uint32_t bit_levels, uint32_t symbol)
|
||||
{
|
||||
uint32_t price = 0;
|
||||
uint32_t model_index = 1;
|
||||
|
||||
do {
|
||||
const uint32_t bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += bit_get_price(probs[model_index], bit);
|
||||
model_index = (model_index << 1) | bit;
|
||||
} while (--bit_levels != 0);
|
||||
|
||||
return price;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -97,7 +97,7 @@ ia64_coder_init(lzma_next_coder *next, lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters, bool is_encoder)
|
||||
{
|
||||
return lzma_simple_coder_init(next, allocator, filters,
|
||||
&ia64_code, 0, 4, is_encoder);
|
||||
&ia64_code, 0, 16, is_encoder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,44 +39,23 @@ copy_or_code(lzma_coder *coder, lzma_allocator *allocator,
|
||||
if (coder->next.code == NULL) {
|
||||
const size_t in_avail = in_size - *in_pos;
|
||||
|
||||
if (coder->is_encoder) {
|
||||
if (action == LZMA_FINISH) {
|
||||
// If uncompressed size is known and the
|
||||
// amount of available input doesn't match
|
||||
// the uncompressed size, return an error.
|
||||
if (coder->uncompressed_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN
|
||||
&& coder->uncompressed_size
|
||||
!= in_avail)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
} else if (coder->uncompressed_size
|
||||
< (lzma_vli)(in_avail)) {
|
||||
// There is too much input available.
|
||||
return LZMA_DATA_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (!coder->is_encoder) {
|
||||
// Limit in_size so that we don't copy too much.
|
||||
if ((lzma_vli)(in_avail) > coder->uncompressed_size)
|
||||
in_size = *in_pos + (size_t)(
|
||||
coder->uncompressed_size);
|
||||
}
|
||||
|
||||
// Store the old position so we can update uncompressed_size.
|
||||
const size_t out_start = *out_pos;
|
||||
|
||||
// Copy the data
|
||||
bufcpy(in, in_pos, in_size, out, out_pos, out_size);
|
||||
|
||||
// Update uncompressed_size.
|
||||
if (coder->uncompressed_size != LZMA_VLI_VALUE_UNKNOWN)
|
||||
coder->uncompressed_size -= *out_pos - out_start;
|
||||
|
||||
// Check if end of stream was reached.
|
||||
if (coder->is_encoder) {
|
||||
if (action == LZMA_FINISH && *in_pos == in_size)
|
||||
coder->end_was_reached = true;
|
||||
} else {
|
||||
} else if (coder->uncompressed_size
|
||||
!= LZMA_VLI_VALUE_UNKNOWN) {
|
||||
coder->uncompressed_size -= *out_pos - out_start;
|
||||
if (coder->uncompressed_size == 0)
|
||||
coder->end_was_reached = true;
|
||||
}
|
||||
@@ -122,6 +101,14 @@ simple_code(lzma_coder *coder, lzma_allocator *allocator,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size, lzma_action action)
|
||||
{
|
||||
// TODO: Add partial support for LZMA_SYNC_FLUSH. We can support it
|
||||
// in cases when the filter is able to filter everything. With most
|
||||
// simple filters it can be done at offset that is a multiple of 2,
|
||||
// 4, or 16. With x86 filter, it needs good luck, and thus cannot
|
||||
// be made to work predictably.
|
||||
if (action == LZMA_SYNC_FLUSH)
|
||||
return LZMA_HEADER_ERROR;
|
||||
|
||||
// Flush already filtered data from coder->buffer[] to out[].
|
||||
if (coder->pos < coder->filtered) {
|
||||
bufcpy(coder->buffer, &coder->pos, coder->filtered,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user