mirror of
https://github.com/PCSX2/xz.git
synced 2026-02-06 20:31:17 +01:00
Compare commits
55 Commits
v5.1.3alph
...
v5.1.4beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c35de31d42 | ||
|
|
e9e097e22c | ||
|
|
642f856bb8 | ||
|
|
6b5e3b9eff | ||
|
|
9adbc2ff37 | ||
|
|
0e0f34b8e4 | ||
|
|
71e1437ab5 | ||
|
|
41dc9ea06e | ||
|
|
5dcffdbcc2 | ||
|
|
a9477d1e0c | ||
|
|
5a76c7c8ee | ||
|
|
9a096f8e57 | ||
|
|
bc7650d87b | ||
|
|
544aaa3d13 | ||
|
|
f48fce093b | ||
|
|
6bf5308e34 | ||
|
|
353212137e | ||
|
|
5db75054e9 | ||
|
|
e1c8f1d01f | ||
|
|
765735cf52 | ||
|
|
59da01785e | ||
|
|
17215f751c | ||
|
|
96864a6ddf | ||
|
|
a115cc3748 | ||
|
|
3ce3e79769 | ||
|
|
381ac14ed7 | ||
|
|
4244b65b06 | ||
|
|
1e60f2c0a0 | ||
|
|
ceca379017 | ||
|
|
8c19216bac | ||
|
|
87f1a24810 | ||
|
|
da1718f266 | ||
|
|
28af24e9cf | ||
|
|
ed9ac85822 | ||
|
|
d716acdae3 | ||
|
|
4d5b7b3fda | ||
|
|
1555a9c566 | ||
|
|
56056571df | ||
|
|
6de61d8721 | ||
|
|
54df428799 | ||
|
|
5876ca27da | ||
|
|
9494fb6d0f | ||
|
|
673a4cb53d | ||
|
|
ad96a871a1 | ||
|
|
3d5c090872 | ||
|
|
69fd4e1c93 | ||
|
|
a19d9e8575 | ||
|
|
e28528f1c8 | ||
|
|
5ad1effc45 | ||
|
|
3e62c68d75 | ||
|
|
e90ea601fb | ||
|
|
b22e94d8d1 | ||
|
|
d1cd8b1cb8 | ||
|
|
76be7c612e | ||
|
|
dd750acbe2 |
31
INSTALL
31
INSTALL
@@ -26,6 +26,8 @@ XZ Utils Installation
|
||||
4.2. "No POSIX conforming shell (sh) was found."
|
||||
4.3. configure works but build fails at crc32_x86.S
|
||||
4.4. Lots of warnings about symbol visibility
|
||||
4.5. "make check" fails
|
||||
4.6. liblzma.so (or similar) not found when running xz
|
||||
|
||||
|
||||
0. Preface
|
||||
@@ -251,6 +253,12 @@ XZ Utils Installation
|
||||
Don't install the scripts xzdiff, xzgrep, xzmore, xzless,
|
||||
and their symlinks.
|
||||
|
||||
--disable-doc
|
||||
Don't install the documentation files to $docdir
|
||||
(often /usr/doc/xz or /usr/local/doc/xz). Man pages
|
||||
will still be installed. The $docdir can be changed
|
||||
with --docdir=DIR.
|
||||
|
||||
--disable-assembler
|
||||
liblzma includes some assembler optimizations. Currently
|
||||
there is only assembler code for CRC32 and CRC64 for
|
||||
@@ -489,3 +497,26 @@ XZ Utils Installation
|
||||
resulting binaries, but fewer warnings looks nicer and may allow
|
||||
using --enable-werror.
|
||||
|
||||
|
||||
4.5. "make check" fails
|
||||
|
||||
A likely reason is that libtool links the test programs against
|
||||
an installed version of liblzma instead of the version that was
|
||||
just built. This is obviously a bug which seems to happen on
|
||||
some platforms. A workaround is to uninstall the old liblzma
|
||||
versions first.
|
||||
|
||||
If the problem isn't the one described above, then it's likely
|
||||
a bug in XZ Utils or in the compiler. See the platform-specific
|
||||
notes in this file for possible known problems. Please report
|
||||
a bug if you cannot solve the problem. See README for contact
|
||||
information.
|
||||
|
||||
|
||||
4.6. liblzma.so (or similar) not found when running xz
|
||||
|
||||
If you installed the package with "make install" and get an error
|
||||
about liblzma.so (or a similarly named file) being missing, try
|
||||
running "ldconfig" to update the run-time linker cache (if your
|
||||
operating system has such a command).
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ endif
|
||||
|
||||
SUBDIRS += src po tests
|
||||
|
||||
if COND_DOC
|
||||
dist_doc_DATA = \
|
||||
AUTHORS \
|
||||
COPYING \
|
||||
@@ -42,6 +43,7 @@ examplesolddir = $(docdir)/examples_old
|
||||
dist_examplesold_DATA = \
|
||||
doc/examples_old/xz_pipe_comp.c \
|
||||
doc/examples_old/xz_pipe_decomp.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
extra \
|
||||
|
||||
50
NEWS
50
NEWS
@@ -2,6 +2,49 @@
|
||||
XZ Utils Release Notes
|
||||
======================
|
||||
|
||||
5.1.4beta (2014-09-14)
|
||||
|
||||
* All fixes from 5.0.6
|
||||
|
||||
* liblzma: Fixed the use of presets in threaded encoder
|
||||
initialization.
|
||||
|
||||
* xz --block-list and --block-size can now be used together
|
||||
in single-threaded mode. Previously the combination only
|
||||
worked in multi-threaded mode.
|
||||
|
||||
* Added support for LZMA_IGNORE_CHECK to liblzma and made it
|
||||
available in xz as --ignore-check.
|
||||
|
||||
* liblzma speed optimizations:
|
||||
|
||||
- Initialization of a new LZMA1 or LZMA2 encoder has been
|
||||
optimized. (The speed of reinitializing an already-allocated
|
||||
encoder isn't affected.) This helps when compressing many
|
||||
small buffers with lzma_stream_buffer_encode() and other
|
||||
similar situations where an already-allocated encoder state
|
||||
isn't reused. This speed-up is visible in xz too if one
|
||||
compresses many small files one at a time instead running xz
|
||||
once and giving all files as command-line arguments.
|
||||
|
||||
- Buffer comparisons are now much faster when unaligned access
|
||||
is allowed (configured with --enable-unaligned-access). This
|
||||
speeds up encoding significantly. There is arch-specific code
|
||||
for 32-bit and 64-bit x86 (32-bit needs SSE2 for the best
|
||||
results and there's no run-time CPU detection for now).
|
||||
For other archs there is only generic code which probably
|
||||
isn't as optimal as arch-specific solutions could be.
|
||||
|
||||
- A few speed optimizations were made to the SHA-256 code.
|
||||
(Note that the builtin SHA-256 code isn't used on all
|
||||
operating systems.)
|
||||
|
||||
* liblzma can now be built with MSVC 2013 update 2 or later
|
||||
using windows/config.h.
|
||||
|
||||
* Vietnamese translation was added.
|
||||
|
||||
|
||||
5.1.3alpha (2013-10-26)
|
||||
|
||||
* All fixes from 5.0.5
|
||||
@@ -121,6 +164,13 @@ XZ Utils Release Notes
|
||||
experimental and may change before it gets into a stable release.
|
||||
|
||||
|
||||
5.0.6 (2014-09-14)
|
||||
|
||||
* xzgrep now exits with status 0 if at least one file matched.
|
||||
|
||||
* A few minor portability and build system fixes
|
||||
|
||||
|
||||
5.0.5 (2013-06-30)
|
||||
|
||||
* lzmadec and liblzma's lzma_alone_decoder(): Support decompressing
|
||||
|
||||
6
THANKS
6
THANKS
@@ -20,6 +20,7 @@ has been important. :-) In alphabetical order:
|
||||
- Daniel Mealha Cabrita
|
||||
- Milo Casagrande
|
||||
- Marek Černocký
|
||||
- Tomer Chachamu
|
||||
- Chris Donawa
|
||||
- Andrew Dudman
|
||||
- Markus Duft
|
||||
@@ -32,10 +33,13 @@ has been important. :-) In alphabetical order:
|
||||
- Bill Glessner
|
||||
- Jason Gorski
|
||||
- Juan Manuel Guerrero
|
||||
- Diederik de Haas
|
||||
- Joachim Henke
|
||||
- Christian Hesse
|
||||
- Vincenzo Innocente
|
||||
- Peter Ivanov
|
||||
- Jouk Jansen
|
||||
- Jun I Jin
|
||||
- Per Øyvind Karlsen
|
||||
- Thomas Klausner
|
||||
- Richard Koch
|
||||
@@ -44,6 +48,7 @@ has been important. :-) In alphabetical order:
|
||||
- Christian Kujau
|
||||
- Stephan Kulow
|
||||
- Peter Lawler
|
||||
- James M Leddy
|
||||
- Hin-Tak Leung
|
||||
- Andraž 'ruskie' Levstik
|
||||
- Cary Lewis
|
||||
@@ -65,6 +70,7 @@ has been important. :-) In alphabetical order:
|
||||
- Diego Elio Pettenò
|
||||
- Elbert Pol
|
||||
- Mikko Pouru
|
||||
- Trần Ngọc Quân
|
||||
- Pavel Raiskup
|
||||
- Robert Readman
|
||||
- Bernhard Reutner-Fischer
|
||||
|
||||
38
TODO
38
TODO
@@ -36,6 +36,15 @@ Known bugs
|
||||
Missing features
|
||||
----------------
|
||||
|
||||
Add support for storing metadata in .xz files. A preliminary
|
||||
idea is to create a new Stream type for metadata. When both
|
||||
metadata and data are wanted in the same .xz file, two or more
|
||||
Streams would be concatenated.
|
||||
|
||||
The state stored in lzma_stream should be cloneable, which would
|
||||
be mostly useful when using a preset dictionary in LZMA2, but
|
||||
it may have other uses too. Compare to deflateCopy() in zlib.
|
||||
|
||||
Support LZMA_FINISH in raw decoder to indicate end of LZMA1 and
|
||||
other streams that don't have an end of payload marker.
|
||||
|
||||
@@ -68,14 +77,35 @@ Missing features
|
||||
This is tricky, because the same error codes are used with
|
||||
slightly different meanings, and this cannot be fixed anymore.
|
||||
|
||||
Make it possible to adjust LZMA2 options in the middle of a Block
|
||||
so that the encoding speed vs. compression ratio can be optimized
|
||||
when the compressed data is streamed over network.
|
||||
|
||||
Improved BCJ filters. The current filters are small but they aren't
|
||||
so great when compressing binary packages that contain various file
|
||||
types. Specifically, they make things worse if there are static
|
||||
libraries or Linux kernel modules. The filtering could also be
|
||||
more effective (without getting overly complex), for example,
|
||||
streamable variant BCJ2 from 7-Zip could be implemented.
|
||||
|
||||
Filter that autodetects specific data types in the input stream
|
||||
and applies appropriate filters for the corrects parts of the input.
|
||||
Perhaps combine this with the BCJ filter improvement point above.
|
||||
|
||||
Long-range LZ77 method as a separate filter or as a new LZMA2
|
||||
match finder.
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Some tutorial is needed for liblzma. I have planned to write some
|
||||
extremely well commented example programs, which would work as
|
||||
a tutorial. I suppose the Doxygen tags are quite OK as a quick
|
||||
reference once one is familiar with the liblzma API.
|
||||
More tutorial programs are needed for liblzma.
|
||||
|
||||
Document the LZMA1 and LZMA2 algorithms.
|
||||
|
||||
|
||||
Miscellaneous
|
||||
------------
|
||||
|
||||
Try to get the media type for .xz registered at IANA.
|
||||
|
||||
|
||||
19
configure.ac
19
configure.ac
@@ -435,6 +435,12 @@ AC_ARG_ENABLE([scripts], [AC_HELP_STRING([--disable-scripts],
|
||||
[], [enable_scripts=yes])
|
||||
AM_CONDITIONAL([COND_SCRIPTS], [test x$enable_scripts != xno])
|
||||
|
||||
AC_ARG_ENABLE([doc], [AC_HELP_STRING([--disable-doc],
|
||||
[do not install documentation files to docdir
|
||||
(man pages will still be installed)])],
|
||||
[], [enable_doc=yes])
|
||||
AM_CONDITIONAL([COND_DOC], [test x$enable_doc != xno])
|
||||
|
||||
|
||||
#####################
|
||||
# Symbol versioning #
|
||||
@@ -554,6 +560,7 @@ echo "Initializing gettext:"
|
||||
AM_GNU_GETTEXT_VERSION([0.18])
|
||||
AM_GNU_GETTEXT([external])
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Checks for header files.
|
||||
###############################################################################
|
||||
@@ -567,6 +574,9 @@ AC_CHECK_HEADERS([fcntl.h limits.h sys/time.h],
|
||||
[],
|
||||
[AC_MSG_ERROR([Required header file(s) are missing.])])
|
||||
|
||||
# This allows the use of the intrinsic functions if they are available.
|
||||
AC_CHECK_HEADERS([immintrin.h])
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
@@ -675,6 +685,15 @@ AM_CONDITIONAL([COND_INTERNAL_SHA256],
|
||||
&& test "x$ac_cv_func_SHA256Init" != xyes \
|
||||
&& test "x$ac_cv_func_CC_SHA256_Init" != xyes])
|
||||
|
||||
# Check for SSE2 intrinsics.
|
||||
AC_CHECK_DECL([_mm_movemask_epi8],
|
||||
[AC_DEFINE([HAVE__MM_MOVEMASK_EPI8], [1],
|
||||
[Define to 1 if _mm_movemask_epi8 is available.])],
|
||||
[],
|
||||
[#ifdef HAVE_IMMINTRIN_H
|
||||
#include <immintrin.h>
|
||||
#endif])
|
||||
|
||||
|
||||
###############################################################################
|
||||
# If using GCC, set some additional AM_CFLAGS:
|
||||
|
||||
@@ -28,8 +28,8 @@ init_encoder(lzma_stream *strm)
|
||||
// Use the default preset (6) for LZMA2.
|
||||
//
|
||||
// The lzma_options_lzma structure and the lzma_lzma_preset() function
|
||||
// are declared in lzma/lzma.h (src/liblzma/api/lzma/lzma.h in the
|
||||
// source package or e.g. /usr/include/lzma/lzma.h depending on
|
||||
// are declared in lzma/lzma12.h (src/liblzma/api/lzma/lzma12.h in the
|
||||
// source package or e.g. /usr/include/lzma/lzma12.h depending on
|
||||
// the install prefix).
|
||||
lzma_options_lzma opt_lzma2;
|
||||
if (lzma_lzma_preset(&opt_lzma2, LZMA_PRESET_DEFAULT)) {
|
||||
@@ -48,7 +48,7 @@ init_encoder(lzma_stream *strm)
|
||||
// Now we could customize the LZMA2 options if we wanted. For example,
|
||||
// we could set the the dictionary size (opt_lzma2.dict_size) to
|
||||
// something else than the default (8 MiB) of the default preset.
|
||||
// See lzma/lzma.h for details of all LZMA2 options.
|
||||
// See lzma/lzma12.h for details of all LZMA2 options.
|
||||
//
|
||||
// The x86 BCJ filter will try to modify the x86 instruction stream so
|
||||
// that LZMA2 can compress it better. The x86 BCJ filter doesn't need
|
||||
|
||||
184
doc/examples/04_compress_easy_mt.c
Normal file
184
doc/examples/04_compress_easy_mt.c
Normal file
@@ -0,0 +1,184 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file 04_compress_easy_mt.c
|
||||
/// \brief Compress in multi-call mode using LZMA2 in multi-threaded mode
|
||||
///
|
||||
/// Usage: ./04_compress_easy_mt < INFILE > OUTFILE
|
||||
///
|
||||
/// Example: ./04_compress_easy_mt < foo > foo.xz
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <lzma.h>
|
||||
|
||||
|
||||
static bool
|
||||
init_encoder(lzma_stream *strm)
|
||||
{
|
||||
// The threaded encoder takes the options as pointer to
|
||||
// a lzma_mt structure.
|
||||
lzma_mt mt = {
|
||||
// No flags are needed.
|
||||
.flags = 0,
|
||||
|
||||
// Set the number of threads to use.
|
||||
// FIXME: Add how to autodetect a reasonable number.
|
||||
.threads = 4,
|
||||
|
||||
// Let liblzma determine a sane block size.
|
||||
.block_size = 0,
|
||||
|
||||
// Use no timeout for lzma_code() calls by setting timeout
|
||||
// to zero. That is, sometimes lzma_code() might block for
|
||||
// a long time (from several seconds to even minutes).
|
||||
// If this is not OK, for example due to progress indicator
|
||||
// needing updates, specify a timeout in milliseconds here.
|
||||
// See the documentation of lzma_mt in lzma/container.h for
|
||||
// information how to choose a reasonable timeout.
|
||||
.timeout = 0,
|
||||
|
||||
// Use the default preset (6) for LZMA2.
|
||||
// To use a preset, filters must be set to NULL.
|
||||
.preset = LZMA_PRESET_DEFAULT,
|
||||
.filters = NULL,
|
||||
|
||||
// Use CRC64 for integrity checking. See also
|
||||
// 01_compress_easy.c about choosing the integrity check.
|
||||
.check = LZMA_CHECK_CRC64,
|
||||
};
|
||||
|
||||
// Initialize the threaded encoder.
|
||||
lzma_ret ret = lzma_stream_encoder_mt(strm, &mt);
|
||||
|
||||
if (ret == LZMA_OK)
|
||||
return true;
|
||||
|
||||
const char *msg;
|
||||
switch (ret) {
|
||||
case LZMA_MEM_ERROR:
|
||||
msg = "Memory allocation failed";
|
||||
break;
|
||||
|
||||
case LZMA_OPTIONS_ERROR:
|
||||
// We are no longer using a plain preset so this error
|
||||
// message has been edited accordingly compared to
|
||||
// 01_compress_easy.c.
|
||||
msg = "Specified filter chain is not supported";
|
||||
break;
|
||||
|
||||
case LZMA_UNSUPPORTED_CHECK:
|
||||
msg = "Specified integrity check is not supported";
|
||||
break;
|
||||
|
||||
default:
|
||||
msg = "Unknown error, possibly a bug";
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error initializing the encoder: %s (error code %u)\n",
|
||||
msg, ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// This function is identical to the one in 01_compress_easy.c.
|
||||
static bool
|
||||
compress(lzma_stream *strm, FILE *infile, FILE *outfile)
|
||||
{
|
||||
lzma_action action = LZMA_RUN;
|
||||
|
||||
uint8_t inbuf[BUFSIZ];
|
||||
uint8_t outbuf[BUFSIZ];
|
||||
|
||||
strm->next_in = NULL;
|
||||
strm->avail_in = 0;
|
||||
strm->next_out = outbuf;
|
||||
strm->avail_out = sizeof(outbuf);
|
||||
|
||||
while (true) {
|
||||
if (strm->avail_in == 0 && !feof(infile)) {
|
||||
strm->next_in = inbuf;
|
||||
strm->avail_in = fread(inbuf, 1, sizeof(inbuf),
|
||||
infile);
|
||||
|
||||
if (ferror(infile)) {
|
||||
fprintf(stderr, "Read error: %s\n",
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (feof(infile))
|
||||
action = LZMA_FINISH;
|
||||
}
|
||||
|
||||
lzma_ret ret = lzma_code(strm, action);
|
||||
|
||||
if (strm->avail_out == 0 || ret == LZMA_STREAM_END) {
|
||||
size_t write_size = sizeof(outbuf) - strm->avail_out;
|
||||
|
||||
if (fwrite(outbuf, 1, write_size, outfile)
|
||||
!= write_size) {
|
||||
fprintf(stderr, "Write error: %s\n",
|
||||
strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
strm->next_out = outbuf;
|
||||
strm->avail_out = sizeof(outbuf);
|
||||
}
|
||||
|
||||
if (ret != LZMA_OK) {
|
||||
if (ret == LZMA_STREAM_END)
|
||||
return true;
|
||||
|
||||
const char *msg;
|
||||
switch (ret) {
|
||||
case LZMA_MEM_ERROR:
|
||||
msg = "Memory allocation failed";
|
||||
break;
|
||||
|
||||
case LZMA_DATA_ERROR:
|
||||
msg = "File size limits exceeded";
|
||||
break;
|
||||
|
||||
default:
|
||||
msg = "Unknown error, possibly a bug";
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Encoder error: %s (error code %u)\n",
|
||||
msg, ret);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern int
|
||||
main(void)
|
||||
{
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
|
||||
bool success = init_encoder(&strm);
|
||||
if (success)
|
||||
success = compress(&strm, stdin, stdout);
|
||||
|
||||
lzma_end(&strm);
|
||||
|
||||
if (fclose(stdout)) {
|
||||
fprintf(stderr, "Write error: %s\n", strerror(errno));
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
@@ -12,7 +12,8 @@ LDFLAGS = -llzma
|
||||
PROGS = \
|
||||
01_compress_easy \
|
||||
02_decompress \
|
||||
03_compress_custom
|
||||
03_compress_custom \
|
||||
04_compress_easy_mt
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@ de
|
||||
fr
|
||||
it
|
||||
pl
|
||||
vi
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
|
||||
////////////////////////////////////////
|
||||
// Shared betewen all threading types //
|
||||
// Shared between all threading types //
|
||||
////////////////////////////////////////
|
||||
|
||||
// Locks a mutex for a duration of a block.
|
||||
|
||||
@@ -165,6 +165,16 @@ typedef unsigned char _Bool;
|
||||
# include <memory.h>
|
||||
#endif
|
||||
|
||||
// As of MSVC 2013, inline and restrict are supported with
|
||||
// non-standard keywords.
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# ifndef inline
|
||||
# define inline __inline
|
||||
# endif
|
||||
# ifndef restrict
|
||||
# define restrict __restrict
|
||||
# endif
|
||||
#endif
|
||||
|
||||
////////////
|
||||
// Macros //
|
||||
|
||||
@@ -12,7 +12,7 @@ CLEANFILES =
|
||||
doc_DATA =
|
||||
|
||||
lib_LTLIBRARIES = liblzma.la
|
||||
liblzma_la_SOURCES = $(top_srcdir)/src/common/tuklib_physmem.c
|
||||
liblzma_la_SOURCES =
|
||||
liblzma_la_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/liblzma/api \
|
||||
-I$(top_srcdir)/src/liblzma/common \
|
||||
@@ -32,6 +32,12 @@ liblzma_la_LDFLAGS += \
|
||||
-Wl,--version-script=$(top_srcdir)/src/liblzma/liblzma.map
|
||||
endif
|
||||
|
||||
liblzma_la_SOURCES += $(top_srcdir)/src/common/tuklib_physmem.c
|
||||
|
||||
if COND_THREADS
|
||||
liblzma_la_SOURCES += $(top_srcdir)/src/common/tuklib_cpucores.c
|
||||
endif
|
||||
|
||||
include $(srcdir)/common/Makefile.inc
|
||||
include $(srcdir)/check/Makefile.inc
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ nobase_include_HEADERS = \
|
||||
lzma/hardware.h \
|
||||
lzma/index.h \
|
||||
lzma/index_hash.h \
|
||||
lzma/lzma.h \
|
||||
lzma/lzma12.h \
|
||||
lzma/stream_flags.h \
|
||||
lzma/version.h \
|
||||
lzma/vli.h
|
||||
|
||||
@@ -286,7 +286,7 @@ extern "C" {
|
||||
#include "lzma/filter.h"
|
||||
#include "lzma/bcj.h"
|
||||
#include "lzma/delta.h"
|
||||
#include "lzma/lzma.h"
|
||||
#include "lzma/lzma12.h"
|
||||
|
||||
/* Container formats */
|
||||
#include "lzma/container.h"
|
||||
|
||||
@@ -31,11 +31,16 @@ typedef struct {
|
||||
/**
|
||||
* \brief Block format version
|
||||
*
|
||||
* To prevent API and ABI breakages if new features are needed in
|
||||
* the Block field, a version number is used to indicate which
|
||||
* fields in this structure are in use. For now, version must always
|
||||
* be zero. With non-zero version, most Block related functions will
|
||||
* return LZMA_OPTIONS_ERROR.
|
||||
* To prevent API and ABI breakages when new features are needed,
|
||||
* a version number is used to indicate which fields in this
|
||||
* structure are in use:
|
||||
* - liblzma >= 5.0.0: version = 0 is supported.
|
||||
* - liblzma >= 5.1.4beta: Support for version = 1 was added,
|
||||
* which adds the ignore_check field.
|
||||
*
|
||||
* If version is greater than one, most Block related functions
|
||||
* will return LZMA_OPTIONS_ERROR (lzma_block_header_decode() works
|
||||
* with any version value).
|
||||
*
|
||||
* Read by:
|
||||
* - All functions that take pointer to lzma_block as argument,
|
||||
@@ -233,7 +238,28 @@ typedef struct {
|
||||
lzma_reserved_enum reserved_enum2;
|
||||
lzma_reserved_enum reserved_enum3;
|
||||
lzma_reserved_enum reserved_enum4;
|
||||
lzma_bool reserved_bool1;
|
||||
|
||||
/**
|
||||
* \brief A flag to Block decoder to not verify the Check field
|
||||
*
|
||||
* This field is supported by liblzma >= 5.1.4beta if .version >= 1.
|
||||
*
|
||||
* If this is set to true, the integrity check won't be calculated
|
||||
* and verified. Unless you know what you are doing, you should
|
||||
* leave this to false. (A reason to set this to true is when the
|
||||
* file integrity is verified externally anyway and you want to
|
||||
* speed up the decompression, which matters mostly when using
|
||||
* SHA-256 as the integrity check.)
|
||||
*
|
||||
* If .version >= 1, read by:
|
||||
* - lzma_block_decoder()
|
||||
* - lzma_block_buffer_decode()
|
||||
*
|
||||
* Written by (.version is ignored):
|
||||
* - lzma_block_header_decode() always sets this to false
|
||||
*/
|
||||
lzma_bool ignore_check;
|
||||
|
||||
lzma_bool reserved_bool2;
|
||||
lzma_bool reserved_bool3;
|
||||
lzma_bool reserved_bool4;
|
||||
@@ -310,14 +336,21 @@ extern LZMA_API(lzma_ret) lzma_block_header_encode(
|
||||
/**
|
||||
* \brief Decode Block Header
|
||||
*
|
||||
* block->version should be set to the highest value supported by the
|
||||
* application; currently the only possible version is zero. This function
|
||||
* will set version to the lowest value that still supports all the features
|
||||
* required by the Block Header.
|
||||
* block->version should (usually) be set to the highest value supported
|
||||
* by the application. If the application sets block->version to a value
|
||||
* higher than supported by the current liblzma version, this function will
|
||||
* downgrade block->version to the highest value supported by it. Thus one
|
||||
* should check the value of block->version after calling this function if
|
||||
* block->version was set to a non-zero value and the application doesn't
|
||||
* otherwise know that the liblzma version being used is new enough to
|
||||
* support the specified block->version.
|
||||
*
|
||||
* The size of the Block Header must have already been decoded with
|
||||
* lzma_block_header_size_decode() macro and stored to block->header_size.
|
||||
*
|
||||
* The integrity check type from Stream Header must have been stored
|
||||
* to block->check.
|
||||
*
|
||||
* block->filters must have been allocated, but they don't need to be
|
||||
* initialized (possible existing filter options are not freed).
|
||||
*
|
||||
@@ -497,7 +530,7 @@ extern LZMA_API(lzma_ret) lzma_block_buffer_encode(
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call uncompress .xz Block encoder
|
||||
* \brief Single-call uncompressed .xz Block encoder
|
||||
*
|
||||
* This is like lzma_block_buffer_encode() except this doesn't try to
|
||||
* compress the data and instead encodes the data using LZMA2 uncompressed
|
||||
|
||||
@@ -473,6 +473,30 @@ extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
|
||||
#define LZMA_TELL_ANY_CHECK UINT32_C(0x04)
|
||||
|
||||
|
||||
/**
|
||||
* This flag makes lzma_code() not calculate and verify the integrity check
|
||||
* of the compressed data in .xz files. This means that invalid integrity
|
||||
* check values won't be detected and LZMA_DATA_ERROR won't be returned in
|
||||
* such cases.
|
||||
*
|
||||
* This flag only affects the checks of the compressed data itself; the CRC32
|
||||
* values in the .xz headers will still be verified normally.
|
||||
*
|
||||
* Don't use this flag unless you know what you are doing. Possible reasons
|
||||
* to use this flag:
|
||||
*
|
||||
* - Trying to recover data from a corrupt .xz file.
|
||||
*
|
||||
* - Speeding up decompression, which matters mostly with SHA-256
|
||||
* or with files that have compressed extremely well. It's recommended
|
||||
* to not use this flag for this purpose unless the file integrity is
|
||||
* verified externally in some other way.
|
||||
*
|
||||
* Support for this flag was added in liblzma 5.1.4beta.
|
||||
*/
|
||||
#define LZMA_IGNORE_CHECK UINT32_C(0x10)
|
||||
|
||||
|
||||
/**
|
||||
* This flag enables decoding of concatenated files with file formats that
|
||||
* allow concatenating compressed files as is. From the formats currently
|
||||
|
||||
@@ -48,3 +48,17 @@
|
||||
* of RAM on the specific operating system.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_physmem(void) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the number of processor cores or threads
|
||||
*
|
||||
* This function may be useful when determining how many threads to use.
|
||||
* If the hardware supports more than one thread per CPU core, the number
|
||||
* of hardware threads is returned if that information is available.
|
||||
*
|
||||
* \brief On success, the number of available CPU threads or cores is
|
||||
* returned. If this information isn't available or an error
|
||||
* occurs, zero is returned.
|
||||
*/
|
||||
extern LZMA_API(uint32_t) lzma_cputhreads(void) lzma_nothrow;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* \file lzma/lzma.h
|
||||
* \file lzma/lzma12.h
|
||||
* \brief LZMA1 and LZMA2 filters
|
||||
*/
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
*/
|
||||
#define LZMA_VERSION_MAJOR 5
|
||||
#define LZMA_VERSION_MINOR 1
|
||||
#define LZMA_VERSION_PATCH 3
|
||||
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
|
||||
#define LZMA_VERSION_PATCH 4
|
||||
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_BETA
|
||||
|
||||
#ifndef LZMA_VERSION_COMMIT
|
||||
# define LZMA_VERSION_COMMIT ""
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "crc_macros.h"
|
||||
|
||||
|
||||
// If you make any changes, do some bench marking! Seemingly unrelated
|
||||
// If you make any changes, do some benchmarking! Seemingly unrelated
|
||||
// changes can very easily ruin the performance (and very probably is
|
||||
// very compiler dependent).
|
||||
extern LZMA_API(uint32_t)
|
||||
|
||||
@@ -23,20 +23,20 @@
|
||||
|
||||
#include "check.h"
|
||||
|
||||
// Avoid bogus warnings in transform().
|
||||
#if TUKLIB_GNUC_REQ(4, 2)
|
||||
# pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
// Rotate a uint32_t. GCC can optimize this to a rotate instruction
|
||||
// at least on x86.
|
||||
static inline uint32_t
|
||||
rotr_32(uint32_t num, unsigned amount)
|
||||
{
|
||||
return (num >> amount) | (num << (32 - amount));
|
||||
}
|
||||
|
||||
// At least on x86, GCC is able to optimize this to a rotate instruction.
|
||||
#define rotr_32(num, amount) ((num) >> (amount) | (num) << (32 - (amount)))
|
||||
|
||||
#define blk0(i) (W[i] = data[i])
|
||||
#define blk0(i) (W[i] = conv32be(data[i]))
|
||||
#define blk2(i) (W[i & 15] += s1(W[(i - 2) & 15]) + W[(i - 7) & 15] \
|
||||
+ s0(W[(i - 15) & 15]))
|
||||
|
||||
#define Ch(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define Maj(x, y, z) ((x & y) | (z & (x | y)))
|
||||
#define Maj(x, y, z) ((x & (y ^ z)) + (y & z))
|
||||
|
||||
#define a(i) T[(0 - i) & 7]
|
||||
#define b(i) T[(1 - i) & 7]
|
||||
@@ -47,16 +47,17 @@
|
||||
#define g(i) T[(6 - i) & 7]
|
||||
#define h(i) T[(7 - i) & 7]
|
||||
|
||||
#define R(i) \
|
||||
h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] \
|
||||
+ (j ? blk2(i) : blk0(i)); \
|
||||
#define R(i, j, blk) \
|
||||
h(i) += S1(e(i)) + Ch(e(i), f(i), g(i)) + SHA256_K[i + j] + blk; \
|
||||
d(i) += h(i); \
|
||||
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
|
||||
#define R0(i) R(i, 0, blk0(i))
|
||||
#define R2(i) R(i, j, blk2(i))
|
||||
|
||||
#define S0(x) (rotr_32(x, 2) ^ rotr_32(x, 13) ^ rotr_32(x, 22))
|
||||
#define S1(x) (rotr_32(x, 6) ^ rotr_32(x, 11) ^ rotr_32(x, 25))
|
||||
#define s0(x) (rotr_32(x, 7) ^ rotr_32(x, 18) ^ (x >> 3))
|
||||
#define s1(x) (rotr_32(x, 17) ^ rotr_32(x, 19) ^ (x >> 10))
|
||||
#define S0(x) rotr_32(x ^ rotr_32(x ^ rotr_32(x, 9), 11), 2)
|
||||
#define S1(x) rotr_32(x ^ rotr_32(x ^ rotr_32(x, 14), 5), 6)
|
||||
#define s0(x) (rotr_32(x ^ rotr_32(x, 11), 7) ^ (x >> 3))
|
||||
#define s1(x) (rotr_32(x ^ rotr_32(x, 2), 17) ^ (x >> 10))
|
||||
|
||||
|
||||
static const uint32_t SHA256_K[64] = {
|
||||
@@ -80,7 +81,7 @@ static const uint32_t SHA256_K[64] = {
|
||||
|
||||
|
||||
static void
|
||||
transform(uint32_t state[static 8], const uint32_t data[static 16])
|
||||
transform(uint32_t state[8], const uint32_t data[16])
|
||||
{
|
||||
uint32_t W[16];
|
||||
uint32_t T[8];
|
||||
@@ -88,12 +89,18 @@ transform(uint32_t state[static 8], const uint32_t data[static 16])
|
||||
// Copy state[] to working vars.
|
||||
memcpy(T, state, sizeof(T));
|
||||
|
||||
// 64 operations, partially loop unrolled
|
||||
for (unsigned int j = 0; j < 64; j += 16) {
|
||||
R( 0); R( 1); R( 2); R( 3);
|
||||
R( 4); R( 5); R( 6); R( 7);
|
||||
R( 8); R( 9); R(10); R(11);
|
||||
R(12); R(13); R(14); R(15);
|
||||
// The first 16 operations unrolled
|
||||
R0( 0); R0( 1); R0( 2); R0( 3);
|
||||
R0( 4); R0( 5); R0( 6); R0( 7);
|
||||
R0( 8); R0( 9); R0(10); R0(11);
|
||||
R0(12); R0(13); R0(14); R0(15);
|
||||
|
||||
// The remaining 48 operations partially unrolled
|
||||
for (unsigned int j = 16; j < 64; j += 16) {
|
||||
R2( 0); R2( 1); R2( 2); R2( 3);
|
||||
R2( 4); R2( 5); R2( 6); R2( 7);
|
||||
R2( 8); R2( 9); R2(10); R2(11);
|
||||
R2(12); R2(13); R2(14); R2(15);
|
||||
}
|
||||
|
||||
// Add the working vars back into state[].
|
||||
@@ -111,18 +118,7 @@ transform(uint32_t state[static 8], const uint32_t data[static 16])
|
||||
static void
|
||||
process(lzma_check_state *check)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
transform(check->state.sha256.state, check->buffer.u32);
|
||||
|
||||
#else
|
||||
uint32_t data[16];
|
||||
|
||||
for (size_t i = 0; i < 16; ++i)
|
||||
data[i] = bswap32(check->buffer.u32[i]);
|
||||
|
||||
transform(check->state.sha256.state, data);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
liblzma_la_SOURCES += \
|
||||
common/common.c \
|
||||
common/common.h \
|
||||
common/memcmplen.h \
|
||||
common/block_util.c \
|
||||
common/easy_preset.c \
|
||||
common/easy_preset.h \
|
||||
@@ -44,6 +45,7 @@ liblzma_la_SOURCES += \
|
||||
|
||||
if COND_THREADS
|
||||
liblzma_la_SOURCES += \
|
||||
common/hardware_cputhreads.c \
|
||||
common/outqueue.c \
|
||||
common/outqueue.h \
|
||||
common/stream_encoder_mt.c
|
||||
|
||||
@@ -233,7 +233,7 @@ block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,
|
||||
|
||||
// The contents of the structure may depend on the version so
|
||||
// check the version before validating the contents of *block.
|
||||
if (block->version != 0)
|
||||
if (block->version > 1)
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX
|
||||
|
||||
@@ -45,6 +45,9 @@ struct lzma_coder_s {
|
||||
|
||||
/// Check of the uncompressed data
|
||||
lzma_check_state check;
|
||||
|
||||
/// True if the integrity check won't be calculated and verified.
|
||||
bool ignore_check;
|
||||
};
|
||||
|
||||
|
||||
@@ -97,8 +100,9 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
coder->block->uncompressed_size))
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
lzma_check_update(&coder->check, coder->block->check,
|
||||
out + out_start, out_used);
|
||||
if (!coder->ignore_check)
|
||||
lzma_check_update(&coder->check, coder->block->check,
|
||||
out + out_start, out_used);
|
||||
|
||||
if (ret != LZMA_STREAM_END)
|
||||
return ret;
|
||||
@@ -140,7 +144,9 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
if (coder->block->check == LZMA_CHECK_NONE)
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
lzma_check_finish(&coder->check, coder->block->check);
|
||||
if (!coder->ignore_check)
|
||||
lzma_check_finish(&coder->check, coder->block->check);
|
||||
|
||||
coder->sequence = SEQ_CHECK;
|
||||
|
||||
// Fall through
|
||||
@@ -155,7 +161,8 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
// Validate the Check only if we support it.
|
||||
// coder->check.buffer may be uninitialized
|
||||
// when the Check ID is not supported.
|
||||
if (lzma_check_is_supported(coder->block->check)
|
||||
if (!coder->ignore_check
|
||||
&& lzma_check_is_supported(coder->block->check)
|
||||
&& memcmp(coder->block->raw_check,
|
||||
coder->check.buffer.u8,
|
||||
check_size) != 0)
|
||||
@@ -224,6 +231,9 @@ lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
next->coder->check_pos = 0;
|
||||
lzma_check_init(&next->coder->check, block->check);
|
||||
|
||||
next->coder->ignore_check = block->version >= 1
|
||||
? block->ignore_check : false;
|
||||
|
||||
// Initialize the filter chain.
|
||||
return lzma_raw_decoder_init(&next->coder->next, allocator,
|
||||
block->filters);
|
||||
|
||||
@@ -166,7 +166,7 @@ lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
|
||||
// The contents of the structure may depend on the version so
|
||||
// check the version first.
|
||||
if (block->version != 0)
|
||||
if (block->version > 1)
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
// If the Check ID is not supported, we cannot calculate the check and
|
||||
|
||||
@@ -46,8 +46,16 @@ lzma_block_header_decode(lzma_block *block,
|
||||
block->filters[i].options = NULL;
|
||||
}
|
||||
|
||||
// Always zero for now.
|
||||
block->version = 0;
|
||||
// Versions 0 and 1 are supported. If a newer version was specified,
|
||||
// we need to downgrade it.
|
||||
if (block->version > 1)
|
||||
block->version = 1;
|
||||
|
||||
// This isn't a Block Header option, but since the decompressor will
|
||||
// read it if version >= 1, it's better to initialize it here than
|
||||
// to expect the caller to do it since in almost all cases this
|
||||
// should be false.
|
||||
block->ignore_check = false;
|
||||
|
||||
// Validate Block Header Size and Check type. The caller must have
|
||||
// already set these, so it is a programming error if this test fails.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_block_header_size(lzma_block *block)
|
||||
{
|
||||
if (block->version != 0)
|
||||
if (block->version > 1)
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
// Block Header Size + Block Flags + CRC32.
|
||||
|
||||
@@ -51,7 +51,7 @@ lzma_block_unpadded_size(const lzma_block *block)
|
||||
// NOTE: This function is used for validation too, so it is
|
||||
// essential that these checks are always done even if
|
||||
// Compressed Size is unknown.
|
||||
if (block == NULL || block->version != 0
|
||||
if (block == NULL || block->version > 1
|
||||
|| block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN
|
||||
|| block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX
|
||||
|| (block->header_size & 3)
|
||||
|
||||
@@ -53,6 +53,27 @@ lzma_alloc(size_t size, const lzma_allocator *allocator)
|
||||
}
|
||||
|
||||
|
||||
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
|
||||
lzma_alloc_zero(size_t size, const lzma_allocator *allocator)
|
||||
{
|
||||
// Some calloc() variants return NULL if called with size == 0.
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
void *ptr;
|
||||
|
||||
if (allocator != NULL && allocator->alloc != NULL) {
|
||||
ptr = allocator->alloc(allocator->opaque, 1, size);
|
||||
if (ptr != NULL)
|
||||
memzero(ptr, size);
|
||||
} else {
|
||||
ptr = calloc(1, size);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_free(void *ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
( LZMA_TELL_NO_CHECK \
|
||||
| LZMA_TELL_UNSUPPORTED_CHECK \
|
||||
| LZMA_TELL_ANY_CHECK \
|
||||
| LZMA_IGNORE_CHECK \
|
||||
| LZMA_CONCATENATED )
|
||||
|
||||
|
||||
@@ -234,6 +235,12 @@ struct lzma_internal_s {
|
||||
extern void *lzma_alloc(size_t size, const lzma_allocator *allocator)
|
||||
lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
|
||||
|
||||
/// Allocates memory and zeroes it (like calloc()). This can be faster
|
||||
/// than lzma_alloc() + memzero() while being backward compatible with
|
||||
/// custom allocators.
|
||||
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
|
||||
lzma_alloc_zero(size_t size, const lzma_allocator *allocator);
|
||||
|
||||
/// Frees memory
|
||||
extern void lzma_free(void *ptr, const lzma_allocator *allocator);
|
||||
|
||||
|
||||
22
src/liblzma/common/hardware_cputhreads.c
Normal file
22
src/liblzma/common/hardware_cputhreads.c
Normal file
@@ -0,0 +1,22 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file hardware_cputhreads.c
|
||||
/// \brief Get the number of CPU threads or cores
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "tuklib_cpucores.h"
|
||||
|
||||
|
||||
extern LZMA_API(uint32_t)
|
||||
lzma_cputhreads(void)
|
||||
{
|
||||
return tuklib_cpucores();
|
||||
}
|
||||
170
src/liblzma/common/memcmplen.h
Normal file
170
src/liblzma/common/memcmplen.h
Normal file
@@ -0,0 +1,170 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file memcmplen.h
|
||||
/// \brief Optimized comparison of two buffers
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_MEMCMPLEN_H
|
||||
#define LZMA_MEMCMPLEN_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef HAVE_IMMINTRIN_H
|
||||
# include <immintrin.h>
|
||||
#endif
|
||||
|
||||
/// How many extra bytes lzma_memcmplen() may read. This depends on
|
||||
/// the method but since it is just a few bytes the biggest possible
|
||||
/// value is used here.
|
||||
#define LZMA_MEMCMPLEN_EXTRA 16
|
||||
|
||||
|
||||
/// Find out how many equal bytes the two buffers have.
|
||||
///
|
||||
/// \param buf1 First buffer
|
||||
/// \param buf2 Second buffer
|
||||
/// \param len How many bytes have already been compared and will
|
||||
/// be assumed to match
|
||||
/// \param limit How many bytes to compare at most, including the
|
||||
/// already-compared bytes. This must be significantly
|
||||
/// smaller than UINT32_MAX to avoid integer overflows.
|
||||
/// Up to LZMA_MEMCMPLEN_EXTRA bytes may be read past
|
||||
/// the specified limit from both buf1 and buf2.
|
||||
///
|
||||
/// \return Number of equal bytes in the buffers is returned.
|
||||
/// This is always at least len and at most limit.
|
||||
static inline uint32_t lzma_attribute((__always_inline__))
|
||||
lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
|
||||
uint32_t len, uint32_t limit)
|
||||
{
|
||||
assert(len <= limit);
|
||||
assert(limit <= UINT32_MAX / 2);
|
||||
|
||||
#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
|
||||
&& ((TUKLIB_GNUC_REQ(3, 4) && defined(__x86_64__)) \
|
||||
|| (defined(__INTEL_COMPILER) && defined(__x86_64__)) \
|
||||
|| (defined(__INTEL_COMPILER) && defined(_M_X64)) \
|
||||
|| (defined(_MSC_VER) && defined(_M_X64)))
|
||||
// NOTE: This will use 64-bit unaligned access which
|
||||
// TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit, but
|
||||
// it's convenient here at least as long as it's x86-64 only.
|
||||
//
|
||||
// I keep this x86-64 only for now since that's where I know this
|
||||
// to be a good method. This may be fine on other 64-bit CPUs too.
|
||||
// On big endian one should use xor instead of subtraction and switch
|
||||
// to __builtin_clzll().
|
||||
while (len < limit) {
|
||||
const uint64_t x = *(const uint64_t *)(buf1 + len)
|
||||
- *(const uint64_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
# if defined(_M_X64) // MSVC or Intel C compiler on Windows
|
||||
unsigned long tmp;
|
||||
_BitScanForward64(&tmp, x);
|
||||
len += (uint32_t)tmp >> 3;
|
||||
# else // GCC, clang, or Intel C compiler
|
||||
len += (uint32_t)__builtin_ctzll(x) >> 3;
|
||||
# endif
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 8;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
|
||||
&& defined(HAVE__MM_MOVEMASK_EPI8) \
|
||||
&& ((defined(__GNUC__) && defined(__SSE2_MATH__)) \
|
||||
|| (defined(__INTEL_COMPILER) && defined(__SSE2__)) \
|
||||
|| (defined(_MSC_VER) && defined(_M_IX86_FP) \
|
||||
&& _M_IX86_FP >= 2))
|
||||
// NOTE: Like above, this will use 128-bit unaligned access which
|
||||
// TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit.
|
||||
//
|
||||
// SSE2 version for 32-bit and 64-bit x86. On x86-64 the above
|
||||
// version is sometimes significantly faster and sometimes
|
||||
// slightly slower than this SSE2 version, so this SSE2
|
||||
// version isn't used on x86-64.
|
||||
while (len < limit) {
|
||||
const uint32_t x = 0xFFFF ^ _mm_movemask_epi8(_mm_cmpeq_epi8(
|
||||
_mm_loadu_si128((const __m128i *)(buf1 + len)),
|
||||
_mm_loadu_si128((const __m128i *)(buf2 + len))));
|
||||
|
||||
if (x != 0) {
|
||||
# if defined(__INTEL_COMPILER)
|
||||
len += _bit_scan_forward(x);
|
||||
# elif defined(_MSC_VER)
|
||||
unsigned long tmp;
|
||||
_BitScanForward(&tmp, x);
|
||||
len += tmp;
|
||||
# else
|
||||
len += __builtin_ctz(x);
|
||||
# endif
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 16;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && !defined(WORDS_BIGENDIAN)
|
||||
// Generic 32-bit little endian method
|
||||
while (len < limit) {
|
||||
uint32_t x = *(const uint32_t *)(buf1 + len)
|
||||
- *(const uint32_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
if ((x & 0xFFFF) == 0) {
|
||||
len += 2;
|
||||
x >>= 16;
|
||||
}
|
||||
|
||||
if ((x & 0xFF) == 0)
|
||||
++len;
|
||||
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 4;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && defined(WORDS_BIGENDIAN)
|
||||
// Generic 32-bit big endian method
|
||||
while (len < limit) {
|
||||
uint32_t x = *(const uint32_t *)(buf1 + len)
|
||||
^ *(const uint32_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
if ((x & 0xFFFF0000) == 0) {
|
||||
len += 2;
|
||||
x <<= 16;
|
||||
}
|
||||
|
||||
if ((x & 0xFF000000) == 0)
|
||||
++len;
|
||||
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 4;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#else
|
||||
// Simple portable version that doesn't use unaligned access.
|
||||
while (len < limit && buf1[len] == buf2[len])
|
||||
++len;
|
||||
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -57,6 +57,10 @@ struct lzma_coder_s {
|
||||
/// If true, LZMA_GET_CHECK is returned after decoding Stream Header.
|
||||
bool tell_any_check;
|
||||
|
||||
/// If true, we will tell the Block decoder to skip calculating
|
||||
/// and verifying the integrity check.
|
||||
bool ignore_check;
|
||||
|
||||
/// If true, we will decode concatenated Streams that possibly have
|
||||
/// Stream Padding between or after them. LZMA_STREAM_END is returned
|
||||
/// once the application isn't giving us any new input, and we aren't
|
||||
@@ -182,8 +186,8 @@ stream_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
|
||||
coder->pos = 0;
|
||||
|
||||
// Version 0 is currently the only possible version.
|
||||
coder->block_options.version = 0;
|
||||
// Version 1 is needed to support the .ignore_check option.
|
||||
coder->block_options.version = 1;
|
||||
|
||||
// Set up a buffer to hold the filter chain. Block Header
|
||||
// decoder will initialize all members of this array so
|
||||
@@ -195,6 +199,11 @@ stream_decode(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
return_if_error(lzma_block_header_decode(&coder->block_options,
|
||||
allocator, coder->buffer));
|
||||
|
||||
// If LZMA_IGNORE_CHECK was used, this flag needs to be set.
|
||||
// It has to be set after lzma_block_header_decode() because
|
||||
// it always resets this to false.
|
||||
coder->block_options.ignore_check = coder->ignore_check;
|
||||
|
||||
// Check the memory usage limit.
|
||||
const uint64_t memusage = lzma_raw_decoder_memusage(filters);
|
||||
lzma_ret ret;
|
||||
@@ -433,6 +442,7 @@ lzma_stream_decoder_init(
|
||||
next->coder->tell_unsupported_check
|
||||
= (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0;
|
||||
next->coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;
|
||||
next->coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0;
|
||||
next->coder->concatenated = (flags & LZMA_CONCATENATED) != 0;
|
||||
next->coder->first_stream = true;
|
||||
|
||||
|
||||
@@ -1036,8 +1036,8 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
|
||||
lzma_free(next->coder->filters[i].options, allocator);
|
||||
|
||||
return_if_error(lzma_filters_copy(options->filters,
|
||||
next->coder->filters, allocator));
|
||||
return_if_error(lzma_filters_copy(
|
||||
filters, next->coder->filters, allocator));
|
||||
|
||||
// Index
|
||||
lzma_index_end(next->coder->index, allocator);
|
||||
|
||||
@@ -95,9 +95,10 @@ global:
|
||||
lzma_vli_size;
|
||||
};
|
||||
|
||||
XZ_5.1.3alpha {
|
||||
XZ_5.1.4beta {
|
||||
global:
|
||||
lzma_block_uncomp_encode;
|
||||
lzma_cputhreads;
|
||||
lzma_get_progress;
|
||||
lzma_stream_encoder_mt;
|
||||
lzma_stream_encoder_mt_memusage;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
# include "lz_encoder_hash_table.h"
|
||||
#endif
|
||||
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
struct lzma_coder_s {
|
||||
/// LZ-based encoder e.g. LZMA
|
||||
@@ -326,25 +328,22 @@ lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
hs += HASH_4_SIZE;
|
||||
*/
|
||||
|
||||
// If the above code calculating hs is modified, make sure that
|
||||
// this assertion stays valid (UINT32_MAX / 5 is not strictly the
|
||||
// exact limit). If it doesn't, you need to calculate that
|
||||
// hash_size_sum + sons_count cannot overflow.
|
||||
assert(hs < UINT32_MAX / 5);
|
||||
|
||||
const uint32_t old_count = mf->hash_size_sum + mf->sons_count;
|
||||
mf->hash_size_sum = hs;
|
||||
const uint32_t old_hash_count = mf->hash_count;
|
||||
const uint32_t old_sons_count = mf->sons_count;
|
||||
mf->hash_count = hs;
|
||||
mf->sons_count = mf->cyclic_size;
|
||||
if (is_bt)
|
||||
mf->sons_count *= 2;
|
||||
|
||||
const uint32_t new_count = mf->hash_size_sum + mf->sons_count;
|
||||
|
||||
// Deallocate the old hash array if it exists and has different size
|
||||
// than what is needed now.
|
||||
if (old_count != new_count) {
|
||||
if (old_hash_count != mf->hash_count
|
||||
|| old_sons_count != mf->sons_count) {
|
||||
lzma_free(mf->hash, allocator);
|
||||
mf->hash = NULL;
|
||||
|
||||
lzma_free(mf->son, allocator);
|
||||
mf->son = NULL;
|
||||
}
|
||||
|
||||
// Maximum number of match finder cycles
|
||||
@@ -366,9 +365,18 @@ lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
{
|
||||
// Allocate the history buffer.
|
||||
if (mf->buffer == NULL) {
|
||||
mf->buffer = lzma_alloc(mf->size, allocator);
|
||||
// lzma_memcmplen() is used for the dictionary buffer
|
||||
// so we need to allocate a few extra bytes to prevent
|
||||
// it from reading past the end of the buffer.
|
||||
mf->buffer = lzma_alloc(mf->size + LZMA_MEMCMPLEN_EXTRA,
|
||||
allocator);
|
||||
if (mf->buffer == NULL)
|
||||
return true;
|
||||
|
||||
// Keep Valgrind happy with lzma_memcmplen() and initialize
|
||||
// the extra bytes whose value may get read but which will
|
||||
// effectively get ignored.
|
||||
memzero(mf->buffer + mf->size, LZMA_MEMCMPLEN_EXTRA);
|
||||
}
|
||||
|
||||
// Use cyclic_size as initial mf->offset. This allows
|
||||
@@ -382,44 +390,49 @@ lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
mf->write_pos = 0;
|
||||
mf->pending = 0;
|
||||
|
||||
// Allocate match finder's hash array.
|
||||
const size_t alloc_count = mf->hash_size_sum + mf->sons_count;
|
||||
|
||||
#if UINT32_MAX >= SIZE_MAX / 4
|
||||
// Check for integer overflow. (Huge dictionaries are not
|
||||
// possible on 32-bit CPU.)
|
||||
if (alloc_count > SIZE_MAX / sizeof(uint32_t))
|
||||
if (mf->hash_count > SIZE_MAX / sizeof(uint32_t)
|
||||
|| mf->sons_count > SIZE_MAX / sizeof(uint32_t))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
// Allocate and initialize the hash table. Since EMPTY_HASH_VALUE
|
||||
// is zero, we can use lzma_alloc_zero() or memzero() for mf->hash.
|
||||
//
|
||||
// We don't need to initialize mf->son, but not doing that may
|
||||
// make Valgrind complain in normalization (see normalize() in
|
||||
// lz_encoder_mf.c). Skipping the initialization is *very* good
|
||||
// when big dictionary is used but only small amount of data gets
|
||||
// actually compressed: most of the mf->son won't get actually
|
||||
// allocated by the kernel, so we avoid wasting RAM and improve
|
||||
// initialization speed a lot.
|
||||
if (mf->hash == NULL) {
|
||||
mf->hash = lzma_alloc(alloc_count * sizeof(uint32_t),
|
||||
mf->hash = lzma_alloc_zero(mf->hash_count * sizeof(uint32_t),
|
||||
allocator);
|
||||
if (mf->hash == NULL)
|
||||
mf->son = lzma_alloc(mf->sons_count * sizeof(uint32_t),
|
||||
allocator);
|
||||
|
||||
if (mf->hash == NULL || mf->son == NULL) {
|
||||
lzma_free(mf->hash, allocator);
|
||||
mf->hash = NULL;
|
||||
|
||||
lzma_free(mf->son, allocator);
|
||||
mf->son = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
for (uint32_t i = 0; i < mf->hash_count; ++i)
|
||||
mf->hash[i] = EMPTY_HASH_VALUE;
|
||||
*/
|
||||
memzero(mf->hash, mf->hash_count * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
mf->son = mf->hash + mf->hash_size_sum;
|
||||
mf->cyclic_pos = 0;
|
||||
|
||||
// Initialize the hash table. Since EMPTY_HASH_VALUE is zero, we
|
||||
// can use memset().
|
||||
/*
|
||||
for (uint32_t i = 0; i < hash_size_sum; ++i)
|
||||
mf->hash[i] = EMPTY_HASH_VALUE;
|
||||
*/
|
||||
memzero(mf->hash, (size_t)(mf->hash_size_sum) * sizeof(uint32_t));
|
||||
|
||||
// We don't need to initialize mf->son, but not doing that will
|
||||
// make Valgrind complain in normalization (see normalize() in
|
||||
// lz_encoder_mf.c).
|
||||
//
|
||||
// Skipping this initialization is *very* good when big dictionary is
|
||||
// used but only small amount of data gets actually compressed: most
|
||||
// of the mf->hash won't get actually allocated by the kernel, so
|
||||
// we avoid wasting RAM and improve initialization speed a lot.
|
||||
//memzero(mf->son, (size_t)(mf->sons_count) * sizeof(uint32_t));
|
||||
|
||||
// Handle preset dictionary.
|
||||
if (lz_options->preset_dict != NULL
|
||||
&& lz_options->preset_dict_size > 0) {
|
||||
@@ -446,7 +459,8 @@ lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
|
||||
lzma_mf mf = {
|
||||
.buffer = NULL,
|
||||
.hash = NULL,
|
||||
.hash_size_sum = 0,
|
||||
.son = NULL,
|
||||
.hash_count = 0,
|
||||
.sons_count = 0,
|
||||
};
|
||||
|
||||
@@ -455,9 +469,8 @@ lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
|
||||
return UINT64_MAX;
|
||||
|
||||
// Calculate the memory usage.
|
||||
return (uint64_t)(mf.hash_size_sum + mf.sons_count)
|
||||
* sizeof(uint32_t)
|
||||
+ (uint64_t)(mf.size) + sizeof(lzma_coder);
|
||||
return ((uint64_t)(mf.hash_count) + mf.sons_count) * sizeof(uint32_t)
|
||||
+ mf.size + sizeof(lzma_coder);
|
||||
}
|
||||
|
||||
|
||||
@@ -466,6 +479,7 @@ lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
|
||||
lzma_free(coder->mf.son, allocator);
|
||||
lzma_free(coder->mf.hash, allocator);
|
||||
lzma_free(coder->mf.buffer, allocator);
|
||||
|
||||
@@ -523,7 +537,8 @@ lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
|
||||
next->coder->mf.buffer = NULL;
|
||||
next->coder->mf.hash = NULL;
|
||||
next->coder->mf.hash_size_sum = 0;
|
||||
next->coder->mf.son = NULL;
|
||||
next->coder->mf.hash_count = 0;
|
||||
next->coder->mf.sons_count = 0;
|
||||
|
||||
next->coder->next = LZMA_NEXT_CODER_INIT;
|
||||
|
||||
@@ -119,7 +119,7 @@ struct lzma_mf_s {
|
||||
lzma_action action;
|
||||
|
||||
/// Number of elements in hash[]
|
||||
uint32_t hash_size_sum;
|
||||
uint32_t hash_count;
|
||||
|
||||
/// Number of elements in son[]
|
||||
uint32_t sons_count;
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "lz_encoder.h"
|
||||
#include "lz_encoder_hash.h"
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
/// \brief Find matches starting from the current byte
|
||||
@@ -65,9 +66,7 @@ lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)
|
||||
// here because the match distances are zero based.
|
||||
const uint8_t *p2 = p1 - matches[count - 1].dist - 1;
|
||||
|
||||
while (len_best < limit
|
||||
&& p1[len_best] == p2[len_best])
|
||||
++len_best;
|
||||
len_best = lzma_memcmplen(p1, p2, len_best, limit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,24 +115,27 @@ normalize(lzma_mf *mf)
|
||||
= (MUST_NORMALIZE_POS - mf->cyclic_size);
|
||||
// & (~(UINT32_C(1) << 10) - 1);
|
||||
|
||||
const uint32_t count = mf->hash_size_sum + mf->sons_count;
|
||||
uint32_t *hash = mf->hash;
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
for (uint32_t i = 0; i < mf->hash_count; ++i) {
|
||||
// If the distance is greater than the dictionary size,
|
||||
// we can simply mark the hash element as empty.
|
||||
//
|
||||
// NOTE: Only the first mf->hash_size_sum elements are
|
||||
// initialized for sure. There may be uninitialized elements
|
||||
// in mf->son. Since we go through both mf->hash and
|
||||
// mf->son here in normalization, Valgrind may complain
|
||||
// that the "if" below depends on uninitialized value. In
|
||||
// this case it is safe to ignore the warning. See also the
|
||||
// comments in lz_encoder_init() in lz_encoder.c.
|
||||
if (hash[i] <= subvalue)
|
||||
hash[i] = EMPTY_HASH_VALUE;
|
||||
if (mf->hash[i] <= subvalue)
|
||||
mf->hash[i] = EMPTY_HASH_VALUE;
|
||||
else
|
||||
hash[i] -= subvalue;
|
||||
mf->hash[i] -= subvalue;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mf->sons_count; ++i) {
|
||||
// Do the same for mf->son.
|
||||
//
|
||||
// NOTE: There may be uninitialized elements in mf->son.
|
||||
// Valgrind may complain that the "if" below depends on
|
||||
// an uninitialized value. In this case it is safe to ignore
|
||||
// the warning. See also the comments in lz_encoder_init()
|
||||
// in lz_encoder.c.
|
||||
if (mf->son[i] <= subvalue)
|
||||
mf->son[i] = EMPTY_HASH_VALUE;
|
||||
else
|
||||
mf->son[i] -= subvalue;
|
||||
}
|
||||
|
||||
// Update offset to match the new locations.
|
||||
@@ -269,10 +271,7 @@ hc_find_func(
|
||||
+ (delta > cyclic_pos ? cyclic_size : 0)];
|
||||
|
||||
if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {
|
||||
uint32_t len = 0;
|
||||
while (++len != len_limit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit);
|
||||
|
||||
if (len_best < len) {
|
||||
len_best = len;
|
||||
@@ -318,9 +317,8 @@ lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches)
|
||||
uint32_t len_best = 2;
|
||||
|
||||
if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
|
||||
for ( ; len_best != len_limit; ++len_best)
|
||||
if (*(cur + len_best - delta2) != cur[len_best])
|
||||
break;
|
||||
len_best = lzma_memcmplen(cur - delta2, cur,
|
||||
len_best, len_limit);
|
||||
|
||||
matches[0].len = len_best;
|
||||
matches[0].dist = delta2 - 1;
|
||||
@@ -397,9 +395,8 @@ lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches)
|
||||
}
|
||||
|
||||
if (matches_count != 0) {
|
||||
for ( ; len_best != len_limit; ++len_best)
|
||||
if (*(cur + len_best - delta2) != cur[len_best])
|
||||
break;
|
||||
len_best = lzma_memcmplen(cur - delta2, cur,
|
||||
len_best, len_limit);
|
||||
|
||||
matches[matches_count - 1].len = len_best;
|
||||
|
||||
@@ -484,9 +481,7 @@ bt_find_func(
|
||||
uint32_t len = my_min(len0, len1);
|
||||
|
||||
if (pb[len] == cur[len]) {
|
||||
while (++len != len_limit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
len = lzma_memcmplen(pb, cur, len + 1, len_limit);
|
||||
|
||||
if (len_best < len) {
|
||||
len_best = len;
|
||||
@@ -549,9 +544,7 @@ bt_skip_func(
|
||||
uint32_t len = my_min(len0, len1);
|
||||
|
||||
if (pb[len] == cur[len]) {
|
||||
while (++len != len_limit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
len = lzma_memcmplen(pb, cur, len + 1, len_limit);
|
||||
|
||||
if (len == len_limit) {
|
||||
*ptr1 = pair[0];
|
||||
@@ -639,9 +632,8 @@ lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches)
|
||||
uint32_t len_best = 2;
|
||||
|
||||
if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
|
||||
for ( ; len_best != len_limit; ++len_best)
|
||||
if (*(cur + len_best - delta2) != cur[len_best])
|
||||
break;
|
||||
len_best = lzma_memcmplen(
|
||||
cur, cur - delta2, len_best, len_limit);
|
||||
|
||||
matches[0].len = len_best;
|
||||
matches[0].dist = delta2 - 1;
|
||||
@@ -712,9 +704,8 @@ lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches)
|
||||
}
|
||||
|
||||
if (matches_count != 0) {
|
||||
for ( ; len_best != len_limit; ++len_best)
|
||||
if (*(cur + len_best - delta2) != cur[len_best])
|
||||
break;
|
||||
len_best = lzma_memcmplen(
|
||||
cur, cur - delta2, len_best, len_limit);
|
||||
|
||||
matches[matches_count - 1].len = len_best;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
#define change_pair(small_dist, big_dist) \
|
||||
@@ -57,9 +58,8 @@ lzma_lzma_optimum_fast(lzma_coder *restrict coder, lzma_mf *restrict mf,
|
||||
|
||||
// The first two bytes matched.
|
||||
// Calculate the length of the match.
|
||||
uint32_t len;
|
||||
for (len = 2; len < buf_avail
|
||||
&& buf[len] == buf_back[len]; ++len) ;
|
||||
const uint32_t len = lzma_memcmplen(
|
||||
buf, buf_back, 2, buf_avail);
|
||||
|
||||
// If we have found a repeated match that is at least
|
||||
// nice_len long, return it immediately.
|
||||
@@ -155,16 +155,7 @@ lzma_lzma_optimum_fast(lzma_coder *restrict coder, lzma_mf *restrict mf,
|
||||
const uint32_t limit = len_main - 1;
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i) {
|
||||
const uint8_t *const buf_back = buf - coder->reps[i] - 1;
|
||||
|
||||
if (not_equal_16(buf, buf_back))
|
||||
continue;
|
||||
|
||||
uint32_t len;
|
||||
for (len = 2; len < limit
|
||||
&& buf[len] == buf_back[len]; ++len) ;
|
||||
|
||||
if (len >= limit) {
|
||||
if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) {
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "fastpos.h"
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
////////////
|
||||
@@ -305,13 +306,9 @@ helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t len_test;
|
||||
for (len_test = 2; len_test < buf_avail
|
||||
&& buf[len_test] == buf_back[len_test];
|
||||
++len_test) ;
|
||||
rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail);
|
||||
|
||||
rep_lens[i] = len_test;
|
||||
if (len_test > rep_lens[rep_max_index])
|
||||
if (rep_lens[i] > rep_lens[rep_max_index])
|
||||
rep_max_index = i;
|
||||
}
|
||||
|
||||
@@ -568,11 +565,7 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
|
||||
const uint8_t *const buf_back = buf - reps[0] - 1;
|
||||
const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
|
||||
|
||||
uint32_t len_test = 1;
|
||||
while (len_test < limit && buf[len_test] == buf_back[len_test])
|
||||
++len_test;
|
||||
|
||||
--len_test;
|
||||
const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1;
|
||||
|
||||
if (len_test >= 2) {
|
||||
lzma_lzma_state state_2 = state;
|
||||
@@ -612,10 +605,7 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
|
||||
if (not_equal_16(buf, buf_back))
|
||||
continue;
|
||||
|
||||
uint32_t len_test;
|
||||
for (len_test = 2; len_test < buf_avail
|
||||
&& buf[len_test] == buf_back[len_test];
|
||||
++len_test) ;
|
||||
uint32_t len_test = lzma_memcmplen(buf, buf_back, 2, buf_avail);
|
||||
|
||||
while (len_end < cur + len_test)
|
||||
coder->opts[++len_end].price = RC_INFINITY_PRICE;
|
||||
|
||||
@@ -30,14 +30,16 @@ lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)
|
||||
options->lp = LZMA_LP_DEFAULT;
|
||||
options->pb = LZMA_PB_DEFAULT;
|
||||
|
||||
options->dict_size = UINT32_C(1) << (uint8_t []){
|
||||
18, 20, 21, 22, 22, 23, 23, 24, 25, 26 }[level];
|
||||
static const uint8_t dict_pow2[]
|
||||
= { 18, 20, 21, 22, 22, 23, 23, 24, 25, 26 };
|
||||
options->dict_size = UINT32_C(1) << dict_pow2[level];
|
||||
|
||||
if (level <= 3) {
|
||||
options->mode = LZMA_MODE_FAST;
|
||||
options->mf = level == 0 ? LZMA_MF_HC3 : LZMA_MF_HC4;
|
||||
options->nice_len = level <= 1 ? 128 : 273;
|
||||
options->depth = (uint8_t []){ 4, 8, 24, 48 }[level];
|
||||
static const uint8_t depths[] = { 4, 8, 24, 48 };
|
||||
options->depth = depths[level];
|
||||
} else {
|
||||
options->mode = LZMA_MODE_NORMAL;
|
||||
options->mf = LZMA_MF_BT4;
|
||||
|
||||
@@ -147,7 +147,9 @@ if test $# -eq 0; then
|
||||
fi
|
||||
|
||||
exec 3>&1
|
||||
res=0
|
||||
|
||||
# res=1 means that no file matched yet
|
||||
res=1
|
||||
|
||||
for i; do
|
||||
case $i in
|
||||
@@ -195,8 +197,17 @@ for i; do
|
||||
fi >&3 5>&-
|
||||
)
|
||||
r=$?
|
||||
|
||||
# fail occured previously, nothing worse can happen
|
||||
test $res -gt 1 && continue
|
||||
|
||||
test "$xz_status" -eq 0 || test "$xz_status" -eq 2 \
|
||||
|| test "$(kill -l "$xz_status" 2> /dev/null)" = "PIPE" || r=2
|
||||
test $res -lt $r && res=$r
|
||||
|
||||
# still no match
|
||||
test $r -eq 1 && continue
|
||||
|
||||
# 0 == match, >=2 == fail
|
||||
res=$r
|
||||
done
|
||||
exit $res
|
||||
|
||||
@@ -36,7 +36,6 @@ xz_SOURCES = \
|
||||
$(top_srcdir)/src/common/tuklib_open_stdxxx.c \
|
||||
$(top_srcdir)/src/common/tuklib_progname.c \
|
||||
$(top_srcdir)/src/common/tuklib_exit.c \
|
||||
$(top_srcdir)/src/common/tuklib_cpucores.c \
|
||||
$(top_srcdir)/src/common/tuklib_mbstr_width.c \
|
||||
$(top_srcdir)/src/common/tuklib_mbstr_fw.c
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ bool opt_stdout = false;
|
||||
bool opt_force = false;
|
||||
bool opt_keep_original = false;
|
||||
bool opt_robot = false;
|
||||
bool opt_ignore_check = false;
|
||||
|
||||
// We don't modify or free() this, but we need to assign it in some
|
||||
// non-const pointers.
|
||||
@@ -141,6 +142,7 @@ parse_real(args_info *args, int argc, char **argv)
|
||||
OPT_INFO_MEMORY,
|
||||
OPT_ROBOT,
|
||||
OPT_FLUSH_TIMEOUT,
|
||||
OPT_IGNORE_CHECK,
|
||||
};
|
||||
|
||||
static const char short_opts[]
|
||||
@@ -169,6 +171,7 @@ parse_real(args_info *args, int argc, char **argv)
|
||||
// Basic compression settings
|
||||
{ "format", required_argument, NULL, 'F' },
|
||||
{ "check", required_argument, NULL, 'C' },
|
||||
{ "ignore-check", no_argument, NULL, OPT_IGNORE_CHECK },
|
||||
{ "block-size", required_argument, NULL, OPT_BLOCK_SIZE },
|
||||
{ "block-list", required_argument, NULL, OPT_BLOCK_LIST },
|
||||
{ "memlimit-compress", required_argument, NULL, OPT_MEM_COMPRESS },
|
||||
@@ -438,6 +441,10 @@ parse_real(args_info *args, int argc, char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
case OPT_IGNORE_CHECK:
|
||||
opt_ignore_check = true;
|
||||
break;
|
||||
|
||||
case OPT_BLOCK_SIZE:
|
||||
opt_block_size = str_to_uint64("block-size", optarg,
|
||||
0, LZMA_VLI_MAX);
|
||||
|
||||
@@ -36,6 +36,7 @@ extern bool opt_force;
|
||||
extern bool opt_keep_original;
|
||||
// extern bool opt_recursive;
|
||||
extern bool opt_robot;
|
||||
extern bool opt_ignore_check;
|
||||
|
||||
extern const char stdin_filename[];
|
||||
|
||||
|
||||
127
src/xz/coder.c
127
src/xz/coder.c
@@ -195,6 +195,29 @@ coder_set_compression_settings(void)
|
||||
// Print the selected filter chain.
|
||||
message_filters_show(V_DEBUG, filters);
|
||||
|
||||
// The --flush-timeout option requires LZMA_SYNC_FLUSH support
|
||||
// from the filter chain. Currently threaded encoder doesn't support
|
||||
// LZMA_SYNC_FLUSH so single-threaded mode must be used.
|
||||
if (opt_mode == MODE_COMPRESS && opt_flush_timeout != 0) {
|
||||
for (size_t i = 0; i < filters_count; ++i) {
|
||||
switch (filters[i].id) {
|
||||
case LZMA_FILTER_LZMA2:
|
||||
case LZMA_FILTER_DELTA:
|
||||
break;
|
||||
|
||||
default:
|
||||
message_fatal(_("The filter chain is "
|
||||
"incompatible with --flush-timeout"));
|
||||
}
|
||||
}
|
||||
|
||||
if (hardware_threads_get() > 1) {
|
||||
message(V_WARNING, _("Switching to single-threaded "
|
||||
"mode due to --flush-timeout"));
|
||||
hardware_threads_set(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the memory usage. Note that if --format=raw was used,
|
||||
// we can be decompressing.
|
||||
const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
|
||||
@@ -237,9 +260,9 @@ coder_set_compression_settings(void)
|
||||
if (memory_usage <= memory_limit)
|
||||
return;
|
||||
|
||||
// If --no-auto-adjust was used or we didn't find LZMA1 or
|
||||
// If --no-adjust was used or we didn't find LZMA1 or
|
||||
// LZMA2 as the last filter, give an error immediately.
|
||||
// --format=raw implies --no-auto-adjust.
|
||||
// --format=raw implies --no-adjust.
|
||||
if (!opt_auto_adjust || opt_format == FORMAT_RAW)
|
||||
memlimit_too_small(memory_usage);
|
||||
|
||||
@@ -427,7 +450,15 @@ coder_init(file_pair *pair)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
uint32_t flags = LZMA_TELL_UNSUPPORTED_CHECK;
|
||||
uint32_t flags = 0;
|
||||
|
||||
// It seems silly to warn about unsupported check if the
|
||||
// check won't be verified anyway due to --ignore-check.
|
||||
if (opt_ignore_check)
|
||||
flags |= LZMA_IGNORE_CHECK;
|
||||
else
|
||||
flags |= LZMA_TELL_UNSUPPORTED_CHECK;
|
||||
|
||||
if (!opt_single_stream)
|
||||
flags |= LZMA_CONCATENATED;
|
||||
|
||||
@@ -514,6 +545,56 @@ coder_init(file_pair *pair)
|
||||
}
|
||||
|
||||
|
||||
/// Resolve conflicts between opt_block_size and opt_block_list in single
|
||||
/// threaded mode. We want to default to opt_block_list, except when it is
|
||||
/// larger than opt_block_size. If this is the case for the current Block
|
||||
/// at *list_pos, then we break into smaller Blocks. Otherwise advance
|
||||
/// to the next Block in opt_block_list, and break apart if needed.
|
||||
static void
|
||||
split_block(uint64_t *block_remaining,
|
||||
uint64_t *next_block_remaining,
|
||||
size_t *list_pos)
|
||||
{
|
||||
if (*next_block_remaining > 0) {
|
||||
// The Block at *list_pos has previously been split up.
|
||||
assert(hardware_threads_get() == 1);
|
||||
assert(opt_block_size > 0);
|
||||
assert(opt_block_list != NULL);
|
||||
|
||||
if (*next_block_remaining > opt_block_size) {
|
||||
// We have to split the current Block at *list_pos
|
||||
// into another opt_block_size length Block.
|
||||
*block_remaining = opt_block_size;
|
||||
} else {
|
||||
// This is the last remaining split Block for the
|
||||
// Block at *list_pos.
|
||||
*block_remaining = *next_block_remaining;
|
||||
}
|
||||
|
||||
*next_block_remaining -= *block_remaining;
|
||||
|
||||
} else {
|
||||
// The Block at *list_pos has been finished. Go to the next
|
||||
// entry in the list. If the end of the list has been reached,
|
||||
// reuse the size of the last Block.
|
||||
if (opt_block_list[*list_pos + 1] != 0)
|
||||
++*list_pos;
|
||||
|
||||
*block_remaining = opt_block_list[*list_pos];
|
||||
|
||||
// If in single-threaded mode, split up the Block if needed.
|
||||
// This is not needed in multi-threaded mode because liblzma
|
||||
// will do this due to how threaded encoding works.
|
||||
if (hardware_threads_get() == 1 && opt_block_size > 0
|
||||
&& *block_remaining > opt_block_size) {
|
||||
*next_block_remaining
|
||||
= *block_remaining - opt_block_size;
|
||||
*block_remaining = opt_block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Compress or decompress using liblzma.
|
||||
static bool
|
||||
coder_normal(file_pair *pair)
|
||||
@@ -537,6 +618,10 @@ coder_normal(file_pair *pair)
|
||||
// only a single block is created.
|
||||
uint64_t block_remaining = UINT64_MAX;
|
||||
|
||||
// next_block_remining for when we are in single-threaded mode and
|
||||
// the Block in --block-list is larger than the --block-size=SIZE.
|
||||
uint64_t next_block_remaining = 0;
|
||||
|
||||
// Position in opt_block_list. Unused if --block-list wasn't used.
|
||||
size_t list_pos = 0;
|
||||
|
||||
@@ -551,14 +636,22 @@ coder_normal(file_pair *pair)
|
||||
|
||||
// If --block-list was used, start with the first size.
|
||||
//
|
||||
// FIXME: Currently this overrides --block-size but this isn't
|
||||
// good. For threaded case, we want --block-size to specify
|
||||
// how big Blocks the encoder needs to be prepared to create
|
||||
// at maximum and --block-list will simultaneously cause new
|
||||
// Blocks to be started at specified intervals. To keep things
|
||||
// logical, the same should be done in single-threaded mode.
|
||||
if (opt_block_list != NULL)
|
||||
block_remaining = opt_block_list[list_pos];
|
||||
// For threaded case, --block-size specifies how big Blocks
|
||||
// the encoder needs to be prepared to create at maximum
|
||||
// and --block-list will simultaneously cause new Blocks
|
||||
// to be started at specified intervals. To keep things
|
||||
// logical, the same is done in single-threaded mode. The
|
||||
// output is still not identical because in single-threaded
|
||||
// mode the size info isn't written into Block Headers.
|
||||
if (opt_block_list != NULL) {
|
||||
if (block_remaining < opt_block_list[list_pos]) {
|
||||
assert(hardware_threads_get() == 1);
|
||||
next_block_remaining = opt_block_list[list_pos]
|
||||
- block_remaining;
|
||||
} else {
|
||||
block_remaining = opt_block_list[list_pos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strm.next_out = out_buf.u8;
|
||||
@@ -622,15 +715,13 @@ coder_normal(file_pair *pair)
|
||||
} else {
|
||||
// Start a new Block after LZMA_FULL_BARRIER.
|
||||
if (opt_block_list == NULL) {
|
||||
assert(hardware_threads_get() == 1);
|
||||
assert(opt_block_size > 0);
|
||||
block_remaining = opt_block_size;
|
||||
} else {
|
||||
// FIXME: Make it work together with
|
||||
// --block-size.
|
||||
if (opt_block_list[list_pos + 1] != 0)
|
||||
++list_pos;
|
||||
|
||||
block_remaining
|
||||
= opt_block_list[list_pos];
|
||||
split_block(&block_remaining,
|
||||
&next_block_remaining,
|
||||
&list_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "private.h"
|
||||
#include "tuklib_cpucores.h"
|
||||
|
||||
|
||||
/// Maximum number of worker threads. This can be set with
|
||||
@@ -33,10 +32,17 @@ hardware_threads_set(uint32_t n)
|
||||
{
|
||||
if (n == 0) {
|
||||
// Automatic number of threads was requested.
|
||||
// Use the number of available CPU cores.
|
||||
threads_max = tuklib_cpucores();
|
||||
// If threading support was enabled at build time,
|
||||
// use the number of available CPU cores. Otherwise
|
||||
// use one thread since disabling threading support
|
||||
// omits lzma_cputhreads() from liblzma.
|
||||
#ifdef MYTHREAD_ENABLED
|
||||
threads_max = lzma_cputhreads();
|
||||
if (threads_max == 0)
|
||||
threads_max = 1;
|
||||
#else
|
||||
threads_max = 1;
|
||||
#endif
|
||||
} else {
|
||||
threads_max = n;
|
||||
}
|
||||
|
||||
@@ -1122,6 +1122,8 @@ message_help(bool long_help)
|
||||
" `auto' (default), `xz', `lzma', and `raw'\n"
|
||||
" -C, --check=CHECK integrity check type: `none' (use with caution),\n"
|
||||
" `crc32', `crc64' (default), or `sha256'"));
|
||||
puts(_(
|
||||
" --ignore-check don't verify the integrity check when decompressing"));
|
||||
}
|
||||
|
||||
puts(_(
|
||||
@@ -1134,19 +1136,23 @@ message_help(bool long_help)
|
||||
|
||||
puts(_(
|
||||
" -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
|
||||
" to use the number of processor cores"));
|
||||
" to use as many threads as there are processor cores"));
|
||||
|
||||
if (long_help) {
|
||||
// FIXME? Mention something about threading?
|
||||
puts(_(
|
||||
" --block-size=SIZE\n"
|
||||
" when compressing to the .xz format, start a new block\n"
|
||||
" after every SIZE bytes of input; 0=disabled (default)"));
|
||||
// FIXME
|
||||
" start a new .xz block after every SIZE bytes of input;\n"
|
||||
" use this to set the block size for threaded compression"));
|
||||
puts(_(
|
||||
" --block-list=SIZES\n"
|
||||
" when compressing to the .xz format, start a new block\n"
|
||||
" after the given intervals of uncompressed data"));
|
||||
" start a new .xz block after the given comma-separated\n"
|
||||
" intervals of uncompressed data"));
|
||||
puts(_(
|
||||
" --flush-timeout=TIMEOUT\n"
|
||||
" when compressing, if more than TIMEOUT milliseconds has\n"
|
||||
" passed since the previous flush and reading more input\n"
|
||||
" would block, all pending data is flushed out"
|
||||
));
|
||||
puts(_( // xgettext:no-c-format
|
||||
" --memlimit-compress=LIMIT\n"
|
||||
" --memlimit-decompress=LIMIT\n"
|
||||
|
||||
@@ -82,17 +82,19 @@ signals_init(void)
|
||||
sigaddset(&hooked_signals, message_progress_sigs[i]);
|
||||
#endif
|
||||
|
||||
struct sigaction sa;
|
||||
// Using "my_sa" because "sa" may conflict with a sockaddr variable
|
||||
// from system headers on Solaris.
|
||||
struct sigaction my_sa;
|
||||
|
||||
// All the signals that we handle we also blocked while the signal
|
||||
// handler runs.
|
||||
sa.sa_mask = hooked_signals;
|
||||
my_sa.sa_mask = hooked_signals;
|
||||
|
||||
// Don't set SA_RESTART, because we want EINTR so that we can check
|
||||
// for user_abort and cleanup before exiting. We block the signals
|
||||
// for which we have established a handler when we don't want EINTR.
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = &signal_handler;
|
||||
my_sa.sa_flags = 0;
|
||||
my_sa.sa_handler = &signal_handler;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(sigs); ++i) {
|
||||
// If the parent process has left some signals ignored,
|
||||
@@ -103,7 +105,7 @@ signals_init(void)
|
||||
continue;
|
||||
|
||||
// Establish the signal handler.
|
||||
if (sigaction(sigs[i], &sa, NULL))
|
||||
if (sigaction(sigs[i], &my_sa, NULL))
|
||||
message_signal_handler();
|
||||
}
|
||||
|
||||
|
||||
@@ -390,7 +390,7 @@ suffix_set(const char *suffix)
|
||||
// Empty suffix and suffixes having a directory separator are
|
||||
// rejected. Such suffixes would break things later.
|
||||
if (suffix[0] == '\0' || has_dir_sep(suffix))
|
||||
message_fatal(_("%s: Invalid filename suffix"), optarg);
|
||||
message_fatal(_("%s: Invalid filename suffix"), suffix);
|
||||
|
||||
// Replace the old custom_suffix (if any) with the new suffix.
|
||||
free(custom_suffix);
|
||||
|
||||
43
src/xz/xz.1
43
src/xz/xz.1
@@ -5,7 +5,7 @@
|
||||
.\" This file has been put into the public domain.
|
||||
.\" You can do whatever you want with this file.
|
||||
.\"
|
||||
.TH XZ 1 "2013-10-25" "Tukaani" "XZ Utils"
|
||||
.TH XZ 1 "2013-11-12" "Tukaani" "XZ Utils"
|
||||
.
|
||||
.SH NAME
|
||||
xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
|
||||
@@ -609,6 +609,25 @@ Integrity of the
|
||||
headers is always verified with CRC32.
|
||||
It is not possible to change or disable it.
|
||||
.TP
|
||||
.B \-\-ignore\-check
|
||||
Don't verify the integrity check of the compressed data when decompressing.
|
||||
The CRC32 values in the
|
||||
.B .xz
|
||||
headers will still be verified normally.
|
||||
.IP ""
|
||||
.B "Do not use this option unless you know what you are doing."
|
||||
Possible reasons to use this option:
|
||||
.RS
|
||||
.IP \(bu 3
|
||||
Trying to recover data from a corrupt .xz file.
|
||||
.IP \(bu 3
|
||||
Speeding up decompression.
|
||||
This matters mostly with SHA-256 or
|
||||
with files that have compressed extremely well.
|
||||
It's recommended to not use this option for this purpose
|
||||
unless the file integrity is verified externally in some other way.
|
||||
.RE
|
||||
.TP
|
||||
.BR \-0 " ... " \-9
|
||||
Select a compression preset level.
|
||||
The default is
|
||||
@@ -809,6 +828,12 @@ format, split the input data into blocks of
|
||||
bytes.
|
||||
The blocks are compressed independently from each other.
|
||||
.\" FIXME: Explain how to these can be used for random access and threading.
|
||||
.IP ""
|
||||
In multi-threaded mode the sizes of the blocks
|
||||
are stored in the block headers.
|
||||
This isn't done in single-threaded mode,
|
||||
so the encoded output won't be
|
||||
identical to that of the multi-threaded mode.
|
||||
.TP
|
||||
.BI \-\-block\-list= sizes
|
||||
When compressing to the
|
||||
@@ -832,26 +857,26 @@ A special value of
|
||||
may be used as the last value to indicate that
|
||||
the rest of the file should be encoded as a single block.
|
||||
.IP ""
|
||||
If this option is used in threaded mode and one specifies
|
||||
If one specifies
|
||||
.I sizes
|
||||
that exceed the encoder's block size
|
||||
(either the default value or the value specified
|
||||
with \fB\-\-block\-size=\fIsize\fR),
|
||||
(either the default value in threaded mode or
|
||||
the value specified with \fB\-\-block\-size=\fIsize\fR),
|
||||
the encoder will create additional blocks while
|
||||
keeping the boundaries specified in
|
||||
.IR sizes .
|
||||
For example, if one specifies
|
||||
.B \-\-threads=2
|
||||
.B \-\-block\-size=10MiB
|
||||
.B \-\-block\-list=5MiB,10MiB,8MiB,12MiB,24MiB
|
||||
and the input file is 80 MiB,
|
||||
one will get 11 blocks:
|
||||
5, 10, 8, 10, 2, 10, 10, 4, 10, 10, and 1 MiB.
|
||||
.IP ""
|
||||
.\" FIXME
|
||||
.B "In single-threaded mode \-\-block\-size is ignored"
|
||||
.B "if \-\-block\-list is also specified."
|
||||
.B "This might change before 5.2.0 is released."
|
||||
In multi-threaded mode the sizes of the blocks
|
||||
are stored in the block headers.
|
||||
This isn't done in single-threaded mode,
|
||||
so the encoded output won't be
|
||||
identical to that of the multi-threaded mode.
|
||||
.TP
|
||||
.BI \-\-flush\-timeout= timeout
|
||||
When compressing, if more than
|
||||
|
||||
@@ -59,7 +59,14 @@ endif
|
||||
if COND_LZMADEC
|
||||
bin_PROGRAMS += lzmadec
|
||||
|
||||
# FIXME: If xzdec is disabled, this will create a dangling symlink.
|
||||
# Create the symlink lzmadec.1->xzdec.1 only if xzdec.1 was installed.
|
||||
# This is better than creating a dangling symlink, especially
|
||||
# because creating the link may fail due to the directory being missing.
|
||||
#
|
||||
# FIXME: The correct solution would be to install xzdec.1 as lzmadec.1
|
||||
# but I don't know what is the sane way to do it and since this is a bit
|
||||
# unusual situation anyway, it's not that important.
|
||||
if COND_XZDEC
|
||||
install-data-hook:
|
||||
cd $(DESTDIR)$(mandir)/man1 && \
|
||||
target=`echo xzdec | sed '$(transform)'` && \
|
||||
@@ -72,3 +79,4 @@ uninstall-hook:
|
||||
link=`echo lzmadec | sed '$(transform)'` && \
|
||||
rm -f $$link.1
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -13,7 +13,8 @@ EXTRA_DIST = \
|
||||
test_scripts.sh \
|
||||
bcj_test.c \
|
||||
compress_prepared_bcj_sparc \
|
||||
compress_prepared_bcj_x86
|
||||
compress_prepared_bcj_x86 \
|
||||
xzgrep_expected_output
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/common \
|
||||
@@ -52,4 +53,5 @@ TESTS += test_scripts.sh
|
||||
endif
|
||||
|
||||
clean-local:
|
||||
-rm -f compress_generated_*
|
||||
-rm -f compress_generated_* \
|
||||
xzgrep_test_output xzgrep_test_1.xz xzgrep_test_2.xz
|
||||
|
||||
@@ -12,16 +12,18 @@
|
||||
# If scripts weren't built, this test is skipped.
|
||||
XZ=../src/xz/xz
|
||||
XZDIFF=../src/scripts/xzdiff
|
||||
test -x "$XZ" || XZ=
|
||||
test -x "$XZDIFF" || XZDIFF=
|
||||
if test -z "$XZ" || test -z "$XZDIFF"; then
|
||||
XZGREP=../src/scripts/xzgrep
|
||||
|
||||
for i in XZ XZDIFF XZGREP; do
|
||||
eval test -x "\$$i" && continue
|
||||
(exit 77)
|
||||
exit 77
|
||||
fi
|
||||
done
|
||||
|
||||
PATH=`pwd`/../src/xz:$PATH
|
||||
export PATH
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
preimage=$srcdir/files/good-1-check-crc32.xz
|
||||
samepostimage=$srcdir/files/good-1-check-crc64.xz
|
||||
otherpostimage=$srcdir/files/good-1-lzma2-1.xz
|
||||
@@ -50,5 +52,25 @@ if test "$status" != 2 ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The exit status must be 0 when a match was found at least from one file,
|
||||
# and 1 when no match was found in any file.
|
||||
cp "$srcdir/files/good-1-lzma2-1.xz" xzgrep_test_1.xz
|
||||
cp "$srcdir/files/good-2-lzma2.xz" xzgrep_test_2.xz
|
||||
for pattern in el Hello NOMATCH; do
|
||||
for opts in "" "-l" "-h" "-H"; do
|
||||
echo "=> xzgrep $opts $pattern <="
|
||||
"$XZGREP" $opts $pattern xzgrep_test_1.xz xzgrep_test_2.xz
|
||||
echo retval $?
|
||||
done
|
||||
done > xzgrep_test_output 2>&1
|
||||
|
||||
if cmp -s "$srcdir/xzgrep_expected_output" xzgrep_test_output ; then
|
||||
:
|
||||
else
|
||||
echo "unexpected output from xzgrep"
|
||||
(exit 1)
|
||||
exit 1
|
||||
fi
|
||||
|
||||
(exit 0)
|
||||
exit 0
|
||||
|
||||
39
tests/xzgrep_expected_output
Normal file
39
tests/xzgrep_expected_output
Normal file
@@ -0,0 +1,39 @@
|
||||
=> xzgrep el <=
|
||||
xzgrep_test_1.xz:elit, sed do eiusmod tempor incididunt ut
|
||||
xzgrep_test_1.xz:in voluptate velit esse cillum dolore eu
|
||||
xzgrep_test_2.xz:Hello
|
||||
retval 0
|
||||
=> xzgrep -l el <=
|
||||
xzgrep_test_1.xz
|
||||
xzgrep_test_2.xz
|
||||
retval 0
|
||||
=> xzgrep -h el <=
|
||||
elit, sed do eiusmod tempor incididunt ut
|
||||
in voluptate velit esse cillum dolore eu
|
||||
Hello
|
||||
retval 0
|
||||
=> xzgrep -H el <=
|
||||
xzgrep_test_1.xz:elit, sed do eiusmod tempor incididunt ut
|
||||
xzgrep_test_1.xz:in voluptate velit esse cillum dolore eu
|
||||
xzgrep_test_2.xz:Hello
|
||||
retval 0
|
||||
=> xzgrep Hello <=
|
||||
xzgrep_test_2.xz:Hello
|
||||
retval 0
|
||||
=> xzgrep -l Hello <=
|
||||
xzgrep_test_2.xz
|
||||
retval 0
|
||||
=> xzgrep -h Hello <=
|
||||
Hello
|
||||
retval 0
|
||||
=> xzgrep -H Hello <=
|
||||
xzgrep_test_2.xz:Hello
|
||||
retval 0
|
||||
=> xzgrep NOMATCH <=
|
||||
retval 1
|
||||
=> xzgrep -l NOMATCH <=
|
||||
retval 1
|
||||
=> xzgrep -h NOMATCH <=
|
||||
retval 1
|
||||
=> xzgrep -H NOMATCH <=
|
||||
retval 1
|
||||
139
windows/config.h
Normal file
139
windows/config.h
Normal file
@@ -0,0 +1,139 @@
|
||||
/* config.h for compiling liblzma (*not* the whole XZ Utils) with MSVC 2013 */
|
||||
|
||||
/* How many MiB of RAM to assume if the real amount cannot be determined. */
|
||||
#define ASSUME_RAM 128
|
||||
|
||||
/* Define to 1 if crc32 integrity check is enabled. */
|
||||
#define HAVE_CHECK_CRC32 1
|
||||
|
||||
/* Define to 1 if crc64 integrity check is enabled. */
|
||||
#define HAVE_CHECK_CRC64 1
|
||||
|
||||
/* Define to 1 if sha256 integrity check is enabled. */
|
||||
#define HAVE_CHECK_SHA256 1
|
||||
|
||||
/* Define to 1 if arm decoder is enabled. */
|
||||
#define HAVE_DECODER_ARM 1
|
||||
|
||||
/* Define to 1 if armthumb decoder is enabled. */
|
||||
#define HAVE_DECODER_ARMTHUMB 1
|
||||
|
||||
/* Define to 1 if delta decoder is enabled. */
|
||||
#define HAVE_DECODER_DELTA 1
|
||||
|
||||
/* Define to 1 if ia64 decoder is enabled. */
|
||||
#define HAVE_DECODER_IA64 1
|
||||
|
||||
/* Define to 1 if lzma1 decoder is enabled. */
|
||||
#define HAVE_DECODER_LZMA1 1
|
||||
|
||||
/* Define to 1 if lzma2 decoder is enabled. */
|
||||
#define HAVE_DECODER_LZMA2 1
|
||||
|
||||
/* Define to 1 if powerpc decoder is enabled. */
|
||||
#define HAVE_DECODER_POWERPC 1
|
||||
|
||||
/* Define to 1 if sparc decoder is enabled. */
|
||||
#define HAVE_DECODER_SPARC 1
|
||||
|
||||
/* Define to 1 if x86 decoder is enabled. */
|
||||
#define HAVE_DECODER_X86 1
|
||||
|
||||
/* Define to 1 if arm encoder is enabled. */
|
||||
#define HAVE_ENCODER_ARM 1
|
||||
|
||||
/* Define to 1 if armthumb encoder is enabled. */
|
||||
#define HAVE_ENCODER_ARMTHUMB 1
|
||||
|
||||
/* Define to 1 if delta encoder is enabled. */
|
||||
#define HAVE_ENCODER_DELTA 1
|
||||
|
||||
/* Define to 1 if ia64 encoder is enabled. */
|
||||
#define HAVE_ENCODER_IA64 1
|
||||
|
||||
/* Define to 1 if lzma1 encoder is enabled. */
|
||||
#define HAVE_ENCODER_LZMA1 1
|
||||
|
||||
/* Define to 1 if lzma2 encoder is enabled. */
|
||||
#define HAVE_ENCODER_LZMA2 1
|
||||
|
||||
/* Define to 1 if powerpc encoder is enabled. */
|
||||
#define HAVE_ENCODER_POWERPC 1
|
||||
|
||||
/* Define to 1 if sparc encoder is enabled. */
|
||||
#define HAVE_ENCODER_SPARC 1
|
||||
|
||||
/* Define to 1 if x86 encoder is enabled. */
|
||||
#define HAVE_ENCODER_X86 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 to enable bt2 match finder. */
|
||||
#define HAVE_MF_BT2 1
|
||||
|
||||
/* Define to 1 to enable bt3 match finder. */
|
||||
#define HAVE_MF_BT3 1
|
||||
|
||||
/* Define to 1 to enable bt4 match finder. */
|
||||
#define HAVE_MF_BT4 1
|
||||
|
||||
/* Define to 1 to enable hc3 match finder. */
|
||||
#define HAVE_MF_HC3 1
|
||||
|
||||
/* Define to 1 to enable hc4 match finder. */
|
||||
#define HAVE_MF_HC4 1
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 or 0, depending whether the compiler supports simple visibility
|
||||
declarations. */
|
||||
#define HAVE_VISIBILITY 0
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
#ifdef _M_IX86
|
||||
/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This
|
||||
avoids use of features that were added in Windows Vista.
|
||||
This is used for 32-bit x86 builds for compatibility reasons since it
|
||||
makes no measurable difference in performance compared to Vista threads. */
|
||||
#define MYTHREAD_WIN95 1
|
||||
#else
|
||||
/* Define to 1 when using Windows Vista compatible threads. This uses features
|
||||
that are not available on Windows XP. */
|
||||
#define MYTHREAD_VISTA 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 to disable debugging code. */
|
||||
#define NDEBUG 1
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "XZ Utils"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "http://tukaani.org/xz/"
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#ifdef _WIN64
|
||||
#define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the system supports fast unaligned access to 16-bit and
|
||||
32-bit integers. */
|
||||
#define TUKLIB_FAST_UNALIGNED_ACCESS 1
|
||||
Reference in New Issue
Block a user