lzma-static (empty) → 5.2.5
raw patch · 166 files changed
+31730/−0 lines, 166 filesdep +HUnitdep +QuickCheckdep +basesetup-changed
Dependencies added: HUnit, QuickCheck, base, bytestring, lzma-static, tasty, tasty-hunit, tasty-quickcheck, unbuildable
Files
- Changelog.md +3/−0
- LICENSE +30/−0
- Setup.hs +2/−0
- autoconf-darwin/config.h +487/−0
- autoconf-linux/config.h +486/−0
- autoconf-win32/config.h +497/−0
- cbits/common/mythread.h +521/−0
- cbits/common/sysdefs.h +199/−0
- cbits/common/tuklib_common.h +71/−0
- cbits/common/tuklib_config.h +7/−0
- cbits/common/tuklib_cpucores.c +100/−0
- cbits/common/tuklib_cpucores.h +23/−0
- cbits/common/tuklib_exit.c +58/−0
- cbits/common/tuklib_exit.h +25/−0
- cbits/common/tuklib_gettext.h +44/−0
- cbits/common/tuklib_integer.h +742/−0
- cbits/common/tuklib_mbstr.h +66/−0
- cbits/common/tuklib_mbstr_fw.c +31/−0
- cbits/common/tuklib_mbstr_width.c +65/−0
- cbits/common/tuklib_open_stdxxx.c +57/−0
- cbits/common/tuklib_open_stdxxx.h +23/−0
- cbits/common/tuklib_physmem.c +216/−0
- cbits/common/tuklib_physmem.h +28/−0
- cbits/common/tuklib_progname.c +50/−0
- cbits/common/tuklib_progname.h +32/−0
- cbits/liblzma/api/lzma.h +326/−0
- cbits/liblzma/api/lzma/base.h +659/−0
- cbits/liblzma/api/lzma/bcj.h +90/−0
- cbits/liblzma/api/lzma/block.h +581/−0
- cbits/liblzma/api/lzma/check.h +150/−0
- cbits/liblzma/api/lzma/container.h +632/−0
- cbits/liblzma/api/lzma/delta.h +77/−0
- cbits/liblzma/api/lzma/filter.h +426/−0
- cbits/liblzma/api/lzma/hardware.h +64/−0
- cbits/liblzma/api/lzma/index.h +686/−0
- cbits/liblzma/api/lzma/index_hash.h +107/−0
- cbits/liblzma/api/lzma/lzma12.h +420/−0
- cbits/liblzma/api/lzma/stream_flags.h +223/−0
- cbits/liblzma/api/lzma/version.h +121/−0
- cbits/liblzma/api/lzma/vli.h +166/−0
- cbits/liblzma/check/check.c +174/−0
- cbits/liblzma/check/check.h +172/−0
- cbits/liblzma/check/crc32_fast.c +82/−0
- cbits/liblzma/check/crc32_small.c +61/−0
- cbits/liblzma/check/crc32_table.c +22/−0
- cbits/liblzma/check/crc32_table_be.h +525/−0
- cbits/liblzma/check/crc32_table_le.h +525/−0
- cbits/liblzma/check/crc32_tablegen.c +117/−0
- cbits/liblzma/check/crc64_fast.c +72/−0
- cbits/liblzma/check/crc64_small.c +53/−0
- cbits/liblzma/check/crc64_table.c +22/−0
- cbits/liblzma/check/crc64_table_be.h +521/−0
- cbits/liblzma/check/crc64_table_le.h +521/−0
- cbits/liblzma/check/crc64_tablegen.c +88/−0
- cbits/liblzma/check/crc_macros.h +30/−0
- cbits/liblzma/check/sha256.c +196/−0
- cbits/liblzma/common/alone_decoder.c +242/−0
- cbits/liblzma/common/alone_decoder.h +23/−0
- cbits/liblzma/common/alone_encoder.c +162/−0
- cbits/liblzma/common/auto_decoder.c +195/−0
- cbits/liblzma/common/block_buffer_decoder.c +80/−0
- cbits/liblzma/common/block_buffer_encoder.c +337/−0
- cbits/liblzma/common/block_buffer_encoder.h +24/−0
- cbits/liblzma/common/block_decoder.c +257/−0
- cbits/liblzma/common/block_decoder.h +22/−0
- cbits/liblzma/common/block_encoder.c +223/−0
- cbits/liblzma/common/block_encoder.h +47/−0
- cbits/liblzma/common/block_header_decoder.c +124/−0
- cbits/liblzma/common/block_header_encoder.c +132/−0
- cbits/liblzma/common/block_util.c +90/−0
- cbits/liblzma/common/common.c +449/−0
- cbits/liblzma/common/common.h +314/−0
- cbits/liblzma/common/easy_buffer_encoder.c +27/−0
- cbits/liblzma/common/easy_decoder_memusage.c +24/−0
- cbits/liblzma/common/easy_encoder.c +24/−0
- cbits/liblzma/common/easy_encoder_memusage.c +24/−0
- cbits/liblzma/common/easy_preset.c +27/−0
- cbits/liblzma/common/easy_preset.h +32/−0
- cbits/liblzma/common/filter_buffer_decoder.c +88/−0
- cbits/liblzma/common/filter_buffer_encoder.c +55/−0
- cbits/liblzma/common/filter_common.c +337/−0
- cbits/liblzma/common/filter_common.h +48/−0
- cbits/liblzma/common/filter_decoder.c +184/−0
- cbits/liblzma/common/filter_decoder.h +23/−0
- cbits/liblzma/common/filter_encoder.c +286/−0
- cbits/liblzma/common/filter_encoder.h +27/−0
- cbits/liblzma/common/filter_flags_decoder.c +46/−0
- cbits/liblzma/common/filter_flags_encoder.c +56/−0
- cbits/liblzma/common/hardware_cputhreads.c +22/−0
- cbits/liblzma/common/hardware_physmem.c +25/−0
- cbits/liblzma/common/index.c +1250/−0
- cbits/liblzma/common/index.h +73/−0
- cbits/liblzma/common/index_decoder.c +352/−0
- cbits/liblzma/common/index_encoder.c +256/−0
- cbits/liblzma/common/index_encoder.h +23/−0
- cbits/liblzma/common/index_hash.c +334/−0
- cbits/liblzma/common/memcmplen.h +164/−0
- cbits/liblzma/common/outqueue.c +184/−0
- cbits/liblzma/common/outqueue.h +156/−0
- cbits/liblzma/common/stream_buffer_decoder.c +91/−0
- cbits/liblzma/common/stream_buffer_encoder.c +141/−0
- cbits/liblzma/common/stream_decoder.c +467/−0
- cbits/liblzma/common/stream_decoder.h +22/−0
- cbits/liblzma/common/stream_encoder.c +340/−0
- cbits/liblzma/common/stream_encoder_mt.c +1143/−0
- cbits/liblzma/common/stream_flags_common.c +47/−0
- cbits/liblzma/common/stream_flags_common.h +33/−0
- cbits/liblzma/common/stream_flags_decoder.c +82/−0
- cbits/liblzma/common/stream_flags_encoder.c +86/−0
- cbits/liblzma/common/vli_decoder.c +86/−0
- cbits/liblzma/common/vli_encoder.c +69/−0
- cbits/liblzma/common/vli_size.c +30/−0
- cbits/liblzma/delta/delta_common.c +73/−0
- cbits/liblzma/delta/delta_common.h +20/−0
- cbits/liblzma/delta/delta_decoder.c +78/−0
- cbits/liblzma/delta/delta_decoder.h +26/−0
- cbits/liblzma/delta/delta_encoder.c +125/−0
- cbits/liblzma/delta/delta_encoder.h +24/−0
- cbits/liblzma/delta/delta_private.h +37/−0
- cbits/liblzma/lz/lz_decoder.c +311/−0
- cbits/liblzma/lz/lz_decoder.h +234/−0
- cbits/liblzma/lz/lz_encoder.c +616/−0
- cbits/liblzma/lz/lz_encoder.h +327/−0
- cbits/liblzma/lz/lz_encoder_hash.h +108/−0
- cbits/liblzma/lz/lz_encoder_hash_table.h +68/−0
- cbits/liblzma/lz/lz_encoder_mf.c +744/−0
- cbits/liblzma/lzma/fastpos.h +141/−0
- cbits/liblzma/lzma/fastpos_table.c +519/−0
- cbits/liblzma/lzma/fastpos_tablegen.c +55/−0
- cbits/liblzma/lzma/lzma2_decoder.c +310/−0
- cbits/liblzma/lzma/lzma2_decoder.h +29/−0
- cbits/liblzma/lzma/lzma2_encoder.c +410/−0
- cbits/liblzma/lzma/lzma2_encoder.h +43/−0
- cbits/liblzma/lzma/lzma_common.h +225/−0
- cbits/liblzma/lzma/lzma_decoder.c +1064/−0
- cbits/liblzma/lzma/lzma_decoder.h +53/−0
- cbits/liblzma/lzma/lzma_encoder.c +677/−0
- cbits/liblzma/lzma/lzma_encoder.h +58/−0
- cbits/liblzma/lzma/lzma_encoder_optimum_fast.c +170/−0
- cbits/liblzma/lzma/lzma_encoder_optimum_normal.c +859/−0
- cbits/liblzma/lzma/lzma_encoder_presets.c +64/−0
- cbits/liblzma/lzma/lzma_encoder_private.h +147/−0
- cbits/liblzma/rangecoder/price.h +92/−0
- cbits/liblzma/rangecoder/price_table.c +22/−0
- cbits/liblzma/rangecoder/price_tablegen.c +87/−0
- cbits/liblzma/rangecoder/range_common.h +71/−0
- cbits/liblzma/rangecoder/range_decoder.h +185/−0
- cbits/liblzma/rangecoder/range_encoder.h +231/−0
- cbits/liblzma/simple/arm.c +71/−0
- cbits/liblzma/simple/armthumb.c +76/−0
- cbits/liblzma/simple/ia64.c +112/−0
- cbits/liblzma/simple/powerpc.c +76/−0
- cbits/liblzma/simple/simple_coder.c +290/−0
- cbits/liblzma/simple/simple_coder.h +72/−0
- cbits/liblzma/simple/simple_decoder.c +40/−0
- cbits/liblzma/simple/simple_decoder.h +22/−0
- cbits/liblzma/simple/simple_encoder.c +38/−0
- cbits/liblzma/simple/simple_encoder.h +23/−0
- cbits/liblzma/simple/simple_private.h +74/−0
- cbits/liblzma/simple/sparc.c +83/−0
- cbits/liblzma/simple/x86.c +159/−0
- cbits/lzma_wrapper.c +65/−0
- lzma-static.cabal +200/−0
- src-tests/lzma-tests.hs +98/−0
- src/Codec/Compression/Lzma.hs +400/−0
- src/LibLzma.hsc +251/−0
+ Changelog.md view
@@ -0,0 +1,3 @@+## 0.0.0.3++* Fix potential reentrancy issue also discovered in `zlib` ([#4](https://github.com/hvr/lzma/issues/4))
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015, Herbert Valerio Riedel++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Herbert Valerio Riedel nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ autoconf-darwin/config.h view
@@ -0,0 +1,487 @@+/* config.h. Generated from config.h.in by configure. */+/* config.h.in. Generated from configure.ac by autoheader. */++/* Define if building universal (internal helper macro) */+/* #undef AC_APPLE_UNIVERSAL_BUILD */++/* How many MiB of RAM to assume if the real amount cannot be determined. */+#define ASSUME_RAM 128++/* Define to 1 if translation of program messages to the user's native+ language is requested. */+#define ENABLE_NLS 1++/* Define to 1 if bswap_16 is available. */+/* #undef HAVE_BSWAP_16 */++/* Define to 1 if bswap_32 is available. */+/* #undef HAVE_BSWAP_32 */++/* Define to 1 if bswap_64 is available. */+/* #undef HAVE_BSWAP_64 */++/* Define to 1 if you have the <byteswap.h> header file. */+/* #undef HAVE_BYTESWAP_H */++/* Define to 1 if the system has the type `CC_SHA256_CTX'. */+/* #undef HAVE_CC_SHA256_CTX */++/* Define to 1 if you have the `CC_SHA256_Init' function. */+/* #undef HAVE_CC_SHA256_INIT */++/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the+ CoreFoundation framework. */+#define HAVE_CFLOCALECOPYCURRENT 1++/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in+ the CoreFoundation framework. */+#define HAVE_CFPREFERENCESCOPYAPPVALUE 1++/* 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 you have the `clock_gettime' function. */+/* #undef HAVE_CLOCK_GETTIME */++/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */+#define HAVE_COMMONCRYPTO_COMMONDIGEST_H 1++/* Define if the GNU dcgettext() function is already present or preinstalled.+ */+#define HAVE_DCGETTEXT 1++/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if+ you don't. */+/* #undef HAVE_DECL_CLOCK_MONOTONIC */++/* Define to 1 if you have the declaration of `program_invocation_name', and+ to 0 if you don't. */+#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0++/* 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 you have the <dlfcn.h> header file. */+#define HAVE_DLFCN_H 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 <fcntl.h> header file. */+#define HAVE_FCNTL_H 1++/* Define to 1 if you have the `futimens' function. */+#define HAVE_FUTIMENS 1++/* Define to 1 if you have the `futimes' function. */+/* #undef HAVE_FUTIMES */++/* Define to 1 if you have the `futimesat' function. */+/* #undef HAVE_FUTIMESAT */++/* Define to 1 if you have the <getopt.h> header file. */+#define HAVE_GETOPT_H 1++/* Define to 1 if you have the `getopt_long' function. */+#define HAVE_GETOPT_LONG 1++/* Define if the GNU gettext() function is already present or preinstalled. */+#define HAVE_GETTEXT 1++/* Define if you have the iconv() function and it works. */+#define HAVE_ICONV 1++/* Define to 1 if you have the <immintrin.h> header file. */+#define HAVE_IMMINTRIN_H 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 if mbrtowc and mbstate_t are properly declared. */+#define HAVE_MBRTOWC 1++/* Define to 1 if you have the <memory.h> header file. */+#define HAVE_MEMORY_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 you have the <minix/sha2.h> header file. */+/* #undef HAVE_MINIX_SHA2_H */++/* Define to 1 if getopt.h declares extern int optreset. */+#define HAVE_OPTRESET 1++/* Define to 1 if you have the `posix_fadvise' function. */+/* #undef HAVE_POSIX_FADVISE */++/* Define to 1 if you have the `pthread_condattr_setclock' function. */+/* #undef HAVE_PTHREAD_CONDATTR_SETCLOCK */++/* Have PTHREAD_PRIO_INHERIT. */+#define HAVE_PTHREAD_PRIO_INHERIT 1++/* Define to 1 if you have the `SHA256Init' function. */+/* #undef HAVE_SHA256INIT */++/* Define to 1 if the system has the type `SHA256_CTX'. */+/* #undef HAVE_SHA256_CTX */++/* Define to 1 if you have the <sha256.h> header file. */+/* #undef HAVE_SHA256_H */++/* Define to 1 if you have the `SHA256_Init' function. */+/* #undef HAVE_SHA256_INIT */++/* Define to 1 if the system has the type `SHA2_CTX'. */+/* #undef HAVE_SHA2_CTX */++/* Define to 1 if you have the <sha2.h> header file. */+/* #undef HAVE_SHA2_H */++/* Define to 1 if optimizing for size. */+/* #undef HAVE_SMALL */++/* 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 <strings.h> header file. */+#define HAVE_STRINGS_H 1++/* Define to 1 if you have the <string.h> header file. */+#define HAVE_STRING_H 1++/* Define to 1 if `st_atimensec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */++/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */+#define HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC 1++/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */++/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */++/* Define to 1 if `st_uatime' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_UATIME */++/* Define to 1 if you have the <sys/byteorder.h> header file. */+/* #undef HAVE_SYS_BYTEORDER_H */++/* Define to 1 if you have the <sys/endian.h> header file. */+/* #undef HAVE_SYS_ENDIAN_H */++/* Define to 1 if you have the <sys/param.h> header file. */+#define HAVE_SYS_PARAM_H 1++/* Define to 1 if you have the <sys/stat.h> header file. */+#define HAVE_SYS_STAT_H 1++/* Define to 1 if you have the <sys/time.h> header file. */+#define HAVE_SYS_TIME_H 1++/* Define to 1 if you have the <sys/types.h> header file. */+#define HAVE_SYS_TYPES_H 1++/* Define to 1 if the system has the type `uintptr_t'. */+#define HAVE_UINTPTR_T 1++/* Define to 1 if you have the <unistd.h> header file. */+#define HAVE_UNISTD_H 1++/* Define to 1 if you have the `utime' function. */+/* #undef HAVE_UTIME */++/* Define to 1 if you have the `utimes' function. */+/* #undef HAVE_UTIMES */++/* Define to 1 or 0, depending whether the compiler supports simple visibility+ declarations. */+#define HAVE_VISIBILITY 1++/* Define to 1 if you have the `wcwidth' function. */+#define HAVE_WCWIDTH 1++/* Define to 1 if the system has the type `_Bool'. */+#define HAVE__BOOL 1++/* Define to 1 if _mm_movemask_epi8 is available. */+#define HAVE__MM_MOVEMASK_EPI8 1++/* Define to the sub-directory where libtool stores uninstalled libraries. */+#define LT_OBJDIR ".libs/"++/* Define to 1 when using POSIX threads (pthreads). */+#define MYTHREAD_POSIX 1++/* Define to 1 when using Windows Vista compatible threads. This uses features+ that are not available on Windows XP. */+/* #undef MYTHREAD_VISTA */++/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This+ avoids use of features that were added in Windows Vista. */+/* #undef MYTHREAD_WIN95 */++/* Define to 1 to disable debugging code. */+#define NDEBUG 1++/* Name of package */+#define PACKAGE "xz"++/* Define to the address where bug reports for this package should be sent. */+#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org"++/* Define to the full name of this package. */+#define PACKAGE_NAME "XZ Utils"++/* Define to the full name and version of this package. */+#define PACKAGE_STRING "XZ Utils 5.2.2"++/* Define to the one symbol short name of this package. */+#define PACKAGE_TARNAME "xz"++/* Define to the home page for this package. */+#define PACKAGE_URL "http://tukaani.org/xz/"++/* Define to the version of this package. */+#define PACKAGE_VERSION "5.2.2"++/* Define to necessary symbol if this constant uses a non-standard name on+ your system. */+/* #undef PTHREAD_CREATE_JOINABLE */++/* The size of `size_t', as computed by sizeof. */+#define SIZEOF_SIZE_T 8++/* Define to 1 if you have the ANSI C header files. */+#define STDC_HEADERS 1++/* Define to 1 if the number of available CPU cores can be detected with+ cpuset(2). */+/* #undef TUKLIB_CPUCORES_CPUSET */++/* Define to 1 if the number of available CPU cores can be detected with+ pstat_getdynamic(). */+/* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */++/* Define to 1 if the number of available CPU cores can be detected with+ sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */+/* #undef TUKLIB_CPUCORES_SYSCONF */++/* Define to 1 if the number of available CPU cores can be detected with+ sysctl(). */+#define TUKLIB_CPUCORES_SYSCTL 1++/* Define to 1 if the system supports fast unaligned access to 16-bit and+ 32-bit integers. */+#define TUKLIB_FAST_UNALIGNED_ACCESS 1++/* Define to 1 if the amount of physical memory can be detected with+ _system_configuration.physmem. */+/* #undef TUKLIB_PHYSMEM_AIX */++/* Define to 1 if the amount of physical memory can be detected with+ getinvent_r(). */+/* #undef TUKLIB_PHYSMEM_GETINVENT_R */++/* Define to 1 if the amount of physical memory can be detected with+ getsysinfo(). */+/* #undef TUKLIB_PHYSMEM_GETSYSINFO */++/* Define to 1 if the amount of physical memory can be detected with+ pstat_getstatic(). */+/* #undef TUKLIB_PHYSMEM_PSTAT_GETSTATIC */++/* Define to 1 if the amount of physical memory can be detected with+ sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES). */+#define TUKLIB_PHYSMEM_SYSCONF 1++/* Define to 1 if the amount of physical memory can be detected with sysctl().+ */+/* #undef TUKLIB_PHYSMEM_SYSCTL */++/* Define to 1 if the amount of physical memory can be detected with Linux+ sysinfo(). */+/* #undef TUKLIB_PHYSMEM_SYSINFO */++/* Enable extensions on AIX 3, Interix. */+#ifndef _ALL_SOURCE+# define _ALL_SOURCE 1+#endif+/* Enable GNU extensions on systems that have them. */+#ifndef _GNU_SOURCE+# define _GNU_SOURCE 1+#endif+/* Enable threading extensions on Solaris. */+#ifndef _POSIX_PTHREAD_SEMANTICS+# define _POSIX_PTHREAD_SEMANTICS 1+#endif+/* Enable extensions on HP NonStop. */+#ifndef _TANDEM_SOURCE+# define _TANDEM_SOURCE 1+#endif+/* Enable general extensions on Solaris. */+#ifndef __EXTENSIONS__+# define __EXTENSIONS__ 1+#endif+++/* Version number of package */+#define VERSION "5.2.2"++/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most+ significant byte first (like Motorola and SPARC, unlike Intel). */+#if defined AC_APPLE_UNIVERSAL_BUILD+# if defined __BIG_ENDIAN__+# define WORDS_BIGENDIAN 1+# endif+#else+# ifndef WORDS_BIGENDIAN+/* # undef WORDS_BIGENDIAN */+# endif+#endif++/* Enable large inode numbers on Mac OS X 10.5. */+#ifndef _DARWIN_USE_64_BIT_INODE+# define _DARWIN_USE_64_BIT_INODE 1+#endif++/* Number of bits in a file offset, on hosts where this is settable. */+/* #undef _FILE_OFFSET_BITS */++/* Define for large files, on AIX-style hosts. */+/* #undef _LARGE_FILES */++/* Define to 1 if on MINIX. */+/* #undef _MINIX */++/* Define to 2 if the system does not provide POSIX.1 features except with+ this defined. */+/* #undef _POSIX_1_SOURCE */++/* Define to 1 if you need to in order for `stat' and other things to work. */+/* #undef _POSIX_SOURCE */++/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT32_T */++/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT64_T */++/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT8_T */++/* Define to rpl_ if the getopt replacement functions and variables should be+ used. */+/* #undef __GETOPT_PREFIX */++/* Define to the type of a signed integer type of width exactly 32 bits if+ such a type exists and the standard includes do not define it. */+/* #undef int32_t */++/* Define to the type of a signed integer type of width exactly 64 bits if+ such a type exists and the standard includes do not define it. */+/* #undef int64_t */++/* Define to the type of an unsigned integer type of width exactly 16 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint16_t */++/* Define to the type of an unsigned integer type of width exactly 32 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint32_t */++/* Define to the type of an unsigned integer type of width exactly 64 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint64_t */++/* Define to the type of an unsigned integer type of width exactly 8 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint8_t */++/* Define to the type of an unsigned integer type wide enough to hold a+ pointer, if such a type exists, and if the system does not define it. */+/* #undef uintptr_t */+
+ autoconf-linux/config.h view
@@ -0,0 +1,486 @@+/* config.h. Generated from config.h.in by configure. */+/* config.h.in. Generated from configure.ac by autoheader. */++/* Define if building universal (internal helper macro) */+/* #undef AC_APPLE_UNIVERSAL_BUILD */++/* How many MiB of RAM to assume if the real amount cannot be determined. */+#define ASSUME_RAM 128++/* Define to 1 if translation of program messages to the user's native+ language is requested. */+#define ENABLE_NLS 1++/* Define to 1 if bswap_16 is available. */+#define HAVE_BSWAP_16 1++/* Define to 1 if bswap_32 is available. */+#define HAVE_BSWAP_32 1++/* Define to 1 if bswap_64 is available. */+#define HAVE_BSWAP_64 1++/* Define to 1 if you have the <byteswap.h> header file. */+#define HAVE_BYTESWAP_H 1++/* Define to 1 if the system has the type `CC_SHA256_CTX'. */+/* #undef HAVE_CC_SHA256_CTX */++/* Define to 1 if you have the `CC_SHA256_Init' function. */+/* #undef HAVE_CC_SHA256_INIT */++/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the+ CoreFoundation framework. */+/* #undef HAVE_CFLOCALECOPYCURRENT */++/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in+ the CoreFoundation framework. */+/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */++/* 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 you have the `clock_gettime' function. */+#define HAVE_CLOCK_GETTIME 1++/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */+/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */++/* Define if the GNU dcgettext() function is already present or preinstalled.+ */+#define HAVE_DCGETTEXT 1++/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if+ you don't. */+#define HAVE_DECL_CLOCK_MONOTONIC 1++/* Define to 1 if you have the declaration of `program_invocation_name', and+ to 0 if you don't. */+#define HAVE_DECL_PROGRAM_INVOCATION_NAME 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 you have the <dlfcn.h> header file. */+#define HAVE_DLFCN_H 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 <fcntl.h> header file. */+#define HAVE_FCNTL_H 1++/* Define to 1 if you have the `futimens' function. */+#define HAVE_FUTIMENS 1++/* Define to 1 if you have the `futimes' function. */+/* #undef HAVE_FUTIMES */++/* Define to 1 if you have the `futimesat' function. */+/* #undef HAVE_FUTIMESAT */++/* Define to 1 if you have the <getopt.h> header file. */+#define HAVE_GETOPT_H 1++/* Define to 1 if you have the `getopt_long' function. */+#define HAVE_GETOPT_LONG 1++/* Define if the GNU gettext() function is already present or preinstalled. */+#define HAVE_GETTEXT 1++/* Define if you have the iconv() function and it works. */+/* #undef HAVE_ICONV */++/* Define to 1 if you have the <immintrin.h> header file. */+#define HAVE_IMMINTRIN_H 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 if mbrtowc and mbstate_t are properly declared. */+#define HAVE_MBRTOWC 1++/* Define to 1 if you have the <memory.h> header file. */+#define HAVE_MEMORY_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 you have the <minix/sha2.h> header file. */+/* #undef HAVE_MINIX_SHA2_H */++/* Define to 1 if getopt.h declares extern int optreset. */+/* #undef HAVE_OPTRESET */++/* Define to 1 if you have the `posix_fadvise' function. */+#define HAVE_POSIX_FADVISE 1++/* Define to 1 if you have the `pthread_condattr_setclock' function. */+#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1++/* Have PTHREAD_PRIO_INHERIT. */+#define HAVE_PTHREAD_PRIO_INHERIT 1++/* Define to 1 if you have the `SHA256Init' function. */+/* #undef HAVE_SHA256INIT */++/* Define to 1 if the system has the type `SHA256_CTX'. */+/* #undef HAVE_SHA256_CTX */++/* Define to 1 if you have the <sha256.h> header file. */+/* #undef HAVE_SHA256_H */++/* Define to 1 if you have the `SHA256_Init' function. */+/* #undef HAVE_SHA256_INIT */++/* Define to 1 if the system has the type `SHA2_CTX'. */+/* #undef HAVE_SHA2_CTX */++/* Define to 1 if you have the <sha2.h> header file. */+/* #undef HAVE_SHA2_H */++/* Define to 1 if optimizing for size. */+/* #undef HAVE_SMALL */++/* 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 <strings.h> header file. */+#define HAVE_STRINGS_H 1++/* Define to 1 if you have the <string.h> header file. */+#define HAVE_STRING_H 1++/* Define to 1 if `st_atimensec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */++/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */++/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */++/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */+#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1++/* Define to 1 if `st_uatime' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_UATIME */++/* Define to 1 if you have the <sys/byteorder.h> header file. */+/* #undef HAVE_SYS_BYTEORDER_H */++/* Define to 1 if you have the <sys/endian.h> header file. */+/* #undef HAVE_SYS_ENDIAN_H */++/* Define to 1 if you have the <sys/param.h> header file. */+#define HAVE_SYS_PARAM_H 1++/* Define to 1 if you have the <sys/stat.h> header file. */+#define HAVE_SYS_STAT_H 1++/* Define to 1 if you have the <sys/time.h> header file. */+#define HAVE_SYS_TIME_H 1++/* Define to 1 if you have the <sys/types.h> header file. */+#define HAVE_SYS_TYPES_H 1++/* Define to 1 if the system has the type `uintptr_t'. */+#define HAVE_UINTPTR_T 1++/* Define to 1 if you have the <unistd.h> header file. */+#define HAVE_UNISTD_H 1++/* Define to 1 if you have the `utime' function. */+/* #undef HAVE_UTIME */++/* Define to 1 if you have the `utimes' function. */+/* #undef HAVE_UTIMES */++/* Define to 1 or 0, depending whether the compiler supports simple visibility+ declarations. */+#define HAVE_VISIBILITY 1++/* Define to 1 if you have the `wcwidth' function. */+#define HAVE_WCWIDTH 1++/* Define to 1 if the system has the type `_Bool'. */+#define HAVE__BOOL 1++/* Define to 1 if _mm_movemask_epi8 is available. */+#define HAVE__MM_MOVEMASK_EPI8 1++/* Define to the sub-directory where libtool stores uninstalled libraries. */+#define LT_OBJDIR ".libs/"++/* Define to 1 when using POSIX threads (pthreads). */+#define MYTHREAD_POSIX 1++/* Define to 1 when using Windows Vista compatible threads. This uses features+ that are not available on Windows XP. */+/* #undef MYTHREAD_VISTA */++/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This+ avoids use of features that were added in Windows Vista. */+/* #undef MYTHREAD_WIN95 */++/* Define to 1 to disable debugging code. */+#define NDEBUG 1++/* Name of package */+#define PACKAGE "xz"++/* Define to the address where bug reports for this package should be sent. */+#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org"++/* Define to the full name of this package. */+#define PACKAGE_NAME "XZ Utils"++/* Define to the full name and version of this package. */+#define PACKAGE_STRING "XZ Utils 5.2.2"++/* Define to the one symbol short name of this package. */+#define PACKAGE_TARNAME "xz"++/* Define to the home page for this package. */+#define PACKAGE_URL "http://tukaani.org/xz/"++/* Define to the version of this package. */+#define PACKAGE_VERSION "5.2.2"++/* Define to necessary symbol if this constant uses a non-standard name on+ your system. */+/* #undef PTHREAD_CREATE_JOINABLE */++/* The size of `size_t', as computed by sizeof. */+#define SIZEOF_SIZE_T 8++/* Define to 1 if you have the ANSI C header files. */+#define STDC_HEADERS 1++/* Define to 1 if the number of available CPU cores can be detected with+ cpuset(2). */+/* #undef TUKLIB_CPUCORES_CPUSET */++/* Define to 1 if the number of available CPU cores can be detected with+ pstat_getdynamic(). */+/* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */++/* Define to 1 if the number of available CPU cores can be detected with+ sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */+#define TUKLIB_CPUCORES_SYSCONF 1++/* Define to 1 if the number of available CPU cores can be detected with+ sysctl(). */+/* #undef TUKLIB_CPUCORES_SYSCTL */++/* Define to 1 if the system supports fast unaligned access to 16-bit and+ 32-bit integers. */+#define TUKLIB_FAST_UNALIGNED_ACCESS 1++/* Define to 1 if the amount of physical memory can be detected with+ _system_configuration.physmem. */+/* #undef TUKLIB_PHYSMEM_AIX */++/* Define to 1 if the amount of physical memory can be detected with+ getinvent_r(). */+/* #undef TUKLIB_PHYSMEM_GETINVENT_R */++/* Define to 1 if the amount of physical memory can be detected with+ getsysinfo(). */+/* #undef TUKLIB_PHYSMEM_GETSYSINFO */++/* Define to 1 if the amount of physical memory can be detected with+ pstat_getstatic(). */+/* #undef TUKLIB_PHYSMEM_PSTAT_GETSTATIC */++/* Define to 1 if the amount of physical memory can be detected with+ sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES). */+#define TUKLIB_PHYSMEM_SYSCONF 1++/* Define to 1 if the amount of physical memory can be detected with sysctl().+ */+/* #undef TUKLIB_PHYSMEM_SYSCTL */++/* Define to 1 if the amount of physical memory can be detected with Linux+ sysinfo(). */+/* #undef TUKLIB_PHYSMEM_SYSINFO */++/* Enable extensions on AIX 3, Interix. */+#ifndef _ALL_SOURCE+# define _ALL_SOURCE 1+#endif+/* Enable GNU extensions on systems that have them. */+#ifndef _GNU_SOURCE+# define _GNU_SOURCE 1+#endif+/* Enable threading extensions on Solaris. */+#ifndef _POSIX_PTHREAD_SEMANTICS+# define _POSIX_PTHREAD_SEMANTICS 1+#endif+/* Enable extensions on HP NonStop. */+#ifndef _TANDEM_SOURCE+# define _TANDEM_SOURCE 1+#endif+/* Enable general extensions on Solaris. */+#ifndef __EXTENSIONS__+# define __EXTENSIONS__ 1+#endif+++/* Version number of package */+#define VERSION "5.2.2"++/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most+ significant byte first (like Motorola and SPARC, unlike Intel). */+#if defined AC_APPLE_UNIVERSAL_BUILD+# if defined __BIG_ENDIAN__+# define WORDS_BIGENDIAN 1+# endif+#else+# ifndef WORDS_BIGENDIAN+/* # undef WORDS_BIGENDIAN */+# endif+#endif++/* Enable large inode numbers on Mac OS X 10.5. */+#ifndef _DARWIN_USE_64_BIT_INODE+# define _DARWIN_USE_64_BIT_INODE 1+#endif++/* Number of bits in a file offset, on hosts where this is settable. */+/* #undef _FILE_OFFSET_BITS */++/* Define for large files, on AIX-style hosts. */+/* #undef _LARGE_FILES */++/* Define to 1 if on MINIX. */+/* #undef _MINIX */++/* Define to 2 if the system does not provide POSIX.1 features except with+ this defined. */+/* #undef _POSIX_1_SOURCE */++/* Define to 1 if you need to in order for `stat' and other things to work. */+/* #undef _POSIX_SOURCE */++/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT32_T */++/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT64_T */++/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT8_T */++/* Define to rpl_ if the getopt replacement functions and variables should be+ used. */+/* #undef __GETOPT_PREFIX */++/* Define to the type of a signed integer type of width exactly 32 bits if+ such a type exists and the standard includes do not define it. */+/* #undef int32_t */++/* Define to the type of a signed integer type of width exactly 64 bits if+ such a type exists and the standard includes do not define it. */+/* #undef int64_t */++/* Define to the type of an unsigned integer type of width exactly 16 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint16_t */++/* Define to the type of an unsigned integer type of width exactly 32 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint32_t */++/* Define to the type of an unsigned integer type of width exactly 64 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint64_t */++/* Define to the type of an unsigned integer type of width exactly 8 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint8_t */++/* Define to the type of an unsigned integer type wide enough to hold a+ pointer, if such a type exists, and if the system does not define it. */+/* #undef uintptr_t */
+ autoconf-win32/config.h view
@@ -0,0 +1,497 @@+/* config.h. Generated from config.h.in by configure. */+/* config.h.in. Generated from configure.ac by autoheader. */++/* Define if building universal (internal helper macro) */+/* #undef AC_APPLE_UNIVERSAL_BUILD */++/* How many MiB of RAM to assume if the real amount cannot be determined. */+#define ASSUME_RAM 128++/* Define to 1 if translation of program messages to the user's native+ language is requested. */+/* #undef ENABLE_NLS */++/* Define to 1 if bswap_16 is available. */+/* #undef HAVE_BSWAP_16 */++/* Define to 1 if bswap_32 is available. */+/* #undef HAVE_BSWAP_32 */++/* Define to 1 if bswap_64 is available. */+/* #undef HAVE_BSWAP_64 */++/* Define to 1 if you have the <byteswap.h> header file. */+/* #undef HAVE_BYTESWAP_H */++/* Define to 1 if the system has the type `CC_SHA256_CTX'. */+/* #undef HAVE_CC_SHA256_CTX */++/* Define to 1 if you have the `CC_SHA256_Init' function. */+/* #undef HAVE_CC_SHA256_INIT */++/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the+ CoreFoundation framework. */+/* #undef HAVE_CFLOCALECOPYCURRENT */++/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in+ the CoreFoundation framework. */+/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */++/* 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 you have the `clock_gettime' function. */+#define HAVE_CLOCK_GETTIME 1++/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */+/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */++/* Define if the GNU dcgettext() function is already present or preinstalled.+ */+/* #undef HAVE_DCGETTEXT */++/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if+ you don't. */+#define HAVE_DECL_CLOCK_MONOTONIC 1++/* Define to 1 if you have the declaration of `program_invocation_name', and+ to 0 if you don't. */+#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0++/* 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 you have the <dlfcn.h> header file. */+/* #undef HAVE_DLFCN_H */++/* 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 <fcntl.h> header file. */+#define HAVE_FCNTL_H 1++/* Define to 1 if you have the `futimens' function. */+/* #undef HAVE_FUTIMENS */++/* Define to 1 if you have the `futimes' function. */+/* #undef HAVE_FUTIMES */++/* Define to 1 if you have the `futimesat' function. */+/* #undef HAVE_FUTIMESAT */++/* Define to 1 if you have the <getopt.h> header file. */+#define HAVE_GETOPT_H 1++/* Define to 1 if you have the `getopt_long' function. */+#define HAVE_GETOPT_LONG 1++/* Define if the GNU gettext() function is already present or preinstalled. */+/* #undef HAVE_GETTEXT */++/* Define if you have the iconv() function and it works. */+/* #undef HAVE_ICONV */++/* Define to 1 if you have the <immintrin.h> header file. */+#define HAVE_IMMINTRIN_H 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 if mbrtowc and mbstate_t are properly declared. */+#define HAVE_MBRTOWC 1++/* Define to 1 if you have the <memory.h> header file. */+#define HAVE_MEMORY_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 you have the <minix/sha2.h> header file. */+/* #undef HAVE_MINIX_SHA2_H */++/* Define to 1 if getopt.h declares extern int optreset. */+/* #undef HAVE_OPTRESET */++/* Define to 1 if you have the `pipe2' function. */+/* #undef HAVE_PIPE2 */++/* Define to 1 if you have the `posix_fadvise' function. */+/* #undef HAVE_POSIX_FADVISE */++/* Define to 1 if you have the `pthread_condattr_setclock' function. */+/* #undef HAVE_PTHREAD_CONDATTR_SETCLOCK */++/* Have PTHREAD_PRIO_INHERIT. */+/* #undef HAVE_PTHREAD_PRIO_INHERIT */++/* Define to 1 if you have the `SHA256Init' function. */+/* #undef HAVE_SHA256INIT */++/* Define to 1 if the system has the type `SHA256_CTX'. */+/* #undef HAVE_SHA256_CTX */++/* Define to 1 if you have the <sha256.h> header file. */+/* #undef HAVE_SHA256_H */++/* Define to 1 if you have the `SHA256_Init' function. */+/* #undef HAVE_SHA256_INIT */++/* Define to 1 if the system has the type `SHA2_CTX'. */+/* #undef HAVE_SHA2_CTX */++/* Define to 1 if you have the <sha2.h> header file. */+/* #undef HAVE_SHA2_H */++/* Define to 1 if optimizing for size. */+/* #undef HAVE_SMALL */++/* 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 <strings.h> header file. */+#define HAVE_STRINGS_H 1++/* Define to 1 if you have the <string.h> header file. */+#define HAVE_STRING_H 1++/* Define to 1 if `st_atimensec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */++/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */++/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */++/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */++/* Define to 1 if `st_uatime' is a member of `struct stat'. */+/* #undef HAVE_STRUCT_STAT_ST_UATIME */++/* Define to 1 if you have the <sys/byteorder.h> header file. */+/* #undef HAVE_SYS_BYTEORDER_H */++/* Define to 1 if you have the <sys/endian.h> header file. */+/* #undef HAVE_SYS_ENDIAN_H */++/* Define to 1 if you have the <sys/param.h> header file. */+#define HAVE_SYS_PARAM_H 1++/* Define to 1 if you have the <sys/stat.h> header file. */+#define HAVE_SYS_STAT_H 1++/* Define to 1 if you have the <sys/time.h> header file. */+#define HAVE_SYS_TIME_H 1++/* Define to 1 if you have the <sys/types.h> header file. */+#define HAVE_SYS_TYPES_H 1++/* Define to 1 if the system has the type `uintptr_t'. */+#define HAVE_UINTPTR_T 1++/* Define to 1 if you have the <unistd.h> header file. */+#define HAVE_UNISTD_H 1++/* Define to 1 if you have the `utime' function. */+#define HAVE_UTIME 1++/* Define to 1 if you have the `utimes' function. */+/* #undef HAVE_UTIMES */++/* Define to 1 or 0, depending whether the compiler supports simple visibility+ declarations. */+#define HAVE_VISIBILITY 1++/* Define to 1 if you have the `wcwidth' function. */+/* #undef HAVE_WCWIDTH */++/* Define to 1 if the system has the type `_Bool'. */+#define HAVE__BOOL 1++/* Define to 1 if _mm_movemask_epi8 is available. */+#define HAVE__MM_MOVEMASK_EPI8 1++/* Define to the sub-directory where libtool stores uninstalled libraries. */+#define LT_OBJDIR ".libs/"++/* Define to 1 when using POSIX threads (pthreads). */+/* #undef MYTHREAD_POSIX */++#ifdef _WIN64+/* Define to 1 when using Windows Vista compatible threads. This uses features+ that are not available on Windows XP. */+# define MYTHREAD_VISTA 1+#else+/* 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+#endif++/* Define to 1 to disable debugging code. */+#define NDEBUG 1++/* Name of package */+#define PACKAGE "xz"++/* Define to the address where bug reports for this package should be sent. */+#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org"++/* Define to the full name of this package. */+#define PACKAGE_NAME "XZ Utils"++/* Define to the full name and version of this package. */+#define PACKAGE_STRING "XZ Utils 5.2.1"++/* Define to the one symbol short name of this package. */+#define PACKAGE_TARNAME "xz"++/* Define to the home page for this package. */+#define PACKAGE_URL "http://tukaani.org/xz/"++/* Define to the version of this package. */+#define PACKAGE_VERSION "5.2.1"++/* Define to necessary symbol if this constant uses a non-standard name on+ your system. */+/* #undef PTHREAD_CREATE_JOINABLE */++/* 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 you have the ANSI C header files. */+#define STDC_HEADERS 1++/* Define to 1 if the number of available CPU cores can be detected with+ cpuset(2). */+/* #undef TUKLIB_CPUCORES_CPUSET */++/* Define to 1 if the number of available CPU cores can be detected with+ pstat_getdynamic(). */+/* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */++/* Define to 1 if the number of available CPU cores can be detected with+ sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */+/* #undef TUKLIB_CPUCORES_SYSCONF */++/* Define to 1 if the number of available CPU cores can be detected with+ sysctl(). */+/* #undef TUKLIB_CPUCORES_SYSCTL */++/* Define to 1 if the system supports fast unaligned access to 16-bit and+ 32-bit integers. */+#define TUKLIB_FAST_UNALIGNED_ACCESS 1++/* Define to 1 if the amount of physical memory can be detected with+ _system_configuration.physmem. */+/* #undef TUKLIB_PHYSMEM_AIX */++/* Define to 1 if the amount of physical memory can be detected with+ getinvent_r(). */+/* #undef TUKLIB_PHYSMEM_GETINVENT_R */++/* Define to 1 if the amount of physical memory can be detected with+ getsysinfo(). */+/* #undef TUKLIB_PHYSMEM_GETSYSINFO */++/* Define to 1 if the amount of physical memory can be detected with+ pstat_getstatic(). */+/* #undef TUKLIB_PHYSMEM_PSTAT_GETSTATIC */++/* Define to 1 if the amount of physical memory can be detected with+ sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES). */+/* #undef TUKLIB_PHYSMEM_SYSCONF */++/* Define to 1 if the amount of physical memory can be detected with sysctl().+ */+/* #undef TUKLIB_PHYSMEM_SYSCTL */++/* Define to 1 if the amount of physical memory can be detected with Linux+ sysinfo(). */+/* #undef TUKLIB_PHYSMEM_SYSINFO */++/* Enable extensions on AIX 3, Interix. */+#ifndef _ALL_SOURCE+# define _ALL_SOURCE 1+#endif+/* Enable GNU extensions on systems that have them. */+#ifndef _GNU_SOURCE+# define _GNU_SOURCE 1+#endif+/* Enable threading extensions on Solaris. */+#ifndef _POSIX_PTHREAD_SEMANTICS+# define _POSIX_PTHREAD_SEMANTICS 1+#endif+/* Enable extensions on HP NonStop. */+#ifndef _TANDEM_SOURCE+# define _TANDEM_SOURCE 1+#endif+/* Enable general extensions on Solaris. */+#ifndef __EXTENSIONS__+# define __EXTENSIONS__ 1+#endif+++/* Version number of package */+#define VERSION "5.2.1"++/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most+ significant byte first (like Motorola and SPARC, unlike Intel). */+#if defined AC_APPLE_UNIVERSAL_BUILD+# if defined __BIG_ENDIAN__+# define WORDS_BIGENDIAN 1+# endif+#else+# ifndef WORDS_BIGENDIAN+/* # undef WORDS_BIGENDIAN */+# endif+#endif++/* Enable large inode numbers on Mac OS X 10.5. */+#ifndef _DARWIN_USE_64_BIT_INODE+# define _DARWIN_USE_64_BIT_INODE 1+#endif++/* Number of bits in a file offset, on hosts where this is settable. */+#define _FILE_OFFSET_BITS 64++/* Define for large files, on AIX-style hosts. */+/* #undef _LARGE_FILES */++/* Define to 1 if on MINIX. */+/* #undef _MINIX */++/* Define to 2 if the system does not provide POSIX.1 features except with+ this defined. */+/* #undef _POSIX_1_SOURCE */++/* Define to 1 if you need to in order for `stat' and other things to work. */+/* #undef _POSIX_SOURCE */++/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT32_T */++/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT64_T */++/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the+ #define below would cause a syntax error. */+/* #undef _UINT8_T */++/* Define to rpl_ if the getopt replacement functions and variables should be+ used. */+/* #undef __GETOPT_PREFIX */++/* Define to the type of a signed integer type of width exactly 32 bits if+ such a type exists and the standard includes do not define it. */+/* #undef int32_t */++/* Define to the type of a signed integer type of width exactly 64 bits if+ such a type exists and the standard includes do not define it. */+/* #undef int64_t */++/* Define to the type of an unsigned integer type of width exactly 16 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint16_t */++/* Define to the type of an unsigned integer type of width exactly 32 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint32_t */++/* Define to the type of an unsigned integer type of width exactly 64 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint64_t */++/* Define to the type of an unsigned integer type of width exactly 8 bits if+ such a type exists and the standard includes do not define it. */+/* #undef uint8_t */++/* Define to the type of an unsigned integer type wide enough to hold a+ pointer, if such a type exists, and if the system does not define it. */+/* #undef uintptr_t */
+ cbits/common/mythread.h view
@@ -0,0 +1,521 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file mythread.h+/// \brief Some threading related helper macros and functions+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef MYTHREAD_H+#define MYTHREAD_H++#include "sysdefs.h"++// If any type of threading is enabled, #define MYTHREAD_ENABLED.+#if defined(MYTHREAD_POSIX) || defined(MYTHREAD_WIN95) \+ || defined(MYTHREAD_VISTA)+# define MYTHREAD_ENABLED 1+#endif+++#ifdef MYTHREAD_ENABLED++////////////////////////////////////////+// Shared between all threading types //+////////////////////////////////////////++// Locks a mutex for a duration of a block.+//+// Perform mythread_mutex_lock(&mutex) in the beginning of a block+// and mythread_mutex_unlock(&mutex) at the end of the block. "break"+// may be used to unlock the mutex and jump out of the block.+// mythread_sync blocks may be nested.+//+// Example:+//+// mythread_sync(mutex) {+// foo();+// if (some_error)+// break; // Skips bar()+// bar();+// }+//+// At least GCC optimizes the loops completely away so it doesn't slow+// things down at all compared to plain mythread_mutex_lock(&mutex)+// and mythread_mutex_unlock(&mutex) calls.+//+#define mythread_sync(mutex) mythread_sync_helper1(mutex, __LINE__)+#define mythread_sync_helper1(mutex, line) mythread_sync_helper2(mutex, line)+#define mythread_sync_helper2(mutex, line) \+ for (unsigned int mythread_i_ ## line = 0; \+ mythread_i_ ## line \+ ? (mythread_mutex_unlock(&(mutex)), 0) \+ : (mythread_mutex_lock(&(mutex)), 1); \+ mythread_i_ ## line = 1) \+ for (unsigned int mythread_j_ ## line = 0; \+ !mythread_j_ ## line; \+ mythread_j_ ## line = 1)+#endif+++#if !defined(MYTHREAD_ENABLED)++//////////////////+// No threading //+//////////////////++// Calls the given function once. This isn't thread safe.+#define mythread_once(func) \+do { \+ static bool once_ = false; \+ if (!once_) { \+ func(); \+ once_ = true; \+ } \+} while (0)+++#if !(defined(_WIN32) && !defined(__CYGWIN__))+// Use sigprocmask() to set the signal mask in single-threaded programs.+#include <signal.h>++static inline void+mythread_sigmask(int how, const sigset_t *restrict set,+ sigset_t *restrict oset)+{+ int ret = sigprocmask(how, set, oset);+ assert(ret == 0);+ (void)ret;+}+#endif+++#elif defined(MYTHREAD_POSIX)++////////////////////+// Using pthreads //+////////////////////++#include <sys/time.h>+#include <pthread.h>+#include <signal.h>+#include <time.h>+#include <errno.h>++#define MYTHREAD_RET_TYPE void *+#define MYTHREAD_RET_VALUE NULL++typedef pthread_t mythread;+typedef pthread_mutex_t mythread_mutex;++typedef struct {+ pthread_cond_t cond;+#ifdef HAVE_CLOCK_GETTIME+ // Clock ID (CLOCK_REALTIME or CLOCK_MONOTONIC) associated with+ // the condition variable.+ clockid_t clk_id;+#endif+} mythread_cond;++typedef struct timespec mythread_condtime;+++// Calls the given function once in a thread-safe way.+#define mythread_once(func) \+ do { \+ static pthread_once_t once_ = PTHREAD_ONCE_INIT; \+ pthread_once(&once_, &func); \+ } while (0)+++// Use pthread_sigmask() to set the signal mask in multi-threaded programs.+// Do nothing on OpenVMS since it lacks pthread_sigmask().+static inline void+mythread_sigmask(int how, const sigset_t *restrict set,+ sigset_t *restrict oset)+{+#ifdef __VMS+ (void)how;+ (void)set;+ (void)oset;+#else+ int ret = pthread_sigmask(how, set, oset);+ assert(ret == 0);+ (void)ret;+#endif+}+++// Creates a new thread with all signals blocked. Returns zero on success+// and non-zero on error.+static inline int+mythread_create(mythread *thread, void *(*func)(void *arg), void *arg)+{+ sigset_t old;+ sigset_t all;+ sigfillset(&all);++ mythread_sigmask(SIG_SETMASK, &all, &old);+ const int ret = pthread_create(thread, NULL, func, arg);+ mythread_sigmask(SIG_SETMASK, &old, NULL);++ return ret;+}++// Joins a thread. Returns zero on success and non-zero on error.+static inline int+mythread_join(mythread thread)+{+ return pthread_join(thread, NULL);+}+++// Initiatlizes a mutex. Returns zero on success and non-zero on error.+static inline int+mythread_mutex_init(mythread_mutex *mutex)+{+ return pthread_mutex_init(mutex, NULL);+}++static inline void+mythread_mutex_destroy(mythread_mutex *mutex)+{+ int ret = pthread_mutex_destroy(mutex);+ assert(ret == 0);+ (void)ret;+}++static inline void+mythread_mutex_lock(mythread_mutex *mutex)+{+ int ret = pthread_mutex_lock(mutex);+ assert(ret == 0);+ (void)ret;+}++static inline void+mythread_mutex_unlock(mythread_mutex *mutex)+{+ int ret = pthread_mutex_unlock(mutex);+ assert(ret == 0);+ (void)ret;+}+++// Initializes a condition variable.+//+// Using CLOCK_MONOTONIC instead of the default CLOCK_REALTIME makes the+// timeout in pthread_cond_timedwait() work correctly also if system time+// is suddenly changed. Unfortunately CLOCK_MONOTONIC isn't available+// everywhere while the default CLOCK_REALTIME is, so the default is+// used if CLOCK_MONOTONIC isn't available.+//+// If clock_gettime() isn't available at all, gettimeofday() will be used.+static inline int+mythread_cond_init(mythread_cond *mycond)+{+#ifdef HAVE_CLOCK_GETTIME+ // NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1.+# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && HAVE_DECL_CLOCK_MONOTONIC+ struct timespec ts;+ pthread_condattr_t condattr;++ // POSIX doesn't seem to *require* that pthread_condattr_setclock()+ // will fail if given an unsupported clock ID. Test that+ // CLOCK_MONOTONIC really is supported using clock_gettime().+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0+ && pthread_condattr_init(&condattr) == 0) {+ int ret = pthread_condattr_setclock(+ &condattr, CLOCK_MONOTONIC);+ if (ret == 0)+ ret = pthread_cond_init(&mycond->cond, &condattr);++ pthread_condattr_destroy(&condattr);++ if (ret == 0) {+ mycond->clk_id = CLOCK_MONOTONIC;+ return 0;+ }+ }++ // If anything above fails, fall back to the default CLOCK_REALTIME.+ // POSIX requires that all implementations of clock_gettime() must+ // support at least CLOCK_REALTIME.+# endif++ mycond->clk_id = CLOCK_REALTIME;+#endif++ return pthread_cond_init(&mycond->cond, NULL);+}++static inline void+mythread_cond_destroy(mythread_cond *cond)+{+ int ret = pthread_cond_destroy(&cond->cond);+ assert(ret == 0);+ (void)ret;+}++static inline void+mythread_cond_signal(mythread_cond *cond)+{+ int ret = pthread_cond_signal(&cond->cond);+ assert(ret == 0);+ (void)ret;+}++static inline void+mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)+{+ int ret = pthread_cond_wait(&cond->cond, mutex);+ assert(ret == 0);+ (void)ret;+}++// Waits on a condition or until a timeout expires. If the timeout expires,+// non-zero is returned, otherwise zero is returned.+static inline int+mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,+ const mythread_condtime *condtime)+{+ int ret = pthread_cond_timedwait(&cond->cond, mutex, condtime);+ assert(ret == 0 || ret == ETIMEDOUT);+ return ret;+}++// Sets condtime to the absolute time that is timeout_ms milliseconds+// in the future. The type of the clock to use is taken from cond.+static inline void+mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,+ uint32_t timeout_ms)+{+ condtime->tv_sec = timeout_ms / 1000;+ condtime->tv_nsec = (timeout_ms % 1000) * 1000000;++#ifdef HAVE_CLOCK_GETTIME+ struct timespec now;+ int ret = clock_gettime(cond->clk_id, &now);+ assert(ret == 0);+ (void)ret;++ condtime->tv_sec += now.tv_sec;+ condtime->tv_nsec += now.tv_nsec;+#else+ (void)cond;++ struct timeval now;+ gettimeofday(&now, NULL);++ condtime->tv_sec += now.tv_sec;+ condtime->tv_nsec += now.tv_usec * 1000L;+#endif++ // tv_nsec must stay in the range [0, 999_999_999].+ if (condtime->tv_nsec >= 1000000000L) {+ condtime->tv_nsec -= 1000000000L;+ ++condtime->tv_sec;+ }+}+++#elif defined(MYTHREAD_WIN95) || defined(MYTHREAD_VISTA)++/////////////////////+// Windows threads //+/////////////////////++#define WIN32_LEAN_AND_MEAN+#ifdef MYTHREAD_VISTA+# undef _WIN32_WINNT+# define _WIN32_WINNT 0x0600+#endif+#include <windows.h>+#include <process.h>++#define MYTHREAD_RET_TYPE unsigned int __stdcall+#define MYTHREAD_RET_VALUE 0++typedef HANDLE mythread;+typedef CRITICAL_SECTION mythread_mutex;++#ifdef MYTHREAD_WIN95+typedef HANDLE mythread_cond;+#else+typedef CONDITION_VARIABLE mythread_cond;+#endif++typedef struct {+ // Tick count (milliseconds) in the beginning of the timeout.+ // NOTE: This is 32 bits so it wraps around after 49.7 days.+ // Multi-day timeouts may not work as expected.+ DWORD start;++ // Length of the timeout in milliseconds. The timeout expires+ // when the current tick count minus "start" is equal or greater+ // than "timeout".+ DWORD timeout;+} mythread_condtime;+++// mythread_once() is only available with Vista threads.+#ifdef MYTHREAD_VISTA+#define mythread_once(func) \+ do { \+ static INIT_ONCE once_ = INIT_ONCE_STATIC_INIT; \+ BOOL pending_; \+ if (!InitOnceBeginInitialize(&once_, 0, &pending_, NULL)) \+ abort(); \+ if (pending_) \+ func(); \+ if (!InitOnceComplete(&once, 0, NULL)) \+ abort(); \+ } while (0)+#endif+++// mythread_sigmask() isn't available on Windows. Even a dummy version would+// make no sense because the other POSIX signal functions are missing anyway.+++static inline int+mythread_create(mythread *thread,+ unsigned int (__stdcall *func)(void *arg), void *arg)+{+ uintptr_t ret = _beginthreadex(NULL, 0, func, arg, 0, NULL);+ if (ret == 0)+ return -1;++ *thread = (HANDLE)ret;+ return 0;+}++static inline int+mythread_join(mythread thread)+{+ int ret = 0;++ if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0)+ ret = -1;++ if (!CloseHandle(thread))+ ret = -1;++ return ret;+}+++static inline int+mythread_mutex_init(mythread_mutex *mutex)+{+ InitializeCriticalSection(mutex);+ return 0;+}++static inline void+mythread_mutex_destroy(mythread_mutex *mutex)+{+ DeleteCriticalSection(mutex);+}++static inline void+mythread_mutex_lock(mythread_mutex *mutex)+{+ EnterCriticalSection(mutex);+}++static inline void+mythread_mutex_unlock(mythread_mutex *mutex)+{+ LeaveCriticalSection(mutex);+}+++static inline int+mythread_cond_init(mythread_cond *cond)+{+#ifdef MYTHREAD_WIN95+ *cond = CreateEvent(NULL, FALSE, FALSE, NULL);+ return *cond == NULL ? -1 : 0;+#else+ InitializeConditionVariable(cond);+ return 0;+#endif+}++static inline void+mythread_cond_destroy(mythread_cond *cond)+{+#ifdef MYTHREAD_WIN95+ CloseHandle(*cond);+#else+ (void)cond;+#endif+}++static inline void+mythread_cond_signal(mythread_cond *cond)+{+#ifdef MYTHREAD_WIN95+ SetEvent(*cond);+#else+ WakeConditionVariable(cond);+#endif+}++static inline void+mythread_cond_wait(mythread_cond *cond, mythread_mutex *mutex)+{+#ifdef MYTHREAD_WIN95+ LeaveCriticalSection(mutex);+ WaitForSingleObject(*cond, INFINITE);+ EnterCriticalSection(mutex);+#else+ BOOL ret = SleepConditionVariableCS(cond, mutex, INFINITE);+ assert(ret);+ (void)ret;+#endif+}++static inline int+mythread_cond_timedwait(mythread_cond *cond, mythread_mutex *mutex,+ const mythread_condtime *condtime)+{+#ifdef MYTHREAD_WIN95+ LeaveCriticalSection(mutex);+#endif++ DWORD elapsed = GetTickCount() - condtime->start;+ DWORD timeout = elapsed >= condtime->timeout+ ? 0 : condtime->timeout - elapsed;++#ifdef MYTHREAD_WIN95+ DWORD ret = WaitForSingleObject(*cond, timeout);+ assert(ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT);++ EnterCriticalSection(mutex);++ return ret == WAIT_TIMEOUT;+#else+ BOOL ret = SleepConditionVariableCS(cond, mutex, timeout);+ assert(ret || GetLastError() == ERROR_TIMEOUT);+ return !ret;+#endif+}++static inline void+mythread_condtime_set(mythread_condtime *condtime, const mythread_cond *cond,+ uint32_t timeout)+{+ (void)cond;+ condtime->start = GetTickCount();+ condtime->timeout = timeout;+}++#endif++#endif
+ cbits/common/sysdefs.h view
@@ -0,0 +1,199 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file sysdefs.h+/// \brief Common includes, definitions, system-specific things etc.+///+/// This file is used also by the lzma command line tool, that's why this+/// file is separate from common.h.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_SYSDEFS_H+#define LZMA_SYSDEFS_H++//////////////+// Includes //+//////////////++#ifdef HAVE_CONFIG_H+# include <config.h>+#endif++// Get standard-compliant stdio functions under MinGW and MinGW-w64.+#ifdef __MINGW32__+# define __USE_MINGW_ANSI_STDIO 1+#endif++// size_t and NULL+#include <stddef.h>++#ifdef HAVE_INTTYPES_H+# include <inttypes.h>+#endif++// C99 says that inttypes.h always includes stdint.h, but some systems+// don't do that, and require including stdint.h separately.+#ifdef HAVE_STDINT_H+# include <stdint.h>+#endif++// Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The+// limits are also used to figure out some macros missing from pre-C99 systems.+#include <limits.h>++// 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.+// Note that this duplicates some code from lzma.h, but this is better since+// we can work without inttypes.h thanks to Autoconf tests.+#ifndef UINT32_C+# if UINT_MAX != 4294967295U+# error UINT32_C is not defined and unsigned int is not 32-bit.+# endif+# 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+#ifndef PRIX32+# define PRIX32 "X"+#endif++#if ULONG_MAX == 4294967295UL+# ifndef UINT64_C+# define UINT64_C(n) n ## ULL+# endif+# ifndef PRIu64+# define PRIu64 "llu"+# endif+# ifndef PRIx64+# define PRIx64 "llx"+# 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+# ifndef PRIX64+# define PRIX64 "lX"+# endif+#endif+#ifndef UINT64_MAX+# define UINT64_MAX UINT64_C(18446744073709551615)+#endif++// Incorrect(?) SIZE_MAX:+// - Interix headers typedef size_t to unsigned long,+// but a few lines later define SIZE_MAX to INT32_MAX.+// - SCO OpenServer (x86) headers typedef size_t to unsigned int+// but define SIZE_MAX to INT32_MAX.+#if defined(__INTERIX) || defined(_SCO_DS)+# undef SIZE_MAX+#endif++// The code currently assumes that size_t is either 32-bit or 64-bit.+#ifndef SIZE_MAX+# if SIZEOF_SIZE_T == 4+# define SIZE_MAX UINT32_MAX+# elif SIZEOF_SIZE_T == 8+# define SIZE_MAX UINT64_MAX+# else+# error size_t is not 32-bit or 64-bit+# endif+#endif+#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX+# error size_t is not 32-bit or 64-bit+#endif++#include <stdlib.h>+#include <assert.h>++// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written+// so that it works with fake bool type, for example:+//+// bool foo = (flags & 0x100) != 0;+// bool bar = !!(flags & 0x100);+//+// This works with the real C99 bool but breaks with fake bool:+//+// bool baz = (flags & 0x100);+//+#ifdef HAVE_STDBOOL_H+# include <stdbool.h>+#else+# if ! HAVE__BOOL+typedef unsigned char _Bool;+# endif+# define bool _Bool+# define false 0+# define true 1+# define __bool_true_false_are_defined 1+#endif++// string.h should be enough but let's include strings.h and memory.h too if+// they exists, since that shouldn't do any harm, but may improve portability.+#include <string.h>++#ifdef HAVE_STRINGS_H+# include <strings.h>+#endif++#ifdef HAVE_MEMORY_H+# 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 //+////////////++#undef memzero+#define memzero(s, n) memset(s, 0, n)++// NOTE: Avoid using MIN() and MAX(), because even conditionally defining+// those macros can cause some portability trouble, since on some systems+// the system headers insist defining their own versions.+#define my_min(x, y) ((x) < (y) ? (x) : (y))+#define my_max(x, y) ((x) > (y) ? (x) : (y))++#ifndef ARRAY_SIZE+# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))+#endif++#if defined(__GNUC__) \+ && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4)+# define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x)))+#else+# define lzma_attr_alloc_size(x)+#endif++#endif
+ cbits/common/tuklib_common.h view
@@ -0,0 +1,71 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_common.h+/// \brief Common definitions for tuklib modules+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_COMMON_H+#define TUKLIB_COMMON_H++// The config file may be replaced by a package-specific file.+// It should include at least stddef.h, inttypes.h, and limits.h.+#include "tuklib_config.h"++// TUKLIB_SYMBOL_PREFIX is prefixed to all symbols exported by+// the tuklib modules. If you use a tuklib module in a library,+// you should use TUKLIB_SYMBOL_PREFIX to make sure that there+// are no symbol conflicts in case someone links your library+// into application that also uses the same tuklib module.+#ifndef TUKLIB_SYMBOL_PREFIX+# define TUKLIB_SYMBOL_PREFIX+#endif++#define TUKLIB_CAT_X(a, b) a ## b+#define TUKLIB_CAT(a, b) TUKLIB_CAT_X(a, b)++#ifndef TUKLIB_SYMBOL+# define TUKLIB_SYMBOL(sym) TUKLIB_CAT(TUKLIB_SYMBOL_PREFIX, sym)+#endif++#ifndef TUKLIB_DECLS_BEGIN+# ifdef __cplusplus+# define TUKLIB_DECLS_BEGIN extern "C" {+# else+# define TUKLIB_DECLS_BEGIN+# endif+#endif++#ifndef TUKLIB_DECLS_END+# ifdef __cplusplus+# define TUKLIB_DECLS_END }+# else+# define TUKLIB_DECLS_END+# endif+#endif++#if defined(__GNUC__) && defined(__GNUC_MINOR__)+# define TUKLIB_GNUC_REQ(major, minor) \+ ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \+ || __GNUC__ > (major))+#else+# define TUKLIB_GNUC_REQ(major, minor) 0+#endif++#if TUKLIB_GNUC_REQ(2, 5)+# define tuklib_attr_noreturn __attribute__((__noreturn__))+#else+# define tuklib_attr_noreturn+#endif++#if (defined(_WIN32) && !defined(__CYGWIN__)) \+ || defined(__OS2__) || defined(__MSDOS__)+# define TUKLIB_DOSLIKE 1+#endif++#endif
+ cbits/common/tuklib_config.h view
@@ -0,0 +1,7 @@+#ifdef HAVE_CONFIG_H+# include "sysdefs.h"+#else+# include <stddef.h>+# include <inttypes.h>+# include <limits.h>+#endif
+ cbits/common/tuklib_cpucores.c view
@@ -0,0 +1,100 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_cpucores.c+/// \brief Get the number of CPU cores online+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_cpucores.h"++#if defined(_WIN32) || defined(__CYGWIN__)+# ifndef _WIN32_WINNT+# define _WIN32_WINNT 0x0500+# endif+# include <windows.h>++// glibc >= 2.9+#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)+# include <sched.h>++// FreeBSD+#elif defined(TUKLIB_CPUCORES_CPUSET)+# include <sys/param.h>+# include <sys/cpuset.h>++#elif defined(TUKLIB_CPUCORES_SYSCTL)+# ifdef HAVE_SYS_PARAM_H+# include <sys/param.h>+# endif+# include <sys/sysctl.h>++#elif defined(TUKLIB_CPUCORES_SYSCONF)+# include <unistd.h>++// HP-UX+#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)+# include <sys/param.h>+# include <sys/pstat.h>+#endif+++extern uint32_t+tuklib_cpucores(void)+{+ uint32_t ret = 0;++#if defined(_WIN32) || defined(__CYGWIN__)+ SYSTEM_INFO sysinfo;+ GetSystemInfo(&sysinfo);+ ret = sysinfo.dwNumberOfProcessors;++#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)+ cpu_set_t cpu_mask;+ if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0)+ ret = (uint32_t)CPU_COUNT(&cpu_mask);++#elif defined(TUKLIB_CPUCORES_CPUSET)+ cpuset_t set;+ if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,+ sizeof(set), &set) == 0) {+# ifdef CPU_COUNT+ ret = (uint32_t)CPU_COUNT(&set);+# else+ for (unsigned i = 0; i < CPU_SETSIZE; ++i)+ if (CPU_ISSET(i, &set))+ ++ret;+# endif+ }++#elif defined(TUKLIB_CPUCORES_SYSCTL)+ int name[2] = { CTL_HW, HW_NCPU };+ int cpus;+ size_t cpus_size = sizeof(cpus);+ if (sysctl(name, 2, &cpus, &cpus_size, NULL, 0) != -1+ && cpus_size == sizeof(cpus) && cpus > 0)+ ret = (uint32_t)cpus;++#elif defined(TUKLIB_CPUCORES_SYSCONF)+# ifdef _SC_NPROCESSORS_ONLN+ // Most systems+ const long cpus = sysconf(_SC_NPROCESSORS_ONLN);+# else+ // IRIX+ const long cpus = sysconf(_SC_NPROC_ONLN);+# endif+ if (cpus > 0)+ ret = (uint32_t)cpus;++#elif defined(TUKLIB_CPUCORES_PSTAT_GETDYNAMIC)+ struct pst_dynamic pst;+ if (pstat_getdynamic(&pst, sizeof(pst), 1, 0) != -1)+ ret = (uint32_t)pst.psd_proc_cnt;+#endif++ return ret;+}
+ cbits/common/tuklib_cpucores.h view
@@ -0,0 +1,23 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_cpucores.h+/// \brief Get the number of CPU cores online+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_CPUCORES_H+#define TUKLIB_CPUCORES_H++#include "tuklib_common.h"+TUKLIB_DECLS_BEGIN++#define tuklib_cpucores TUKLIB_SYMBOL(tuklib_cpucores)+extern uint32_t tuklib_cpucores(void);++TUKLIB_DECLS_END+#endif
+ cbits/common/tuklib_exit.c view
@@ -0,0 +1,58 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_exit.c+/// \brief Close stdout and stderr, and exit+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_common.h"++#include <stdlib.h>+#include <stdio.h>+#include <string.h>++#include "tuklib_gettext.h"+#include "tuklib_progname.h"+#include "tuklib_exit.h"+++extern void+tuklib_exit(int status, int err_status, int show_error)+{+ if (status != err_status) {+ // Close stdout. If something goes wrong,+ // print an error message to stderr.+ const int ferror_err = ferror(stdout);+ const int fclose_err = fclose(stdout);+ if (ferror_err || fclose_err) {+ status = err_status;++ // If it was fclose() that failed, we have the reason+ // in errno. If only ferror() indicated an error,+ // we have no idea what the reason was.+ if (show_error)+ fprintf(stderr, "%s: %s: %s\n", progname,+ _("Writing to standard "+ "output failed"),+ fclose_err ? strerror(errno)+ : _("Unknown error"));+ }+ }++ if (status != err_status) {+ // Close stderr. If something goes wrong, there's+ // nothing where we could print an error message.+ // Just set the exit status.+ const int ferror_err = ferror(stderr);+ const int fclose_err = fclose(stderr);+ if (fclose_err || ferror_err)+ status = err_status;+ }++ exit(status);+}
+ cbits/common/tuklib_exit.h view
@@ -0,0 +1,25 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_exit.h+/// \brief Close stdout and stderr, and exit+/// \note Requires tuklib_progname and tuklib_gettext modules+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_EXIT_H+#define TUKLIB_EXIT_H++#include "tuklib_common.h"+TUKLIB_DECLS_BEGIN++#define tuklib_exit TUKLIB_SYMBOL(tuklib_exit)+extern void tuklib_exit(int status, int err_status, int show_error)+ tuklib_attr_noreturn;++TUKLIB_DECLS_END+#endif
+ cbits/common/tuklib_gettext.h view
@@ -0,0 +1,44 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_gettext.h+/// \brief Wrapper for gettext and friends+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_GETTEXT_H+#define TUKLIB_GETTEXT_H++#include "tuklib_common.h"+#include <locale.h>++#ifndef TUKLIB_GETTEXT+# ifdef ENABLE_NLS+# define TUKLIB_GETTEXT 1+# else+# define TUKLIB_GETTEXT 0+# endif+#endif++#if TUKLIB_GETTEXT+# include <libintl.h>+# define tuklib_gettext_init(package, localedir) \+ do { \+ setlocale(LC_ALL, ""); \+ bindtextdomain(package, localedir); \+ textdomain(package); \+ } while (0)+# define _(msgid) gettext(msgid)+#else+# define tuklib_gettext_init(package, localedir) \+ setlocale(LC_ALL, "")+# define _(msgid) (msgid)+# define ngettext(msgid1, msgid2, n) ((n) == 1 ? (msgid1) : (msgid2))+#endif+#define N_(msgid) msgid++#endif
+ cbits/common/tuklib_integer.h view
@@ -0,0 +1,742 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_integer.h+/// \brief Various integer and bit operations+///+/// This file provides macros or functions to do some basic integer and bit+/// operations.+///+/// Native endian inline functions (XX = 16, 32, or 64):+/// - Unaligned native endian reads: readXXne(ptr)+/// - Unaligned native endian writes: writeXXne(ptr, num)+/// - Aligned native endian reads: aligned_readXXne(ptr)+/// - Aligned native endian writes: aligned_writeXXne(ptr, num)+///+/// Endianness-converting integer operations (these can be macros!)+/// (XX = 16, 32, or 64; Y = b or l):+/// - Byte swapping: bswapXX(num)+/// - Byte order conversions to/from native (byteswaps if Y isn't+/// the native endianness): convXXYe(num)+/// - Unaligned reads (16/32-bit only): readXXYe(ptr)+/// - Unaligned writes (16/32-bit only): writeXXYe(ptr, num)+/// - Aligned reads: aligned_readXXYe(ptr)+/// - Aligned writes: aligned_writeXXYe(ptr, num)+///+/// Since the above can macros, the arguments should have no side effects+/// because they may be evaluated more than once.+///+/// Bit scan operations for non-zero 32-bit integers (inline functions):+/// - Bit scan reverse (find highest non-zero bit): bsr32(num)+/// - Count leading zeros: clz32(num)+/// - Count trailing zeros: ctz32(num)+/// - Bit scan forward (simply an alias for ctz32()): bsf32(num)+///+/// The above bit scan operations return 0-31. If num is zero,+/// the result is undefined.+//+// Authors: Lasse Collin+// Joachim Henke+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_INTEGER_H+#define TUKLIB_INTEGER_H++#include "tuklib_common.h"+#include <string.h>++// Newer Intel C compilers require immintrin.h for _bit_scan_reverse()+// and such functions.+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)+# include <immintrin.h>+#endif+++///////////////////+// Byte swapping //+///////////////////++#if defined(HAVE___BUILTIN_BSWAPXX)+ // GCC >= 4.8 and Clang+# define bswap16(n) __builtin_bswap16(n)+# define bswap32(n) __builtin_bswap32(n)+# define bswap64(n) __builtin_bswap64(n)++#elif defined(HAVE_BYTESWAP_H)+ // glibc, uClibc, dietlibc+# include <byteswap.h>+# ifdef HAVE_BSWAP_16+# define bswap16(num) bswap_16(num)+# endif+# ifdef HAVE_BSWAP_32+# define bswap32(num) bswap_32(num)+# endif+# ifdef HAVE_BSWAP_64+# define bswap64(num) bswap_64(num)+# endif++#elif defined(HAVE_SYS_ENDIAN_H)+ // *BSDs and Darwin+# include <sys/endian.h>++#elif defined(HAVE_SYS_BYTEORDER_H)+ // Solaris+# include <sys/byteorder.h>+# ifdef BSWAP_16+# define bswap16(num) BSWAP_16(num)+# endif+# ifdef BSWAP_32+# define bswap32(num) BSWAP_32(num)+# endif+# ifdef BSWAP_64+# define bswap64(num) BSWAP_64(num)+# endif+# ifdef BE_16+# define conv16be(num) BE_16(num)+# endif+# ifdef BE_32+# define conv32be(num) BE_32(num)+# endif+# ifdef BE_64+# define conv64be(num) BE_64(num)+# endif+# ifdef LE_16+# define conv16le(num) LE_16(num)+# endif+# ifdef LE_32+# define conv32le(num) LE_32(num)+# endif+# ifdef LE_64+# define conv64le(num) LE_64(num)+# endif+#endif++#ifndef bswap16+# define bswap16(n) (uint16_t)( \+ (((n) & 0x00FFU) << 8) \+ | (((n) & 0xFF00U) >> 8) \+ )+#endif++#ifndef bswap32+# define bswap32(n) (uint32_t)( \+ (((n) & UINT32_C(0x000000FF)) << 24) \+ | (((n) & UINT32_C(0x0000FF00)) << 8) \+ | (((n) & UINT32_C(0x00FF0000)) >> 8) \+ | (((n) & UINT32_C(0xFF000000)) >> 24) \+ )+#endif++#ifndef bswap64+# define bswap64(n) (uint64_t)( \+ (((n) & UINT64_C(0x00000000000000FF)) << 56) \+ | (((n) & UINT64_C(0x000000000000FF00)) << 40) \+ | (((n) & UINT64_C(0x0000000000FF0000)) << 24) \+ | (((n) & UINT64_C(0x00000000FF000000)) << 8) \+ | (((n) & UINT64_C(0x000000FF00000000)) >> 8) \+ | (((n) & UINT64_C(0x0000FF0000000000)) >> 24) \+ | (((n) & UINT64_C(0x00FF000000000000)) >> 40) \+ | (((n) & UINT64_C(0xFF00000000000000)) >> 56) \+ )+#endif++// Define conversion macros using the basic byte swapping macros.+#ifdef WORDS_BIGENDIAN+# ifndef conv16be+# define conv16be(num) ((uint16_t)(num))+# endif+# ifndef conv32be+# define conv32be(num) ((uint32_t)(num))+# endif+# ifndef conv64be+# define conv64be(num) ((uint64_t)(num))+# endif+# ifndef conv16le+# define conv16le(num) bswap16(num)+# endif+# ifndef conv32le+# define conv32le(num) bswap32(num)+# endif+# ifndef conv64le+# define conv64le(num) bswap64(num)+# endif+#else+# ifndef conv16be+# define conv16be(num) bswap16(num)+# endif+# ifndef conv32be+# define conv32be(num) bswap32(num)+# endif+# ifndef conv64be+# define conv64be(num) bswap64(num)+# endif+# ifndef conv16le+# define conv16le(num) ((uint16_t)(num))+# endif+# ifndef conv32le+# define conv32le(num) ((uint32_t)(num))+# endif+# ifndef conv64le+# define conv64le(num) ((uint64_t)(num))+# endif+#endif+++////////////////////////////////+// Unaligned reads and writes //+////////////////////////////////++// The traditional way of casting e.g. *(const uint16_t *)uint8_pointer+// is bad even if the uint8_pointer is properly aligned because this kind+// of casts break strict aliasing rules and result in undefined behavior.+// With unaligned pointers it's even worse: compilers may emit vector+// instructions that require aligned pointers even if non-vector+// instructions work with unaligned pointers.+//+// Using memcpy() is the standard compliant way to do unaligned access.+// Many modern compilers inline it so there is no function call overhead.+// For those compilers that don't handle the memcpy() method well, the+// old casting method (that violates strict aliasing) can be requested at+// build time. A third method, casting to a packed struct, would also be+// an option but isn't provided to keep things simpler (it's already a mess).+// Hopefully this is flexible enough in practice.++static inline uint16_t+read16ne(const uint8_t *buf)+{+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \+ && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)+ return *(const uint16_t *)buf;+#else+ uint16_t num;+ memcpy(&num, buf, sizeof(num));+ return num;+#endif+}+++static inline uint32_t+read32ne(const uint8_t *buf)+{+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \+ && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)+ return *(const uint32_t *)buf;+#else+ uint32_t num;+ memcpy(&num, buf, sizeof(num));+ return num;+#endif+}+++static inline uint64_t+read64ne(const uint8_t *buf)+{+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \+ && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)+ return *(const uint64_t *)buf;+#else+ uint64_t num;+ memcpy(&num, buf, sizeof(num));+ return num;+#endif+}+++static inline void+write16ne(uint8_t *buf, uint16_t num)+{+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \+ && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)+ *(uint16_t *)buf = num;+#else+ memcpy(buf, &num, sizeof(num));+#endif+ return;+}+++static inline void+write32ne(uint8_t *buf, uint32_t num)+{+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \+ && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)+ *(uint32_t *)buf = num;+#else+ memcpy(buf, &num, sizeof(num));+#endif+ return;+}+++static inline void+write64ne(uint8_t *buf, uint64_t num)+{+#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \+ && defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING)+ *(uint64_t *)buf = num;+#else+ memcpy(buf, &num, sizeof(num));+#endif+ return;+}+++static inline uint16_t+read16be(const uint8_t *buf)+{+#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)+ uint16_t num = read16ne(buf);+ return conv16be(num);+#else+ uint16_t num = ((uint16_t)buf[0] << 8) | (uint16_t)buf[1];+ return num;+#endif+}+++static inline uint16_t+read16le(const uint8_t *buf)+{+#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)+ uint16_t num = read16ne(buf);+ return conv16le(num);+#else+ uint16_t num = ((uint16_t)buf[0]) | ((uint16_t)buf[1] << 8);+ return num;+#endif+}+++static inline uint32_t+read32be(const uint8_t *buf)+{+#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)+ uint32_t num = read32ne(buf);+ return conv32be(num);+#else+ uint32_t num = (uint32_t)buf[0] << 24;+ num |= (uint32_t)buf[1] << 16;+ num |= (uint32_t)buf[2] << 8;+ num |= (uint32_t)buf[3];+ return num;+#endif+}+++static inline uint32_t+read32le(const uint8_t *buf)+{+#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)+ uint32_t num = read32ne(buf);+ return conv32le(num);+#else+ uint32_t num = (uint32_t)buf[0];+ num |= (uint32_t)buf[1] << 8;+ num |= (uint32_t)buf[2] << 16;+ num |= (uint32_t)buf[3] << 24;+ return num;+#endif+}+++// NOTE: Possible byte swapping must be done in a macro to allow the compiler+// to optimize byte swapping of constants when using glibc's or *BSD's+// byte swapping macros. The actual write is done in an inline function+// to make type checking of the buf pointer possible.+#if defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)+# define write16be(buf, num) write16ne(buf, conv16be(num))+# define write32be(buf, num) write32ne(buf, conv32be(num))+#endif++#if !defined(WORDS_BIGENDIAN) || defined(TUKLIB_FAST_UNALIGNED_ACCESS)+# define write16le(buf, num) write16ne(buf, conv16le(num))+# define write32le(buf, num) write32ne(buf, conv32le(num))+#endif+++#ifndef write16be+static inline void+write16be(uint8_t *buf, uint16_t num)+{+ buf[0] = (uint8_t)(num >> 8);+ buf[1] = (uint8_t)num;+ return;+}+#endif+++#ifndef write16le+static inline void+write16le(uint8_t *buf, uint16_t num)+{+ buf[0] = (uint8_t)num;+ buf[1] = (uint8_t)(num >> 8);+ return;+}+#endif+++#ifndef write32be+static inline void+write32be(uint8_t *buf, uint32_t num)+{+ buf[0] = (uint8_t)(num >> 24);+ buf[1] = (uint8_t)(num >> 16);+ buf[2] = (uint8_t)(num >> 8);+ buf[3] = (uint8_t)num;+ return;+}+#endif+++#ifndef write32le+static inline void+write32le(uint8_t *buf, uint32_t num)+{+ buf[0] = (uint8_t)num;+ buf[1] = (uint8_t)(num >> 8);+ buf[2] = (uint8_t)(num >> 16);+ buf[3] = (uint8_t)(num >> 24);+ return;+}+#endif+++//////////////////////////////+// Aligned reads and writes //+//////////////////////////////++// Separate functions for aligned reads and writes are provided since on+// strict-align archs aligned access is much faster than unaligned access.+//+// Just like in the unaligned case, memcpy() is needed to avoid+// strict aliasing violations. However, on archs that don't support+// unaligned access the compiler cannot know that the pointers given+// to memcpy() are aligned which results in slow code. As of C11 there is+// no standard way to tell the compiler that we know that the address is+// aligned but some compilers have language extensions to do that. With+// such language extensions the memcpy() method gives excellent results.+//+// What to do on a strict-align system when no known language extentensions+// are available? Falling back to byte-by-byte access would be safe but ruin+// optimizations that have been made specifically with aligned access in mind.+// As a compromise, aligned reads will fall back to non-compliant type punning+// but aligned writes will be byte-by-byte, that is, fast reads are preferred+// over fast writes. This obviously isn't great but hopefully it's a working+// compromise for now.+//+// __builtin_assume_aligned is support by GCC >= 4.7 and clang >= 3.6.+#ifdef HAVE___BUILTIN_ASSUME_ALIGNED+# define tuklib_memcpy_aligned(dest, src, size) \+ memcpy(dest, __builtin_assume_aligned(src, size), size)+#else+# define tuklib_memcpy_aligned(dest, src, size) \+ memcpy(dest, src, size)+# ifndef TUKLIB_FAST_UNALIGNED_ACCESS+# define TUKLIB_USE_UNSAFE_ALIGNED_READS 1+# endif+#endif+++static inline uint16_t+aligned_read16ne(const uint8_t *buf)+{+#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \+ || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)+ return *(const uint16_t *)buf;+#else+ uint16_t num;+ tuklib_memcpy_aligned(&num, buf, sizeof(num));+ return num;+#endif+}+++static inline uint32_t+aligned_read32ne(const uint8_t *buf)+{+#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \+ || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)+ return *(const uint32_t *)buf;+#else+ uint32_t num;+ tuklib_memcpy_aligned(&num, buf, sizeof(num));+ return num;+#endif+}+++static inline uint64_t+aligned_read64ne(const uint8_t *buf)+{+#if defined(TUKLIB_USE_UNSAFE_TYPE_PUNNING) \+ || defined(TUKLIB_USE_UNSAFE_ALIGNED_READS)+ return *(const uint64_t *)buf;+#else+ uint64_t num;+ tuklib_memcpy_aligned(&num, buf, sizeof(num));+ return num;+#endif+}+++static inline void+aligned_write16ne(uint8_t *buf, uint16_t num)+{+#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING+ *(uint16_t *)buf = num;+#else+ tuklib_memcpy_aligned(buf, &num, sizeof(num));+#endif+ return;+}+++static inline void+aligned_write32ne(uint8_t *buf, uint32_t num)+{+#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING+ *(uint32_t *)buf = num;+#else+ tuklib_memcpy_aligned(buf, &num, sizeof(num));+#endif+ return;+}+++static inline void+aligned_write64ne(uint8_t *buf, uint64_t num)+{+#ifdef TUKLIB_USE_UNSAFE_TYPE_PUNNING+ *(uint64_t *)buf = num;+#else+ tuklib_memcpy_aligned(buf, &num, sizeof(num));+#endif+ return;+}+++static inline uint16_t+aligned_read16be(const uint8_t *buf)+{+ uint16_t num = aligned_read16ne(buf);+ return conv16be(num);+}+++static inline uint16_t+aligned_read16le(const uint8_t *buf)+{+ uint16_t num = aligned_read16ne(buf);+ return conv16le(num);+}+++static inline uint32_t+aligned_read32be(const uint8_t *buf)+{+ uint32_t num = aligned_read32ne(buf);+ return conv32be(num);+}+++static inline uint32_t+aligned_read32le(const uint8_t *buf)+{+ uint32_t num = aligned_read32ne(buf);+ return conv32le(num);+}+++static inline uint64_t+aligned_read64be(const uint8_t *buf)+{+ uint64_t num = aligned_read64ne(buf);+ return conv64be(num);+}+++static inline uint64_t+aligned_read64le(const uint8_t *buf)+{+ uint64_t num = aligned_read64ne(buf);+ return conv64le(num);+}+++// These need to be macros like in the unaligned case.+#define aligned_write16be(buf, num) aligned_write16ne((buf), conv16be(num))+#define aligned_write16le(buf, num) aligned_write16ne((buf), conv16le(num))+#define aligned_write32be(buf, num) aligned_write32ne((buf), conv32be(num))+#define aligned_write32le(buf, num) aligned_write32ne((buf), conv32le(num))+#define aligned_write64be(buf, num) aligned_write64ne((buf), conv64be(num))+#define aligned_write64le(buf, num) aligned_write64ne((buf), conv64le(num))+++////////////////////+// Bit operations //+////////////////////++static inline uint32_t+bsr32(uint32_t n)+{+ // Check for ICC first, since it tends to define __GNUC__ too.+#if defined(__INTEL_COMPILER)+ return _bit_scan_reverse(n);++#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX+ // GCC >= 3.4 has __builtin_clz(), which gives good results on+ // multiple architectures. On x86, __builtin_clz() ^ 31U becomes+ // either plain BSR (so the XOR gets optimized away) or LZCNT and+ // XOR (if -march indicates that SSE4a instructions are supported).+ return (uint32_t)__builtin_clz(n) ^ 31U;++#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+ uint32_t i;+ __asm__("bsrl %1, %0" : "=r" (i) : "rm" (n));+ return i;++#elif defined(_MSC_VER)+ unsigned long i;+ _BitScanReverse(&i, n);+ return i;++#else+ uint32_t i = 31;++ if ((n & 0xFFFF0000) == 0) {+ n <<= 16;+ i = 15;+ }++ if ((n & 0xFF000000) == 0) {+ n <<= 8;+ i -= 8;+ }++ if ((n & 0xF0000000) == 0) {+ n <<= 4;+ i -= 4;+ }++ if ((n & 0xC0000000) == 0) {+ n <<= 2;+ i -= 2;+ }++ if ((n & 0x80000000) == 0)+ --i;++ return i;+#endif+}+++static inline uint32_t+clz32(uint32_t n)+{+#if defined(__INTEL_COMPILER)+ return _bit_scan_reverse(n) ^ 31U;++#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX+ return (uint32_t)__builtin_clz(n);++#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+ uint32_t i;+ __asm__("bsrl %1, %0\n\t"+ "xorl $31, %0"+ : "=r" (i) : "rm" (n));+ return i;++#elif defined(_MSC_VER)+ unsigned long i;+ _BitScanReverse(&i, n);+ return i ^ 31U;++#else+ uint32_t i = 0;++ if ((n & 0xFFFF0000) == 0) {+ n <<= 16;+ i = 16;+ }++ if ((n & 0xFF000000) == 0) {+ n <<= 8;+ i += 8;+ }++ if ((n & 0xF0000000) == 0) {+ n <<= 4;+ i += 4;+ }++ if ((n & 0xC0000000) == 0) {+ n <<= 2;+ i += 2;+ }++ if ((n & 0x80000000) == 0)+ ++i;++ return i;+#endif+}+++static inline uint32_t+ctz32(uint32_t n)+{+#if defined(__INTEL_COMPILER)+ return _bit_scan_forward(n);++#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX+ return (uint32_t)__builtin_ctz(n);++#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))+ uint32_t i;+ __asm__("bsfl %1, %0" : "=r" (i) : "rm" (n));+ return i;++#elif defined(_MSC_VER)+ unsigned long i;+ _BitScanForward(&i, n);+ return i;++#else+ uint32_t i = 0;++ if ((n & 0x0000FFFF) == 0) {+ n >>= 16;+ i = 16;+ }++ if ((n & 0x000000FF) == 0) {+ n >>= 8;+ i += 8;+ }++ if ((n & 0x0000000F) == 0) {+ n >>= 4;+ i += 4;+ }++ if ((n & 0x00000003) == 0) {+ n >>= 2;+ i += 2;+ }++ if ((n & 0x00000001) == 0)+ ++i;++ return i;+#endif+}++#define bsf32 ctz32++#endif
+ cbits/common/tuklib_mbstr.h view
@@ -0,0 +1,66 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_mbstr.h+/// \brief Utility functions for handling multibyte strings+///+/// If not enough multibyte string support is available in the C library,+/// these functions keep working with the assumption that all strings+/// are in a single-byte character set without combining characters, e.g.+/// US-ASCII or ISO-8859-*.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_MBSTR_H+#define TUKLIB_MBSTR_H++#include "tuklib_common.h"+TUKLIB_DECLS_BEGIN++#define tuklib_mbstr_width TUKLIB_SYMBOL(tuklib_mbstr_width)+extern size_t tuklib_mbstr_width(const char *str, size_t *bytes);+///<+/// \brief Get the number of columns needed for the multibyte string+///+/// This is somewhat similar to wcswidth() but works on multibyte strings.+///+/// \param str String whose width is to be calculated. If the+/// current locale uses a multibyte character set+/// that has shift states, the string must begin+/// and end in the initial shift state.+/// \param bytes If this is not NULL, *bytes is set to the+/// value returned by strlen(str) (even if an+/// error occurs when calculating the width).+///+/// \return On success, the number of columns needed to display the+/// string e.g. in a terminal emulator is returned. On error,+/// (size_t)-1 is returned. Possible errors include invalid,+/// partial, or non-printable multibyte character in str, or+/// that str doesn't end in the initial shift state.++#define tuklib_mbstr_fw TUKLIB_SYMBOL(tuklib_mbstr_fw)+extern int tuklib_mbstr_fw(const char *str, int columns_min);+///<+/// \brief Get the field width for printf() e.g. to align table columns+///+/// Printing simple tables to a terminal can be done using the field field+/// feature in the printf() format string, but it works only with single-byte+/// character sets. To do the same with multibyte strings, tuklib_mbstr_fw()+/// can be used to calculate appropriate field width.+///+/// The behavior of this function is undefined, if+/// - str is NULL or not terminated with '\0';+/// - columns_min <= 0; or+/// - the calculated field width exceeds INT_MAX.+///+/// \return If tuklib_mbstr_width(str, NULL) fails, -1 is returned.+/// If str needs more columns than columns_min, zero is returned.+/// Otherwise a positive integer is returned, which can be+/// used as the field width, e.g. printf("%*s", fw, str).++TUKLIB_DECLS_END+#endif
+ cbits/common/tuklib_mbstr_fw.c view
@@ -0,0 +1,31 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_mbstr_fw.c+/// \brief Get the field width for printf() e.g. to align table columns+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_mbstr.h"+++extern int+tuklib_mbstr_fw(const char *str, int columns_min)+{+ size_t len;+ const size_t width = tuklib_mbstr_width(str, &len);+ if (width == (size_t)-1)+ return -1;++ if (width > (size_t)columns_min)+ return 0;++ if (width < (size_t)columns_min)+ len += (size_t)columns_min - width;++ return len;+}
+ cbits/common/tuklib_mbstr_width.c view
@@ -0,0 +1,65 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_mbstr_width.c+/// \brief Calculate width of a multibyte string+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_mbstr.h"+#include <string.h>++#if defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)+# include <wchar.h>+#endif+++extern size_t+tuklib_mbstr_width(const char *str, size_t *bytes)+{+ const size_t len = strlen(str);+ if (bytes != NULL)+ *bytes = len;++#if !(defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH))+ // In single-byte mode, the width of the string is the same+ // as its length.+ return len;++#else+ mbstate_t state;+ memset(&state, 0, sizeof(state));++ size_t width = 0;+ size_t i = 0;++ // Convert one multibyte character at a time to wchar_t+ // and get its width using wcwidth().+ while (i < len) {+ wchar_t wc;+ const size_t ret = mbrtowc(&wc, str + i, len - i, &state);+ if (ret < 1 || ret > len)+ return (size_t)-1;++ i += ret;++ const int wc_width = wcwidth(wc);+ if (wc_width < 0)+ return (size_t)-1;++ width += (size_t)wc_width;+ }++ // Require that the string ends in the initial shift state.+ // This way the caller can be combine the string with other+ // strings without needing to worry about the shift states.+ if (!mbsinit(&state))+ return (size_t)-1;++ return width;+#endif+}
+ cbits/common/tuklib_open_stdxxx.c view
@@ -0,0 +1,57 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_open_stdxxx.c+/// \brief Make sure that file descriptors 0, 1, and 2 are open+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_open_stdxxx.h"++#ifndef TUKLIB_DOSLIKE+# include <stdlib.h>+# include <errno.h>+# include <fcntl.h>+# include <unistd.h>+#endif+++extern void+tuklib_open_stdxxx(int err_status)+{+#ifdef TUKLIB_DOSLIKE+ // Do nothing, just silence warnings.+ (void)err_status;++#else+ for (int i = 0; i <= 2; ++i) {+ // We use fcntl() to check if the file descriptor is open.+ if (fcntl(i, F_GETFD) == -1 && errno == EBADF) {+ // With stdin, we could use /dev/full so that+ // writing to stdin would fail. However, /dev/full+ // is Linux specific, and if the program tries to+ // write to stdin, there's already a problem anyway.+ const int fd = open("/dev/null", O_NOCTTY+ | (i == 0 ? O_WRONLY : O_RDONLY));++ if (fd != i) {+ if (fd != -1)+ (void)close(fd);++ // Something went wrong. Exit with the+ // exit status we were given. Don't try+ // to print an error message, since stderr+ // may very well be non-existent. This+ // error should be extremely rare.+ exit(err_status);+ }+ }+ }+#endif++ return;+}
+ cbits/common/tuklib_open_stdxxx.h view
@@ -0,0 +1,23 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_open_stdxxx.h+/// \brief Make sure that file descriptors 0, 1, and 2 are open+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_OPEN_STDXXX_H+#define TUKLIB_OPEN_STDXXX_H++#include "tuklib_common.h"+TUKLIB_DECLS_BEGIN++#define tuklib_open_stdxx TUKLIB_SYMBOL(tuklib_open_stdxxx)+extern void tuklib_open_stdxxx(int err_status);++TUKLIB_DECLS_END+#endif
+ cbits/common/tuklib_physmem.c view
@@ -0,0 +1,216 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_physmem.c+/// \brief Get the amount of physical memory+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_physmem.h"++// We want to use Windows-specific code on Cygwin, which also has memory+// information available via sysconf(), but on Cygwin 1.5 and older it+// gives wrong results (from our point of view).+#if defined(_WIN32) || defined(__CYGWIN__)+# ifndef _WIN32_WINNT+# define _WIN32_WINNT 0x0500+# endif+# include <windows.h>++#elif defined(__OS2__)+# define INCL_DOSMISC+# include <os2.h>++#elif defined(__DJGPP__)+# include <dpmi.h>++#elif defined(__VMS)+# include <lib$routines.h>+# include <syidef.h>+# include <ssdef.h>++#elif defined(AMIGA) || defined(__AROS__)+# define __USE_INLINE__+# include <proto/exec.h>++#elif defined(__QNX__)+# include <sys/syspage.h>+# include <string.h>++#elif defined(TUKLIB_PHYSMEM_AIX)+# include <sys/systemcfg.h>++#elif defined(TUKLIB_PHYSMEM_SYSCONF)+# include <unistd.h>++#elif defined(TUKLIB_PHYSMEM_SYSCTL)+# ifdef HAVE_SYS_PARAM_H+# include <sys/param.h>+# endif+# include <sys/sysctl.h>++// Tru64+#elif defined(TUKLIB_PHYSMEM_GETSYSINFO)+# include <sys/sysinfo.h>+# include <machine/hal_sysinfo.h>++// HP-UX+#elif defined(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)+# include <sys/param.h>+# include <sys/pstat.h>++// IRIX+#elif defined(TUKLIB_PHYSMEM_GETINVENT_R)+# include <invent.h>++// This sysinfo() is Linux-specific.+#elif defined(TUKLIB_PHYSMEM_SYSINFO)+# include <sys/sysinfo.h>+#endif+++extern uint64_t+tuklib_physmem(void)+{+ uint64_t ret = 0;++#if defined(_WIN32) || defined(__CYGWIN__)+ if ((GetVersion() & 0xFF) >= 5) {+ // Windows 2000 and later have GlobalMemoryStatusEx() which+ // supports reporting values greater than 4 GiB. To keep the+ // code working also on older Windows versions, use+ // GlobalMemoryStatusEx() conditionally.+ HMODULE kernel32 = GetModuleHandle("kernel32.dll");+ if (kernel32 != NULL) {+ typedef BOOL (WINAPI *gmse_type)(LPMEMORYSTATUSEX);+ gmse_type gmse = (gmse_type)GetProcAddress(+ kernel32, "GlobalMemoryStatusEx");+ if (gmse != NULL) {+ MEMORYSTATUSEX meminfo;+ meminfo.dwLength = sizeof(meminfo);+ if (gmse(&meminfo))+ ret = meminfo.ullTotalPhys;+ }+ }+ }++ if (ret == 0) {+ // GlobalMemoryStatus() is supported by Windows 95 and later,+ // so it is fine to link against it unconditionally. Note that+ // GlobalMemoryStatus() has no return value.+ MEMORYSTATUS meminfo;+ meminfo.dwLength = sizeof(meminfo);+ GlobalMemoryStatus(&meminfo);+ ret = meminfo.dwTotalPhys;+ }++#elif defined(__OS2__)+ unsigned long mem;+ if (DosQuerySysInfo(QSV_TOTPHYSMEM, QSV_TOTPHYSMEM,+ &mem, sizeof(mem)) == 0)+ ret = mem;++#elif defined(__DJGPP__)+ __dpmi_free_mem_info meminfo;+ if (__dpmi_get_free_memory_information(&meminfo) == 0+ && meminfo.total_number_of_physical_pages+ != (unsigned long)-1)+ ret = (uint64_t)meminfo.total_number_of_physical_pages * 4096;++#elif defined(__VMS)+ int vms_mem;+ int val = SYI$_MEMSIZE;+ if (LIB$GETSYI(&val, &vms_mem, 0, 0, 0, 0) == SS$_NORMAL)+ ret = (uint64_t)vms_mem * 8192;++#elif defined(AMIGA) || defined(__AROS__)+ ret = AvailMem(MEMF_TOTAL);++#elif defined(__QNX__)+ const struct asinfo_entry *entries = SYSPAGE_ENTRY(asinfo);+ size_t count = SYSPAGE_ENTRY_SIZE(asinfo) / sizeof(struct asinfo_entry);+ const char *strings = SYSPAGE_ENTRY(strings)->data;++ for (size_t i = 0; i < count; ++i)+ if (strcmp(strings + entries[i].name, "ram") == 0)+ ret += entries[i].end - entries[i].start + 1;++#elif defined(TUKLIB_PHYSMEM_AIX)+ ret = _system_configuration.physmem;++#elif defined(TUKLIB_PHYSMEM_SYSCONF)+ const long pagesize = sysconf(_SC_PAGESIZE);+ const long pages = sysconf(_SC_PHYS_PAGES);+ if (pagesize != -1 && pages != -1)+ // According to docs, pagesize * pages can overflow.+ // Simple case is 32-bit box with 4 GiB or more RAM,+ // which may report exactly 4 GiB of RAM, and "long"+ // being 32-bit will overflow. Casting to uint64_t+ // hopefully avoids overflows in the near future.+ ret = (uint64_t)pagesize * (uint64_t)pages;++#elif defined(TUKLIB_PHYSMEM_SYSCTL)+ int name[2] = {+ CTL_HW,+#ifdef HW_PHYSMEM64+ HW_PHYSMEM64+#else+ HW_PHYSMEM+#endif+ };+ union {+ uint32_t u32;+ uint64_t u64;+ } mem;+ size_t mem_ptr_size = sizeof(mem.u64);+ if (sysctl(name, 2, &mem.u64, &mem_ptr_size, NULL, 0) != -1) {+ // IIRC, 64-bit "return value" is possible on some 64-bit+ // BSD systems even with HW_PHYSMEM (instead of HW_PHYSMEM64),+ // so support both.+ if (mem_ptr_size == sizeof(mem.u64))+ ret = mem.u64;+ else if (mem_ptr_size == sizeof(mem.u32))+ ret = mem.u32;+ }++#elif defined(TUKLIB_PHYSMEM_GETSYSINFO)+ // Docs are unclear if "start" is needed, but it doesn't hurt+ // much to have it.+ int memkb;+ int start = 0;+ if (getsysinfo(GSI_PHYSMEM, (caddr_t)&memkb, sizeof(memkb), &start)+ != -1)+ ret = (uint64_t)memkb * 1024;++#elif defined(TUKLIB_PHYSMEM_PSTAT_GETSTATIC)+ struct pst_static pst;+ if (pstat_getstatic(&pst, sizeof(pst), 1, 0) != -1)+ ret = (uint64_t)pst.physical_memory * (uint64_t)pst.page_size;++#elif defined(TUKLIB_PHYSMEM_GETINVENT_R)+ inv_state_t *st = NULL;+ if (setinvent_r(&st) != -1) {+ inventory_t *i;+ while ((i = getinvent_r(st)) != NULL) {+ if (i->inv_class == INV_MEMORY+ && i->inv_type == INV_MAIN_MB) {+ ret = (uint64_t)i->inv_state << 20;+ break;+ }+ }++ endinvent_r(st);+ }++#elif defined(TUKLIB_PHYSMEM_SYSINFO)+ struct sysinfo si;+ if (sysinfo(&si) == 0)+ ret = (uint64_t)si.totalram * si.mem_unit;+#endif++ return ret;+}
+ cbits/common/tuklib_physmem.h view
@@ -0,0 +1,28 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_physmem.h+/// \brief Get the amount of physical memory+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_PHYSMEM_H+#define TUKLIB_PHYSMEM_H++#include "tuklib_common.h"+TUKLIB_DECLS_BEGIN++#define tuklib_physmem TUKLIB_SYMBOL(tuklib_physmem)+extern uint64_t tuklib_physmem(void);+///<+/// \brief Get the amount of physical memory in bytes+///+/// \return Amount of physical memory in bytes. On error, zero is+/// returned.++TUKLIB_DECLS_END+#endif
+ cbits/common/tuklib_progname.c view
@@ -0,0 +1,50 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_progname.c+/// \brief Program name to be displayed in messages+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "tuklib_progname.h"+#include <string.h>+++#if !HAVE_DECL_PROGRAM_INVOCATION_NAME+char *progname = NULL;+#endif+++extern void+tuklib_progname_init(char **argv)+{+#ifdef TUKLIB_DOSLIKE+ // On these systems, argv[0] always has the full path and .exe+ // suffix even if the user just types the plain program name.+ // We modify argv[0] to make it nicer to read.++ // Strip the leading path.+ char *p = argv[0] + strlen(argv[0]);+ while (argv[0] < p && p[-1] != '/' && p[-1] != '\\')+ --p;++ argv[0] = p;++ // Strip the .exe suffix.+ p = strrchr(p, '.');+ if (p != NULL)+ *p = '\0';++ // Make it lowercase.+ for (p = argv[0]; *p != '\0'; ++p)+ if (*p >= 'A' && *p <= 'Z')+ *p = *p - 'A' + 'a';+#endif++ progname = argv[0];+ return;+}
+ cbits/common/tuklib_progname.h view
@@ -0,0 +1,32 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file tuklib_progname.h+/// \brief Program name to be displayed in messages+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef TUKLIB_PROGNAME_H+#define TUKLIB_PROGNAME_H++#include "tuklib_common.h"+#include <errno.h>++TUKLIB_DECLS_BEGIN++#if HAVE_DECL_PROGRAM_INVOCATION_NAME+# define progname program_invocation_name+#else+# define progname TUKLIB_SYMBOL(tuklib_progname)+ extern char *progname;+#endif++#define tuklib_progname_init TUKLIB_SYMBOL(tuklib_progname_init)+extern void tuklib_progname_init(char **argv);++TUKLIB_DECLS_END+#endif
+ cbits/liblzma/api/lzma.h view
@@ -0,0 +1,326 @@+/**+ * \file api/lzma.h+ * \brief The public API of liblzma data compression library+ *+ * liblzma is a public domain general-purpose data compression library with+ * a zlib-like API. The native file format is .xz, but also the old .lzma+ * format and raw (no headers) streams are supported. Multiple compression+ * algorithms (filters) are supported. Currently LZMA2 is the primary filter.+ *+ * liblzma is part of XZ Utils <http://tukaani.org/xz/>. XZ Utils includes+ * a gzip-like command line tool named xz and some other tools. XZ Utils+ * is developed and maintained by Lasse Collin.+ *+ * Major parts of liblzma are based on Igor Pavlov's public domain LZMA SDK+ * <http://7-zip.org/sdk.html>.+ *+ * The SHA-256 implementation is based on the public domain code found from+ * 7-Zip <http://7-zip.org/>, which has a modified version of the public+ * domain SHA-256 code found from Crypto++ <http://www.cryptopp.com/>.+ * The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai.+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ */++#ifndef LZMA_H+#define LZMA_H++/*****************************+ * Required standard headers *+ *****************************/++/*+ * liblzma API headers need some standard types and macros. To allow+ * including lzma.h without requiring the application to include other+ * headers first, lzma.h includes the required standard headers unless+ * they already seem to be included already or if LZMA_MANUAL_HEADERS+ * has been defined.+ *+ * Here's what types and macros are needed and from which headers:+ * - stddef.h: size_t, NULL+ * - stdint.h: uint8_t, uint32_t, uint64_t, UINT32_C(n), uint64_C(n),+ * UINT32_MAX, UINT64_MAX+ *+ * However, inttypes.h is a little more portable than stdint.h, although+ * inttypes.h declares some unneeded things compared to plain stdint.h.+ *+ * The hacks below aren't perfect, specifically they assume that inttypes.h+ * exists and that it typedefs at least uint8_t, uint32_t, and uint64_t,+ * and that, in case of incomplete inttypes.h, unsigned int is 32-bit.+ * If the application already takes care of setting up all the types and+ * macros properly (for example by using gnulib's stdint.h or inttypes.h),+ * we try to detect that the macros are already defined and don't include+ * inttypes.h here again. However, you may define LZMA_MANUAL_HEADERS to+ * force this file to never include any system headers.+ *+ * Some could argue that liblzma API should provide all the required types,+ * for example lzma_uint64, LZMA_UINT64_C(n), and LZMA_UINT64_MAX. This was+ * seen as an unnecessary mess, since most systems already provide all the+ * necessary types and macros in the standard headers.+ *+ * Note that liblzma API still has lzma_bool, because using stdbool.h would+ * break C89 and C++ programs on many systems. sizeof(bool) in C99 isn't+ * necessarily the same as sizeof(bool) in C++.+ */++#ifndef LZMA_MANUAL_HEADERS+ /*+ * I suppose this works portably also in C++. Note that in C++,+ * we need to get size_t into the global namespace.+ */+# include <stddef.h>++ /*+ * Skip inttypes.h if we already have all the required macros. If we+ * have the macros, we assume that we have the matching typedefs too.+ */+# if !defined(UINT32_C) || !defined(UINT64_C) \+ || !defined(UINT32_MAX) || !defined(UINT64_MAX)+ /*+ * MSVC versions older than 2013 have no C99 support, and+ * thus they cannot be used to compile liblzma. Using an+ * existing liblzma.dll with old MSVC can work though(*),+ * but we need to define the required standard integer+ * types here in a MSVC-specific way.+ *+ * (*) If you do this, the existing liblzma.dll probably uses+ * a different runtime library than your MSVC-built+ * application. Mixing runtimes is generally bad, but+ * in this case it should work as long as you avoid+ * the few rarely-needed liblzma functions that allocate+ * memory and expect the caller to free it using free().+ */+# if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1800+ typedef unsigned __int8 uint8_t;+ typedef unsigned __int32 uint32_t;+ typedef unsigned __int64 uint64_t;+# else+ /* Use the standard inttypes.h. */+# ifdef __cplusplus+ /*+ * C99 sections 7.18.2 and 7.18.4 specify+ * that C++ implementations define the limit+ * and constant macros only if specifically+ * requested. Note that if you want the+ * format macros (PRIu64 etc.) too, you need+ * to define __STDC_FORMAT_MACROS before+ * including lzma.h, since re-including+ * inttypes.h with __STDC_FORMAT_MACROS+ * defined doesn't necessarily work.+ */+# ifndef __STDC_LIMIT_MACROS+# define __STDC_LIMIT_MACROS 1+# endif+# ifndef __STDC_CONSTANT_MACROS+# define __STDC_CONSTANT_MACROS 1+# endif+# endif++# include <inttypes.h>+# endif++ /*+ * Some old systems have only the typedefs in inttypes.h, and+ * lack all the macros. For those systems, we need a few more+ * hacks. We assume that unsigned int is 32-bit and unsigned+ * long is either 32-bit or 64-bit. If these hacks aren't+ * enough, the application has to setup the types manually+ * before including lzma.h.+ */+# ifndef UINT32_C+# if defined(_WIN32) && defined(_MSC_VER)+# define UINT32_C(n) n ## UI32+# else+# define UINT32_C(n) n ## U+# endif+# endif++# ifndef UINT64_C+# if defined(_WIN32) && defined(_MSC_VER)+# define UINT64_C(n) n ## UI64+# else+ /* Get ULONG_MAX. */+# include <limits.h>+# if ULONG_MAX == 4294967295UL+# define UINT64_C(n) n ## ULL+# else+# define UINT64_C(n) n ## UL+# endif+# endif+# endif++# ifndef UINT32_MAX+# define UINT32_MAX (UINT32_C(4294967295))+# endif++# ifndef UINT64_MAX+# define UINT64_MAX (UINT64_C(18446744073709551615))+# endif+# endif+#endif /* ifdef LZMA_MANUAL_HEADERS */+++/******************+ * LZMA_API macro *+ ******************/++/*+ * Some systems require that the functions and function pointers are+ * declared specially in the headers. LZMA_API_IMPORT is for importing+ * symbols and LZMA_API_CALL is to specify the calling convention.+ *+ * By default it is assumed that the application will link dynamically+ * against liblzma. #define LZMA_API_STATIC in your application if you+ * want to link against static liblzma. If you don't care about portability+ * to operating systems like Windows, or at least don't care about linking+ * against static liblzma on them, don't worry about LZMA_API_STATIC. That+ * is, most developers will never need to use LZMA_API_STATIC.+ *+ * The GCC variants are a special case on Windows (Cygwin and MinGW).+ * We rely on GCC doing the right thing with its auto-import feature,+ * and thus don't use __declspec(dllimport). This way developers don't+ * need to worry about LZMA_API_STATIC. Also the calling convention is+ * omitted on Cygwin but not on MinGW.+ */+#ifndef LZMA_API_IMPORT+# if !defined(LZMA_API_STATIC) && defined(_WIN32) && !defined(__GNUC__)+# define LZMA_API_IMPORT __declspec(dllimport)+# else+# define LZMA_API_IMPORT+# endif+#endif++#ifndef LZMA_API_CALL+# if defined(_WIN32) && !defined(__CYGWIN__)+# define LZMA_API_CALL __cdecl+# else+# define LZMA_API_CALL+# endif+#endif++#ifndef LZMA_API+# define LZMA_API(type) LZMA_API_IMPORT type LZMA_API_CALL+#endif+++/***********+ * nothrow *+ ***********/++/*+ * None of the functions in liblzma may throw an exception. Even+ * the functions that use callback functions won't throw exceptions,+ * because liblzma would break if a callback function threw an exception.+ */+#ifndef lzma_nothrow+# if defined(__cplusplus)+# if __cplusplus >= 201103L+# define lzma_nothrow noexcept+# else+# define lzma_nothrow throw()+# endif+# elif defined(__GNUC__) && (__GNUC__ > 3 \+ || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))+# define lzma_nothrow __attribute__((__nothrow__))+# else+# define lzma_nothrow+# endif+#endif+++/********************+ * GNU C extensions *+ ********************/++/*+ * GNU C extensions are used conditionally in the public API. It doesn't+ * break anything if these are sometimes enabled and sometimes not, only+ * affects warnings and optimizations.+ */+#if defined(__GNUC__) && __GNUC__ >= 3+# ifndef lzma_attribute+# define lzma_attribute(attr) __attribute__(attr)+# endif++ /* warn_unused_result was added in GCC 3.4. */+# ifndef lzma_attr_warn_unused_result+# if __GNUC__ == 3 && __GNUC_MINOR__ < 4+# define lzma_attr_warn_unused_result+# endif+# endif++#else+# ifndef lzma_attribute+# define lzma_attribute(attr)+# endif+#endif+++#ifndef lzma_attr_pure+# define lzma_attr_pure lzma_attribute((__pure__))+#endif++#ifndef lzma_attr_const+# define lzma_attr_const lzma_attribute((__const__))+#endif++#ifndef lzma_attr_warn_unused_result+# define lzma_attr_warn_unused_result \+ lzma_attribute((__warn_unused_result__))+#endif+++/**************+ * Subheaders *+ **************/++#ifdef __cplusplus+extern "C" {+#endif++/*+ * Subheaders check that this is defined. It is to prevent including+ * them directly from applications.+ */+#define LZMA_H_INTERNAL 1++/* Basic features */+#include "lzma/version.h"+#include "lzma/base.h"+#include "lzma/vli.h"+#include "lzma/check.h"++/* Filters */+#include "lzma/filter.h"+#include "lzma/bcj.h"+#include "lzma/delta.h"+#include "lzma/lzma12.h"++/* Container formats */+#include "lzma/container.h"++/* Advanced features */+#include "lzma/stream_flags.h"+#include "lzma/block.h"+#include "lzma/index.h"+#include "lzma/index_hash.h"++/* Hardware information */+#include "lzma/hardware.h"++/*+ * All subheaders included. Undefine LZMA_H_INTERNAL to prevent applications+ * re-including the subheaders.+ */+#undef LZMA_H_INTERNAL++#ifdef __cplusplus+}+#endif++#endif /* ifndef LZMA_H */
+ cbits/liblzma/api/lzma/base.h view
@@ -0,0 +1,659 @@+/**+ * \file lzma/base.h+ * \brief Data types and functions used in many places in liblzma API+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Boolean+ *+ * This is here because C89 doesn't have stdbool.h. To set a value for+ * variables having type lzma_bool, you can use+ * - C99's `true' and `false' from stdbool.h;+ * - C++'s internal `true' and `false'; or+ * - integers one (true) and zero (false).+ */+typedef unsigned char lzma_bool;+++/**+ * \brief Type of reserved enumeration variable in structures+ *+ * To avoid breaking library ABI when new features are added, several+ * structures contain extra variables that may be used in future. Since+ * sizeof(enum) can be different than sizeof(int), and sizeof(enum) may+ * even vary depending on the range of enumeration constants, we specify+ * a separate type to be used for reserved enumeration variables. All+ * enumeration constants in liblzma API will be non-negative and less+ * than 128, which should guarantee that the ABI won't break even when+ * new constants are added to existing enumerations.+ */+typedef enum {+ LZMA_RESERVED_ENUM = 0+} lzma_reserved_enum;+++/**+ * \brief Return values used by several functions in liblzma+ *+ * Check the descriptions of specific functions to find out which return+ * values they can return. With some functions the return values may have+ * more specific meanings than described here; those differences are+ * described per-function basis.+ */+typedef enum {+ LZMA_OK = 0,+ /**<+ * \brief Operation completed successfully+ */++ LZMA_STREAM_END = 1,+ /**<+ * \brief End of stream was reached+ *+ * In encoder, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or+ * LZMA_FINISH was finished. In decoder, this indicates+ * that all the data was successfully decoded.+ *+ * In all cases, when LZMA_STREAM_END is returned, the last+ * output bytes should be picked from strm->next_out.+ */++ LZMA_NO_CHECK = 2,+ /**<+ * \brief Input stream has no integrity check+ *+ * This return value can be returned only if the+ * LZMA_TELL_NO_CHECK flag was used when initializing+ * the decoder. LZMA_NO_CHECK is just a warning, and+ * the decoding can be continued normally.+ *+ * It is possible to call lzma_get_check() immediately after+ * lzma_code has returned LZMA_NO_CHECK. The result will+ * naturally be LZMA_CHECK_NONE, but the possibility to call+ * lzma_get_check() may be convenient in some applications.+ */++ LZMA_UNSUPPORTED_CHECK = 3,+ /**<+ * \brief Cannot calculate the integrity check+ *+ * The usage of this return value is different in encoders+ * and decoders.+ *+ * Encoders can return this value only from the initialization+ * function. If initialization fails with this value, the+ * encoding cannot be done, because there's no way to produce+ * output with the correct integrity check.+ *+ * Decoders can return this value only from lzma_code() and+ * only if the LZMA_TELL_UNSUPPORTED_CHECK flag was used when+ * initializing the decoder. The decoding can still be+ * continued normally even if the check type is unsupported,+ * but naturally the check will not be validated, and possible+ * errors may go undetected.+ *+ * With decoder, it is possible to call lzma_get_check()+ * immediately after lzma_code() has returned+ * LZMA_UNSUPPORTED_CHECK. This way it is possible to find+ * out what the unsupported Check ID was.+ */++ LZMA_GET_CHECK = 4,+ /**<+ * \brief Integrity check type is now available+ *+ * This value can be returned only by the lzma_code() function+ * and only if the decoder was initialized with the+ * LZMA_TELL_ANY_CHECK flag. LZMA_GET_CHECK tells the+ * application that it may now call lzma_get_check() to find+ * out the Check ID. This can be used, for example, to+ * implement a decoder that accepts only files that have+ * strong enough integrity check.+ */++ LZMA_MEM_ERROR = 5,+ /**<+ * \brief Cannot allocate memory+ *+ * Memory allocation failed, or the size of the allocation+ * would be greater than SIZE_MAX.+ *+ * Due to internal implementation reasons, the coding cannot+ * be continued even if more memory were made available after+ * LZMA_MEM_ERROR.+ */++ LZMA_MEMLIMIT_ERROR = 6,+ /**+ * \brief Memory usage limit was reached+ *+ * Decoder would need more memory than allowed by the+ * specified memory usage limit. To continue decoding,+ * the memory usage limit has to be increased with+ * lzma_memlimit_set().+ */++ LZMA_FORMAT_ERROR = 7,+ /**<+ * \brief File format not recognized+ *+ * The decoder did not recognize the input as supported file+ * format. This error can occur, for example, when trying to+ * decode .lzma format file with lzma_stream_decoder,+ * because lzma_stream_decoder accepts only the .xz format.+ */++ LZMA_OPTIONS_ERROR = 8,+ /**<+ * \brief Invalid or unsupported options+ *+ * Invalid or unsupported options, for example+ * - unsupported filter(s) or filter options; or+ * - reserved bits set in headers (decoder only).+ *+ * Rebuilding liblzma with more features enabled, or+ * upgrading to a newer version of liblzma may help.+ */++ LZMA_DATA_ERROR = 9,+ /**<+ * \brief Data is corrupt+ *+ * The usage of this return value is different in encoders+ * and decoders. In both encoder and decoder, the coding+ * cannot continue after this error.+ *+ * Encoders return this if size limits of the target file+ * format would be exceeded. These limits are huge, thus+ * getting this error from an encoder is mostly theoretical.+ * For example, the maximum compressed and uncompressed+ * size of a .xz Stream is roughly 8 EiB (2^63 bytes).+ *+ * Decoders return this error if the input data is corrupt.+ * This can mean, for example, invalid CRC32 in headers+ * or invalid check of uncompressed data.+ */++ LZMA_BUF_ERROR = 10,+ /**<+ * \brief No progress is possible+ *+ * This error code is returned when the coder cannot consume+ * any new input and produce any new output. The most common+ * reason for this error is that the input stream being+ * decoded is truncated or corrupt.+ *+ * This error is not fatal. Coding can be continued normally+ * by providing more input and/or more output space, if+ * possible.+ *+ * Typically the first call to lzma_code() that can do no+ * progress returns LZMA_OK instead of LZMA_BUF_ERROR. Only+ * the second consecutive call doing no progress will return+ * LZMA_BUF_ERROR. This is intentional.+ *+ * With zlib, Z_BUF_ERROR may be returned even if the+ * application is doing nothing wrong, so apps will need+ * to handle Z_BUF_ERROR specially. The above hack+ * guarantees that liblzma never returns LZMA_BUF_ERROR+ * to properly written applications unless the input file+ * is truncated or corrupt. This should simplify the+ * applications a little.+ */++ LZMA_PROG_ERROR = 11,+ /**<+ * \brief Programming error+ *+ * This indicates that the arguments given to the function are+ * invalid or the internal state of the decoder is corrupt.+ * - Function arguments are invalid or the structures+ * pointed by the argument pointers are invalid+ * e.g. if strm->next_out has been set to NULL and+ * strm->avail_out > 0 when calling lzma_code().+ * - lzma_* functions have been called in wrong order+ * e.g. lzma_code() was called right after lzma_end().+ * - If errors occur randomly, the reason might be flaky+ * hardware.+ *+ * If you think that your code is correct, this error code+ * can be a sign of a bug in liblzma. See the documentation+ * how to report bugs.+ */+} lzma_ret;+++/**+ * \brief The `action' argument for lzma_code()+ *+ * After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FULL_BARRIER,+ * or LZMA_FINISH, the same `action' must is used until lzma_code() returns+ * LZMA_STREAM_END. Also, the amount of input (that is, strm->avail_in) must+ * not be modified by the application until lzma_code() returns+ * LZMA_STREAM_END. Changing the `action' or modifying the amount of input+ * will make lzma_code() return LZMA_PROG_ERROR.+ */+typedef enum {+ LZMA_RUN = 0,+ /**<+ * \brief Continue coding+ *+ * Encoder: Encode as much input as possible. Some internal+ * buffering will probably be done (depends on the filter+ * chain in use), which causes latency: the input used won't+ * usually be decodeable from the output of the same+ * lzma_code() call.+ *+ * Decoder: Decode as much input as possible and produce as+ * much output as possible.+ */++ LZMA_SYNC_FLUSH = 1,+ /**<+ * \brief Make all the input available at output+ *+ * Normally the encoder introduces some latency.+ * LZMA_SYNC_FLUSH forces all the buffered data to be+ * available at output without resetting the internal+ * state of the encoder. This way it is possible to use+ * compressed stream for example for communication over+ * network.+ *+ * Only some filters support LZMA_SYNC_FLUSH. Trying to use+ * LZMA_SYNC_FLUSH with filters that don't support it will+ * make lzma_code() return LZMA_OPTIONS_ERROR. For example,+ * LZMA1 doesn't support LZMA_SYNC_FLUSH but LZMA2 does.+ *+ * Using LZMA_SYNC_FLUSH very often can dramatically reduce+ * the compression ratio. With some filters (for example,+ * LZMA2), fine-tuning the compression options may help+ * mitigate this problem significantly (for example,+ * match finder with LZMA2).+ *+ * Decoders don't support LZMA_SYNC_FLUSH.+ */++ LZMA_FULL_FLUSH = 2,+ /**<+ * \brief Finish encoding of the current Block+ *+ * All the input data going to the current Block must have+ * been given to the encoder (the last bytes can still be+ * pending in *next_in). Call lzma_code() with LZMA_FULL_FLUSH+ * until it returns LZMA_STREAM_END. Then continue normally+ * with LZMA_RUN or finish the Stream with LZMA_FINISH.+ *+ * This action is currently supported only by Stream encoder+ * and easy encoder (which uses Stream encoder). If there is+ * no unfinished Block, no empty Block is created.+ */++ LZMA_FULL_BARRIER = 4,+ /**<+ * \brief Finish encoding of the current Block+ *+ * This is like LZMA_FULL_FLUSH except that this doesn't+ * necessarily wait until all the input has been made+ * available via the output buffer. That is, lzma_code()+ * might return LZMA_STREAM_END as soon as all the input+ * has been consumed (avail_in == 0).+ *+ * LZMA_FULL_BARRIER is useful with a threaded encoder if+ * one wants to split the .xz Stream into Blocks at specific+ * offsets but doesn't care if the output isn't flushed+ * immediately. Using LZMA_FULL_BARRIER allows keeping+ * the threads busy while LZMA_FULL_FLUSH would make+ * lzma_code() wait until all the threads have finished+ * until more data could be passed to the encoder.+ *+ * With a lzma_stream initialized with the single-threaded+ * lzma_stream_encoder() or lzma_easy_encoder(),+ * LZMA_FULL_BARRIER is an alias for LZMA_FULL_FLUSH.+ */++ LZMA_FINISH = 3+ /**<+ * \brief Finish the coding operation+ *+ * All the input data must have been given to the encoder+ * (the last bytes can still be pending in next_in).+ * Call lzma_code() with LZMA_FINISH until it returns+ * LZMA_STREAM_END. Once LZMA_FINISH has been used,+ * the amount of input must no longer be changed by+ * the application.+ *+ * When decoding, using LZMA_FINISH is optional unless the+ * LZMA_CONCATENATED flag was used when the decoder was+ * initialized. When LZMA_CONCATENATED was not used, the only+ * effect of LZMA_FINISH is that the amount of input must not+ * be changed just like in the encoder.+ */+} lzma_action;+++/**+ * \brief Custom functions for memory handling+ *+ * A pointer to lzma_allocator may be passed via lzma_stream structure+ * to liblzma, and some advanced functions take a pointer to lzma_allocator+ * as a separate function argument. The library will use the functions+ * specified in lzma_allocator for memory handling instead of the default+ * malloc() and free(). C++ users should note that the custom memory+ * handling functions must not throw exceptions.+ *+ * Single-threaded mode only: liblzma doesn't make an internal copy of+ * lzma_allocator. Thus, it is OK to change these function pointers in+ * the middle of the coding process, but obviously it must be done+ * carefully to make sure that the replacement `free' can deallocate+ * memory allocated by the earlier `alloc' function(s).+ *+ * Multithreaded mode: liblzma might internally store pointers to the+ * lzma_allocator given via the lzma_stream structure. The application+ * must not change the allocator pointer in lzma_stream or the contents+ * of the pointed lzma_allocator structure until lzma_end() has been used+ * to free the memory associated with that lzma_stream. The allocation+ * functions might be called simultaneously from multiple threads, and+ * thus they must be thread safe.+ */+typedef struct {+ /**+ * \brief Pointer to a custom memory allocation function+ *+ * If you don't want a custom allocator, but still want+ * custom free(), set this to NULL and liblzma will use+ * the standard malloc().+ *+ * \param opaque lzma_allocator.opaque (see below)+ * \param nmemb Number of elements like in calloc(). liblzma+ * will always set nmemb to 1, so it is safe to+ * ignore nmemb in a custom allocator if you like.+ * The nmemb argument exists only for+ * compatibility with zlib and libbzip2.+ * \param size Size of an element in bytes.+ * liblzma never sets this to zero.+ *+ * \return Pointer to the beginning of a memory block of+ * `size' bytes, or NULL if allocation fails+ * for some reason. When allocation fails, functions+ * of liblzma return LZMA_MEM_ERROR.+ *+ * The allocator should not waste time zeroing the allocated buffers.+ * This is not only about speed, but also memory usage, since the+ * operating system kernel doesn't necessarily allocate the requested+ * memory in physical memory until it is actually used. With small+ * input files, liblzma may actually need only a fraction of the+ * memory that it requested for allocation.+ *+ * \note LZMA_MEM_ERROR is also used when the size of the+ * allocation would be greater than SIZE_MAX. Thus,+ * don't assume that the custom allocator must have+ * returned NULL if some function from liblzma+ * returns LZMA_MEM_ERROR.+ */+ void *(LZMA_API_CALL *alloc)(void *opaque, size_t nmemb, size_t size);++ /**+ * \brief Pointer to a custom memory freeing function+ *+ * If you don't want a custom freeing function, but still+ * want a custom allocator, set this to NULL and liblzma+ * will use the standard free().+ *+ * \param opaque lzma_allocator.opaque (see below)+ * \param ptr Pointer returned by lzma_allocator.alloc(),+ * or when it is set to NULL, a pointer returned+ * by the standard malloc().+ */+ void (LZMA_API_CALL *free)(void *opaque, void *ptr);++ /**+ * \brief Pointer passed to .alloc() and .free()+ *+ * opaque is passed as the first argument to lzma_allocator.alloc()+ * and lzma_allocator.free(). This intended to ease implementing+ * custom memory allocation functions for use with liblzma.+ *+ * If you don't need this, you should set this to NULL.+ */+ void *opaque;++} lzma_allocator;+++/**+ * \brief Internal data structure+ *+ * The contents of this structure is not visible outside the library.+ */+typedef struct lzma_internal_s lzma_internal;+++/**+ * \brief Passing data to and from liblzma+ *+ * The lzma_stream structure is used for+ * - passing pointers to input and output buffers to liblzma;+ * - defining custom memory hander functions; and+ * - holding a pointer to coder-specific internal data structures.+ *+ * Typical usage:+ *+ * - After allocating lzma_stream (on stack or with malloc()), it must be+ * initialized to LZMA_STREAM_INIT (see LZMA_STREAM_INIT for details).+ *+ * - Initialize a coder to the lzma_stream, for example by using+ * lzma_easy_encoder() or lzma_auto_decoder(). Some notes:+ * - In contrast to zlib, strm->next_in and strm->next_out are+ * ignored by all initialization functions, thus it is safe+ * to not initialize them yet.+ * - The initialization functions always set strm->total_in and+ * strm->total_out to zero.+ * - If the initialization function fails, no memory is left allocated+ * that would require freeing with lzma_end() even if some memory was+ * associated with the lzma_stream structure when the initialization+ * function was called.+ *+ * - Use lzma_code() to do the actual work.+ *+ * - Once the coding has been finished, the existing lzma_stream can be+ * reused. It is OK to reuse lzma_stream with different initialization+ * function without calling lzma_end() first. Old allocations are+ * automatically freed.+ *+ * - Finally, use lzma_end() to free the allocated memory. lzma_end() never+ * frees the lzma_stream structure itself.+ *+ * Application may modify the values of total_in and total_out as it wants.+ * They are updated by liblzma to match the amount of data read and+ * written but aren't used for anything else except as a possible return+ * values from lzma_get_progress().+ */+typedef struct {+ 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. */++ uint8_t *next_out; /**< Pointer to the next output position. */+ size_t avail_out; /**< Amount of free space in next_out. */+ uint64_t total_out; /**< Total number of bytes written by liblzma. */++ /**+ * \brief Custom memory allocation functions+ *+ * In most cases this is NULL which makes liblzma use+ * the standard malloc() and free().+ *+ * \note In 5.0.x this is not a const pointer.+ */+ const lzma_allocator *allocator;++ /** Internal state is not visible to applications. */+ lzma_internal *internal;++ /*+ * Reserved space to allow possible future extensions without+ * breaking the ABI. Excluding the initialization of this structure,+ * you should not touch these, because the names of these variables+ * may change.+ */+ void *reserved_ptr1;+ void *reserved_ptr2;+ void *reserved_ptr3;+ void *reserved_ptr4;+ uint64_t reserved_int1;+ uint64_t reserved_int2;+ size_t reserved_int3;+ size_t reserved_int4;+ lzma_reserved_enum reserved_enum1;+ lzma_reserved_enum reserved_enum2;++} lzma_stream;+++/**+ * \brief Initialization for lzma_stream+ *+ * When you declare an instance of lzma_stream, you can immediately+ * initialize it so that initialization functions know that no memory+ * has been allocated yet:+ *+ * lzma_stream strm = LZMA_STREAM_INIT;+ *+ * If you need to initialize a dynamically allocated lzma_stream, you can use+ * memset(strm_pointer, 0, sizeof(lzma_stream)). Strictly speaking, this+ * violates the C standard since NULL may have different internal+ * representation than zero, but it should be portable enough in practice.+ * Anyway, for maximum portability, you can use something like this:+ *+ * lzma_stream tmp = LZMA_STREAM_INIT;+ * *strm = tmp;+ */+#define LZMA_STREAM_INIT \+ { NULL, 0, 0, NULL, 0, 0, NULL, NULL, \+ NULL, NULL, NULL, NULL, 0, 0, 0, 0, \+ LZMA_RESERVED_ENUM, LZMA_RESERVED_ENUM }+++/**+ * \brief Encode or decode data+ *+ * Once the lzma_stream has been successfully initialized (e.g. with+ * lzma_stream_encoder()), the actual encoding or decoding is done+ * using this function. The application has to update strm->next_in,+ * strm->avail_in, strm->next_out, and strm->avail_out to pass input+ * to and get output from liblzma.+ *+ * See the description of the coder-specific initialization function to find+ * out what `action' values are supported by the coder.+ */+extern LZMA_API(lzma_ret) lzma_code(lzma_stream *strm, lzma_action action)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Free memory allocated for the coder data structures+ *+ * \param strm Pointer to lzma_stream that is at least initialized+ * with LZMA_STREAM_INIT.+ *+ * After lzma_end(strm), strm->internal is guaranteed to be NULL. No other+ * members of the lzma_stream structure are touched.+ *+ * \note zlib indicates an error if application end()s unfinished+ * stream structure. liblzma doesn't do this, and assumes that+ * application knows what it is doing.+ */+extern LZMA_API(void) lzma_end(lzma_stream *strm) lzma_nothrow;+++/**+ * \brief Get progress information+ *+ * In single-threaded mode, applications can get progress information from+ * strm->total_in and strm->total_out. In multi-threaded mode this is less+ * useful because a significant amount of both input and output data gets+ * buffered internally by liblzma. This makes total_in and total_out give+ * misleading information and also makes the progress indicator updates+ * non-smooth.+ *+ * This function gives realistic progress information also in multi-threaded+ * mode by taking into account the progress made by each thread. In+ * single-threaded mode *progress_in and *progress_out are set to+ * strm->total_in and strm->total_out, respectively.+ */+extern LZMA_API(void) lzma_get_progress(lzma_stream *strm,+ uint64_t *progress_in, uint64_t *progress_out) lzma_nothrow;+++/**+ * \brief Get the memory usage of decoder filter chain+ *+ * This function is currently supported only when *strm has been initialized+ * with a function that takes a memlimit argument. With other functions, you+ * should use e.g. lzma_raw_encoder_memusage() or lzma_raw_decoder_memusage()+ * to estimate the memory requirements.+ *+ * This function is useful e.g. after LZMA_MEMLIMIT_ERROR to find out how big+ * the memory usage limit should have been to decode the input. Note that+ * this may give misleading information if decoding .xz Streams that have+ * multiple Blocks, because each Block can have different memory requirements.+ *+ * \return How much memory is currently allocated for the filter+ * decoders. If no filter chain is currently allocated,+ * some non-zero value is still returned, which is less than+ * or equal to what any filter chain would indicate as its+ * memory requirement.+ *+ * If this function isn't supported by *strm or some other error+ * occurs, zero is returned.+ */+extern LZMA_API(uint64_t) lzma_memusage(const lzma_stream *strm)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the current memory usage limit+ *+ * This function is supported only when *strm has been initialized with+ * a function that takes a memlimit argument.+ *+ * \return On success, the current memory usage limit is returned+ * (always non-zero). On error, zero is returned.+ */+extern LZMA_API(uint64_t) lzma_memlimit_get(const lzma_stream *strm)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Set the memory usage limit+ *+ * This function is supported only when *strm has been initialized with+ * a function that takes a memlimit argument.+ *+ * liblzma 5.2.3 and earlier has a bug where memlimit value of 0 causes+ * this function to do nothing (leaving the limit unchanged) and still+ * return LZMA_OK. Later versions treat 0 as if 1 had been specified (so+ * lzma_memlimit_get() will return 1 even if you specify 0 here).+ *+ * \return - LZMA_OK: New memory usage limit successfully set.+ * - LZMA_MEMLIMIT_ERROR: The new limit is too small.+ * The limit was not changed.+ * - LZMA_PROG_ERROR: Invalid arguments, e.g. *strm doesn't+ * support memory usage limit.+ */+extern LZMA_API(lzma_ret) lzma_memlimit_set(+ lzma_stream *strm, uint64_t memlimit) lzma_nothrow;
+ cbits/liblzma/api/lzma/bcj.h view
@@ -0,0 +1,90 @@+/**+ * \file lzma/bcj.h+ * \brief Branch/Call/Jump conversion filters+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/* Filter IDs for lzma_filter.id */++#define LZMA_FILTER_X86 LZMA_VLI_C(0x04)+ /**<+ * Filter for x86 binaries+ */++#define LZMA_FILTER_POWERPC LZMA_VLI_C(0x05)+ /**<+ * Filter for Big endian PowerPC binaries+ */++#define LZMA_FILTER_IA64 LZMA_VLI_C(0x06)+ /**<+ * Filter for IA-64 (Itanium) binaries.+ */++#define LZMA_FILTER_ARM LZMA_VLI_C(0x07)+ /**<+ * Filter for ARM binaries.+ */++#define LZMA_FILTER_ARMTHUMB LZMA_VLI_C(0x08)+ /**<+ * Filter for ARM-Thumb binaries.+ */++#define LZMA_FILTER_SPARC LZMA_VLI_C(0x09)+ /**<+ * Filter for SPARC binaries.+ */+++/**+ * \brief Options for BCJ filters+ *+ * The BCJ filters never change the size of the data. Specifying options+ * for them is optional: if pointer to options is NULL, default value is+ * used. You probably never need to specify options to BCJ filters, so just+ * set the options pointer to NULL and be happy.+ *+ * 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 BCJ filters support+ * LZMA_SYNC_FLUSH. If LZMA_SYNC_FLUSH is specified,+ * LZMA_OPTIONS_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 {+ /**+ * \brief Start offset for conversions+ *+ * This setting is useful only when the same filter is used+ * _separately_ for multiple sections of the same executable file,+ * and the sections contain cross-section branch/call/jump+ * instructions. In that case it is beneficial to set the start+ * offset of the non-first sections so that the relative addresses+ * of the cross-section branch/call/jump instructions will use the+ * same absolute addresses as in the first section.+ *+ * When the pointer to options is NULL, the default value (zero)+ * is used.+ */+ uint32_t start_offset;++} lzma_options_bcj;
+ cbits/liblzma/api/lzma/block.h view
@@ -0,0 +1,581 @@+/**+ * \file lzma/block.h+ * \brief .xz Block handling+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Options for the Block and Block Header encoders and decoders+ *+ * Different Block handling functions use different parts of this structure.+ * Some read some members, other functions write, and some do both. Only the+ * members listed for reading need to be initialized when the specified+ * functions are called. The members marked for writing will be assigned+ * new values at some point either by calling the given function or by+ * later calls to lzma_code().+ */+typedef struct {+ /**+ * \brief Block format version+ *+ * 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,+ * including lzma_block_header_decode().+ *+ * Written by:+ * - lzma_block_header_decode()+ */+ uint32_t version;++ /**+ * \brief Size of the Block Header field+ *+ * This is always a multiple of four.+ *+ * Read by:+ * - lzma_block_header_encode()+ * - lzma_block_header_decode()+ * - lzma_block_compressed_size()+ * - lzma_block_unpadded_size()+ * - lzma_block_total_size()+ * - lzma_block_decoder()+ * - lzma_block_buffer_decode()+ *+ * Written by:+ * - lzma_block_header_size()+ * - lzma_block_buffer_encode()+ */+ uint32_t header_size;+# define LZMA_BLOCK_HEADER_SIZE_MIN 8+# define LZMA_BLOCK_HEADER_SIZE_MAX 1024++ /**+ * \brief Type of integrity Check+ *+ * The Check ID is not stored into the Block Header, thus its value+ * must be provided also when decoding.+ *+ * Read by:+ * - lzma_block_header_encode()+ * - lzma_block_header_decode()+ * - lzma_block_compressed_size()+ * - lzma_block_unpadded_size()+ * - lzma_block_total_size()+ * - lzma_block_encoder()+ * - lzma_block_decoder()+ * - lzma_block_buffer_encode()+ * - lzma_block_buffer_decode()+ */+ lzma_check check;++ /**+ * \brief Size of the Compressed Data in bytes+ *+ * Encoding: If this is not LZMA_VLI_UNKNOWN, Block Header encoder+ * will store this value to the Block Header. Block encoder doesn't+ * care about this value, but will set it once the encoding has been+ * finished.+ *+ * Decoding: If this is not LZMA_VLI_UNKNOWN, Block decoder will+ * verify that the size of the Compressed Data field matches+ * compressed_size.+ *+ * Usually you don't know this value when encoding in streamed mode,+ * and thus cannot write this field into the Block Header.+ *+ * In non-streamed mode you can reserve space for this field before+ * encoding the actual Block. After encoding the data, finish the+ * Block by encoding the Block Header. Steps in detail:+ *+ * - Set compressed_size to some big enough value. If you don't know+ * better, use LZMA_VLI_MAX, but remember that bigger values take+ * more space in Block Header.+ *+ * - Call lzma_block_header_size() to see how much space you need to+ * reserve for the Block Header.+ *+ * - Encode the Block using lzma_block_encoder() and lzma_code().+ * It sets compressed_size to the correct value.+ *+ * - Use lzma_block_header_encode() to encode the Block Header.+ * Because space was reserved in the first step, you don't need+ * to call lzma_block_header_size() anymore, because due to+ * reserving, header_size has to be big enough. If it is "too big",+ * lzma_block_header_encode() will add enough Header Padding to+ * make Block Header to match the size specified by header_size.+ *+ * Read by:+ * - lzma_block_header_size()+ * - lzma_block_header_encode()+ * - lzma_block_compressed_size()+ * - lzma_block_unpadded_size()+ * - lzma_block_total_size()+ * - lzma_block_decoder()+ * - lzma_block_buffer_decode()+ *+ * Written by:+ * - lzma_block_header_decode()+ * - lzma_block_compressed_size()+ * - lzma_block_encoder()+ * - lzma_block_decoder()+ * - lzma_block_buffer_encode()+ * - lzma_block_buffer_decode()+ */+ lzma_vli compressed_size;++ /**+ * \brief Uncompressed Size in bytes+ *+ * This is handled very similarly to compressed_size above.+ *+ * uncompressed_size is needed by fewer functions than+ * compressed_size. This is because uncompressed_size isn't+ * needed to validate that Block stays within proper limits.+ *+ * Read by:+ * - lzma_block_header_size()+ * - lzma_block_header_encode()+ * - lzma_block_decoder()+ * - lzma_block_buffer_decode()+ *+ * Written by:+ * - lzma_block_header_decode()+ * - lzma_block_encoder()+ * - lzma_block_decoder()+ * - lzma_block_buffer_encode()+ * - lzma_block_buffer_decode()+ */+ lzma_vli uncompressed_size;++ /**+ * \brief Array of filters+ *+ * There can be 1-4 filters. The end of the array is marked with+ * .id = LZMA_VLI_UNKNOWN.+ *+ * Read by:+ * - lzma_block_header_size()+ * - lzma_block_header_encode()+ * - lzma_block_encoder()+ * - lzma_block_decoder()+ * - lzma_block_buffer_encode()+ * - lzma_block_buffer_decode()+ *+ * Written by:+ * - lzma_block_header_decode(): Note that this does NOT free()+ * the old filter options structures. All unused filters[] will+ * have .id == LZMA_VLI_UNKNOWN and .options == NULL. If+ * decoding fails, all filters[] are guaranteed to be+ * LZMA_VLI_UNKNOWN and NULL.+ *+ * \note Because of the array is terminated with+ * .id = LZMA_VLI_UNKNOWN, the actual array must+ * have LZMA_FILTERS_MAX + 1 members or the Block+ * Header decoder will overflow the buffer.+ */+ lzma_filter *filters;++ /**+ * \brief Raw value stored in the Check field+ *+ * After successful coding, the first lzma_check_size(check) bytes+ * of this array contain the raw value stored in the Check field.+ *+ * Note that CRC32 and CRC64 are stored in little endian byte order.+ * Take it into account if you display the Check values to the user.+ *+ * Written by:+ * - lzma_block_encoder()+ * - lzma_block_decoder()+ * - lzma_block_buffer_encode()+ * - lzma_block_buffer_decode()+ */+ uint8_t raw_check[LZMA_CHECK_SIZE_MAX];++ /*+ * Reserved space to allow possible future extensions without+ * breaking the ABI. You should not touch these, because the names+ * of these variables may change. These are and will never be used+ * with the currently supported options, so it is safe to leave these+ * uninitialized.+ */+ void *reserved_ptr1;+ void *reserved_ptr2;+ void *reserved_ptr3;+ uint32_t reserved_int1;+ uint32_t reserved_int2;+ lzma_vli reserved_int3;+ lzma_vli reserved_int4;+ lzma_vli reserved_int5;+ lzma_vli reserved_int6;+ lzma_vli reserved_int7;+ lzma_vli reserved_int8;+ lzma_reserved_enum reserved_enum1;+ lzma_reserved_enum reserved_enum2;+ lzma_reserved_enum reserved_enum3;+ lzma_reserved_enum reserved_enum4;++ /**+ * \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;+ lzma_bool reserved_bool5;+ lzma_bool reserved_bool6;+ lzma_bool reserved_bool7;+ lzma_bool reserved_bool8;++} lzma_block;+++/**+ * \brief Decode the Block Header Size field+ *+ * To decode Block Header using lzma_block_header_decode(), the size of the+ * Block Header has to be known and stored into lzma_block.header_size.+ * The size can be calculated from the first byte of a Block using this macro.+ * Note that if the first byte is 0x00, it indicates beginning of Index; use+ * this macro only when the byte is not 0x00.+ *+ * There is no encoding macro, because Block Header encoder is enough for that.+ */+#define lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4)+++/**+ * \brief Calculate Block Header Size+ *+ * Calculate the minimum size needed for the Block Header field using the+ * settings specified in the lzma_block structure. Note that it is OK to+ * increase the calculated header_size value as long as it is a multiple of+ * four and doesn't exceed LZMA_BLOCK_HEADER_SIZE_MAX. Increasing header_size+ * just means that lzma_block_header_encode() will add Header Padding.+ *+ * \return - LZMA_OK: Size calculated successfully and stored to+ * block->header_size.+ * - LZMA_OPTIONS_ERROR: Unsupported version, filters or+ * filter options.+ * - LZMA_PROG_ERROR: Invalid values like compressed_size == 0.+ *+ * \note This doesn't check that all the options are valid i.e. this+ * may return LZMA_OK even if lzma_block_header_encode() or+ * lzma_block_encoder() would fail. If you want to validate the+ * filter chain, consider using lzma_memlimit_encoder() which as+ * a side-effect validates the filter chain.+ */+extern LZMA_API(lzma_ret) lzma_block_header_size(lzma_block *block)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Encode Block Header+ *+ * The caller must have calculated the size of the Block Header already with+ * lzma_block_header_size(). If a value larger than the one calculated by+ * lzma_block_header_size() is used, the Block Header will be padded to the+ * specified size.+ *+ * \param out Beginning of the output buffer. This must be+ * at least block->header_size bytes.+ * \param block Block options to be encoded.+ *+ * \return - LZMA_OK: Encoding was successful. block->header_size+ * bytes were written to output buffer.+ * - LZMA_OPTIONS_ERROR: Invalid or unsupported options.+ * - LZMA_PROG_ERROR: Invalid arguments, for example+ * block->header_size is invalid or block->filters is NULL.+ */+extern LZMA_API(lzma_ret) lzma_block_header_encode(+ const lzma_block *block, uint8_t *out)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Decode 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).+ *+ * \param block Destination for Block options.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() (and also free()+ * if an error occurs).+ * \param in Beginning of the input buffer. This must be+ * at least block->header_size bytes.+ *+ * \return - LZMA_OK: Decoding was successful. block->header_size+ * bytes were read from the input buffer.+ * - LZMA_OPTIONS_ERROR: The Block Header specifies some+ * unsupported options such as unsupported filters. This can+ * happen also if block->version was set to a too low value+ * compared to what would be required to properly represent+ * the information stored in the Block Header.+ * - LZMA_DATA_ERROR: Block Header is corrupt, for example,+ * the CRC32 doesn't match.+ * - LZMA_PROG_ERROR: Invalid arguments, for example+ * block->header_size is invalid or block->filters is NULL.+ */+extern LZMA_API(lzma_ret) lzma_block_header_decode(lzma_block *block,+ const lzma_allocator *allocator, const uint8_t *in)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Validate and set Compressed Size according to Unpadded Size+ *+ * Block Header stores Compressed Size, but Index has Unpadded Size. If the+ * application has already parsed the Index and is now decoding Blocks,+ * it can calculate Compressed Size from Unpadded Size. This function does+ * exactly that with error checking:+ *+ * - Compressed Size calculated from Unpadded Size must be positive integer,+ * that is, Unpadded Size must be big enough that after Block Header and+ * Check fields there's still at least one byte for Compressed Size.+ *+ * - If Compressed Size was present in Block Header, the new value+ * calculated from Unpadded Size is compared against the value+ * from Block Header.+ *+ * \note This function must be called _after_ decoding the Block Header+ * field so that it can properly validate Compressed Size if it+ * was present in Block Header.+ *+ * \return - LZMA_OK: block->compressed_size was set successfully.+ * - LZMA_DATA_ERROR: unpadded_size is too small compared to+ * block->header_size and lzma_check_size(block->check).+ * - LZMA_PROG_ERROR: Some values are invalid. For example,+ * block->header_size must be a multiple of four and+ * between 8 and 1024 inclusive.+ */+extern LZMA_API(lzma_ret) lzma_block_compressed_size(+ lzma_block *block, lzma_vli unpadded_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Calculate Unpadded Size+ *+ * The Index field stores Unpadded Size and Uncompressed Size. The latter+ * can be taken directly from the lzma_block structure after coding a Block,+ * but Unpadded Size needs to be calculated from Block Header Size,+ * Compressed Size, and size of the Check field. This is where this function+ * is needed.+ *+ * \return Unpadded Size on success, or zero on error.+ */+extern LZMA_API(lzma_vli) lzma_block_unpadded_size(const lzma_block *block)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Calculate the total encoded size of a Block+ *+ * This is equivalent to lzma_block_unpadded_size() except that the returned+ * value includes the size of the Block Padding field.+ *+ * \return On success, total encoded size of the Block. On error,+ * zero is returned.+ */+extern LZMA_API(lzma_vli) lzma_block_total_size(const lzma_block *block)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Initialize .xz Block encoder+ *+ * Valid actions for lzma_code() are LZMA_RUN, LZMA_SYNC_FLUSH (only if the+ * filter chain supports it), and LZMA_FINISH.+ *+ * \return - LZMA_OK: All good, continue with lzma_code().+ * - LZMA_MEM_ERROR+ * - LZMA_OPTIONS_ERROR+ * - LZMA_UNSUPPORTED_CHECK: block->check specifies a Check ID+ * that is not supported by this build of liblzma. Initializing+ * the encoder failed.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_block_encoder(+ lzma_stream *strm, lzma_block *block)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Initialize .xz Block decoder+ *+ * Valid actions for lzma_code() are LZMA_RUN and LZMA_FINISH. Using+ * LZMA_FINISH is not required. It is supported only for convenience.+ *+ * \return - LZMA_OK: All good, continue with lzma_code().+ * - LZMA_UNSUPPORTED_CHECK: Initialization was successful, but+ * the given Check ID is not supported, thus Check will be+ * ignored.+ * - LZMA_PROG_ERROR+ * - LZMA_MEM_ERROR+ */+extern LZMA_API(lzma_ret) lzma_block_decoder(+ lzma_stream *strm, lzma_block *block)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Calculate maximum output size for single-call Block encoding+ *+ * This is equivalent to lzma_stream_buffer_bound() but for .xz Blocks.+ * See the documentation of lzma_stream_buffer_bound().+ */+extern LZMA_API(size_t) lzma_block_buffer_bound(size_t uncompressed_size)+ lzma_nothrow;+++/**+ * \brief Single-call .xz Block encoder+ *+ * In contrast to the multi-call encoder initialized with+ * lzma_block_encoder(), this function encodes also the Block Header. This+ * is required to make it possible to write appropriate Block Header also+ * in case the data isn't compressible, and different filter chain has to be+ * used to encode the data in uncompressed form using uncompressed chunks+ * of the LZMA2 filter.+ *+ * When the data isn't compressible, header_size, compressed_size, and+ * uncompressed_size are set just like when the data was compressible, but+ * it is possible that header_size is too small to hold the filter chain+ * specified in block->filters, because that isn't necessarily the filter+ * chain that was actually used to encode the data. lzma_block_unpadded_size()+ * still works normally, because it doesn't read the filters array.+ *+ * \param block Block options: block->version, block->check,+ * and block->filters must have been initialized.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_size Size of the input buffer+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_BUF_ERROR: Not enough output buffer space.+ * - LZMA_UNSUPPORTED_CHECK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_MEM_ERROR+ * - LZMA_DATA_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_block_buffer_encode(+ lzma_block *block, const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \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+ * chunks. The required output buffer size can be determined with+ * lzma_block_buffer_bound().+ *+ * Since the data won't be compressed, this function ignores block->filters.+ * This function doesn't take lzma_allocator because this function doesn't+ * allocate any memory from the heap.+ */+extern LZMA_API(lzma_ret) lzma_block_uncomp_encode(lzma_block *block,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Single-call .xz Block decoder+ *+ * This is single-call equivalent of lzma_block_decoder(), and requires that+ * the caller has already decoded Block Header and checked its memory usage.+ *+ * \param block Block options just like with lzma_block_decoder().+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_pos The next byte will be read from in[*in_pos].+ * *in_pos is updated only if decoding succeeds.+ * \param in_size Size of the input buffer; the first byte that+ * won't be read is in[in_size].+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Decoding was successful.+ * - LZMA_OPTIONS_ERROR+ * - LZMA_DATA_ERROR+ * - LZMA_MEM_ERROR+ * - LZMA_BUF_ERROR: Output buffer was too small.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_block_buffer_decode(+ lzma_block *block, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+ lzma_nothrow;
+ cbits/liblzma/api/lzma/check.h view
@@ -0,0 +1,150 @@+/**+ * \file lzma/check.h+ * \brief Integrity checks+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Type of the integrity check (Check ID)+ *+ * The .xz format supports multiple types of checks that are calculated+ * from the uncompressed data. They vary in both speed and ability to+ * detect errors.+ */+typedef enum {+ LZMA_CHECK_NONE = 0,+ /**<+ * No Check is calculated.+ *+ * Size of the Check field: 0 bytes+ */++ LZMA_CHECK_CRC32 = 1,+ /**<+ * CRC32 using the polynomial from the IEEE 802.3 standard+ *+ * Size of the Check field: 4 bytes+ */++ LZMA_CHECK_CRC64 = 4,+ /**<+ * CRC64 using the polynomial from the ECMA-182 standard+ *+ * Size of the Check field: 8 bytes+ */++ LZMA_CHECK_SHA256 = 10+ /**<+ * SHA-256+ *+ * Size of the Check field: 32 bytes+ */+} lzma_check;+++/**+ * \brief Maximum valid Check ID+ *+ * The .xz file format specification specifies 16 Check IDs (0-15). Some+ * of them are only reserved, that is, no actual Check algorithm has been+ * assigned. When decoding, liblzma still accepts unknown Check IDs for+ * future compatibility. If a valid but unsupported Check ID is detected,+ * liblzma can indicate a warning; see the flags LZMA_TELL_NO_CHECK,+ * LZMA_TELL_UNSUPPORTED_CHECK, and LZMA_TELL_ANY_CHECK in container.h.+ */+#define LZMA_CHECK_ID_MAX 15+++/**+ * \brief Test if the given Check ID is supported+ *+ * Return true if the given Check ID is supported by this liblzma build.+ * Otherwise false is returned. It is safe to call this with a value that+ * is not in the range [0, 15]; in that case the return value is always false.+ *+ * You can assume that LZMA_CHECK_NONE and LZMA_CHECK_CRC32 are always+ * supported (even if liblzma is built with limited features).+ */+extern LZMA_API(lzma_bool) lzma_check_is_supported(lzma_check check)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Get the size of the Check field with the given Check ID+ *+ * Although not all Check IDs have a check algorithm associated, the size of+ * every Check is already frozen. This function returns the size (in bytes) of+ * the Check field with the specified Check ID. The values are:+ * { 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64 }+ *+ * If the argument is not in the range [0, 15], UINT32_MAX is returned.+ */+extern LZMA_API(uint32_t) lzma_check_size(lzma_check check)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Maximum size of a Check field+ */+#define LZMA_CHECK_SIZE_MAX 64+++/**+ * \brief Calculate CRC32+ *+ * Calculate CRC32 using the polynomial from the IEEE 802.3 standard.+ *+ * \param buf Pointer to the input buffer+ * \param size Size of the input buffer+ * \param crc Previously returned CRC value. This is used to+ * calculate the CRC of a big buffer in smaller chunks.+ * Set to zero when starting a new calculation.+ *+ * \return Updated CRC value, which can be passed to this function+ * again to continue CRC calculation.+ */+extern LZMA_API(uint32_t) lzma_crc32(+ const uint8_t *buf, size_t size, uint32_t crc)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Calculate CRC64+ *+ * Calculate CRC64 using the polynomial from the ECMA-182 standard.+ *+ * This function is used similarly to lzma_crc32(). See its documentation.+ */+extern LZMA_API(uint64_t) lzma_crc64(+ const uint8_t *buf, size_t size, uint64_t crc)+ lzma_nothrow lzma_attr_pure;+++/*+ * SHA-256 functions are currently not exported to public API.+ * Contact Lasse Collin if you think it should be.+ */+++/**+ * \brief Get the type of the integrity check+ *+ * This function can be called only immediately after lzma_code() has+ * returned LZMA_NO_CHECK, LZMA_UNSUPPORTED_CHECK, or LZMA_GET_CHECK.+ * Calling this function in any other situation has undefined behavior.+ */+extern LZMA_API(lzma_check) lzma_get_check(const lzma_stream *strm)+ lzma_nothrow;
+ cbits/liblzma/api/lzma/container.h view
@@ -0,0 +1,632 @@+/**+ * \file lzma/container.h+ * \brief File formats+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/************+ * Encoding *+ ************/++/**+ * \brief Default compression preset+ *+ * It's not straightforward to recommend a default preset, because in some+ * cases keeping the resource usage relatively low is more important that+ * getting the maximum compression ratio.+ */+#define LZMA_PRESET_DEFAULT UINT32_C(6)+++/**+ * \brief Mask for preset level+ *+ * This is useful only if you need to extract the level from the preset+ * variable. That should be rare.+ */+#define LZMA_PRESET_LEVEL_MASK UINT32_C(0x1F)+++/*+ * Preset flags+ *+ * Currently only one flag is defined.+ */++/**+ * \brief Extreme compression preset+ *+ * This flag modifies the preset to make the encoding significantly slower+ * while improving the compression ratio only marginally. This is useful+ * when you don't mind wasting time to get as small result as possible.+ *+ * This flag doesn't affect the memory usage requirements of the decoder (at+ * least not significantly). The memory usage of the encoder may be increased+ * a little but only at the lowest preset levels (0-3).+ */+#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)+++/**+ * \brief Multithreading options+ */+typedef struct {+ /**+ * \brief Flags+ *+ * Set this to zero if no flags are wanted.+ *+ * No flags are currently supported.+ */+ uint32_t flags;++ /**+ * \brief Number of worker threads to use+ */+ uint32_t threads;++ /**+ * \brief Maximum uncompressed size of a Block+ *+ * The encoder will start a new .xz Block every block_size bytes.+ * Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code()+ * the caller may tell liblzma to start a new Block earlier.+ *+ * With LZMA2, a recommended block size is 2-4 times the LZMA2+ * dictionary size. With very small dictionaries, it is recommended+ * to use at least 1 MiB block size for good compression ratio, even+ * if this is more than four times the dictionary size. Note that+ * these are only recommendations for typical use cases; feel free+ * to use other values. Just keep in mind that using a block size+ * less than the LZMA2 dictionary size is waste of RAM.+ *+ * Set this to 0 to let liblzma choose the block size depending+ * on the compression options. For LZMA2 it will be 3*dict_size+ * or 1 MiB, whichever is more.+ *+ * For each thread, about 3 * block_size bytes of memory will be+ * allocated. This may change in later liblzma versions. If so,+ * the memory usage will probably be reduced, not increased.+ */+ uint64_t block_size;++ /**+ * \brief Timeout to allow lzma_code() to return early+ *+ * Multithreading can make liblzma to consume input and produce+ * output in a very bursty way: it may first read a lot of input+ * to fill internal buffers, then no input or output occurs for+ * a while.+ *+ * In single-threaded mode, lzma_code() won't return until it has+ * either consumed all the input or filled the output buffer. If+ * this is done in multithreaded mode, it may cause a call+ * lzma_code() to take even tens of seconds, which isn't acceptable+ * in all applications.+ *+ * To avoid very long blocking times in lzma_code(), a timeout+ * (in milliseconds) may be set here. If lzma_code() would block+ * longer than this number of milliseconds, it will return with+ * LZMA_OK. Reasonable values are 100 ms or more. The xz command+ * line tool uses 300 ms.+ *+ * If long blocking times are fine for you, set timeout to a special+ * value of 0, which will disable the timeout mechanism and will make+ * lzma_code() block until all the input is consumed or the output+ * buffer has been filled.+ *+ * \note Even with a timeout, lzma_code() might sometimes take+ * somewhat long time to return. No timing guarantees+ * are made.+ */+ uint32_t timeout;++ /**+ * \brief Compression preset (level and possible flags)+ *+ * The preset is set just like with lzma_easy_encoder().+ * The preset is ignored if filters below is non-NULL.+ */+ uint32_t preset;++ /**+ * \brief Filter chain (alternative to a preset)+ *+ * If this is NULL, the preset above is used. Otherwise the preset+ * is ignored and the filter chain specified here is used.+ */+ const lzma_filter *filters;++ /**+ * \brief Integrity check type+ *+ * See check.h for available checks. The xz command line tool+ * defaults to LZMA_CHECK_CRC64, which is a good choice if you+ * are unsure.+ */+ lzma_check check;++ /*+ * Reserved space to allow possible future extensions without+ * breaking the ABI. You should not touch these, because the names+ * of these variables may change. These are and will never be used+ * with the currently supported options, so it is safe to leave these+ * uninitialized.+ */+ lzma_reserved_enum reserved_enum1;+ lzma_reserved_enum reserved_enum2;+ lzma_reserved_enum reserved_enum3;+ uint32_t reserved_int1;+ uint32_t reserved_int2;+ uint32_t reserved_int3;+ uint32_t reserved_int4;+ uint64_t reserved_int5;+ uint64_t reserved_int6;+ uint64_t reserved_int7;+ uint64_t reserved_int8;+ void *reserved_ptr1;+ void *reserved_ptr2;+ void *reserved_ptr3;+ void *reserved_ptr4;++} lzma_mt;+++/**+ * \brief Calculate approximate memory usage of easy encoder+ *+ * This function is a wrapper for lzma_raw_encoder_memusage().+ *+ * \param preset Compression preset (level and possible flags)+ *+ * \return Number of bytes of memory required for the given+ * preset when encoding. If an error occurs, for example+ * due to unsupported preset, UINT64_MAX is returned.+ */+extern LZMA_API(uint64_t) lzma_easy_encoder_memusage(uint32_t preset)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Calculate approximate decoder memory usage of a preset+ *+ * This function is a wrapper for lzma_raw_decoder_memusage().+ *+ * \param preset Compression preset (level and possible flags)+ *+ * \return Number of bytes of memory required to decompress a file+ * that was compressed using the given preset. If an error+ * occurs, for example due to unsupported preset, UINT64_MAX+ * is returned.+ */+extern LZMA_API(uint64_t) lzma_easy_decoder_memusage(uint32_t preset)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Initialize .xz Stream encoder using a preset number+ *+ * This function is intended for those who just want to use the basic features+ * if liblzma (that is, most developers out there).+ *+ * \param strm Pointer to lzma_stream that is at least initialized+ * with LZMA_STREAM_INIT.+ * \param preset Compression preset to use. A preset consist of level+ * number and zero or more flags. Usually flags aren't+ * used, so preset is simply a number [0, 9] which match+ * the options -0 ... -9 of the xz command line tool.+ * Additional flags can be be set using bitwise-or with+ * the preset level number, e.g. 6 | LZMA_PRESET_EXTREME.+ * \param check Integrity check type to use. See check.h for available+ * checks. The xz command line tool defaults to+ * LZMA_CHECK_CRC64, which is a good choice if you are+ * unsure. LZMA_CHECK_CRC32 is good too as long as the+ * uncompressed file is not many gigabytes.+ *+ * \return - LZMA_OK: Initialization succeeded. Use lzma_code() to+ * encode your data.+ * - LZMA_MEM_ERROR: Memory allocation failed.+ * - LZMA_OPTIONS_ERROR: The given compression preset is not+ * supported by this build of liblzma.+ * - LZMA_UNSUPPORTED_CHECK: The given check type is not+ * supported by this liblzma build.+ * - LZMA_PROG_ERROR: One or more of the parameters have values+ * that will never be valid. For example, strm == NULL.+ *+ * If initialization fails (return value is not LZMA_OK), all the memory+ * allocated for *strm by liblzma is always freed. Thus, there is no need+ * to call lzma_end() after failed initialization.+ *+ * 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 or flags that don't support LZMA_SYNC_FLUSH.+ */+extern LZMA_API(lzma_ret) lzma_easy_encoder(+ lzma_stream *strm, uint32_t preset, lzma_check check)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Single-call .xz Stream encoding using a preset number+ *+ * The maximum required output buffer size can be calculated with+ * lzma_stream_buffer_bound().+ *+ * \param preset Compression preset to use. See the description+ * in lzma_easy_encoder().+ * \param check Type of the integrity check to calculate from+ * uncompressed data.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_size Size of the input buffer+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_BUF_ERROR: Not enough output buffer space.+ * - LZMA_UNSUPPORTED_CHECK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_MEM_ERROR+ * - LZMA_DATA_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_easy_buffer_encode(+ uint32_t preset, lzma_check check,+ const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;+++/**+ * \brief Initialize .xz Stream encoder using a custom filter chain+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param filters Array of filters. This must be terminated with+ * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h for+ * more information.+ * \param check Type of the integrity check to calculate from+ * uncompressed data.+ *+ * \return - LZMA_OK: Initialization was successful.+ * - LZMA_MEM_ERROR+ * - LZMA_UNSUPPORTED_CHECK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,+ const lzma_filter *filters, lzma_check check)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Calculate approximate memory usage of multithreaded .xz encoder+ *+ * Since doing the encoding in threaded mode doesn't affect the memory+ * requirements of single-threaded decompressor, you can use+ * lzma_easy_decoder_memusage(options->preset) or+ * lzma_raw_decoder_memusage(options->filters) to calculate+ * the decompressor memory requirements.+ *+ * \param options Compression options+ *+ * \return Number of bytes of memory required for encoding with the+ * given options. If an error occurs, for example due to+ * unsupported preset or filter chain, UINT64_MAX is returned.+ */+extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(+ const lzma_mt *options) lzma_nothrow lzma_attr_pure;+++/**+ * \brief Initialize multithreaded .xz Stream encoder+ *+ * This provides the functionality of lzma_easy_encoder() and+ * lzma_stream_encoder() as a single function for multithreaded use.+ *+ * The supported actions for lzma_code() are LZMA_RUN, LZMA_FULL_FLUSH,+ * LZMA_FULL_BARRIER, and LZMA_FINISH. Support for LZMA_SYNC_FLUSH might be+ * added in the future.+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param options Pointer to multithreaded compression options+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_UNSUPPORTED_CHECK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(+ lzma_stream *strm, const lzma_mt *options)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Initialize .lzma encoder (legacy file format)+ *+ * The .lzma format is sometimes called the LZMA_Alone format, which is the+ * reason for the name of this function. The .lzma format supports only the+ * LZMA1 filter. There is no support for integrity checks like CRC32.+ *+ * Use this function if and only if you need to create files readable by+ * legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format+ * is strongly recommended.+ *+ * The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH.+ * No kind of flushing is supported, because the file format doesn't make+ * it possible.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_alone_encoder(+ lzma_stream *strm, const lzma_options_lzma *options)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Calculate output buffer size for single-call Stream encoder+ *+ * When trying to compress uncompressible data, the encoded size will be+ * slightly bigger than the input data. This function calculates how much+ * output buffer space is required to be sure that lzma_stream_buffer_encode()+ * doesn't return LZMA_BUF_ERROR.+ *+ * The calculated value is not exact, but it is guaranteed to be big enough.+ * The actual maximum output space required may be slightly smaller (up to+ * about 100 bytes). This should not be a problem in practice.+ *+ * If the calculated maximum size doesn't fit into size_t or would make the+ * Stream grow past LZMA_VLI_MAX (which should never happen in practice),+ * zero is returned to indicate the error.+ *+ * \note The limit calculated by this function applies only to+ * single-call encoding. Multi-call encoding may (and probably+ * will) have larger maximum expansion when encoding+ * uncompressible data. Currently there is no function to+ * calculate the maximum expansion of multi-call encoding.+ */+extern LZMA_API(size_t) lzma_stream_buffer_bound(size_t uncompressed_size)+ lzma_nothrow;+++/**+ * \brief Single-call .xz Stream encoder+ *+ * \param filters Array of filters. This must be terminated with+ * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h+ * for more information.+ * \param check Type of the integrity check to calculate from+ * uncompressed data.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_size Size of the input buffer+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_BUF_ERROR: Not enough output buffer space.+ * - LZMA_UNSUPPORTED_CHECK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_MEM_ERROR+ * - LZMA_DATA_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(+ lzma_filter *filters, lzma_check check,+ const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/************+ * Decoding *+ ************/++/**+ * This flag makes lzma_code() return LZMA_NO_CHECK if the input stream+ * being decoded has no integrity check. Note that when used with+ * lzma_auto_decoder(), all .lzma files will trigger LZMA_NO_CHECK+ * if LZMA_TELL_NO_CHECK is used.+ */+#define LZMA_TELL_NO_CHECK UINT32_C(0x01)+++/**+ * This flag makes lzma_code() return LZMA_UNSUPPORTED_CHECK if the input+ * stream has an integrity check, but the type of the integrity check is not+ * supported by this liblzma version or build. Such files can still be+ * decoded, but the integrity check cannot be verified.+ */+#define LZMA_TELL_UNSUPPORTED_CHECK UINT32_C(0x02)+++/**+ * This flag makes lzma_code() return LZMA_GET_CHECK as soon as the type+ * of the integrity check is known. The type can then be got with+ * lzma_get_check().+ */+#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+ * supported by liblzma, only the .xz format allows concatenated files.+ * Concatenated files are not allowed with the legacy .lzma format.+ *+ * This flag also affects the usage of the `action' argument for lzma_code().+ * When LZMA_CONCATENATED is used, lzma_code() won't return LZMA_STREAM_END+ * unless LZMA_FINISH is used as `action'. Thus, the application has to set+ * LZMA_FINISH in the same way as it does when encoding.+ *+ * If LZMA_CONCATENATED is not used, the decoders still accept LZMA_FINISH+ * as `action' for lzma_code(), but the usage of LZMA_FINISH isn't required.+ */+#define LZMA_CONCATENATED UINT32_C(0x08)+++/**+ * \brief Initialize .xz Stream decoder+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param memlimit Memory usage limit as bytes. Use UINT64_MAX+ * to effectively disable the limiter. liblzma+ * 5.2.3 and earlier don't allow 0 here and return+ * LZMA_PROG_ERROR; later versions treat 0 as if 1+ * had been specified.+ * \param flags Bitwise-or of zero or more of the decoder flags:+ * LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,+ * LZMA_TELL_ANY_CHECK, LZMA_CONCATENATED+ *+ * \return - LZMA_OK: Initialization was successful.+ * - LZMA_MEM_ERROR: Cannot allocate memory.+ * - LZMA_OPTIONS_ERROR: Unsupported flags+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_stream_decoder(+ lzma_stream *strm, uint64_t memlimit, uint32_t flags)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Decode .xz Streams and .lzma files with autodetection+ *+ * This decoder autodetects between the .xz and .lzma file formats, and+ * calls lzma_stream_decoder() or lzma_alone_decoder() once the type+ * of the input file has been detected.+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param memlimit Memory usage limit as bytes. Use UINT64_MAX+ * to effectively disable the limiter. liblzma+ * 5.2.3 and earlier don't allow 0 here and return+ * LZMA_PROG_ERROR; later versions treat 0 as if 1+ * had been specified.+ * \param flags Bitwise-or of flags, or zero for no flags.+ *+ * \return - LZMA_OK: Initialization was successful.+ * - LZMA_MEM_ERROR: Cannot allocate memory.+ * - LZMA_OPTIONS_ERROR: Unsupported flags+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_auto_decoder(+ lzma_stream *strm, uint64_t memlimit, uint32_t flags)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Initialize .lzma decoder (legacy file format)+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param memlimit Memory usage limit as bytes. Use UINT64_MAX+ * to effectively disable the limiter. liblzma+ * 5.2.3 and earlier don't allow 0 here and return+ * LZMA_PROG_ERROR; later versions treat 0 as if 1+ * had been specified.+ *+ * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.+ * There is no need to use LZMA_FINISH, but it's allowed because it may+ * simplify certain types of applications.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_alone_decoder(+ lzma_stream *strm, uint64_t memlimit)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Single-call .xz Stream decoder+ *+ * \param memlimit Pointer to how much memory the decoder is allowed+ * to allocate. The value pointed by this pointer is+ * modified if and only if LZMA_MEMLIMIT_ERROR is+ * returned.+ * \param flags Bitwise-or of zero or more of the decoder flags:+ * LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,+ * LZMA_CONCATENATED. Note that LZMA_TELL_ANY_CHECK+ * is not allowed and will return LZMA_PROG_ERROR.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_pos The next byte will be read from in[*in_pos].+ * *in_pos is updated only if decoding succeeds.+ * \param in_size Size of the input buffer; the first byte that+ * won't be read is in[in_size].+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if decoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Decoding was successful.+ * - LZMA_FORMAT_ERROR+ * - LZMA_OPTIONS_ERROR+ * - LZMA_DATA_ERROR+ * - LZMA_NO_CHECK: This can be returned only if using+ * the LZMA_TELL_NO_CHECK flag.+ * - LZMA_UNSUPPORTED_CHECK: This can be returned only if using+ * the LZMA_TELL_UNSUPPORTED_CHECK flag.+ * - LZMA_MEM_ERROR+ * - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.+ * The minimum required memlimit value was stored to *memlimit.+ * - LZMA_BUF_ERROR: Output buffer was too small.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_stream_buffer_decode(+ uint64_t *memlimit, uint32_t flags,+ const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+ lzma_nothrow lzma_attr_warn_unused_result;
+ cbits/liblzma/api/lzma/delta.h view
@@ -0,0 +1,77 @@+/**+ * \file lzma/delta.h+ * \brief Delta filter+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Filter ID+ *+ * Filter ID of the Delta filter. This is used as lzma_filter.id.+ */+#define LZMA_FILTER_DELTA LZMA_VLI_C(0x03)+++/**+ * \brief Type of the delta calculation+ *+ * Currently only byte-wise delta is supported. Other possible types could+ * be, for example, delta of 16/32/64-bit little/big endian integers, but+ * these are not currently planned since byte-wise delta is almost as good.+ */+typedef enum {+ LZMA_DELTA_TYPE_BYTE+} lzma_delta_type;+++/**+ * \brief Options for the Delta filter+ *+ * These options are needed by both encoder and decoder.+ */+typedef struct {+ /** For now, this must always be LZMA_DELTA_TYPE_BYTE. */+ lzma_delta_type type;++ /**+ * \brief Delta distance+ *+ * With the only currently supported type, LZMA_DELTA_TYPE_BYTE,+ * the distance is as bytes.+ *+ * Examples:+ * - 16-bit stereo audio: distance = 4 bytes+ * - 24-bit RGB image data: distance = 3 bytes+ */+ uint32_t dist;+# define LZMA_DELTA_DIST_MIN 1+# define LZMA_DELTA_DIST_MAX 256++ /*+ * Reserved space to allow possible future extensions without+ * breaking the ABI. You should not touch these, because the names+ * of these variables may change. These are and will never be used+ * when type is LZMA_DELTA_TYPE_BYTE, so it is safe to leave these+ * uninitialized.+ */+ uint32_t reserved_int1;+ uint32_t reserved_int2;+ uint32_t reserved_int3;+ uint32_t reserved_int4;+ void *reserved_ptr1;+ void *reserved_ptr2;++} lzma_options_delta;
+ cbits/liblzma/api/lzma/filter.h view
@@ -0,0 +1,426 @@+/**+ * \file lzma/filter.h+ * \brief Common filter related types and functions+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Maximum number of filters in a chain+ *+ * A filter chain can have 1-4 filters, of which three are allowed to change+ * the size of the data. Usually only one or two filters are needed.+ */+#define LZMA_FILTERS_MAX 4+++/**+ * \brief Filter options+ *+ * This structure is used to pass Filter ID and a pointer filter's+ * options to liblzma. A few functions work with a single lzma_filter+ * structure, while most functions expect a filter chain.+ *+ * A filter chain is indicated with an array of lzma_filter structures.+ * The array is terminated with .id = LZMA_VLI_UNKNOWN. Thus, the filter+ * array must have LZMA_FILTERS_MAX + 1 elements (that is, five) to+ * be able to hold any arbitrary filter chain. This is important when+ * using lzma_block_header_decode() from block.h, because too small+ * array would make liblzma write past the end of the filters array.+ */+typedef struct {+ /**+ * \brief Filter ID+ *+ * Use constants whose name begin with `LZMA_FILTER_' to specify+ * different filters. In an array of lzma_filter structures, use+ * LZMA_VLI_UNKNOWN to indicate end of filters.+ *+ * \note This is not an enum, because on some systems enums+ * cannot be 64-bit.+ */+ lzma_vli id;++ /**+ * \brief Pointer to filter-specific options structure+ *+ * If the filter doesn't need options, set this to NULL. If id is+ * set to LZMA_VLI_UNKNOWN, options is ignored, and thus+ * doesn't need be initialized.+ */+ void *options;++} lzma_filter;+++/**+ * \brief Test if the given Filter ID is supported for encoding+ *+ * Return true if the give Filter ID is supported for encoding by this+ * liblzma build. Otherwise false is returned.+ *+ * There is no way to list which filters are available in this particular+ * liblzma version and build. It would be useless, because the application+ * couldn't know what kind of options the filter would need.+ */+extern LZMA_API(lzma_bool) lzma_filter_encoder_is_supported(lzma_vli id)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Test if the given Filter ID is supported for decoding+ *+ * Return true if the give Filter ID is supported for decoding by this+ * liblzma build. Otherwise false is returned.+ */+extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Copy the filters array+ *+ * Copy the Filter IDs and filter-specific options from src to dest.+ * Up to LZMA_FILTERS_MAX filters are copied, plus the terminating+ * .id == LZMA_VLI_UNKNOWN. Thus, dest should have at least+ * LZMA_FILTERS_MAX + 1 elements space unless the caller knows that+ * src is smaller than that.+ *+ * Unless the filter-specific options is NULL, the Filter ID has to be+ * supported by liblzma, because liblzma needs to know the size of every+ * filter-specific options structure. The filter-specific options are not+ * validated. If options is NULL, any unsupported Filter IDs are copied+ * without returning an error.+ *+ * Old filter-specific options in dest are not freed, so dest doesn't+ * need to be initialized by the caller in any way.+ *+ * If an error occurs, memory possibly already allocated by this function+ * is always freed.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_OPTIONS_ERROR: Unsupported Filter ID and its options+ * is not NULL.+ * - LZMA_PROG_ERROR: src or dest is NULL.+ */+extern LZMA_API(lzma_ret) lzma_filters_copy(+ const lzma_filter *src, lzma_filter *dest,+ const lzma_allocator *allocator) lzma_nothrow;+++/**+ * \brief Calculate approximate memory requirements for raw encoder+ *+ * This function can be used to calculate the memory requirements for+ * Block and Stream encoders too because Block and Stream encoders don't+ * need significantly more memory than raw encoder.+ *+ * \param filters Array of filters terminated with+ * .id == LZMA_VLI_UNKNOWN.+ *+ * \return Number of bytes of memory required for the given+ * filter chain when encoding. If an error occurs,+ * for example due to unsupported filter chain,+ * UINT64_MAX is returned.+ */+extern LZMA_API(uint64_t) lzma_raw_encoder_memusage(const lzma_filter *filters)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Calculate approximate memory requirements for raw decoder+ *+ * This function can be used to calculate the memory requirements for+ * Block and Stream decoders too because Block and Stream decoders don't+ * need significantly more memory than raw decoder.+ *+ * \param filters Array of filters terminated with+ * .id == LZMA_VLI_UNKNOWN.+ *+ * \return Number of bytes of memory required for the given+ * filter chain when decoding. If an error occurs,+ * for example due to unsupported filter chain,+ * UINT64_MAX is returned.+ */+extern LZMA_API(uint64_t) lzma_raw_decoder_memusage(const lzma_filter *filters)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Initialize raw encoder+ *+ * This function may be useful when implementing custom file formats.+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param filters Array of lzma_filter structures. The end of the+ * array must be marked with .id = LZMA_VLI_UNKNOWN.+ *+ * The `action' with lzma_code() can be LZMA_RUN, LZMA_SYNC_FLUSH (if the+ * filter chain supports it), or LZMA_FINISH.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_raw_encoder(+ lzma_stream *strm, const lzma_filter *filters)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Initialize raw decoder+ *+ * The initialization of raw decoder goes similarly to raw encoder.+ *+ * The `action' with lzma_code() can be LZMA_RUN or LZMA_FINISH. Using+ * LZMA_FINISH is not required, it is supported just for convenience.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_raw_decoder(+ lzma_stream *strm, const lzma_filter *filters)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Update the filter chain in the encoder+ *+ * This function is for advanced users only. This function has two slightly+ * different purposes:+ *+ * - After LZMA_FULL_FLUSH when using Stream encoder: Set a new filter+ * chain, which will be used starting from the next Block.+ *+ * - After LZMA_SYNC_FLUSH using Raw, Block, or Stream encoder: Change+ * the filter-specific options in the middle of encoding. The actual+ * filters in the chain (Filter IDs) cannot be changed. In the future,+ * it might become possible to change the filter options without+ * using LZMA_SYNC_FLUSH.+ *+ * While rarely useful, this function may be called also when no data has+ * been compressed yet. In that case, this function will behave as if+ * LZMA_FULL_FLUSH (Stream encoder) or LZMA_SYNC_FLUSH (Raw or Block+ * encoder) had been used right before calling this function.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_MEMLIMIT_ERROR+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_filters_update(+ lzma_stream *strm, const lzma_filter *filters) lzma_nothrow;+++/**+ * \brief Single-call raw encoder+ *+ * \param filters Array of lzma_filter structures. The end of the+ * array must be marked with .id = LZMA_VLI_UNKNOWN.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_size Size of the input buffer+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_BUF_ERROR: Not enough output buffer space.+ * - LZMA_OPTIONS_ERROR+ * - LZMA_MEM_ERROR+ * - LZMA_DATA_ERROR+ * - LZMA_PROG_ERROR+ *+ * \note There is no function to calculate how big output buffer+ * would surely be big enough. (lzma_stream_buffer_bound()+ * works only for lzma_stream_buffer_encode(); raw encoder+ * won't necessarily meet that bound.)+ */+extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(+ const lzma_filter *filters, const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size, uint8_t *out,+ size_t *out_pos, size_t out_size) lzma_nothrow;+++/**+ * \brief Single-call raw decoder+ *+ * \param filters Array of lzma_filter structures. The end of the+ * array must be marked with .id = LZMA_VLI_UNKNOWN.+ * \param allocator lzma_allocator for custom allocator functions.+ * Set to NULL to use malloc() and free().+ * \param in Beginning of the input buffer+ * \param in_pos The next byte will be read from in[*in_pos].+ * *in_pos is updated only if decoding succeeds.+ * \param in_size Size of the input buffer; the first byte that+ * won't be read is in[in_size].+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ */+extern LZMA_API(lzma_ret) lzma_raw_buffer_decode(+ const lzma_filter *filters, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;+++/**+ * \brief Get the size of the Filter Properties field+ *+ * This function may be useful when implementing custom file formats+ * using the raw encoder and decoder.+ *+ * \param size Pointer to uint32_t to hold the size of the properties+ * \param filter Filter ID and options (the size of the properties may+ * vary depending on the options)+ *+ * \return - LZMA_OK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ *+ * \note This function validates the Filter ID, but does not+ * necessarily validate the options. Thus, it is possible+ * that this returns LZMA_OK while the following call to+ * lzma_properties_encode() returns LZMA_OPTIONS_ERROR.+ */+extern LZMA_API(lzma_ret) lzma_properties_size(+ uint32_t *size, const lzma_filter *filter) lzma_nothrow;+++/**+ * \brief Encode the Filter Properties field+ *+ * \param filter Filter ID and options+ * \param props Buffer to hold the encoded options. The size of+ * buffer must have been already determined with+ * lzma_properties_size().+ *+ * \return - LZMA_OK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_PROG_ERROR+ *+ * \note Even this function won't validate more options than actually+ * necessary. Thus, it is possible that encoding the properties+ * succeeds but using the same options to initialize the encoder+ * will fail.+ *+ * \note If lzma_properties_size() indicated that the size+ * of the Filter Properties field is zero, calling+ * lzma_properties_encode() is not required, but it+ * won't do any harm either.+ */+extern LZMA_API(lzma_ret) lzma_properties_encode(+ const lzma_filter *filter, uint8_t *props) lzma_nothrow;+++/**+ * \brief Decode the Filter Properties field+ *+ * \param filter filter->id must have been set to the correct+ * Filter ID. filter->options doesn't need to be+ * initialized (it's not freed by this function). The+ * decoded options will be stored in filter->options;+ * it's application's responsibility to free it when+ * appropriate. filter->options is set to NULL if+ * there are no properties or if an error occurs.+ * \param allocator Custom memory allocator used to allocate the+ * options. Set to NULL to use the default malloc(),+ * and in case of an error, also free().+ * \param props Input buffer containing the properties.+ * \param props_size Size of the properties. This must be the exact+ * size; giving too much or too little input will+ * return LZMA_OPTIONS_ERROR.+ *+ * \return - LZMA_OK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_MEM_ERROR+ */+extern LZMA_API(lzma_ret) lzma_properties_decode(+ lzma_filter *filter, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size) lzma_nothrow;+++/**+ * \brief Calculate encoded size of a Filter Flags field+ *+ * Knowing the size of Filter Flags is useful to know when allocating+ * memory to hold the encoded Filter Flags.+ *+ * \param size Pointer to integer to hold the calculated size+ * \param filter Filter ID and associated options whose encoded+ * size is to be calculated+ *+ * \return - LZMA_OK: *size set successfully. Note that this doesn't+ * guarantee that filter->options is valid, thus+ * lzma_filter_flags_encode() may still fail.+ * - LZMA_OPTIONS_ERROR: Unknown Filter ID or unsupported options.+ * - LZMA_PROG_ERROR: Invalid options+ *+ * \note If you need to calculate size of List of Filter Flags,+ * you need to loop over every lzma_filter entry.+ */+extern LZMA_API(lzma_ret) lzma_filter_flags_size(+ uint32_t *size, const lzma_filter *filter)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Encode Filter Flags into given buffer+ *+ * In contrast to some functions, this doesn't allocate the needed buffer.+ * This is due to how this function is used internally by liblzma.+ *+ * \param filter Filter ID and options to be encoded+ * \param out Beginning of the output buffer+ * \param out_pos out[*out_pos] is the next write position. This+ * is updated by the encoder.+ * \param out_size out[out_size] is the first byte to not write.+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_OPTIONS_ERROR: Invalid or unsupported options.+ * - LZMA_PROG_ERROR: Invalid options or not enough output+ * buffer space (you should have checked it with+ * lzma_filter_flags_size()).+ */+extern LZMA_API(lzma_ret) lzma_filter_flags_encode(const lzma_filter *filter,+ uint8_t *out, size_t *out_pos, size_t out_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Decode Filter Flags from given buffer+ *+ * The decoded result is stored into *filter. The old value of+ * filter->options is not free()d.+ *+ * \return - LZMA_OK+ * - LZMA_OPTIONS_ERROR+ * - LZMA_MEM_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_filter_flags_decode(+ lzma_filter *filter, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size)+ lzma_nothrow lzma_attr_warn_unused_result;
+ cbits/liblzma/api/lzma/hardware.h view
@@ -0,0 +1,64 @@+/**+ * \file lzma/hardware.h+ * \brief Hardware information+ *+ * Since liblzma can consume a lot of system resources, it also provides+ * ways to limit the resource usage. Applications linking against liblzma+ * need to do the actual decisions how much resources to let liblzma to use.+ * To ease making these decisions, liblzma provides functions to find out+ * the relevant capabilities of the underlying hardware. Currently there+ * is only a function to find out the amount of RAM, but in the future there+ * will be also a function to detect how many concurrent threads the system+ * can run.+ *+ * \note On some operating systems, these function may temporarily+ * load a shared library or open file descriptor(s) to find out+ * the requested hardware information. Unless the application+ * assumes that specific file descriptors are not touched by+ * other threads, this should have no effect on thread safety.+ * Possible operations involving file descriptors will restart+ * the syscalls if they return EINTR.+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Get the total amount of physical memory (RAM) in bytes+ *+ * This function may be useful when determining a reasonable memory+ * usage limit for decompressing or how much memory it is OK to use+ * for compressing.+ *+ * \return On success, the total amount of physical memory in bytes+ * is returned. If the amount of RAM cannot be determined,+ * zero is returned. This can happen if an error occurs+ * or if there is no code in liblzma to detect the amount+ * 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;
+ cbits/liblzma/api/lzma/index.h view
@@ -0,0 +1,686 @@+/**+ * \file lzma/index.h+ * \brief Handling of .xz Index and related information+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Opaque data type to hold the Index(es) and other information+ *+ * lzma_index often holds just one .xz Index and possibly the Stream Flags+ * of the same Stream and size of the Stream Padding field. However,+ * multiple lzma_indexes can be concatenated with lzma_index_cat() and then+ * there may be information about multiple Streams in the same lzma_index.+ *+ * Notes about thread safety: Only one thread may modify lzma_index at+ * a time. All functions that take non-const pointer to lzma_index+ * modify it. As long as no thread is modifying the lzma_index, getting+ * information from the same lzma_index can be done from multiple threads+ * at the same time with functions that take a const pointer to+ * lzma_index or use lzma_index_iter. The same iterator must be used+ * only by one thread at a time, of course, but there can be as many+ * iterators for the same lzma_index as needed.+ */+typedef struct lzma_index_s lzma_index;+++/**+ * \brief Iterator to get information about Blocks and Streams+ */+typedef struct {+ struct {+ /**+ * \brief Pointer to Stream Flags+ *+ * This is NULL if Stream Flags have not been set for+ * this Stream with lzma_index_stream_flags().+ */+ const lzma_stream_flags *flags;++ const void *reserved_ptr1;+ const void *reserved_ptr2;+ const void *reserved_ptr3;++ /**+ * \brief Stream number in the lzma_index+ *+ * The first Stream is 1.+ */+ lzma_vli number;++ /**+ * \brief Number of Blocks in the Stream+ *+ * If this is zero, the block structure below has+ * undefined values.+ */+ lzma_vli block_count;++ /**+ * \brief Compressed start offset of this Stream+ *+ * The offset is relative to the beginning of the lzma_index+ * (i.e. usually the beginning of the .xz file).+ */+ lzma_vli compressed_offset;++ /**+ * \brief Uncompressed start offset of this Stream+ *+ * The offset is relative to the beginning of the lzma_index+ * (i.e. usually the beginning of the .xz file).+ */+ lzma_vli uncompressed_offset;++ /**+ * \brief Compressed size of this Stream+ *+ * This includes all headers except the possible+ * Stream Padding after this Stream.+ */+ lzma_vli compressed_size;++ /**+ * \brief Uncompressed size of this Stream+ */+ lzma_vli uncompressed_size;++ /**+ * \brief Size of Stream Padding after this Stream+ *+ * If it hasn't been set with lzma_index_stream_padding(),+ * this defaults to zero. Stream Padding is always+ * a multiple of four bytes.+ */+ lzma_vli padding;++ lzma_vli reserved_vli1;+ lzma_vli reserved_vli2;+ lzma_vli reserved_vli3;+ lzma_vli reserved_vli4;+ } stream;++ struct {+ /**+ * \brief Block number in the file+ *+ * The first Block is 1.+ */+ lzma_vli number_in_file;++ /**+ * \brief Compressed start offset of this Block+ *+ * This offset is relative to the beginning of the+ * lzma_index (i.e. usually the beginning of the .xz file).+ * Normally this is where you should seek in the .xz file+ * to start decompressing this Block.+ */+ lzma_vli compressed_file_offset;++ /**+ * \brief Uncompressed start offset of this Block+ *+ * This offset is relative to the beginning of the lzma_index+ * (i.e. usually the beginning of the .xz file).+ *+ * When doing random-access reading, it is possible that+ * the target offset is not exactly at Block boundary. One+ * will need to compare the target offset against+ * uncompressed_file_offset or uncompressed_stream_offset,+ * and possibly decode and throw away some amount of data+ * before reaching the target offset.+ */+ lzma_vli uncompressed_file_offset;++ /**+ * \brief Block number in this Stream+ *+ * The first Block is 1.+ */+ lzma_vli number_in_stream;++ /**+ * \brief Compressed start offset of this Block+ *+ * This offset is relative to the beginning of the Stream+ * containing this Block.+ */+ lzma_vli compressed_stream_offset;++ /**+ * \brief Uncompressed start offset of this Block+ *+ * This offset is relative to the beginning of the Stream+ * containing this Block.+ */+ lzma_vli uncompressed_stream_offset;++ /**+ * \brief Uncompressed size of this Block+ *+ * You should pass this to the Block decoder if you will+ * decode this Block. It will allow the Block decoder to+ * validate the uncompressed size.+ */+ lzma_vli uncompressed_size;++ /**+ * \brief Unpadded size of this Block+ *+ * You should pass this to the Block decoder if you will+ * decode this Block. It will allow the Block decoder to+ * validate the unpadded size.+ */+ lzma_vli unpadded_size;++ /**+ * \brief Total compressed size+ *+ * This includes all headers and padding in this Block.+ * This is useful if you need to know how many bytes+ * the Block decoder will actually read.+ */+ lzma_vli total_size;++ lzma_vli reserved_vli1;+ lzma_vli reserved_vli2;+ lzma_vli reserved_vli3;+ lzma_vli reserved_vli4;++ const void *reserved_ptr1;+ const void *reserved_ptr2;+ const void *reserved_ptr3;+ const void *reserved_ptr4;+ } block;++ /*+ * Internal data which is used to store the state of the iterator.+ * The exact format may vary between liblzma versions, so don't+ * touch these in any way.+ */+ union {+ const void *p;+ size_t s;+ lzma_vli v;+ } internal[6];+} lzma_index_iter;+++/**+ * \brief Operation mode for lzma_index_iter_next()+ */+typedef enum {+ LZMA_INDEX_ITER_ANY = 0,+ /**<+ * \brief Get the next Block or Stream+ *+ * Go to the next Block if the current Stream has at least+ * one Block left. Otherwise go to the next Stream even if+ * it has no Blocks. If the Stream has no Blocks+ * (lzma_index_iter.stream.block_count == 0),+ * lzma_index_iter.block will have undefined values.+ */++ LZMA_INDEX_ITER_STREAM = 1,+ /**<+ * \brief Get the next Stream+ *+ * Go to the next Stream even if the current Stream has+ * unread Blocks left. If the next Stream has at least one+ * Block, the iterator will point to the first Block.+ * If there are no Blocks, lzma_index_iter.block will have+ * undefined values.+ */++ LZMA_INDEX_ITER_BLOCK = 2,+ /**<+ * \brief Get the next Block+ *+ * Go to the next Block if the current Stream has at least+ * one Block left. If the current Stream has no Blocks left,+ * the next Stream with at least one Block is located and+ * the iterator will be made to point to the first Block of+ * that Stream.+ */++ LZMA_INDEX_ITER_NONEMPTY_BLOCK = 3+ /**<+ * \brief Get the next non-empty Block+ *+ * This is like LZMA_INDEX_ITER_BLOCK except that it will+ * skip Blocks whose Uncompressed Size is zero.+ */++} lzma_index_iter_mode;+++/**+ * \brief Calculate memory usage of lzma_index+ *+ * On disk, the size of the Index field depends on both the number of Records+ * stored and how big values the Records store (due to variable-length integer+ * encoding). When the Index is kept in lzma_index structure, the memory usage+ * depends only on the number of Records/Blocks stored in the Index(es), and+ * in case of concatenated lzma_indexes, the number of Streams. The size in+ * RAM is almost always significantly bigger than in the encoded form on disk.+ *+ * This function calculates an approximate amount of memory needed hold+ * the given number of Streams and Blocks in lzma_index structure. This+ * value may vary between CPU architectures and also between liblzma versions+ * if the internal implementation is modified.+ */+extern LZMA_API(uint64_t) lzma_index_memusage(+ lzma_vli streams, lzma_vli blocks) lzma_nothrow;+++/**+ * \brief Calculate the memory usage of an existing lzma_index+ *+ * This is a shorthand for lzma_index_memusage(lzma_index_stream_count(i),+ * lzma_index_block_count(i)).+ */+extern LZMA_API(uint64_t) lzma_index_memused(const lzma_index *i)+ lzma_nothrow;+++/**+ * \brief Allocate and initialize a new lzma_index structure+ *+ * \return On success, a pointer to an empty initialized lzma_index is+ * returned. If allocation fails, NULL is returned.+ */+extern LZMA_API(lzma_index *) lzma_index_init(const lzma_allocator *allocator)+ lzma_nothrow;+++/**+ * \brief Deallocate lzma_index+ *+ * If i is NULL, this does nothing.+ */+extern LZMA_API(void) lzma_index_end(+ lzma_index *i, const lzma_allocator *allocator) lzma_nothrow;+++/**+ * \brief Add a new Block to lzma_index+ *+ * \param i Pointer to a lzma_index structure+ * \param allocator Pointer to lzma_allocator, or NULL to+ * use malloc()+ * \param unpadded_size Unpadded Size of a Block. This can be+ * calculated with lzma_block_unpadded_size()+ * after encoding or decoding the Block.+ * \param uncompressed_size Uncompressed Size of a Block. This can be+ * taken directly from lzma_block structure+ * after encoding or decoding the Block.+ *+ * Appending a new Block does not invalidate iterators. For example,+ * if an iterator was pointing to the end of the lzma_index, after+ * lzma_index_append() it is possible to read the next Block with+ * an existing iterator.+ *+ * \return - LZMA_OK+ * - LZMA_MEM_ERROR+ * - LZMA_DATA_ERROR: Compressed or uncompressed size of the+ * Stream or size of the Index field would grow too big.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_append(+ lzma_index *i, const lzma_allocator *allocator,+ lzma_vli unpadded_size, lzma_vli uncompressed_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Set the Stream Flags+ *+ * Set the Stream Flags of the last (and typically the only) Stream+ * in lzma_index. This can be useful when reading information from the+ * lzma_index, because to decode Blocks, knowing the integrity check type+ * is needed.+ *+ * The given Stream Flags are copied into internal preallocated structure+ * in the lzma_index, thus the caller doesn't need to keep the *stream_flags+ * available after calling this function.+ *+ * \return - LZMA_OK+ * - LZMA_OPTIONS_ERROR: Unsupported stream_flags->version.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_stream_flags(+ lzma_index *i, const lzma_stream_flags *stream_flags)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Get the types of integrity Checks+ *+ * If lzma_index_stream_flags() is used to set the Stream Flags for+ * every Stream, lzma_index_checks() can be used to get a bitmask to+ * indicate which Check types have been used. It can be useful e.g. if+ * showing the Check types to the user.+ *+ * The bitmask is 1 << check_id, e.g. CRC32 is 1 << 1 and SHA-256 is 1 << 10.+ */+extern LZMA_API(uint32_t) lzma_index_checks(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Set the amount of Stream Padding+ *+ * Set the amount of Stream Padding of the last (and typically the only)+ * Stream in the lzma_index. This is needed when planning to do random-access+ * reading within multiple concatenated Streams.+ *+ * By default, the amount of Stream Padding is assumed to be zero bytes.+ *+ * \return - LZMA_OK+ * - LZMA_DATA_ERROR: The file size would grow too big.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_stream_padding(+ lzma_index *i, lzma_vli stream_padding)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Get the number of Streams+ */+extern LZMA_API(lzma_vli) lzma_index_stream_count(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the number of Blocks+ *+ * This returns the total number of Blocks in lzma_index. To get number+ * of Blocks in individual Streams, use lzma_index_iter.+ */+extern LZMA_API(lzma_vli) lzma_index_block_count(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the size of the Index field as bytes+ *+ * This is needed to verify the Backward Size field in the Stream Footer.+ */+extern LZMA_API(lzma_vli) lzma_index_size(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the total size of the Stream+ *+ * If multiple lzma_indexes have been combined, this works as if the Blocks+ * were in a single Stream. This is useful if you are going to combine+ * Blocks from multiple Streams into a single new Stream.+ */+extern LZMA_API(lzma_vli) lzma_index_stream_size(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the total size of the Blocks+ *+ * This doesn't include the Stream Header, Stream Footer, Stream Padding,+ * or Index fields.+ */+extern LZMA_API(lzma_vli) lzma_index_total_size(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the total size of the file+ *+ * When no lzma_indexes have been combined with lzma_index_cat() and there is+ * no Stream Padding, this function is identical to lzma_index_stream_size().+ * If multiple lzma_indexes have been combined, this includes also the headers+ * of each separate Stream and the possible Stream Padding fields.+ */+extern LZMA_API(lzma_vli) lzma_index_file_size(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Get the uncompressed size of the file+ */+extern LZMA_API(lzma_vli) lzma_index_uncompressed_size(const lzma_index *i)+ lzma_nothrow lzma_attr_pure;+++/**+ * \brief Initialize an iterator+ *+ * \param iter Pointer to a lzma_index_iter structure+ * \param i lzma_index to which the iterator will be associated+ *+ * This function associates the iterator with the given lzma_index, and calls+ * lzma_index_iter_rewind() on the iterator.+ *+ * This function doesn't allocate any memory, thus there is no+ * lzma_index_iter_end(). The iterator is valid as long as the+ * associated lzma_index is valid, that is, until lzma_index_end() or+ * using it as source in lzma_index_cat(). Specifically, lzma_index doesn't+ * become invalid if new Blocks are added to it with lzma_index_append() or+ * if it is used as the destination in lzma_index_cat().+ *+ * It is safe to make copies of an initialized lzma_index_iter, for example,+ * to easily restart reading at some particular position.+ */+extern LZMA_API(void) lzma_index_iter_init(+ lzma_index_iter *iter, const lzma_index *i) lzma_nothrow;+++/**+ * \brief Rewind the iterator+ *+ * Rewind the iterator so that next call to lzma_index_iter_next() will+ * return the first Block or Stream.+ */+extern LZMA_API(void) lzma_index_iter_rewind(lzma_index_iter *iter)+ lzma_nothrow;+++/**+ * \brief Get the next Block or Stream+ *+ * \param iter Iterator initialized with lzma_index_iter_init()+ * \param mode Specify what kind of information the caller wants+ * to get. See lzma_index_iter_mode for details.+ *+ * \return If next Block or Stream matching the mode was found, *iter+ * is updated and this function returns false. If no Block or+ * Stream matching the mode is found, *iter is not modified+ * and this function returns true. If mode is set to an unknown+ * value, *iter is not modified and this function returns true.+ */+extern LZMA_API(lzma_bool) lzma_index_iter_next(+ lzma_index_iter *iter, lzma_index_iter_mode mode)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Locate a Block+ *+ * If it is possible to seek in the .xz file, it is possible to parse+ * the Index field(s) and use lzma_index_iter_locate() to do random-access+ * reading with granularity of Block size.+ *+ * \param iter Iterator that was earlier initialized with+ * lzma_index_iter_init().+ * \param target Uncompressed target offset which the caller would+ * like to locate from the Stream+ *+ * If the target is smaller than the uncompressed size of the Stream (can be+ * checked with lzma_index_uncompressed_size()):+ * - Information about the Stream and Block containing the requested+ * uncompressed offset is stored into *iter.+ * - Internal state of the iterator is adjusted so that+ * lzma_index_iter_next() can be used to read subsequent Blocks or Streams.+ * - This function returns false.+ *+ * If target is greater than the uncompressed size of the Stream, *iter+ * is not modified, and this function returns true.+ */+extern LZMA_API(lzma_bool) lzma_index_iter_locate(+ lzma_index_iter *iter, lzma_vli target) lzma_nothrow;+++/**+ * \brief Concatenate lzma_indexes+ *+ * Concatenating lzma_indexes is useful when doing random-access reading in+ * multi-Stream .xz file, or when combining multiple Streams into single+ * Stream.+ *+ * \param dest lzma_index after which src is appended+ * \param src lzma_index to be appended after dest. If this+ * function succeeds, the memory allocated for src+ * is freed or moved to be part of dest, and all+ * iterators pointing to src will become invalid.+ * \param allocator Custom memory allocator; can be NULL to use+ * malloc() and free().+ *+ * \return - LZMA_OK: lzma_indexes were concatenated successfully.+ * src is now a dangling pointer.+ * - LZMA_DATA_ERROR: *dest would grow too big.+ * - LZMA_MEM_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_cat(lzma_index *dest, lzma_index *src,+ const lzma_allocator *allocator)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Duplicate lzma_index+ *+ * \return A copy of the lzma_index, or NULL if memory allocation failed.+ */+extern LZMA_API(lzma_index *) lzma_index_dup(+ const lzma_index *i, const lzma_allocator *allocator)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Initialize .xz Index encoder+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param i Pointer to lzma_index which should be encoded.+ *+ * The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.+ * It is enough to use only one of them (you can choose freely).+ *+ * \return - LZMA_OK: Initialization succeeded, continue with lzma_code().+ * - LZMA_MEM_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_encoder(+ lzma_stream *strm, const lzma_index *i)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Initialize .xz Index decoder+ *+ * \param strm Pointer to properly prepared lzma_stream+ * \param i The decoded Index will be made available via+ * this pointer. Initially this function will+ * set *i to NULL (the old value is ignored). If+ * decoding succeeds (lzma_code() returns+ * LZMA_STREAM_END), *i will be set to point+ * to a new lzma_index, which the application+ * has to later free with lzma_index_end().+ * \param memlimit How much memory the resulting lzma_index is+ * allowed to require. liblzma 5.2.3 and earlier+ * don't allow 0 here and return LZMA_PROG_ERROR;+ * later versions treat 0 as if 1 had been specified.+ *+ * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.+ * There is no need to use LZMA_FINISH, but it's allowed because it may+ * simplify certain types of applications.+ *+ * \return - LZMA_OK: Initialization succeeded, continue with lzma_code().+ * - LZMA_MEM_ERROR+ * - LZMA_PROG_ERROR+ *+ * liblzma 5.2.3 and older list also LZMA_MEMLIMIT_ERROR here+ * but that error code has never been possible from this+ * initialization function.+ */+extern LZMA_API(lzma_ret) lzma_index_decoder(+ lzma_stream *strm, lzma_index **i, uint64_t memlimit)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Single-call .xz Index encoder+ *+ * \param i lzma_index to be encoded+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * *out_pos is updated only if encoding succeeds.+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_BUF_ERROR: Output buffer is too small. Use+ * lzma_index_size() to find out how much output+ * space is needed.+ * - LZMA_PROG_ERROR+ *+ * \note This function doesn't take allocator argument since all+ * the internal data is allocated on stack.+ */+extern LZMA_API(lzma_ret) lzma_index_buffer_encode(const lzma_index *i,+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;+++/**+ * \brief Single-call .xz Index decoder+ *+ * \param i If decoding succeeds, *i will point to a new+ * lzma_index, which the application has to+ * later free with lzma_index_end(). If an error+ * occurs, *i will be NULL. The old value of *i+ * is always ignored and thus doesn't need to be+ * initialized by the caller.+ * \param memlimit Pointer to how much memory the resulting+ * lzma_index is allowed to require. The value+ * pointed by this pointer is modified if and only+ * if LZMA_MEMLIMIT_ERROR is returned.+ * \param allocator Pointer to lzma_allocator, or NULL to use malloc()+ * \param in Beginning of the input buffer+ * \param in_pos The next byte will be read from in[*in_pos].+ * *in_pos is updated only if decoding succeeds.+ * \param in_size Size of the input buffer; the first byte that+ * won't be read is in[in_size].+ *+ * \return - LZMA_OK: Decoding was successful.+ * - LZMA_MEM_ERROR+ * - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.+ * The minimum required memlimit value was stored to *memlimit.+ * - LZMA_DATA_ERROR+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,+ uint64_t *memlimit, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size)+ lzma_nothrow;
+ cbits/liblzma/api/lzma/index_hash.h view
@@ -0,0 +1,107 @@+/**+ * \file lzma/index_hash.h+ * \brief Validate Index by using a hash function+ *+ * Hashing makes it possible to use constant amount of memory to validate+ * Index of arbitrary size.+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif++/**+ * \brief Opaque data type to hold the Index hash+ */+typedef struct lzma_index_hash_s lzma_index_hash;+++/**+ * \brief Allocate and initialize a new lzma_index_hash structure+ *+ * If index_hash is NULL, a new lzma_index_hash structure is allocated,+ * initialized, and a pointer to it returned. If allocation fails, NULL+ * is returned.+ *+ * If index_hash is non-NULL, it is reinitialized and the same pointer+ * returned. In this case, return value cannot be NULL or a different+ * pointer than the index_hash that was given as an argument.+ */+extern LZMA_API(lzma_index_hash *) lzma_index_hash_init(+ lzma_index_hash *index_hash, const lzma_allocator *allocator)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Deallocate lzma_index_hash structure+ */+extern LZMA_API(void) lzma_index_hash_end(+ lzma_index_hash *index_hash, const lzma_allocator *allocator)+ lzma_nothrow;+++/**+ * \brief Add a new Record to an Index hash+ *+ * \param index Pointer to a lzma_index_hash structure+ * \param unpadded_size Unpadded Size of a Block+ * \param uncompressed_size Uncompressed Size of a Block+ *+ * \return - LZMA_OK+ * - LZMA_DATA_ERROR: Compressed or uncompressed size of the+ * Stream or size of the Index field would grow too big.+ * - LZMA_PROG_ERROR: Invalid arguments or this function is being+ * used when lzma_index_hash_decode() has already been used.+ */+extern LZMA_API(lzma_ret) lzma_index_hash_append(lzma_index_hash *index_hash,+ lzma_vli unpadded_size, lzma_vli uncompressed_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Decode and validate the Index field+ *+ * After telling the sizes of all Blocks with lzma_index_hash_append(),+ * the actual Index field is decoded with this function. Specifically,+ * once decoding of the Index field has been started, no more Records+ * can be added using lzma_index_hash_append().+ *+ * This function doesn't use lzma_stream structure to pass the input data.+ * Instead, the input buffer is specified using three arguments. This is+ * because it matches better the internal APIs of liblzma.+ *+ * \param index_hash Pointer to a lzma_index_hash structure+ * \param in Pointer to the beginning of the input buffer+ * \param in_pos in[*in_pos] is the next byte to process+ * \param in_size in[in_size] is the first byte not to process+ *+ * \return - LZMA_OK: So far good, but more input is needed.+ * - LZMA_STREAM_END: Index decoded successfully and it matches+ * the Records given with lzma_index_hash_append().+ * - LZMA_DATA_ERROR: Index is corrupt or doesn't match the+ * information given with lzma_index_hash_append().+ * - LZMA_BUF_ERROR: Cannot progress because *in_pos >= in_size.+ * - LZMA_PROG_ERROR+ */+extern LZMA_API(lzma_ret) lzma_index_hash_decode(lzma_index_hash *index_hash,+ const uint8_t *in, size_t *in_pos, size_t in_size)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Get the size of the Index field as bytes+ *+ * This is needed to verify the Backward Size field in the Stream Footer.+ */+extern LZMA_API(lzma_vli) lzma_index_hash_size(+ const lzma_index_hash *index_hash)+ lzma_nothrow lzma_attr_pure;
+ cbits/liblzma/api/lzma/lzma12.h view
@@ -0,0 +1,420 @@+/**+ * \file lzma/lzma12.h+ * \brief LZMA1 and LZMA2 filters+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief LZMA1 Filter ID+ *+ * LZMA1 is the very same thing as what was called just LZMA in LZMA Utils,+ * 7-Zip, and LZMA SDK. It's called LZMA1 here to prevent developers from+ * accidentally using LZMA when they actually want LZMA2.+ *+ * LZMA1 shouldn't be used for new applications unless you _really_ know+ * what you are doing. LZMA2 is almost always a better choice.+ */+#define LZMA_FILTER_LZMA1 LZMA_VLI_C(0x4000000000000001)++/**+ * \brief LZMA2 Filter ID+ *+ * Usually you want this instead of LZMA1. Compared to LZMA1, LZMA2 adds+ * support for LZMA_SYNC_FLUSH, uncompressed chunks (smaller expansion+ * when trying to compress uncompressible data), possibility to change+ * lc/lp/pb in the middle of encoding, and some other internal improvements.+ */+#define LZMA_FILTER_LZMA2 LZMA_VLI_C(0x21)+++/**+ * \brief Match finders+ *+ * Match finder has major effect on both speed and compression ratio.+ * Usually hash chains are faster than binary trees.+ *+ * If you will use LZMA_SYNC_FLUSH often, the hash chains may be a better+ * choice, because binary trees get much higher compression ratio penalty+ * with LZMA_SYNC_FLUSH.+ *+ * The memory usage formulas are only rough estimates, which are closest to+ * reality when dict_size is a power of two. The formulas are more complex+ * in reality, and can also change a little between liblzma versions. Use+ * lzma_raw_encoder_memusage() to get more accurate estimate of memory usage.+ */+typedef enum {+ LZMA_MF_HC3 = 0x03,+ /**<+ * \brief Hash Chain with 2- and 3-byte hashing+ *+ * Minimum nice_len: 3+ *+ * Memory usage:+ * - dict_size <= 16 MiB: dict_size * 7.5+ * - dict_size > 16 MiB: dict_size * 5.5 + 64 MiB+ */++ LZMA_MF_HC4 = 0x04,+ /**<+ * \brief Hash Chain with 2-, 3-, and 4-byte hashing+ *+ * Minimum nice_len: 4+ *+ * Memory usage:+ * - dict_size <= 32 MiB: dict_size * 7.5+ * - dict_size > 32 MiB: dict_size * 6.5+ */++ LZMA_MF_BT2 = 0x12,+ /**<+ * \brief Binary Tree with 2-byte hashing+ *+ * Minimum nice_len: 2+ *+ * Memory usage: dict_size * 9.5+ */++ LZMA_MF_BT3 = 0x13,+ /**<+ * \brief Binary Tree with 2- and 3-byte hashing+ *+ * Minimum nice_len: 3+ *+ * Memory usage:+ * - dict_size <= 16 MiB: dict_size * 11.5+ * - dict_size > 16 MiB: dict_size * 9.5 + 64 MiB+ */++ LZMA_MF_BT4 = 0x14+ /**<+ * \brief Binary Tree with 2-, 3-, and 4-byte hashing+ *+ * Minimum nice_len: 4+ *+ * Memory usage:+ * - dict_size <= 32 MiB: dict_size * 11.5+ * - dict_size > 32 MiB: dict_size * 10.5+ */+} lzma_match_finder;+++/**+ * \brief Test if given match finder is supported+ *+ * Return true if the given match finder is supported by this liblzma build.+ * Otherwise false is returned. It is safe to call this with a value that+ * isn't listed in lzma_match_finder enumeration; the return value will be+ * false.+ *+ * There is no way to list which match finders are available in this+ * particular liblzma version and build. It would be useless, because+ * a new match finder, which the application developer wasn't aware,+ * could require giving additional options to the encoder that the older+ * match finders don't need.+ */+extern LZMA_API(lzma_bool) lzma_mf_is_supported(lzma_match_finder match_finder)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Compression modes+ *+ * This selects the function used to analyze the data produced by the match+ * finder.+ */+typedef enum {+ LZMA_MODE_FAST = 1,+ /**<+ * \brief Fast compression+ *+ * Fast mode is usually at its best when combined with+ * a hash chain match finder.+ */++ LZMA_MODE_NORMAL = 2+ /**<+ * \brief Normal compression+ *+ * This is usually notably slower than fast mode. Use this+ * together with binary tree match finders to expose the+ * full potential of the LZMA1 or LZMA2 encoder.+ */+} lzma_mode;+++/**+ * \brief Test if given compression mode is supported+ *+ * Return true if the given compression mode is supported by this liblzma+ * build. Otherwise false is returned. It is safe to call this with a value+ * that isn't listed in lzma_mode enumeration; the return value will be false.+ *+ * There is no way to list which modes are available in this particular+ * liblzma version and build. It would be useless, because a new compression+ * mode, which the application developer wasn't aware, could require giving+ * additional options to the encoder that the older modes don't need.+ */+extern LZMA_API(lzma_bool) lzma_mode_is_supported(lzma_mode mode)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Options specific to the LZMA1 and LZMA2 filters+ *+ * Since LZMA1 and LZMA2 share most of the code, it's simplest to share+ * the options structure too. For encoding, all but the reserved variables+ * need to be initialized unless specifically mentioned otherwise.+ * lzma_lzma_preset() can be used to get a good starting point.+ *+ * For raw decoding, both LZMA1 and LZMA2 need dict_size, preset_dict, and+ * preset_dict_size (if preset_dict != NULL). LZMA1 needs also lc, lp, and pb.+ */+typedef struct {+ /**+ * \brief Dictionary size in bytes+ *+ * Dictionary size indicates how many bytes of the recently processed+ * uncompressed data is kept in memory. One method to reduce size of+ * the uncompressed data is to store distance-length pairs, which+ * indicate what data to repeat from the dictionary buffer. Thus,+ * the bigger the dictionary, the better the compression ratio+ * usually is.+ *+ * Maximum size of the dictionary depends on multiple things:+ * - Memory usage limit+ * - Available address space (not a problem on 64-bit systems)+ * - Selected match finder (encoder only)+ *+ * Currently the maximum dictionary size for encoding is 1.5 GiB+ * (i.e. (UINT32_C(1) << 30) + (UINT32_C(1) << 29)) even on 64-bit+ * systems for certain match finder implementation reasons. In the+ * future, there may be match finders that support bigger+ * dictionaries.+ *+ * Decoder already supports dictionaries up to 4 GiB - 1 B (i.e.+ * UINT32_MAX), so increasing the maximum dictionary size of the+ * encoder won't cause problems for old decoders.+ *+ * Because extremely small dictionaries sizes would have unneeded+ * overhead in the decoder, the minimum dictionary size is 4096 bytes.+ *+ * \note When decoding, too big dictionary does no other harm+ * than wasting memory.+ */+ uint32_t dict_size;+# define LZMA_DICT_SIZE_MIN UINT32_C(4096)+# define LZMA_DICT_SIZE_DEFAULT (UINT32_C(1) << 23)++ /**+ * \brief Pointer to an initial dictionary+ *+ * It is possible to initialize the LZ77 history window using+ * a preset dictionary. It is useful when compressing many+ * similar, relatively small chunks of data independently from+ * each other. The preset dictionary should contain typical+ * strings that occur in the files being compressed. The most+ * probable strings should be near the end of the preset dictionary.+ *+ * This feature should be used only in special situations. For+ * now, it works correctly only with raw encoding and decoding.+ * Currently none of the container formats supported by+ * liblzma allow preset dictionary when decoding, thus if+ * you create a .xz or .lzma file with preset dictionary, it+ * cannot be decoded with the regular decoder functions. In the+ * future, the .xz format will likely get support for preset+ * dictionary though.+ */+ const uint8_t *preset_dict;++ /**+ * \brief Size of the preset dictionary+ *+ * Specifies the size of the preset dictionary. If the size is+ * bigger than dict_size, only the last dict_size bytes are+ * processed.+ *+ * This variable is read only when preset_dict is not NULL.+ * If preset_dict is not NULL but preset_dict_size is zero,+ * no preset dictionary is used (identical to only setting+ * preset_dict to NULL).+ */+ uint32_t preset_dict_size;++ /**+ * \brief Number of literal context bits+ *+ * How many of the highest bits of the previous uncompressed+ * eight-bit byte (also known as `literal') are taken into+ * account when predicting the bits of the next literal.+ *+ * E.g. in typical English text, an upper-case letter is+ * often followed by a lower-case letter, and a lower-case+ * letter is usually followed by another lower-case letter.+ * In the US-ASCII character set, the highest three bits are 010+ * for upper-case letters and 011 for lower-case letters.+ * When lc is at least 3, the literal coding can take advantage of+ * this property in the uncompressed data.+ *+ * There is a limit that applies to literal context bits and literal+ * position bits together: lc + lp <= 4. Without this limit the+ * decoding could become very slow, which could have security related+ * results in some cases like email servers doing virus scanning.+ * This limit also simplifies the internal implementation in liblzma.+ *+ * There may be LZMA1 streams that have lc + lp > 4 (maximum possible+ * lc would be 8). It is not possible to decode such streams with+ * liblzma.+ */+ uint32_t lc;+# define LZMA_LCLP_MIN 0+# define LZMA_LCLP_MAX 4+# define LZMA_LC_DEFAULT 3++ /**+ * \brief Number of literal position bits+ *+ * lp affects what kind of alignment in the uncompressed data is+ * assumed when encoding literals. A literal is a single 8-bit byte.+ * See pb below for more information about alignment.+ */+ uint32_t lp;+# define LZMA_LP_DEFAULT 0++ /**+ * \brief Number of position bits+ *+ * pb affects what kind of alignment in the uncompressed data is+ * assumed in general. The default means four-byte alignment+ * (2^ pb =2^2=4), which is often a good choice when there's+ * no better guess.+ *+ * When the alignment is known, setting pb accordingly may reduce+ * the file size a little. E.g. with text files having one-byte+ * alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can+ * improve compression slightly. For UTF-16 text, pb=1 is a good+ * choice. If the alignment is an odd number like 3 bytes, pb=0+ * might be the best choice.+ *+ * Even though the assumed alignment can be adjusted with pb and+ * lp, LZMA1 and LZMA2 still slightly favor 16-byte alignment.+ * It might be worth taking into account when designing file formats+ * that are likely to be often compressed with LZMA1 or LZMA2.+ */+ uint32_t pb;+# define LZMA_PB_MIN 0+# define LZMA_PB_MAX 4+# define LZMA_PB_DEFAULT 2++ /** Compression mode */+ lzma_mode mode;++ /**+ * \brief Nice length of a match+ *+ * This determines how many bytes the encoder compares from the match+ * candidates when looking for the best match. Once a match of at+ * least nice_len bytes long is found, the encoder stops looking for+ * better candidates and encodes the match. (Naturally, if the found+ * match is actually longer than nice_len, the actual length is+ * encoded; it's not truncated to nice_len.)+ *+ * Bigger values usually increase the compression ratio and+ * compression time. For most files, 32 to 128 is a good value,+ * which gives very good compression ratio at good speed.+ *+ * The exact minimum value depends on the match finder. The maximum+ * is 273, which is the maximum length of a match that LZMA1 and+ * LZMA2 can encode.+ */+ uint32_t nice_len;++ /** Match finder ID */+ lzma_match_finder mf;++ /**+ * \brief Maximum search depth in the match finder+ *+ * For every input byte, match finder searches through the hash chain+ * or binary tree in a loop, each iteration going one step deeper in+ * the chain or tree. The searching stops if+ * - a match of at least nice_len bytes long is found;+ * - all match candidates from the hash chain or binary tree have+ * been checked; or+ * - maximum search depth is reached.+ *+ * Maximum search depth is needed to prevent the match finder from+ * wasting too much time in case there are lots of short match+ * candidates. On the other hand, stopping the search before all+ * candidates have been checked can reduce compression ratio.+ *+ * Setting depth to zero tells liblzma to use an automatic default+ * value, that depends on the selected match finder and nice_len.+ * The default is in the range [4, 200] or so (it may vary between+ * liblzma versions).+ *+ * Using a bigger depth value than the default can increase+ * compression ratio in some cases. There is no strict maximum value,+ * but high values (thousands or millions) should be used with care:+ * the encoder could remain fast enough with typical input, but+ * malicious input could cause the match finder to slow down+ * dramatically, possibly creating a denial of service attack.+ */+ uint32_t depth;++ /*+ * Reserved space to allow possible future extensions without+ * breaking the ABI. You should not touch these, because the names+ * of these variables may change. These are and will never be used+ * with the currently supported options, so it is safe to leave these+ * uninitialized.+ */+ uint32_t reserved_int1;+ uint32_t reserved_int2;+ uint32_t reserved_int3;+ uint32_t reserved_int4;+ uint32_t reserved_int5;+ uint32_t reserved_int6;+ uint32_t reserved_int7;+ uint32_t reserved_int8;+ lzma_reserved_enum reserved_enum1;+ lzma_reserved_enum reserved_enum2;+ lzma_reserved_enum reserved_enum3;+ lzma_reserved_enum reserved_enum4;+ void *reserved_ptr1;+ void *reserved_ptr2;++} lzma_options_lzma;+++/**+ * \brief Set a compression preset to lzma_options_lzma structure+ *+ * 0 is the fastest and 9 is the slowest. These match the switches -0 .. -9+ * of the xz command line tool. In addition, it is possible to bitwise-or+ * flags to the preset. Currently only LZMA_PRESET_EXTREME is supported.+ * The flags are defined in container.h, because the flags are used also+ * with lzma_easy_encoder().+ *+ * The preset values are subject to changes between liblzma versions.+ *+ * This function is available only if LZMA1 or LZMA2 encoder has been enabled+ * when building liblzma.+ *+ * \return On success, false is returned. If the preset is not+ * supported, true is returned.+ */+extern LZMA_API(lzma_bool) lzma_lzma_preset(+ lzma_options_lzma *options, uint32_t preset) lzma_nothrow;
+ cbits/liblzma/api/lzma/stream_flags.h view
@@ -0,0 +1,223 @@+/**+ * \file lzma/stream_flags.h+ * \brief .xz Stream Header and Stream Footer encoder and decoder+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Size of Stream Header and Stream Footer+ *+ * Stream Header and Stream Footer have the same size and they are not+ * going to change even if a newer version of the .xz file format is+ * developed in future.+ */+#define LZMA_STREAM_HEADER_SIZE 12+++/**+ * \brief Options for encoding/decoding Stream Header and Stream Footer+ */+typedef struct {+ /**+ * \brief Stream Flags format version+ *+ * To prevent API and ABI breakages if new features are needed in+ * Stream Header or Stream Footer, 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, the+ * lzma_stream_header_encode() and lzma_stream_footer_encode()+ * will return LZMA_OPTIONS_ERROR.+ *+ * lzma_stream_header_decode() and lzma_stream_footer_decode()+ * will always set this to the lowest value that supports all the+ * features indicated by the Stream Flags field. The application+ * must check that the version number set by the decoding functions+ * is supported by the application. Otherwise it is possible that+ * the application will decode the Stream incorrectly.+ */+ uint32_t version;++ /**+ * \brief Backward Size+ *+ * Backward Size must be a multiple of four bytes. In this Stream+ * format version, Backward Size is the size of the Index field.+ *+ * Backward Size isn't actually part of the Stream Flags field, but+ * it is convenient to include in this structure anyway. Backward+ * Size is present only in the Stream Footer. There is no need to+ * initialize backward_size when encoding Stream Header.+ *+ * lzma_stream_header_decode() always sets backward_size to+ * LZMA_VLI_UNKNOWN so that it is convenient to use+ * lzma_stream_flags_compare() when both Stream Header and Stream+ * Footer have been decoded.+ */+ lzma_vli backward_size;+# define LZMA_BACKWARD_SIZE_MIN 4+# define LZMA_BACKWARD_SIZE_MAX (LZMA_VLI_C(1) << 34)++ /**+ * \brief Check ID+ *+ * This indicates the type of the integrity check calculated from+ * uncompressed data.+ */+ lzma_check check;++ /*+ * Reserved space to allow possible future extensions without+ * breaking the ABI. You should not touch these, because the+ * names of these variables may change.+ *+ * (We will never be able to use all of these since Stream Flags+ * is just two bytes plus Backward Size of four bytes. But it's+ * nice to have the proper types when they are needed.)+ */+ lzma_reserved_enum reserved_enum1;+ lzma_reserved_enum reserved_enum2;+ lzma_reserved_enum reserved_enum3;+ lzma_reserved_enum reserved_enum4;+ lzma_bool reserved_bool1;+ lzma_bool reserved_bool2;+ lzma_bool reserved_bool3;+ lzma_bool reserved_bool4;+ lzma_bool reserved_bool5;+ lzma_bool reserved_bool6;+ lzma_bool reserved_bool7;+ lzma_bool reserved_bool8;+ uint32_t reserved_int1;+ uint32_t reserved_int2;++} lzma_stream_flags;+++/**+ * \brief Encode Stream Header+ *+ * \param options Stream Header options to be encoded.+ * options->backward_size is ignored and doesn't+ * need to be initialized.+ * \param out Beginning of the output buffer of+ * LZMA_STREAM_HEADER_SIZE bytes.+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_OPTIONS_ERROR: options->version is not supported by+ * this liblzma version.+ * - LZMA_PROG_ERROR: Invalid options.+ */+extern LZMA_API(lzma_ret) lzma_stream_header_encode(+ const lzma_stream_flags *options, uint8_t *out)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Encode Stream Footer+ *+ * \param options Stream Footer options to be encoded.+ * \param out Beginning of the output buffer of+ * LZMA_STREAM_HEADER_SIZE bytes.+ *+ * \return - LZMA_OK: Encoding was successful.+ * - LZMA_OPTIONS_ERROR: options->version is not supported by+ * this liblzma version.+ * - LZMA_PROG_ERROR: Invalid options.+ */+extern LZMA_API(lzma_ret) lzma_stream_footer_encode(+ const lzma_stream_flags *options, uint8_t *out)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Decode Stream Header+ *+ * \param options Target for the decoded Stream Header options.+ * \param in Beginning of the input buffer of+ * LZMA_STREAM_HEADER_SIZE bytes.+ *+ * options->backward_size is always set to LZMA_VLI_UNKNOWN. This is to+ * help comparing Stream Flags from Stream Header and Stream Footer with+ * lzma_stream_flags_compare().+ *+ * \return - LZMA_OK: Decoding was successful.+ * - LZMA_FORMAT_ERROR: Magic bytes don't match, thus the given+ * buffer cannot be Stream Header.+ * - LZMA_DATA_ERROR: CRC32 doesn't match, thus the header+ * is corrupt.+ * - LZMA_OPTIONS_ERROR: Unsupported options are present+ * in the header.+ *+ * \note When decoding .xz files that contain multiple Streams, it may+ * make sense to print "file format not recognized" only if+ * decoding of the Stream Header of the _first_ Stream gives+ * LZMA_FORMAT_ERROR. If non-first Stream Header gives+ * LZMA_FORMAT_ERROR, the message used for LZMA_DATA_ERROR is+ * probably more appropriate.+ *+ * For example, Stream decoder in liblzma uses LZMA_DATA_ERROR if+ * LZMA_FORMAT_ERROR is returned by lzma_stream_header_decode()+ * when decoding non-first Stream.+ */+extern LZMA_API(lzma_ret) lzma_stream_header_decode(+ lzma_stream_flags *options, const uint8_t *in)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Decode Stream Footer+ *+ * \param options Target for the decoded Stream Header options.+ * \param in Beginning of the input buffer of+ * LZMA_STREAM_HEADER_SIZE bytes.+ *+ * \return - LZMA_OK: Decoding was successful.+ * - LZMA_FORMAT_ERROR: Magic bytes don't match, thus the given+ * buffer cannot be Stream Footer.+ * - LZMA_DATA_ERROR: CRC32 doesn't match, thus the Stream Footer+ * is corrupt.+ * - LZMA_OPTIONS_ERROR: Unsupported options are present+ * in Stream Footer.+ *+ * \note If Stream Header was already decoded successfully, but+ * decoding Stream Footer returns LZMA_FORMAT_ERROR, the+ * application should probably report some other error message+ * than "file format not recognized", since the file more likely+ * is corrupt (possibly truncated). Stream decoder in liblzma+ * uses LZMA_DATA_ERROR in this situation.+ */+extern LZMA_API(lzma_ret) lzma_stream_footer_decode(+ lzma_stream_flags *options, const uint8_t *in)+ lzma_nothrow lzma_attr_warn_unused_result;+++/**+ * \brief Compare two lzma_stream_flags structures+ *+ * backward_size values are compared only if both are not+ * LZMA_VLI_UNKNOWN.+ *+ * \return - LZMA_OK: Both are equal. If either had backward_size set+ * to LZMA_VLI_UNKNOWN, backward_size values were not+ * compared or validated.+ * - LZMA_DATA_ERROR: The structures differ.+ * - LZMA_OPTIONS_ERROR: version in either structure is greater+ * than the maximum supported version (currently zero).+ * - LZMA_PROG_ERROR: Invalid value, e.g. invalid check or+ * backward_size.+ */+extern LZMA_API(lzma_ret) lzma_stream_flags_compare(+ const lzma_stream_flags *a, const lzma_stream_flags *b)+ lzma_nothrow lzma_attr_pure;
+ cbits/liblzma/api/lzma/version.h view
@@ -0,0 +1,121 @@+/**+ * \file lzma/version.h+ * \brief Version number+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/*+ * Version number split into components+ */+#define LZMA_VERSION_MAJOR 5+#define LZMA_VERSION_MINOR 2+#define LZMA_VERSION_PATCH 5+#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE++#ifndef LZMA_VERSION_COMMIT+# define LZMA_VERSION_COMMIT ""+#endif+++/*+ * Map symbolic stability levels to integers.+ */+#define LZMA_VERSION_STABILITY_ALPHA 0+#define LZMA_VERSION_STABILITY_BETA 1+#define LZMA_VERSION_STABILITY_STABLE 2+++/**+ * \brief Compile-time version number+ *+ * The version number is of format xyyyzzzs where+ * - x = major+ * - yyy = minor+ * - zzz = revision+ * - s indicates stability: 0 = alpha, 1 = beta, 2 = stable+ *+ * The same xyyyzzz triplet is never reused with different stability levels.+ * For example, if 5.1.0alpha has been released, there will never be 5.1.0beta+ * or 5.1.0 stable.+ *+ * \note The version number of liblzma has nothing to with+ * the version number of Igor Pavlov's LZMA SDK.+ */+#define LZMA_VERSION (LZMA_VERSION_MAJOR * UINT32_C(10000000) \+ + LZMA_VERSION_MINOR * UINT32_C(10000) \+ + LZMA_VERSION_PATCH * UINT32_C(10) \+ + LZMA_VERSION_STABILITY)+++/*+ * Macros to construct the compile-time version string+ */+#if LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_ALPHA+# define LZMA_VERSION_STABILITY_STRING "alpha"+#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_BETA+# define LZMA_VERSION_STABILITY_STRING "beta"+#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_STABLE+# define LZMA_VERSION_STABILITY_STRING ""+#else+# error Incorrect LZMA_VERSION_STABILITY+#endif++#define LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit) \+ #major "." #minor "." #patch stability commit++#define LZMA_VERSION_STRING_C(major, minor, patch, stability, commit) \+ LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit)+++/**+ * \brief Compile-time version as a string+ *+ * This can be for example "4.999.5alpha", "4.999.8beta", or "5.0.0" (stable+ * versions don't have any "stable" suffix). In future, a snapshot built+ * from source code repository may include an additional suffix, for example+ * "4.999.8beta-21-g1d92". The commit ID won't be available in numeric form+ * in LZMA_VERSION macro.+ */+#define LZMA_VERSION_STRING LZMA_VERSION_STRING_C( \+ LZMA_VERSION_MAJOR, LZMA_VERSION_MINOR, \+ LZMA_VERSION_PATCH, LZMA_VERSION_STABILITY_STRING, \+ LZMA_VERSION_COMMIT)+++/* #ifndef is needed for use with windres (MinGW or Cygwin). */+#ifndef LZMA_H_INTERNAL_RC++/**+ * \brief Run-time version number as an integer+ *+ * Return the value of LZMA_VERSION macro at the compile time of liblzma.+ * This allows the application to compare if it was built against the same,+ * older, or newer version of liblzma that is currently running.+ */+extern LZMA_API(uint32_t) lzma_version_number(void)+ lzma_nothrow lzma_attr_const;+++/**+ * \brief Run-time version as a string+ *+ * This function may be useful if you want to display which version of+ * liblzma your application is currently using.+ */+extern LZMA_API(const char *) lzma_version_string(void)+ lzma_nothrow lzma_attr_const;++#endif
+ cbits/liblzma/api/lzma/vli.h view
@@ -0,0 +1,166 @@+/**+ * \file lzma/vli.h+ * \brief Variable-length integer handling+ *+ * In the .xz format, most integers are encoded in a variable-length+ * representation, which is sometimes called little endian base-128 encoding.+ * This saves space when smaller values are more likely than bigger values.+ *+ * The encoding scheme encodes seven bits to every byte, using minimum+ * number of bytes required to represent the given value. Encodings that use+ * non-minimum number of bytes are invalid, thus every integer has exactly+ * one encoded representation. The maximum number of bits in a VLI is 63,+ * thus the vli argument must be less than or equal to UINT64_MAX / 2. You+ * should use LZMA_VLI_MAX for clarity.+ */++/*+ * Author: Lasse Collin+ *+ * This file has been put into the public domain.+ * You can do whatever you want with this file.+ *+ * See ../lzma.h for information about liblzma as a whole.+ */++#ifndef LZMA_H_INTERNAL+# error Never include this file directly. Use <lzma.h> instead.+#endif+++/**+ * \brief Maximum supported value of a variable-length integer+ */+#define LZMA_VLI_MAX (UINT64_MAX / 2)++/**+ * \brief VLI value to denote that the value is unknown+ */+#define LZMA_VLI_UNKNOWN UINT64_MAX++/**+ * \brief Maximum supported encoded length of variable length integers+ */+#define LZMA_VLI_BYTES_MAX 9++/**+ * \brief VLI constant suffix+ */+#define LZMA_VLI_C(n) UINT64_C(n)+++/**+ * \brief Variable-length integer type+ *+ * Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is+ * indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the+ * underlying integer type.+ *+ * lzma_vli will be uint64_t for the foreseeable future. If a bigger size+ * is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will+ * not overflow lzma_vli. This simplifies integer overflow detection.+ */+typedef uint64_t lzma_vli;+++/**+ * \brief Validate a variable-length integer+ *+ * This is useful to test that application has given acceptable values+ * for example in the uncompressed_size and compressed_size variables.+ *+ * \return True if the integer is representable as VLI or if it+ * indicates unknown value.+ */+#define lzma_vli_is_valid(vli) \+ ((vli) <= LZMA_VLI_MAX || (vli) == LZMA_VLI_UNKNOWN)+++/**+ * \brief Encode a variable-length integer+ *+ * This function has two modes: single-call and multi-call. Single-call mode+ * encodes the whole integer at once; it is an error if the output buffer is+ * too small. Multi-call mode saves the position in *vli_pos, and thus it is+ * possible to continue encoding if the buffer becomes full before the whole+ * integer has been encoded.+ *+ * \param vli Integer to be encoded+ * \param vli_pos How many VLI-encoded bytes have already been written+ * out. When starting to encode a new integer in+ * multi-call mode, *vli_pos must be set to zero.+ * To use single-call encoding, set vli_pos to NULL.+ * \param out Beginning of the output buffer+ * \param out_pos The next byte will be written to out[*out_pos].+ * \param out_size Size of the out buffer; the first byte into+ * which no data is written to is out[out_size].+ *+ * \return Slightly different return values are used in multi-call and+ * single-call modes.+ *+ * Single-call (vli_pos == NULL):+ * - LZMA_OK: Integer successfully encoded.+ * - LZMA_PROG_ERROR: Arguments are not sane. This can be due+ * to too little output space; single-call mode doesn't use+ * LZMA_BUF_ERROR, since the application should have checked+ * the encoded size with lzma_vli_size().+ *+ * Multi-call (vli_pos != NULL):+ * - LZMA_OK: So far all OK, but the integer is not+ * completely written out yet.+ * - LZMA_STREAM_END: Integer successfully encoded.+ * - LZMA_BUF_ERROR: No output space was provided.+ * - LZMA_PROG_ERROR: Arguments are not sane.+ */+extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli, size_t *vli_pos,+ uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;+++/**+ * \brief Decode a variable-length integer+ *+ * Like lzma_vli_encode(), this function has single-call and multi-call modes.+ *+ * \param vli Pointer to decoded integer. The decoder will+ * initialize it to zero when *vli_pos == 0, so+ * application isn't required to initialize *vli.+ * \param vli_pos How many bytes have already been decoded. When+ * starting to decode a new integer in multi-call+ * mode, *vli_pos must be initialized to zero. To+ * use single-call decoding, set vli_pos to NULL.+ * \param in Beginning of the input buffer+ * \param in_pos The next byte will be read from in[*in_pos].+ * \param in_size Size of the input buffer; the first byte that+ * won't be read is in[in_size].+ *+ * \return Slightly different return values are used in multi-call and+ * single-call modes.+ *+ * Single-call (vli_pos == NULL):+ * - LZMA_OK: Integer successfully decoded.+ * - LZMA_DATA_ERROR: Integer is corrupt. This includes hitting+ * the end of the input buffer before the whole integer was+ * decoded; providing no input at all will use LZMA_DATA_ERROR.+ * - LZMA_PROG_ERROR: Arguments are not sane.+ *+ * Multi-call (vli_pos != NULL):+ * - LZMA_OK: So far all OK, but the integer is not+ * completely decoded yet.+ * - LZMA_STREAM_END: Integer successfully decoded.+ * - LZMA_DATA_ERROR: Integer is corrupt.+ * - LZMA_BUF_ERROR: No input was provided.+ * - LZMA_PROG_ERROR: Arguments are not sane.+ */+extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *vli, size_t *vli_pos,+ const uint8_t *in, size_t *in_pos, size_t in_size)+ lzma_nothrow;+++/**+ * \brief Get the number of bytes required to encode a VLI+ *+ * \return Number of bytes on success (1-9). If vli isn't valid,+ * zero is returned.+ */+extern LZMA_API(uint32_t) lzma_vli_size(lzma_vli vli)+ lzma_nothrow lzma_attr_pure;
+ cbits/liblzma/check/check.c view
@@ -0,0 +1,174 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file check.c+/// \brief Single API to access different integrity checks+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "check.h"+++extern LZMA_API(lzma_bool)+lzma_check_is_supported(lzma_check type)+{+ if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)+ return false;++ static const lzma_bool available_checks[LZMA_CHECK_ID_MAX + 1] = {+ true, // LZMA_CHECK_NONE++#ifdef HAVE_CHECK_CRC32+ true,+#else+ false,+#endif++ false, // Reserved+ false, // Reserved++#ifdef HAVE_CHECK_CRC64+ true,+#else+ false,+#endif++ false, // Reserved+ false, // Reserved+ false, // Reserved+ false, // Reserved+ false, // Reserved++#ifdef HAVE_CHECK_SHA256+ true,+#else+ false,+#endif++ false, // Reserved+ false, // Reserved+ false, // Reserved+ false, // Reserved+ false, // Reserved+ };++ return available_checks[(unsigned int)(type)];+}+++extern LZMA_API(uint32_t)+lzma_check_size(lzma_check type)+{+ if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)+ return UINT32_MAX;++ // See file-format.txt section 2.1.1.2.+ static const uint8_t check_sizes[LZMA_CHECK_ID_MAX + 1] = {+ 0,+ 4, 4, 4,+ 8, 8, 8,+ 16, 16, 16,+ 32, 32, 32,+ 64, 64, 64+ };++ return check_sizes[(unsigned int)(type)];+}+++extern void+lzma_check_init(lzma_check_state *check, lzma_check type)+{+ switch (type) {+ case LZMA_CHECK_NONE:+ break;++#ifdef HAVE_CHECK_CRC32+ case LZMA_CHECK_CRC32:+ check->state.crc32 = 0;+ break;+#endif++#ifdef HAVE_CHECK_CRC64+ case LZMA_CHECK_CRC64:+ check->state.crc64 = 0;+ break;+#endif++#ifdef HAVE_CHECK_SHA256+ case LZMA_CHECK_SHA256:+ lzma_sha256_init(check);+ break;+#endif++ default:+ break;+ }++ return;+}+++extern void+lzma_check_update(lzma_check_state *check, lzma_check type,+ const uint8_t *buf, size_t size)+{+ switch (type) {+#ifdef HAVE_CHECK_CRC32+ case LZMA_CHECK_CRC32:+ check->state.crc32 = lzma_crc32(buf, size, check->state.crc32);+ break;+#endif++#ifdef HAVE_CHECK_CRC64+ case LZMA_CHECK_CRC64:+ check->state.crc64 = lzma_crc64(buf, size, check->state.crc64);+ break;+#endif++#ifdef HAVE_CHECK_SHA256+ case LZMA_CHECK_SHA256:+ lzma_sha256_update(buf, size, check);+ break;+#endif++ default:+ break;+ }++ return;+}+++extern void+lzma_check_finish(lzma_check_state *check, lzma_check type)+{+ switch (type) {+#ifdef HAVE_CHECK_CRC32+ case LZMA_CHECK_CRC32:+ check->buffer.u32[0] = conv32le(check->state.crc32);+ break;+#endif++#ifdef HAVE_CHECK_CRC64+ case LZMA_CHECK_CRC64:+ check->buffer.u64[0] = conv64le(check->state.crc64);+ break;+#endif++#ifdef HAVE_CHECK_SHA256+ case LZMA_CHECK_SHA256:+ lzma_sha256_finish(check);+ break;+#endif++ default:+ break;+ }++ return;+}
+ cbits/liblzma/check/check.h view
@@ -0,0 +1,172 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file check.h+/// \brief Internal API to different integrity check functions+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_CHECK_H+#define LZMA_CHECK_H++#include "common.h"++// If the function for external SHA-256 is missing, use the internal SHA-256+// code. Due to how configure works, these defines can only get defined when+// both a usable header and a type have already been found.+#if !(defined(HAVE_CC_SHA256_INIT) \+ || defined(HAVE_SHA256_INIT) \+ || defined(HAVE_SHA256INIT))+# define HAVE_INTERNAL_SHA256 1+#endif++#if defined(HAVE_INTERNAL_SHA256)+// Nothing+#elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)+# include <CommonCrypto/CommonDigest.h>+#elif defined(HAVE_SHA256_H)+# include <sys/types.h>+# include <sha256.h>+#elif defined(HAVE_SHA2_H)+# include <sys/types.h>+# include <sha2.h>+#endif++#if defined(HAVE_INTERNAL_SHA256)+/// State for the internal SHA-256 implementation+typedef struct {+ /// Internal state+ uint32_t state[8];++ /// Size of the message excluding padding+ uint64_t size;+} lzma_sha256_state;+#elif defined(HAVE_CC_SHA256_CTX)+typedef CC_SHA256_CTX lzma_sha256_state;+#elif defined(HAVE_SHA256_CTX)+typedef SHA256_CTX lzma_sha256_state;+#elif defined(HAVE_SHA2_CTX)+typedef SHA2_CTX lzma_sha256_state;+#endif++#if defined(HAVE_INTERNAL_SHA256)+// Nothing+#elif defined(HAVE_CC_SHA256_INIT)+# define LZMA_SHA256FUNC(x) CC_SHA256_ ## x+#elif defined(HAVE_SHA256_INIT)+# define LZMA_SHA256FUNC(x) SHA256_ ## x+#elif defined(HAVE_SHA256INIT)+# define LZMA_SHA256FUNC(x) SHA256 ## x+#endif++// Index hashing needs the best possible hash function (preferably+// a cryptographic hash) for maximum reliability.+#if defined(HAVE_CHECK_SHA256)+# define LZMA_CHECK_BEST LZMA_CHECK_SHA256+#elif defined(HAVE_CHECK_CRC64)+# define LZMA_CHECK_BEST LZMA_CHECK_CRC64+#else+# define LZMA_CHECK_BEST LZMA_CHECK_CRC32+#endif+++/// \brief Structure to hold internal state of the check being calculated+///+/// \note This is not in the public API because this structure may+/// change in future if new integrity check algorithms are added.+typedef struct {+ /// Buffer to hold the final result and a temporary buffer for SHA256.+ union {+ uint8_t u8[64];+ uint32_t u32[16];+ uint64_t u64[8];+ } buffer;++ /// Check-specific data+ union {+ uint32_t crc32;+ uint64_t crc64;+ lzma_sha256_state sha256;+ } state;++} lzma_check_state;+++/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep+/// the array two-dimensional.+#ifdef HAVE_SMALL+extern uint32_t lzma_crc32_table[1][256];+extern void lzma_crc32_init(void);+#else+extern const uint32_t lzma_crc32_table[8][256];+extern const uint64_t lzma_crc64_table[4][256];+#endif+++/// \brief Initialize *check depending on type+///+/// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not+/// supported by the current version or build of liblzma.+/// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.+extern void lzma_check_init(lzma_check_state *check, lzma_check type);++/// Update the check state+extern void lzma_check_update(lzma_check_state *check, lzma_check type,+ const uint8_t *buf, size_t size);++/// Finish the check calculation and store the result to check->buffer.u8.+extern void lzma_check_finish(lzma_check_state *check, lzma_check type);+++#ifndef LZMA_SHA256FUNC++/// Prepare SHA-256 state for new input.+extern void lzma_sha256_init(lzma_check_state *check);++/// Update the SHA-256 hash state+extern void lzma_sha256_update(+ const uint8_t *buf, size_t size, lzma_check_state *check);++/// Finish the SHA-256 calculation and store the result to check->buffer.u8.+extern void lzma_sha256_finish(lzma_check_state *check);+++#else++static inline void+lzma_sha256_init(lzma_check_state *check)+{+ LZMA_SHA256FUNC(Init)(&check->state.sha256);+}+++static inline void+lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)+{+#if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX+ // Darwin's CC_SHA256_Update takes uint32_t as the buffer size,+ // so use a loop to support size_t.+ while (size > UINT32_MAX) {+ LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);+ buf += UINT32_MAX;+ size -= UINT32_MAX;+ }+#endif++ LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);+}+++static inline void+lzma_sha256_finish(lzma_check_state *check)+{+ LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);+}++#endif++#endif
+ cbits/liblzma/check/crc32_fast.c view
@@ -0,0 +1,82 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc32.c+/// \brief CRC32 calculation+///+/// Calculate the CRC32 using the slice-by-eight algorithm.+/// It is explained in this document:+/// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf+/// The code in this file is not the same as in Intel's paper, but+/// the basic principle is identical.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "check.h"+#include "crc_macros.h"+++// 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)+lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)+{+ crc = ~crc;++#ifdef WORDS_BIGENDIAN+ crc = bswap32(crc);+#endif++ if (size > 8) {+ // Fix the alignment, if needed. The if statement above+ // ensures that this won't read past the end of buf[].+ while ((uintptr_t)(buf) & 7) {+ crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);+ --size;+ }++ // Calculate the position where to stop.+ const uint8_t *const limit = buf + (size & ~(size_t)(7));++ // Calculate how many bytes must be calculated separately+ // before returning the result.+ size &= (size_t)(7);++ // Calculate the CRC32 using the slice-by-eight algorithm.+ while (buf < limit) {+ crc ^= aligned_read32ne(buf);+ buf += 4;++ crc = lzma_crc32_table[7][A(crc)]+ ^ lzma_crc32_table[6][B(crc)]+ ^ lzma_crc32_table[5][C(crc)]+ ^ lzma_crc32_table[4][D(crc)];++ const uint32_t tmp = aligned_read32ne(buf);+ buf += 4;++ // At least with some compilers, it is critical for+ // performance, that the crc variable is XORed+ // between the two table-lookup pairs.+ crc = lzma_crc32_table[3][A(tmp)]+ ^ lzma_crc32_table[2][B(tmp)]+ ^ crc+ ^ lzma_crc32_table[1][C(tmp)]+ ^ lzma_crc32_table[0][D(tmp)];+ }+ }++ while (size-- != 0)+ crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);++#ifdef WORDS_BIGENDIAN+ crc = bswap32(crc);+#endif++ return ~crc;+}
+ cbits/liblzma/check/crc32_small.c view
@@ -0,0 +1,61 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc32_small.c+/// \brief CRC32 calculation (size-optimized)+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "check.h"+++uint32_t lzma_crc32_table[1][256];+++static void+crc32_init(void)+{+ static const uint32_t poly32 = UINT32_C(0xEDB88320);++ for (size_t b = 0; b < 256; ++b) {+ uint32_t r = b;+ for (size_t i = 0; i < 8; ++i) {+ if (r & 1)+ r = (r >> 1) ^ poly32;+ else+ r >>= 1;+ }++ lzma_crc32_table[0][b] = r;+ }++ return;+}+++extern void+lzma_crc32_init(void)+{+ mythread_once(crc32_init);+ return;+}+++extern LZMA_API(uint32_t)+lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)+{+ lzma_crc32_init();++ crc = ~crc;++ while (size != 0) {+ crc = lzma_crc32_table[0][*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);+ --size;+ }++ return ~crc;+}
+ cbits/liblzma/check/crc32_table.c view
@@ -0,0 +1,22 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc32_table.c+/// \brief Precalculated CRC32 table with correct endianness+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"++// Having the declaration here silences clang -Wmissing-variable-declarations.+extern const uint32_t lzma_crc32_table[8][256];++#ifdef WORDS_BIGENDIAN+# include "crc32_table_be.h"+#else+# include "crc32_table_le.h"+#endif
+ cbits/liblzma/check/crc32_table_be.h view
@@ -0,0 +1,525 @@+/* This file has been automatically generated by crc32_tablegen.c. */++const uint32_t lzma_crc32_table[8][256] = {+ {+ 0x00000000, 0x96300777, 0x2C610EEE, 0xBA510999,+ 0x19C46D07, 0x8FF46A70, 0x35A563E9, 0xA395649E,+ 0x3288DB0E, 0xA4B8DC79, 0x1EE9D5E0, 0x88D9D297,+ 0x2B4CB609, 0xBD7CB17E, 0x072DB8E7, 0x911DBF90,+ 0x6410B71D, 0xF220B06A, 0x4871B9F3, 0xDE41BE84,+ 0x7DD4DA1A, 0xEBE4DD6D, 0x51B5D4F4, 0xC785D383,+ 0x56986C13, 0xC0A86B64, 0x7AF962FD, 0xECC9658A,+ 0x4F5C0114, 0xD96C0663, 0x633D0FFA, 0xF50D088D,+ 0xC8206E3B, 0x5E10694C, 0xE44160D5, 0x727167A2,+ 0xD1E4033C, 0x47D4044B, 0xFD850DD2, 0x6BB50AA5,+ 0xFAA8B535, 0x6C98B242, 0xD6C9BBDB, 0x40F9BCAC,+ 0xE36CD832, 0x755CDF45, 0xCF0DD6DC, 0x593DD1AB,+ 0xAC30D926, 0x3A00DE51, 0x8051D7C8, 0x1661D0BF,+ 0xB5F4B421, 0x23C4B356, 0x9995BACF, 0x0FA5BDB8,+ 0x9EB80228, 0x0888055F, 0xB2D90CC6, 0x24E90BB1,+ 0x877C6F2F, 0x114C6858, 0xAB1D61C1, 0x3D2D66B6,+ 0x9041DC76, 0x0671DB01, 0xBC20D298, 0x2A10D5EF,+ 0x8985B171, 0x1FB5B606, 0xA5E4BF9F, 0x33D4B8E8,+ 0xA2C90778, 0x34F9000F, 0x8EA80996, 0x18980EE1,+ 0xBB0D6A7F, 0x2D3D6D08, 0x976C6491, 0x015C63E6,+ 0xF4516B6B, 0x62616C1C, 0xD8306585, 0x4E0062F2,+ 0xED95066C, 0x7BA5011B, 0xC1F40882, 0x57C40FF5,+ 0xC6D9B065, 0x50E9B712, 0xEAB8BE8B, 0x7C88B9FC,+ 0xDF1DDD62, 0x492DDA15, 0xF37CD38C, 0x654CD4FB,+ 0x5861B24D, 0xCE51B53A, 0x7400BCA3, 0xE230BBD4,+ 0x41A5DF4A, 0xD795D83D, 0x6DC4D1A4, 0xFBF4D6D3,+ 0x6AE96943, 0xFCD96E34, 0x468867AD, 0xD0B860DA,+ 0x732D0444, 0xE51D0333, 0x5F4C0AAA, 0xC97C0DDD,+ 0x3C710550, 0xAA410227, 0x10100BBE, 0x86200CC9,+ 0x25B56857, 0xB3856F20, 0x09D466B9, 0x9FE461CE,+ 0x0EF9DE5E, 0x98C9D929, 0x2298D0B0, 0xB4A8D7C7,+ 0x173DB359, 0x810DB42E, 0x3B5CBDB7, 0xAD6CBAC0,+ 0x2083B8ED, 0xB6B3BF9A, 0x0CE2B603, 0x9AD2B174,+ 0x3947D5EA, 0xAF77D29D, 0x1526DB04, 0x8316DC73,+ 0x120B63E3, 0x843B6494, 0x3E6A6D0D, 0xA85A6A7A,+ 0x0BCF0EE4, 0x9DFF0993, 0x27AE000A, 0xB19E077D,+ 0x44930FF0, 0xD2A30887, 0x68F2011E, 0xFEC20669,+ 0x5D5762F7, 0xCB676580, 0x71366C19, 0xE7066B6E,+ 0x761BD4FE, 0xE02BD389, 0x5A7ADA10, 0xCC4ADD67,+ 0x6FDFB9F9, 0xF9EFBE8E, 0x43BEB717, 0xD58EB060,+ 0xE8A3D6D6, 0x7E93D1A1, 0xC4C2D838, 0x52F2DF4F,+ 0xF167BBD1, 0x6757BCA6, 0xDD06B53F, 0x4B36B248,+ 0xDA2B0DD8, 0x4C1B0AAF, 0xF64A0336, 0x607A0441,+ 0xC3EF60DF, 0x55DF67A8, 0xEF8E6E31, 0x79BE6946,+ 0x8CB361CB, 0x1A8366BC, 0xA0D26F25, 0x36E26852,+ 0x95770CCC, 0x03470BBB, 0xB9160222, 0x2F260555,+ 0xBE3BBAC5, 0x280BBDB2, 0x925AB42B, 0x046AB35C,+ 0xA7FFD7C2, 0x31CFD0B5, 0x8B9ED92C, 0x1DAEDE5B,+ 0xB0C2649B, 0x26F263EC, 0x9CA36A75, 0x0A936D02,+ 0xA906099C, 0x3F360EEB, 0x85670772, 0x13570005,+ 0x824ABF95, 0x147AB8E2, 0xAE2BB17B, 0x381BB60C,+ 0x9B8ED292, 0x0DBED5E5, 0xB7EFDC7C, 0x21DFDB0B,+ 0xD4D2D386, 0x42E2D4F1, 0xF8B3DD68, 0x6E83DA1F,+ 0xCD16BE81, 0x5B26B9F6, 0xE177B06F, 0x7747B718,+ 0xE65A0888, 0x706A0FFF, 0xCA3B0666, 0x5C0B0111,+ 0xFF9E658F, 0x69AE62F8, 0xD3FF6B61, 0x45CF6C16,+ 0x78E20AA0, 0xEED20DD7, 0x5483044E, 0xC2B30339,+ 0x612667A7, 0xF71660D0, 0x4D476949, 0xDB776E3E,+ 0x4A6AD1AE, 0xDC5AD6D9, 0x660BDF40, 0xF03BD837,+ 0x53AEBCA9, 0xC59EBBDE, 0x7FCFB247, 0xE9FFB530,+ 0x1CF2BDBD, 0x8AC2BACA, 0x3093B353, 0xA6A3B424,+ 0x0536D0BA, 0x9306D7CD, 0x2957DE54, 0xBF67D923,+ 0x2E7A66B3, 0xB84A61C4, 0x021B685D, 0x942B6F2A,+ 0x37BE0BB4, 0xA18E0CC3, 0x1BDF055A, 0x8DEF022D+ }, {+ 0x00000000, 0x41311B19, 0x82623632, 0xC3532D2B,+ 0x04C56C64, 0x45F4777D, 0x86A75A56, 0xC796414F,+ 0x088AD9C8, 0x49BBC2D1, 0x8AE8EFFA, 0xCBD9F4E3,+ 0x0C4FB5AC, 0x4D7EAEB5, 0x8E2D839E, 0xCF1C9887,+ 0x5112C24A, 0x1023D953, 0xD370F478, 0x9241EF61,+ 0x55D7AE2E, 0x14E6B537, 0xD7B5981C, 0x96848305,+ 0x59981B82, 0x18A9009B, 0xDBFA2DB0, 0x9ACB36A9,+ 0x5D5D77E6, 0x1C6C6CFF, 0xDF3F41D4, 0x9E0E5ACD,+ 0xA2248495, 0xE3159F8C, 0x2046B2A7, 0x6177A9BE,+ 0xA6E1E8F1, 0xE7D0F3E8, 0x2483DEC3, 0x65B2C5DA,+ 0xAAAE5D5D, 0xEB9F4644, 0x28CC6B6F, 0x69FD7076,+ 0xAE6B3139, 0xEF5A2A20, 0x2C09070B, 0x6D381C12,+ 0xF33646DF, 0xB2075DC6, 0x715470ED, 0x30656BF4,+ 0xF7F32ABB, 0xB6C231A2, 0x75911C89, 0x34A00790,+ 0xFBBC9F17, 0xBA8D840E, 0x79DEA925, 0x38EFB23C,+ 0xFF79F373, 0xBE48E86A, 0x7D1BC541, 0x3C2ADE58,+ 0x054F79F0, 0x447E62E9, 0x872D4FC2, 0xC61C54DB,+ 0x018A1594, 0x40BB0E8D, 0x83E823A6, 0xC2D938BF,+ 0x0DC5A038, 0x4CF4BB21, 0x8FA7960A, 0xCE968D13,+ 0x0900CC5C, 0x4831D745, 0x8B62FA6E, 0xCA53E177,+ 0x545DBBBA, 0x156CA0A3, 0xD63F8D88, 0x970E9691,+ 0x5098D7DE, 0x11A9CCC7, 0xD2FAE1EC, 0x93CBFAF5,+ 0x5CD76272, 0x1DE6796B, 0xDEB55440, 0x9F844F59,+ 0x58120E16, 0x1923150F, 0xDA703824, 0x9B41233D,+ 0xA76BFD65, 0xE65AE67C, 0x2509CB57, 0x6438D04E,+ 0xA3AE9101, 0xE29F8A18, 0x21CCA733, 0x60FDBC2A,+ 0xAFE124AD, 0xEED03FB4, 0x2D83129F, 0x6CB20986,+ 0xAB2448C9, 0xEA1553D0, 0x29467EFB, 0x687765E2,+ 0xF6793F2F, 0xB7482436, 0x741B091D, 0x352A1204,+ 0xF2BC534B, 0xB38D4852, 0x70DE6579, 0x31EF7E60,+ 0xFEF3E6E7, 0xBFC2FDFE, 0x7C91D0D5, 0x3DA0CBCC,+ 0xFA368A83, 0xBB07919A, 0x7854BCB1, 0x3965A7A8,+ 0x4B98833B, 0x0AA99822, 0xC9FAB509, 0x88CBAE10,+ 0x4F5DEF5F, 0x0E6CF446, 0xCD3FD96D, 0x8C0EC274,+ 0x43125AF3, 0x022341EA, 0xC1706CC1, 0x804177D8,+ 0x47D73697, 0x06E62D8E, 0xC5B500A5, 0x84841BBC,+ 0x1A8A4171, 0x5BBB5A68, 0x98E87743, 0xD9D96C5A,+ 0x1E4F2D15, 0x5F7E360C, 0x9C2D1B27, 0xDD1C003E,+ 0x120098B9, 0x533183A0, 0x9062AE8B, 0xD153B592,+ 0x16C5F4DD, 0x57F4EFC4, 0x94A7C2EF, 0xD596D9F6,+ 0xE9BC07AE, 0xA88D1CB7, 0x6BDE319C, 0x2AEF2A85,+ 0xED796BCA, 0xAC4870D3, 0x6F1B5DF8, 0x2E2A46E1,+ 0xE136DE66, 0xA007C57F, 0x6354E854, 0x2265F34D,+ 0xE5F3B202, 0xA4C2A91B, 0x67918430, 0x26A09F29,+ 0xB8AEC5E4, 0xF99FDEFD, 0x3ACCF3D6, 0x7BFDE8CF,+ 0xBC6BA980, 0xFD5AB299, 0x3E099FB2, 0x7F3884AB,+ 0xB0241C2C, 0xF1150735, 0x32462A1E, 0x73773107,+ 0xB4E17048, 0xF5D06B51, 0x3683467A, 0x77B25D63,+ 0x4ED7FACB, 0x0FE6E1D2, 0xCCB5CCF9, 0x8D84D7E0,+ 0x4A1296AF, 0x0B238DB6, 0xC870A09D, 0x8941BB84,+ 0x465D2303, 0x076C381A, 0xC43F1531, 0x850E0E28,+ 0x42984F67, 0x03A9547E, 0xC0FA7955, 0x81CB624C,+ 0x1FC53881, 0x5EF42398, 0x9DA70EB3, 0xDC9615AA,+ 0x1B0054E5, 0x5A314FFC, 0x996262D7, 0xD85379CE,+ 0x174FE149, 0x567EFA50, 0x952DD77B, 0xD41CCC62,+ 0x138A8D2D, 0x52BB9634, 0x91E8BB1F, 0xD0D9A006,+ 0xECF37E5E, 0xADC26547, 0x6E91486C, 0x2FA05375,+ 0xE836123A, 0xA9070923, 0x6A542408, 0x2B653F11,+ 0xE479A796, 0xA548BC8F, 0x661B91A4, 0x272A8ABD,+ 0xE0BCCBF2, 0xA18DD0EB, 0x62DEFDC0, 0x23EFE6D9,+ 0xBDE1BC14, 0xFCD0A70D, 0x3F838A26, 0x7EB2913F,+ 0xB924D070, 0xF815CB69, 0x3B46E642, 0x7A77FD5B,+ 0xB56B65DC, 0xF45A7EC5, 0x370953EE, 0x763848F7,+ 0xB1AE09B8, 0xF09F12A1, 0x33CC3F8A, 0x72FD2493+ }, {+ 0x00000000, 0x376AC201, 0x6ED48403, 0x59BE4602,+ 0xDCA80907, 0xEBC2CB06, 0xB27C8D04, 0x85164F05,+ 0xB851130E, 0x8F3BD10F, 0xD685970D, 0xE1EF550C,+ 0x64F91A09, 0x5393D808, 0x0A2D9E0A, 0x3D475C0B,+ 0x70A3261C, 0x47C9E41D, 0x1E77A21F, 0x291D601E,+ 0xAC0B2F1B, 0x9B61ED1A, 0xC2DFAB18, 0xF5B56919,+ 0xC8F23512, 0xFF98F713, 0xA626B111, 0x914C7310,+ 0x145A3C15, 0x2330FE14, 0x7A8EB816, 0x4DE47A17,+ 0xE0464D38, 0xD72C8F39, 0x8E92C93B, 0xB9F80B3A,+ 0x3CEE443F, 0x0B84863E, 0x523AC03C, 0x6550023D,+ 0x58175E36, 0x6F7D9C37, 0x36C3DA35, 0x01A91834,+ 0x84BF5731, 0xB3D59530, 0xEA6BD332, 0xDD011133,+ 0x90E56B24, 0xA78FA925, 0xFE31EF27, 0xC95B2D26,+ 0x4C4D6223, 0x7B27A022, 0x2299E620, 0x15F32421,+ 0x28B4782A, 0x1FDEBA2B, 0x4660FC29, 0x710A3E28,+ 0xF41C712D, 0xC376B32C, 0x9AC8F52E, 0xADA2372F,+ 0xC08D9A70, 0xF7E75871, 0xAE591E73, 0x9933DC72,+ 0x1C259377, 0x2B4F5176, 0x72F11774, 0x459BD575,+ 0x78DC897E, 0x4FB64B7F, 0x16080D7D, 0x2162CF7C,+ 0xA4748079, 0x931E4278, 0xCAA0047A, 0xFDCAC67B,+ 0xB02EBC6C, 0x87447E6D, 0xDEFA386F, 0xE990FA6E,+ 0x6C86B56B, 0x5BEC776A, 0x02523168, 0x3538F369,+ 0x087FAF62, 0x3F156D63, 0x66AB2B61, 0x51C1E960,+ 0xD4D7A665, 0xE3BD6464, 0xBA032266, 0x8D69E067,+ 0x20CBD748, 0x17A11549, 0x4E1F534B, 0x7975914A,+ 0xFC63DE4F, 0xCB091C4E, 0x92B75A4C, 0xA5DD984D,+ 0x989AC446, 0xAFF00647, 0xF64E4045, 0xC1248244,+ 0x4432CD41, 0x73580F40, 0x2AE64942, 0x1D8C8B43,+ 0x5068F154, 0x67023355, 0x3EBC7557, 0x09D6B756,+ 0x8CC0F853, 0xBBAA3A52, 0xE2147C50, 0xD57EBE51,+ 0xE839E25A, 0xDF53205B, 0x86ED6659, 0xB187A458,+ 0x3491EB5D, 0x03FB295C, 0x5A456F5E, 0x6D2FAD5F,+ 0x801B35E1, 0xB771F7E0, 0xEECFB1E2, 0xD9A573E3,+ 0x5CB33CE6, 0x6BD9FEE7, 0x3267B8E5, 0x050D7AE4,+ 0x384A26EF, 0x0F20E4EE, 0x569EA2EC, 0x61F460ED,+ 0xE4E22FE8, 0xD388EDE9, 0x8A36ABEB, 0xBD5C69EA,+ 0xF0B813FD, 0xC7D2D1FC, 0x9E6C97FE, 0xA90655FF,+ 0x2C101AFA, 0x1B7AD8FB, 0x42C49EF9, 0x75AE5CF8,+ 0x48E900F3, 0x7F83C2F2, 0x263D84F0, 0x115746F1,+ 0x944109F4, 0xA32BCBF5, 0xFA958DF7, 0xCDFF4FF6,+ 0x605D78D9, 0x5737BAD8, 0x0E89FCDA, 0x39E33EDB,+ 0xBCF571DE, 0x8B9FB3DF, 0xD221F5DD, 0xE54B37DC,+ 0xD80C6BD7, 0xEF66A9D6, 0xB6D8EFD4, 0x81B22DD5,+ 0x04A462D0, 0x33CEA0D1, 0x6A70E6D3, 0x5D1A24D2,+ 0x10FE5EC5, 0x27949CC4, 0x7E2ADAC6, 0x494018C7,+ 0xCC5657C2, 0xFB3C95C3, 0xA282D3C1, 0x95E811C0,+ 0xA8AF4DCB, 0x9FC58FCA, 0xC67BC9C8, 0xF1110BC9,+ 0x740744CC, 0x436D86CD, 0x1AD3C0CF, 0x2DB902CE,+ 0x4096AF91, 0x77FC6D90, 0x2E422B92, 0x1928E993,+ 0x9C3EA696, 0xAB546497, 0xF2EA2295, 0xC580E094,+ 0xF8C7BC9F, 0xCFAD7E9E, 0x9613389C, 0xA179FA9D,+ 0x246FB598, 0x13057799, 0x4ABB319B, 0x7DD1F39A,+ 0x3035898D, 0x075F4B8C, 0x5EE10D8E, 0x698BCF8F,+ 0xEC9D808A, 0xDBF7428B, 0x82490489, 0xB523C688,+ 0x88649A83, 0xBF0E5882, 0xE6B01E80, 0xD1DADC81,+ 0x54CC9384, 0x63A65185, 0x3A181787, 0x0D72D586,+ 0xA0D0E2A9, 0x97BA20A8, 0xCE0466AA, 0xF96EA4AB,+ 0x7C78EBAE, 0x4B1229AF, 0x12AC6FAD, 0x25C6ADAC,+ 0x1881F1A7, 0x2FEB33A6, 0x765575A4, 0x413FB7A5,+ 0xC429F8A0, 0xF3433AA1, 0xAAFD7CA3, 0x9D97BEA2,+ 0xD073C4B5, 0xE71906B4, 0xBEA740B6, 0x89CD82B7,+ 0x0CDBCDB2, 0x3BB10FB3, 0x620F49B1, 0x55658BB0,+ 0x6822D7BB, 0x5F4815BA, 0x06F653B8, 0x319C91B9,+ 0xB48ADEBC, 0x83E01CBD, 0xDA5E5ABF, 0xED3498BE+ }, {+ 0x00000000, 0x6567BCB8, 0x8BC809AA, 0xEEAFB512,+ 0x5797628F, 0x32F0DE37, 0xDC5F6B25, 0xB938D79D,+ 0xEF28B4C5, 0x8A4F087D, 0x64E0BD6F, 0x018701D7,+ 0xB8BFD64A, 0xDDD86AF2, 0x3377DFE0, 0x56106358,+ 0x9F571950, 0xFA30A5E8, 0x149F10FA, 0x71F8AC42,+ 0xC8C07BDF, 0xADA7C767, 0x43087275, 0x266FCECD,+ 0x707FAD95, 0x1518112D, 0xFBB7A43F, 0x9ED01887,+ 0x27E8CF1A, 0x428F73A2, 0xAC20C6B0, 0xC9477A08,+ 0x3EAF32A0, 0x5BC88E18, 0xB5673B0A, 0xD00087B2,+ 0x6938502F, 0x0C5FEC97, 0xE2F05985, 0x8797E53D,+ 0xD1878665, 0xB4E03ADD, 0x5A4F8FCF, 0x3F283377,+ 0x8610E4EA, 0xE3775852, 0x0DD8ED40, 0x68BF51F8,+ 0xA1F82BF0, 0xC49F9748, 0x2A30225A, 0x4F579EE2,+ 0xF66F497F, 0x9308F5C7, 0x7DA740D5, 0x18C0FC6D,+ 0x4ED09F35, 0x2BB7238D, 0xC518969F, 0xA07F2A27,+ 0x1947FDBA, 0x7C204102, 0x928FF410, 0xF7E848A8,+ 0x3D58149B, 0x583FA823, 0xB6901D31, 0xD3F7A189,+ 0x6ACF7614, 0x0FA8CAAC, 0xE1077FBE, 0x8460C306,+ 0xD270A05E, 0xB7171CE6, 0x59B8A9F4, 0x3CDF154C,+ 0x85E7C2D1, 0xE0807E69, 0x0E2FCB7B, 0x6B4877C3,+ 0xA20F0DCB, 0xC768B173, 0x29C70461, 0x4CA0B8D9,+ 0xF5986F44, 0x90FFD3FC, 0x7E5066EE, 0x1B37DA56,+ 0x4D27B90E, 0x284005B6, 0xC6EFB0A4, 0xA3880C1C,+ 0x1AB0DB81, 0x7FD76739, 0x9178D22B, 0xF41F6E93,+ 0x03F7263B, 0x66909A83, 0x883F2F91, 0xED589329,+ 0x546044B4, 0x3107F80C, 0xDFA84D1E, 0xBACFF1A6,+ 0xECDF92FE, 0x89B82E46, 0x67179B54, 0x027027EC,+ 0xBB48F071, 0xDE2F4CC9, 0x3080F9DB, 0x55E74563,+ 0x9CA03F6B, 0xF9C783D3, 0x176836C1, 0x720F8A79,+ 0xCB375DE4, 0xAE50E15C, 0x40FF544E, 0x2598E8F6,+ 0x73888BAE, 0x16EF3716, 0xF8408204, 0x9D273EBC,+ 0x241FE921, 0x41785599, 0xAFD7E08B, 0xCAB05C33,+ 0x3BB659ED, 0x5ED1E555, 0xB07E5047, 0xD519ECFF,+ 0x6C213B62, 0x094687DA, 0xE7E932C8, 0x828E8E70,+ 0xD49EED28, 0xB1F95190, 0x5F56E482, 0x3A31583A,+ 0x83098FA7, 0xE66E331F, 0x08C1860D, 0x6DA63AB5,+ 0xA4E140BD, 0xC186FC05, 0x2F294917, 0x4A4EF5AF,+ 0xF3762232, 0x96119E8A, 0x78BE2B98, 0x1DD99720,+ 0x4BC9F478, 0x2EAE48C0, 0xC001FDD2, 0xA566416A,+ 0x1C5E96F7, 0x79392A4F, 0x97969F5D, 0xF2F123E5,+ 0x05196B4D, 0x607ED7F5, 0x8ED162E7, 0xEBB6DE5F,+ 0x528E09C2, 0x37E9B57A, 0xD9460068, 0xBC21BCD0,+ 0xEA31DF88, 0x8F566330, 0x61F9D622, 0x049E6A9A,+ 0xBDA6BD07, 0xD8C101BF, 0x366EB4AD, 0x53090815,+ 0x9A4E721D, 0xFF29CEA5, 0x11867BB7, 0x74E1C70F,+ 0xCDD91092, 0xA8BEAC2A, 0x46111938, 0x2376A580,+ 0x7566C6D8, 0x10017A60, 0xFEAECF72, 0x9BC973CA,+ 0x22F1A457, 0x479618EF, 0xA939ADFD, 0xCC5E1145,+ 0x06EE4D76, 0x6389F1CE, 0x8D2644DC, 0xE841F864,+ 0x51792FF9, 0x341E9341, 0xDAB12653, 0xBFD69AEB,+ 0xE9C6F9B3, 0x8CA1450B, 0x620EF019, 0x07694CA1,+ 0xBE519B3C, 0xDB362784, 0x35999296, 0x50FE2E2E,+ 0x99B95426, 0xFCDEE89E, 0x12715D8C, 0x7716E134,+ 0xCE2E36A9, 0xAB498A11, 0x45E63F03, 0x208183BB,+ 0x7691E0E3, 0x13F65C5B, 0xFD59E949, 0x983E55F1,+ 0x2106826C, 0x44613ED4, 0xAACE8BC6, 0xCFA9377E,+ 0x38417FD6, 0x5D26C36E, 0xB389767C, 0xD6EECAC4,+ 0x6FD61D59, 0x0AB1A1E1, 0xE41E14F3, 0x8179A84B,+ 0xD769CB13, 0xB20E77AB, 0x5CA1C2B9, 0x39C67E01,+ 0x80FEA99C, 0xE5991524, 0x0B36A036, 0x6E511C8E,+ 0xA7166686, 0xC271DA3E, 0x2CDE6F2C, 0x49B9D394,+ 0xF0810409, 0x95E6B8B1, 0x7B490DA3, 0x1E2EB11B,+ 0x483ED243, 0x2D596EFB, 0xC3F6DBE9, 0xA6916751,+ 0x1FA9B0CC, 0x7ACE0C74, 0x9461B966, 0xF10605DE+ }, {+ 0x00000000, 0xB029603D, 0x6053C07A, 0xD07AA047,+ 0xC0A680F5, 0x708FE0C8, 0xA0F5408F, 0x10DC20B2,+ 0xC14B7030, 0x7162100D, 0xA118B04A, 0x1131D077,+ 0x01EDF0C5, 0xB1C490F8, 0x61BE30BF, 0xD1975082,+ 0x8297E060, 0x32BE805D, 0xE2C4201A, 0x52ED4027,+ 0x42316095, 0xF21800A8, 0x2262A0EF, 0x924BC0D2,+ 0x43DC9050, 0xF3F5F06D, 0x238F502A, 0x93A63017,+ 0x837A10A5, 0x33537098, 0xE329D0DF, 0x5300B0E2,+ 0x042FC1C1, 0xB406A1FC, 0x647C01BB, 0xD4556186,+ 0xC4894134, 0x74A02109, 0xA4DA814E, 0x14F3E173,+ 0xC564B1F1, 0x754DD1CC, 0xA537718B, 0x151E11B6,+ 0x05C23104, 0xB5EB5139, 0x6591F17E, 0xD5B89143,+ 0x86B821A1, 0x3691419C, 0xE6EBE1DB, 0x56C281E6,+ 0x461EA154, 0xF637C169, 0x264D612E, 0x96640113,+ 0x47F35191, 0xF7DA31AC, 0x27A091EB, 0x9789F1D6,+ 0x8755D164, 0x377CB159, 0xE706111E, 0x572F7123,+ 0x4958F358, 0xF9719365, 0x290B3322, 0x9922531F,+ 0x89FE73AD, 0x39D71390, 0xE9ADB3D7, 0x5984D3EA,+ 0x88138368, 0x383AE355, 0xE8404312, 0x5869232F,+ 0x48B5039D, 0xF89C63A0, 0x28E6C3E7, 0x98CFA3DA,+ 0xCBCF1338, 0x7BE67305, 0xAB9CD342, 0x1BB5B37F,+ 0x0B6993CD, 0xBB40F3F0, 0x6B3A53B7, 0xDB13338A,+ 0x0A846308, 0xBAAD0335, 0x6AD7A372, 0xDAFEC34F,+ 0xCA22E3FD, 0x7A0B83C0, 0xAA712387, 0x1A5843BA,+ 0x4D773299, 0xFD5E52A4, 0x2D24F2E3, 0x9D0D92DE,+ 0x8DD1B26C, 0x3DF8D251, 0xED827216, 0x5DAB122B,+ 0x8C3C42A9, 0x3C152294, 0xEC6F82D3, 0x5C46E2EE,+ 0x4C9AC25C, 0xFCB3A261, 0x2CC90226, 0x9CE0621B,+ 0xCFE0D2F9, 0x7FC9B2C4, 0xAFB31283, 0x1F9A72BE,+ 0x0F46520C, 0xBF6F3231, 0x6F159276, 0xDF3CF24B,+ 0x0EABA2C9, 0xBE82C2F4, 0x6EF862B3, 0xDED1028E,+ 0xCE0D223C, 0x7E244201, 0xAE5EE246, 0x1E77827B,+ 0x92B0E6B1, 0x2299868C, 0xF2E326CB, 0x42CA46F6,+ 0x52166644, 0xE23F0679, 0x3245A63E, 0x826CC603,+ 0x53FB9681, 0xE3D2F6BC, 0x33A856FB, 0x838136C6,+ 0x935D1674, 0x23747649, 0xF30ED60E, 0x4327B633,+ 0x102706D1, 0xA00E66EC, 0x7074C6AB, 0xC05DA696,+ 0xD0818624, 0x60A8E619, 0xB0D2465E, 0x00FB2663,+ 0xD16C76E1, 0x614516DC, 0xB13FB69B, 0x0116D6A6,+ 0x11CAF614, 0xA1E39629, 0x7199366E, 0xC1B05653,+ 0x969F2770, 0x26B6474D, 0xF6CCE70A, 0x46E58737,+ 0x5639A785, 0xE610C7B8, 0x366A67FF, 0x864307C2,+ 0x57D45740, 0xE7FD377D, 0x3787973A, 0x87AEF707,+ 0x9772D7B5, 0x275BB788, 0xF72117CF, 0x470877F2,+ 0x1408C710, 0xA421A72D, 0x745B076A, 0xC4726757,+ 0xD4AE47E5, 0x648727D8, 0xB4FD879F, 0x04D4E7A2,+ 0xD543B720, 0x656AD71D, 0xB510775A, 0x05391767,+ 0x15E537D5, 0xA5CC57E8, 0x75B6F7AF, 0xC59F9792,+ 0xDBE815E9, 0x6BC175D4, 0xBBBBD593, 0x0B92B5AE,+ 0x1B4E951C, 0xAB67F521, 0x7B1D5566, 0xCB34355B,+ 0x1AA365D9, 0xAA8A05E4, 0x7AF0A5A3, 0xCAD9C59E,+ 0xDA05E52C, 0x6A2C8511, 0xBA562556, 0x0A7F456B,+ 0x597FF589, 0xE95695B4, 0x392C35F3, 0x890555CE,+ 0x99D9757C, 0x29F01541, 0xF98AB506, 0x49A3D53B,+ 0x983485B9, 0x281DE584, 0xF86745C3, 0x484E25FE,+ 0x5892054C, 0xE8BB6571, 0x38C1C536, 0x88E8A50B,+ 0xDFC7D428, 0x6FEEB415, 0xBF941452, 0x0FBD746F,+ 0x1F6154DD, 0xAF4834E0, 0x7F3294A7, 0xCF1BF49A,+ 0x1E8CA418, 0xAEA5C425, 0x7EDF6462, 0xCEF6045F,+ 0xDE2A24ED, 0x6E0344D0, 0xBE79E497, 0x0E5084AA,+ 0x5D503448, 0xED795475, 0x3D03F432, 0x8D2A940F,+ 0x9DF6B4BD, 0x2DDFD480, 0xFDA574C7, 0x4D8C14FA,+ 0x9C1B4478, 0x2C322445, 0xFC488402, 0x4C61E43F,+ 0x5CBDC48D, 0xEC94A4B0, 0x3CEE04F7, 0x8CC764CA+ }, {+ 0x00000000, 0xA5D35CCB, 0x0BA1C84D, 0xAE729486,+ 0x1642919B, 0xB391CD50, 0x1DE359D6, 0xB830051D,+ 0x6D8253EC, 0xC8510F27, 0x66239BA1, 0xC3F0C76A,+ 0x7BC0C277, 0xDE139EBC, 0x70610A3A, 0xD5B256F1,+ 0x9B02D603, 0x3ED18AC8, 0x90A31E4E, 0x35704285,+ 0x8D404798, 0x28931B53, 0x86E18FD5, 0x2332D31E,+ 0xF68085EF, 0x5353D924, 0xFD214DA2, 0x58F21169,+ 0xE0C21474, 0x451148BF, 0xEB63DC39, 0x4EB080F2,+ 0x3605AC07, 0x93D6F0CC, 0x3DA4644A, 0x98773881,+ 0x20473D9C, 0x85946157, 0x2BE6F5D1, 0x8E35A91A,+ 0x5B87FFEB, 0xFE54A320, 0x502637A6, 0xF5F56B6D,+ 0x4DC56E70, 0xE81632BB, 0x4664A63D, 0xE3B7FAF6,+ 0xAD077A04, 0x08D426CF, 0xA6A6B249, 0x0375EE82,+ 0xBB45EB9F, 0x1E96B754, 0xB0E423D2, 0x15377F19,+ 0xC08529E8, 0x65567523, 0xCB24E1A5, 0x6EF7BD6E,+ 0xD6C7B873, 0x7314E4B8, 0xDD66703E, 0x78B52CF5,+ 0x6C0A580F, 0xC9D904C4, 0x67AB9042, 0xC278CC89,+ 0x7A48C994, 0xDF9B955F, 0x71E901D9, 0xD43A5D12,+ 0x01880BE3, 0xA45B5728, 0x0A29C3AE, 0xAFFA9F65,+ 0x17CA9A78, 0xB219C6B3, 0x1C6B5235, 0xB9B80EFE,+ 0xF7088E0C, 0x52DBD2C7, 0xFCA94641, 0x597A1A8A,+ 0xE14A1F97, 0x4499435C, 0xEAEBD7DA, 0x4F388B11,+ 0x9A8ADDE0, 0x3F59812B, 0x912B15AD, 0x34F84966,+ 0x8CC84C7B, 0x291B10B0, 0x87698436, 0x22BAD8FD,+ 0x5A0FF408, 0xFFDCA8C3, 0x51AE3C45, 0xF47D608E,+ 0x4C4D6593, 0xE99E3958, 0x47ECADDE, 0xE23FF115,+ 0x378DA7E4, 0x925EFB2F, 0x3C2C6FA9, 0x99FF3362,+ 0x21CF367F, 0x841C6AB4, 0x2A6EFE32, 0x8FBDA2F9,+ 0xC10D220B, 0x64DE7EC0, 0xCAACEA46, 0x6F7FB68D,+ 0xD74FB390, 0x729CEF5B, 0xDCEE7BDD, 0x793D2716,+ 0xAC8F71E7, 0x095C2D2C, 0xA72EB9AA, 0x02FDE561,+ 0xBACDE07C, 0x1F1EBCB7, 0xB16C2831, 0x14BF74FA,+ 0xD814B01E, 0x7DC7ECD5, 0xD3B57853, 0x76662498,+ 0xCE562185, 0x6B857D4E, 0xC5F7E9C8, 0x6024B503,+ 0xB596E3F2, 0x1045BF39, 0xBE372BBF, 0x1BE47774,+ 0xA3D47269, 0x06072EA2, 0xA875BA24, 0x0DA6E6EF,+ 0x4316661D, 0xE6C53AD6, 0x48B7AE50, 0xED64F29B,+ 0x5554F786, 0xF087AB4D, 0x5EF53FCB, 0xFB266300,+ 0x2E9435F1, 0x8B47693A, 0x2535FDBC, 0x80E6A177,+ 0x38D6A46A, 0x9D05F8A1, 0x33776C27, 0x96A430EC,+ 0xEE111C19, 0x4BC240D2, 0xE5B0D454, 0x4063889F,+ 0xF8538D82, 0x5D80D149, 0xF3F245CF, 0x56211904,+ 0x83934FF5, 0x2640133E, 0x883287B8, 0x2DE1DB73,+ 0x95D1DE6E, 0x300282A5, 0x9E701623, 0x3BA34AE8,+ 0x7513CA1A, 0xD0C096D1, 0x7EB20257, 0xDB615E9C,+ 0x63515B81, 0xC682074A, 0x68F093CC, 0xCD23CF07,+ 0x189199F6, 0xBD42C53D, 0x133051BB, 0xB6E30D70,+ 0x0ED3086D, 0xAB0054A6, 0x0572C020, 0xA0A19CEB,+ 0xB41EE811, 0x11CDB4DA, 0xBFBF205C, 0x1A6C7C97,+ 0xA25C798A, 0x078F2541, 0xA9FDB1C7, 0x0C2EED0C,+ 0xD99CBBFD, 0x7C4FE736, 0xD23D73B0, 0x77EE2F7B,+ 0xCFDE2A66, 0x6A0D76AD, 0xC47FE22B, 0x61ACBEE0,+ 0x2F1C3E12, 0x8ACF62D9, 0x24BDF65F, 0x816EAA94,+ 0x395EAF89, 0x9C8DF342, 0x32FF67C4, 0x972C3B0F,+ 0x429E6DFE, 0xE74D3135, 0x493FA5B3, 0xECECF978,+ 0x54DCFC65, 0xF10FA0AE, 0x5F7D3428, 0xFAAE68E3,+ 0x821B4416, 0x27C818DD, 0x89BA8C5B, 0x2C69D090,+ 0x9459D58D, 0x318A8946, 0x9FF81DC0, 0x3A2B410B,+ 0xEF9917FA, 0x4A4A4B31, 0xE438DFB7, 0x41EB837C,+ 0xF9DB8661, 0x5C08DAAA, 0xF27A4E2C, 0x57A912E7,+ 0x19199215, 0xBCCACEDE, 0x12B85A58, 0xB76B0693,+ 0x0F5B038E, 0xAA885F45, 0x04FACBC3, 0xA1299708,+ 0x749BC1F9, 0xD1489D32, 0x7F3A09B4, 0xDAE9557F,+ 0x62D95062, 0xC70A0CA9, 0x6978982F, 0xCCABC4E4+ }, {+ 0x00000000, 0xB40B77A6, 0x29119F97, 0x9D1AE831,+ 0x13244FF4, 0xA72F3852, 0x3A35D063, 0x8E3EA7C5,+ 0x674EEF33, 0xD3459895, 0x4E5F70A4, 0xFA540702,+ 0x746AA0C7, 0xC061D761, 0x5D7B3F50, 0xE97048F6,+ 0xCE9CDE67, 0x7A97A9C1, 0xE78D41F0, 0x53863656,+ 0xDDB89193, 0x69B3E635, 0xF4A90E04, 0x40A279A2,+ 0xA9D23154, 0x1DD946F2, 0x80C3AEC3, 0x34C8D965,+ 0xBAF67EA0, 0x0EFD0906, 0x93E7E137, 0x27EC9691,+ 0x9C39BDCF, 0x2832CA69, 0xB5282258, 0x012355FE,+ 0x8F1DF23B, 0x3B16859D, 0xA60C6DAC, 0x12071A0A,+ 0xFB7752FC, 0x4F7C255A, 0xD266CD6B, 0x666DBACD,+ 0xE8531D08, 0x5C586AAE, 0xC142829F, 0x7549F539,+ 0x52A563A8, 0xE6AE140E, 0x7BB4FC3F, 0xCFBF8B99,+ 0x41812C5C, 0xF58A5BFA, 0x6890B3CB, 0xDC9BC46D,+ 0x35EB8C9B, 0x81E0FB3D, 0x1CFA130C, 0xA8F164AA,+ 0x26CFC36F, 0x92C4B4C9, 0x0FDE5CF8, 0xBBD52B5E,+ 0x79750B44, 0xCD7E7CE2, 0x506494D3, 0xE46FE375,+ 0x6A5144B0, 0xDE5A3316, 0x4340DB27, 0xF74BAC81,+ 0x1E3BE477, 0xAA3093D1, 0x372A7BE0, 0x83210C46,+ 0x0D1FAB83, 0xB914DC25, 0x240E3414, 0x900543B2,+ 0xB7E9D523, 0x03E2A285, 0x9EF84AB4, 0x2AF33D12,+ 0xA4CD9AD7, 0x10C6ED71, 0x8DDC0540, 0x39D772E6,+ 0xD0A73A10, 0x64AC4DB6, 0xF9B6A587, 0x4DBDD221,+ 0xC38375E4, 0x77880242, 0xEA92EA73, 0x5E999DD5,+ 0xE54CB68B, 0x5147C12D, 0xCC5D291C, 0x78565EBA,+ 0xF668F97F, 0x42638ED9, 0xDF7966E8, 0x6B72114E,+ 0x820259B8, 0x36092E1E, 0xAB13C62F, 0x1F18B189,+ 0x9126164C, 0x252D61EA, 0xB83789DB, 0x0C3CFE7D,+ 0x2BD068EC, 0x9FDB1F4A, 0x02C1F77B, 0xB6CA80DD,+ 0x38F42718, 0x8CFF50BE, 0x11E5B88F, 0xA5EECF29,+ 0x4C9E87DF, 0xF895F079, 0x658F1848, 0xD1846FEE,+ 0x5FBAC82B, 0xEBB1BF8D, 0x76AB57BC, 0xC2A0201A,+ 0xF2EA1688, 0x46E1612E, 0xDBFB891F, 0x6FF0FEB9,+ 0xE1CE597C, 0x55C52EDA, 0xC8DFC6EB, 0x7CD4B14D,+ 0x95A4F9BB, 0x21AF8E1D, 0xBCB5662C, 0x08BE118A,+ 0x8680B64F, 0x328BC1E9, 0xAF9129D8, 0x1B9A5E7E,+ 0x3C76C8EF, 0x887DBF49, 0x15675778, 0xA16C20DE,+ 0x2F52871B, 0x9B59F0BD, 0x0643188C, 0xB2486F2A,+ 0x5B3827DC, 0xEF33507A, 0x7229B84B, 0xC622CFED,+ 0x481C6828, 0xFC171F8E, 0x610DF7BF, 0xD5068019,+ 0x6ED3AB47, 0xDAD8DCE1, 0x47C234D0, 0xF3C94376,+ 0x7DF7E4B3, 0xC9FC9315, 0x54E67B24, 0xE0ED0C82,+ 0x099D4474, 0xBD9633D2, 0x208CDBE3, 0x9487AC45,+ 0x1AB90B80, 0xAEB27C26, 0x33A89417, 0x87A3E3B1,+ 0xA04F7520, 0x14440286, 0x895EEAB7, 0x3D559D11,+ 0xB36B3AD4, 0x07604D72, 0x9A7AA543, 0x2E71D2E5,+ 0xC7019A13, 0x730AEDB5, 0xEE100584, 0x5A1B7222,+ 0xD425D5E7, 0x602EA241, 0xFD344A70, 0x493F3DD6,+ 0x8B9F1DCC, 0x3F946A6A, 0xA28E825B, 0x1685F5FD,+ 0x98BB5238, 0x2CB0259E, 0xB1AACDAF, 0x05A1BA09,+ 0xECD1F2FF, 0x58DA8559, 0xC5C06D68, 0x71CB1ACE,+ 0xFFF5BD0B, 0x4BFECAAD, 0xD6E4229C, 0x62EF553A,+ 0x4503C3AB, 0xF108B40D, 0x6C125C3C, 0xD8192B9A,+ 0x56278C5F, 0xE22CFBF9, 0x7F3613C8, 0xCB3D646E,+ 0x224D2C98, 0x96465B3E, 0x0B5CB30F, 0xBF57C4A9,+ 0x3169636C, 0x856214CA, 0x1878FCFB, 0xAC738B5D,+ 0x17A6A003, 0xA3ADD7A5, 0x3EB73F94, 0x8ABC4832,+ 0x0482EFF7, 0xB0899851, 0x2D937060, 0x999807C6,+ 0x70E84F30, 0xC4E33896, 0x59F9D0A7, 0xEDF2A701,+ 0x63CC00C4, 0xD7C77762, 0x4ADD9F53, 0xFED6E8F5,+ 0xD93A7E64, 0x6D3109C2, 0xF02BE1F3, 0x44209655,+ 0xCA1E3190, 0x7E154636, 0xE30FAE07, 0x5704D9A1,+ 0xBE749157, 0x0A7FE6F1, 0x97650EC0, 0x236E7966,+ 0xAD50DEA3, 0x195BA905, 0x84414134, 0x304A3692+ }, {+ 0x00000000, 0x9E00AACC, 0x7D072542, 0xE3078F8E,+ 0xFA0E4A84, 0x640EE048, 0x87096FC6, 0x1909C50A,+ 0xB51BE5D3, 0x2B1B4F1F, 0xC81CC091, 0x561C6A5D,+ 0x4F15AF57, 0xD115059B, 0x32128A15, 0xAC1220D9,+ 0x2B31BB7C, 0xB53111B0, 0x56369E3E, 0xC83634F2,+ 0xD13FF1F8, 0x4F3F5B34, 0xAC38D4BA, 0x32387E76,+ 0x9E2A5EAF, 0x002AF463, 0xE32D7BED, 0x7D2DD121,+ 0x6424142B, 0xFA24BEE7, 0x19233169, 0x87239BA5,+ 0x566276F9, 0xC862DC35, 0x2B6553BB, 0xB565F977,+ 0xAC6C3C7D, 0x326C96B1, 0xD16B193F, 0x4F6BB3F3,+ 0xE379932A, 0x7D7939E6, 0x9E7EB668, 0x007E1CA4,+ 0x1977D9AE, 0x87777362, 0x6470FCEC, 0xFA705620,+ 0x7D53CD85, 0xE3536749, 0x0054E8C7, 0x9E54420B,+ 0x875D8701, 0x195D2DCD, 0xFA5AA243, 0x645A088F,+ 0xC8482856, 0x5648829A, 0xB54F0D14, 0x2B4FA7D8,+ 0x324662D2, 0xAC46C81E, 0x4F414790, 0xD141ED5C,+ 0xEDC29D29, 0x73C237E5, 0x90C5B86B, 0x0EC512A7,+ 0x17CCD7AD, 0x89CC7D61, 0x6ACBF2EF, 0xF4CB5823,+ 0x58D978FA, 0xC6D9D236, 0x25DE5DB8, 0xBBDEF774,+ 0xA2D7327E, 0x3CD798B2, 0xDFD0173C, 0x41D0BDF0,+ 0xC6F32655, 0x58F38C99, 0xBBF40317, 0x25F4A9DB,+ 0x3CFD6CD1, 0xA2FDC61D, 0x41FA4993, 0xDFFAE35F,+ 0x73E8C386, 0xEDE8694A, 0x0EEFE6C4, 0x90EF4C08,+ 0x89E68902, 0x17E623CE, 0xF4E1AC40, 0x6AE1068C,+ 0xBBA0EBD0, 0x25A0411C, 0xC6A7CE92, 0x58A7645E,+ 0x41AEA154, 0xDFAE0B98, 0x3CA98416, 0xA2A92EDA,+ 0x0EBB0E03, 0x90BBA4CF, 0x73BC2B41, 0xEDBC818D,+ 0xF4B54487, 0x6AB5EE4B, 0x89B261C5, 0x17B2CB09,+ 0x909150AC, 0x0E91FA60, 0xED9675EE, 0x7396DF22,+ 0x6A9F1A28, 0xF49FB0E4, 0x17983F6A, 0x899895A6,+ 0x258AB57F, 0xBB8A1FB3, 0x588D903D, 0xC68D3AF1,+ 0xDF84FFFB, 0x41845537, 0xA283DAB9, 0x3C837075,+ 0xDA853B53, 0x4485919F, 0xA7821E11, 0x3982B4DD,+ 0x208B71D7, 0xBE8BDB1B, 0x5D8C5495, 0xC38CFE59,+ 0x6F9EDE80, 0xF19E744C, 0x1299FBC2, 0x8C99510E,+ 0x95909404, 0x0B903EC8, 0xE897B146, 0x76971B8A,+ 0xF1B4802F, 0x6FB42AE3, 0x8CB3A56D, 0x12B30FA1,+ 0x0BBACAAB, 0x95BA6067, 0x76BDEFE9, 0xE8BD4525,+ 0x44AF65FC, 0xDAAFCF30, 0x39A840BE, 0xA7A8EA72,+ 0xBEA12F78, 0x20A185B4, 0xC3A60A3A, 0x5DA6A0F6,+ 0x8CE74DAA, 0x12E7E766, 0xF1E068E8, 0x6FE0C224,+ 0x76E9072E, 0xE8E9ADE2, 0x0BEE226C, 0x95EE88A0,+ 0x39FCA879, 0xA7FC02B5, 0x44FB8D3B, 0xDAFB27F7,+ 0xC3F2E2FD, 0x5DF24831, 0xBEF5C7BF, 0x20F56D73,+ 0xA7D6F6D6, 0x39D65C1A, 0xDAD1D394, 0x44D17958,+ 0x5DD8BC52, 0xC3D8169E, 0x20DF9910, 0xBEDF33DC,+ 0x12CD1305, 0x8CCDB9C9, 0x6FCA3647, 0xF1CA9C8B,+ 0xE8C35981, 0x76C3F34D, 0x95C47CC3, 0x0BC4D60F,+ 0x3747A67A, 0xA9470CB6, 0x4A408338, 0xD44029F4,+ 0xCD49ECFE, 0x53494632, 0xB04EC9BC, 0x2E4E6370,+ 0x825C43A9, 0x1C5CE965, 0xFF5B66EB, 0x615BCC27,+ 0x7852092D, 0xE652A3E1, 0x05552C6F, 0x9B5586A3,+ 0x1C761D06, 0x8276B7CA, 0x61713844, 0xFF719288,+ 0xE6785782, 0x7878FD4E, 0x9B7F72C0, 0x057FD80C,+ 0xA96DF8D5, 0x376D5219, 0xD46ADD97, 0x4A6A775B,+ 0x5363B251, 0xCD63189D, 0x2E649713, 0xB0643DDF,+ 0x6125D083, 0xFF257A4F, 0x1C22F5C1, 0x82225F0D,+ 0x9B2B9A07, 0x052B30CB, 0xE62CBF45, 0x782C1589,+ 0xD43E3550, 0x4A3E9F9C, 0xA9391012, 0x3739BADE,+ 0x2E307FD4, 0xB030D518, 0x53375A96, 0xCD37F05A,+ 0x4A146BFF, 0xD414C133, 0x37134EBD, 0xA913E471,+ 0xB01A217B, 0x2E1A8BB7, 0xCD1D0439, 0x531DAEF5,+ 0xFF0F8E2C, 0x610F24E0, 0x8208AB6E, 0x1C0801A2,+ 0x0501C4A8, 0x9B016E64, 0x7806E1EA, 0xE6064B26+ }+};
+ cbits/liblzma/check/crc32_table_le.h view
@@ -0,0 +1,525 @@+/* This file has been automatically generated by crc32_tablegen.c. */++const uint32_t lzma_crc32_table[8][256] = {+ {+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D+ }, {+ 0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3,+ 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7,+ 0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB,+ 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF,+ 0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192,+ 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496,+ 0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A,+ 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E,+ 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761,+ 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265,+ 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69,+ 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D,+ 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530,+ 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034,+ 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38,+ 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C,+ 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6,+ 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2,+ 0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE,+ 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA,+ 0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97,+ 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93,+ 0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F,+ 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B,+ 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864,+ 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60,+ 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C,+ 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768,+ 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35,+ 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31,+ 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D,+ 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539,+ 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88,+ 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C,+ 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180,+ 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484,+ 0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9,+ 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD,+ 0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1,+ 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5,+ 0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A,+ 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E,+ 0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522,+ 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026,+ 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B,+ 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F,+ 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773,+ 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277,+ 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D,+ 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189,+ 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85,+ 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81,+ 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC,+ 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8,+ 0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4,+ 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0,+ 0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F,+ 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B,+ 0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27,+ 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23,+ 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E,+ 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A,+ 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876,+ 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72+ }, {+ 0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59,+ 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685,+ 0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1,+ 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D,+ 0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29,+ 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5,+ 0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91,+ 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D,+ 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9,+ 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065,+ 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901,+ 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD,+ 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9,+ 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315,+ 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71,+ 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD,+ 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399,+ 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45,+ 0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221,+ 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD,+ 0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9,+ 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835,+ 0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151,+ 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D,+ 0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579,+ 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5,+ 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1,+ 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D,+ 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609,+ 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5,+ 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1,+ 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D,+ 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9,+ 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05,+ 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461,+ 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD,+ 0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9,+ 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75,+ 0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711,+ 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD,+ 0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339,+ 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5,+ 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281,+ 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D,+ 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049,+ 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895,+ 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1,+ 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D,+ 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819,+ 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5,+ 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1,+ 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D,+ 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69,+ 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5,+ 0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1,+ 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D,+ 0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9,+ 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625,+ 0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41,+ 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D,+ 0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89,+ 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555,+ 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31,+ 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED+ }, {+ 0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE,+ 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9,+ 0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701,+ 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056,+ 0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871,+ 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26,+ 0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E,+ 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9,+ 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0,+ 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787,+ 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F,+ 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68,+ 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F,+ 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018,+ 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0,+ 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7,+ 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3,+ 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084,+ 0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C,+ 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B,+ 0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C,+ 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B,+ 0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3,+ 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4,+ 0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED,+ 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA,+ 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002,+ 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755,+ 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72,+ 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825,+ 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D,+ 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA,+ 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5,+ 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82,+ 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A,+ 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D,+ 0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A,+ 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D,+ 0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5,+ 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2,+ 0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB,+ 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC,+ 0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04,+ 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953,+ 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174,+ 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623,+ 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B,+ 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC,+ 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8,+ 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF,+ 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907,+ 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50,+ 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677,+ 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120,+ 0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98,+ 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF,+ 0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6,+ 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981,+ 0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639,+ 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E,+ 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949,+ 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E,+ 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6,+ 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1+ }, {+ 0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0,+ 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10,+ 0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111,+ 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1,+ 0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52,+ 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92,+ 0x5090DC43, 0x6DF0F5F3, 0x2A508F23, 0x1730A693,+ 0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053,+ 0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4,+ 0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314,+ 0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15,+ 0x0431C205, 0x3951EBB5, 0x7EF19165, 0x4391B8D5,+ 0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256,+ 0x54A11E46, 0x69C137F6, 0x2E614D26, 0x13016496,+ 0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997,+ 0x64D15587, 0x59B17C37, 0x1E1106E7, 0x23712F57,+ 0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299,+ 0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459,+ 0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958,+ 0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98,+ 0x3813CFCB, 0x0573E67B, 0x42D39CAB, 0x7FB3B51B,+ 0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB,+ 0x0863840A, 0x3503ADBA, 0x72A3D76A, 0x4FC3FEDA,+ 0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A,+ 0x9932774D, 0xA4525EFD, 0xE3F2242D, 0xDE920D9D,+ 0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D,+ 0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C,+ 0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C,+ 0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F,+ 0x0C52460F, 0x31326FBF, 0x7692156F, 0x4BF23CDF,+ 0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE,+ 0x3C220DCE, 0x0142247E, 0x46E25EAE, 0x7B82771E,+ 0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42,+ 0x44661652, 0x79063FE2, 0x3EA64532, 0x03C66C82,+ 0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183,+ 0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743,+ 0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0,+ 0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00,+ 0xE1766CD1, 0xDC164561, 0x9BB63FB1, 0xA6D61601,+ 0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1,+ 0x70279F96, 0x4D47B626, 0x0AE7CCF6, 0x3787E546,+ 0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386,+ 0x4057D457, 0x7D37FDE7, 0x3A978737, 0x07F7AE87,+ 0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847,+ 0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4,+ 0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404,+ 0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905,+ 0xD537E515, 0xE857CCA5, 0xAFF7B675, 0x92979FC5,+ 0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B,+ 0x1C954E1B, 0x21F567AB, 0x66551D7B, 0x5B3534CB,+ 0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA,+ 0x2CE505DA, 0x11852C6A, 0x562556BA, 0x6B457F0A,+ 0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589,+ 0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349,+ 0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48,+ 0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888,+ 0x28D4C7DF, 0x15B4EE6F, 0x521494BF, 0x6F74BD0F,+ 0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF,+ 0x18A48C1E, 0x25C4A5AE, 0x6264DF7E, 0x5F04F6CE,+ 0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E,+ 0x4834505D, 0x755479ED, 0x32F4033D, 0x0F942A8D,+ 0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D,+ 0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C,+ 0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C+ }, {+ 0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE,+ 0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8,+ 0xEC53826D, 0x270F51C8, 0xA19B2366, 0x6AC7F0C3,+ 0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5,+ 0x03D6029B, 0xC88AD13E, 0x4E1EA390, 0x85427035,+ 0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223,+ 0xEF8580F6, 0x24D95353, 0xA24D21FD, 0x6911F258,+ 0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E,+ 0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798,+ 0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E,+ 0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5,+ 0x706EC54D, 0xBB3216E8, 0x3DA66446, 0xF6FAB7E3,+ 0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503,+ 0x9FEB45BB, 0x54B7961E, 0xD223E4B0, 0x197F3715,+ 0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E,+ 0x73B8C7D6, 0xB8E41473, 0x3E7066DD, 0xF52CB578,+ 0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2,+ 0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4,+ 0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF,+ 0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9,+ 0x0C8E08F7, 0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59,+ 0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F,+ 0xE0DD8A9A, 0x2B81593F, 0xAD152B91, 0x6649F834,+ 0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22,+ 0x08F40F5A, 0xC3A8DCFF, 0x453CAE51, 0x8E607DF4,+ 0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2,+ 0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99,+ 0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F,+ 0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F,+ 0x90B34FD7, 0x5BEF9C72, 0xDD7BEEDC, 0x16273D79,+ 0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02,+ 0x7CE0CDBA, 0xB7BC1E1F, 0x31286CB1, 0xFA74BF14,+ 0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676,+ 0x852156CE, 0x4E7D856B, 0xC8E9F7C5, 0x03B52460,+ 0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B,+ 0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D,+ 0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED,+ 0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB,+ 0xF135942E, 0x3A69478B, 0xBCFD3525, 0x77A1E680,+ 0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496,+ 0x191C11EE, 0xD240C24B, 0x54D4B0E5, 0x9F886340,+ 0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156,+ 0xF54F9383, 0x3E134026, 0xB8873288, 0x73DBE12D,+ 0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B,+ 0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB,+ 0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD,+ 0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6,+ 0x6D08D30E, 0xA65400AB, 0x20C07205, 0xEB9CA1A0,+ 0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A,+ 0x8A795CA2, 0x41258F07, 0xC7B1FDA9, 0x0CED2E0C,+ 0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77,+ 0x662ADECF, 0xAD760D6A, 0x2BE27FC4, 0xE0BEAC61,+ 0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81,+ 0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97,+ 0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC,+ 0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA,+ 0x16441B82, 0xDD18C827, 0x5B8CBA89, 0x90D0692C,+ 0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A,+ 0xFA1799EF, 0x314B4A4A, 0xB7DF38E4, 0x7C83EB41,+ 0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957,+ 0x15921919, 0xDECECABC, 0x585AB812, 0x93066BB7,+ 0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1,+ 0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA,+ 0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC+ }, {+ 0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D,+ 0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E,+ 0x33EF4E67, 0x959845D3, 0xA4705F4E, 0x020754FA,+ 0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9,+ 0x67DE9CCE, 0xC1A9977A, 0xF0418DE7, 0x56368653,+ 0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240,+ 0x5431D2A9, 0xF246D91D, 0xC3AEC380, 0x65D9C834,+ 0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27,+ 0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301,+ 0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712,+ 0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66,+ 0x081D53E8, 0xAE6A585C, 0x9F8242C1, 0x39F54975,+ 0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF,+ 0x5C2C8141, 0xFA5B8AF5, 0xCBB39068, 0x6DC49BDC,+ 0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8,+ 0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F, 0x5E2BD5BB,+ 0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4,+ 0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7,+ 0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183,+ 0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590,+ 0x23D5E9B7, 0x85A2E203, 0xB44AF89E, 0x123DF32A,+ 0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739,+ 0x103AA7D0, 0xB64DAC64, 0x87A5B6F9, 0x21D2BD4D,+ 0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E,+ 0x8BB64CE5, 0x2DC14751, 0x1C295DCC, 0xBA5E5678,+ 0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B,+ 0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F,+ 0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C,+ 0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6,+ 0x1827F438, 0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5,+ 0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1,+ 0x2BC8BA5F, 0x8DBFB1EB, 0xBC57AB76, 0x1A20A0C2,+ 0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F,+ 0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8, 0x4DB1D47C,+ 0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08,+ 0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B,+ 0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1,+ 0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2,+ 0xDC27385B, 0x7A5033EF, 0x4BB82972, 0xEDCF22C6,+ 0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5,+ 0x47ABD36E, 0xE1DCD8DA, 0xD034C247, 0x7643C9F3,+ 0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0,+ 0x74449D09, 0xD23396BD, 0xE3DB8C20, 0x45AC8794,+ 0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387,+ 0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D,+ 0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E,+ 0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A,+ 0xE7D525D4, 0x41A22E60, 0x704A34FD, 0xD63D3F49,+ 0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516,+ 0x3852BB98, 0x9E25B02C, 0xAFCDAAB1, 0x09BAA105,+ 0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71,+ 0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6, 0x3A55EF62,+ 0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8,+ 0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB,+ 0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF,+ 0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC,+ 0x03A0A617, 0xA5D7ADA3, 0x943FB73E, 0x3248BC8A,+ 0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899,+ 0x304FE870, 0x9638E3C4, 0xA7D0F959, 0x01A7F2ED,+ 0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE,+ 0x647E3AD9, 0xC209316D, 0xF3E12BF0, 0x55962044,+ 0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457,+ 0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23,+ 0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30+ }, {+ 0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3,+ 0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919,+ 0xD3E51BB5, 0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56,+ 0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC,+ 0x7CBB312B, 0xB01131B5, 0x3E9E3656, 0xF23436C8,+ 0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832,+ 0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3, 0x21D12D7D,+ 0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387,+ 0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5,+ 0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F,+ 0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00,+ 0xAED97719, 0x62737787, 0xECFC7064, 0x205670FA,+ 0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E,+ 0x01875D87, 0xCD2D5D19, 0x43A25AFA, 0x8F085A64,+ 0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B,+ 0xD2624632, 0x1EC846AC, 0x9047414F, 0x5CED41D1,+ 0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E,+ 0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4,+ 0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB,+ 0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041,+ 0x5526F3C6, 0x998CF358, 0x1703F4BB, 0xDBA9F425,+ 0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF,+ 0x86C3E873, 0x4A69E8ED, 0xC4E6EF0E, 0x084CEF90,+ 0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A,+ 0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6, 0x5E64A758,+ 0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2,+ 0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED,+ 0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217,+ 0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673,+ 0x281A9F6A, 0xE4B09FF4, 0x6A3F9817, 0xA6959889,+ 0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6,+ 0xFBFF84DF, 0x37558441, 0xB9DA83A2, 0x7570833C,+ 0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239,+ 0xD7718B20, 0x1BDB8BBE, 0x95548C5D, 0x59FE8CC3,+ 0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C,+ 0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776,+ 0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312,+ 0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8,+ 0xFC65AF44, 0x30CFAFDA, 0xBE40A839, 0x72EAA8A7,+ 0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D,+ 0xAA4DE78C, 0x66E7E712, 0xE868E0F1, 0x24C2E06F,+ 0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95,+ 0x79A8FC39, 0xB502FCA7, 0x3B8DFB44, 0xF727FBDA,+ 0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520,+ 0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144,+ 0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE,+ 0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1,+ 0x8159C3E8, 0x4DF3C376, 0xC37CC495, 0x0FD6C40B,+ 0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4,+ 0xFEEC49CD, 0x32464953, 0xBCC94EB0, 0x70634E2E,+ 0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61,+ 0x2D095278, 0xE1A352E6, 0x6F2C5505, 0xA386559B,+ 0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF,+ 0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05,+ 0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A,+ 0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0,+ 0x83D02561, 0x4F7A25FF, 0xC1F5221C, 0x0D5F2282,+ 0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78,+ 0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937,+ 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD,+ 0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9,+ 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53,+ 0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C,+ 0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6+ }+};
+ cbits/liblzma/check/crc32_tablegen.c view
@@ -0,0 +1,117 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc32_tablegen.c+/// \brief Generate crc32_table_le.h and crc32_table_be.h+///+/// Compiling: gcc -std=c99 -o crc32_tablegen crc32_tablegen.c+/// Add -DWORDS_BIGENDIAN to generate big endian table.+/// Add -DLZ_HASH_TABLE to generate lz_encoder_hash_table.h (little endian).+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include <stdio.h>+#include "../../common/tuklib_integer.h"+++static uint32_t crc32_table[8][256];+++static void+init_crc32_table(void)+{+ static const uint32_t poly32 = UINT32_C(0xEDB88320);++ for (size_t s = 0; s < 8; ++s) {+ for (size_t b = 0; b < 256; ++b) {+ uint32_t r = s == 0 ? b : crc32_table[s - 1][b];++ for (size_t i = 0; i < 8; ++i) {+ if (r & 1)+ r = (r >> 1) ^ poly32;+ else+ r >>= 1;+ }++ crc32_table[s][b] = r;+ }+ }++#ifdef WORDS_BIGENDIAN+ for (size_t s = 0; s < 8; ++s)+ for (size_t b = 0; b < 256; ++b)+ crc32_table[s][b] = bswap32(crc32_table[s][b]);+#endif++ return;+}+++static void+print_crc32_table(void)+{+ printf("/* This file has been automatically generated by "+ "crc32_tablegen.c. */\n\n"+ "const uint32_t lzma_crc32_table[8][256] = {\n\t{");++ for (size_t s = 0; s < 8; ++s) {+ for (size_t b = 0; b < 256; ++b) {+ if ((b % 4) == 0)+ printf("\n\t\t");++ printf("0x%08" PRIX32, crc32_table[s][b]);++ if (b != 255)+ printf(",%s", (b+1) % 4 == 0 ? "" : " ");+ }++ if (s == 7)+ printf("\n\t}\n};\n");+ else+ printf("\n\t}, {");+ }++ return;+}+++static void+print_lz_table(void)+{+ printf("/* This file has been automatically generated by "+ "crc32_tablegen.c. */\n\n"+ "const uint32_t lzma_lz_hash_table[256] = {");++ for (size_t b = 0; b < 256; ++b) {+ if ((b % 4) == 0)+ printf("\n\t");++ printf("0x%08" PRIX32, crc32_table[0][b]);++ if (b != 255)+ printf(",%s", (b+1) % 4 == 0 ? "" : " ");+ }++ printf("\n};\n");++ return;+}+++int+main(void)+{+ init_crc32_table();++#ifdef LZ_HASH_TABLE+ print_lz_table();+#else+ print_crc32_table();+#endif++ return 0;+}
+ cbits/liblzma/check/crc64_fast.c view
@@ -0,0 +1,72 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc64.c+/// \brief CRC64 calculation+///+/// Calculate the CRC64 using the slice-by-four algorithm. This is the same+/// idea that is used in crc32_fast.c, but for CRC64 we use only four tables+/// instead of eight to avoid increasing CPU cache usage.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "check.h"+#include "crc_macros.h"+++#ifdef WORDS_BIGENDIAN+# define A1(x) ((x) >> 56)+#else+# define A1 A+#endif+++// See the comments in crc32_fast.c. They aren't duplicated here.+extern LZMA_API(uint64_t)+lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)+{+ crc = ~crc;++#ifdef WORDS_BIGENDIAN+ crc = bswap64(crc);+#endif++ if (size > 4) {+ while ((uintptr_t)(buf) & 3) {+ crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);+ --size;+ }++ const uint8_t *const limit = buf + (size & ~(size_t)(3));+ size &= (size_t)(3);++ while (buf < limit) {+#ifdef WORDS_BIGENDIAN+ const uint32_t tmp = (crc >> 32)+ ^ aligned_read32ne(buf);+#else+ const uint32_t tmp = crc ^ aligned_read32ne(buf);+#endif+ buf += 4;++ crc = lzma_crc64_table[3][A(tmp)]+ ^ lzma_crc64_table[2][B(tmp)]+ ^ S32(crc)+ ^ lzma_crc64_table[1][C(tmp)]+ ^ lzma_crc64_table[0][D(tmp)];+ }+ }++ while (size-- != 0)+ crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);++#ifdef WORDS_BIGENDIAN+ crc = bswap64(crc);+#endif++ return ~crc;+}
+ cbits/liblzma/check/crc64_small.c view
@@ -0,0 +1,53 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc64_small.c+/// \brief CRC64 calculation (size-optimized)+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "check.h"+++static uint64_t crc64_table[256];+++static void+crc64_init(void)+{+ static const uint64_t poly64 = UINT64_C(0xC96C5795D7870F42);++ for (size_t b = 0; b < 256; ++b) {+ uint64_t r = b;+ for (size_t i = 0; i < 8; ++i) {+ if (r & 1)+ r = (r >> 1) ^ poly64;+ else+ r >>= 1;+ }++ crc64_table[b] = r;+ }++ return;+}+++extern LZMA_API(uint64_t)+lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)+{+ mythread_once(crc64_init);++ crc = ~crc;++ while (size != 0) {+ crc = crc64_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8);+ --size;+ }++ return ~crc;+}
+ cbits/liblzma/check/crc64_table.c view
@@ -0,0 +1,22 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc64_table.c+/// \brief Precalculated CRC64 table with correct endianness+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"++// Having the declaration here silences clang -Wmissing-variable-declarations.+extern const uint64_t lzma_crc64_table[4][256];++#ifdef WORDS_BIGENDIAN+# include "crc64_table_be.h"+#else+# include "crc64_table_le.h"+#endif
+ cbits/liblzma/check/crc64_table_be.h view
@@ -0,0 +1,521 @@+/* This file has been automatically generated by crc64_tablegen.c. */++const uint64_t lzma_crc64_table[4][256] = {+ {+ UINT64_C(0x0000000000000000), UINT64_C(0x6F5FA703BE4C2EB3),+ UINT64_C(0x5BA040A8573684F4), UINT64_C(0x34FFE7ABE97AAA47),+ UINT64_C(0x335E8FFF84C3D07B), UINT64_C(0x5C0128FC3A8FFEC8),+ UINT64_C(0x68FECF57D3F5548F), UINT64_C(0x07A168546DB97A3C),+ UINT64_C(0x66BC1EFF0987A1F7), UINT64_C(0x09E3B9FCB7CB8F44),+ UINT64_C(0x3D1C5E575EB12503), UINT64_C(0x5243F954E0FD0BB0),+ UINT64_C(0x55E291008D44718C), UINT64_C(0x3ABD360333085F3F),+ UINT64_C(0x0E42D1A8DA72F578), UINT64_C(0x611D76AB643EDBCB),+ UINT64_C(0x4966335138A19B7D), UINT64_C(0x2639945286EDB5CE),+ UINT64_C(0x12C673F96F971F89), UINT64_C(0x7D99D4FAD1DB313A),+ UINT64_C(0x7A38BCAEBC624B06), UINT64_C(0x15671BAD022E65B5),+ UINT64_C(0x2198FC06EB54CFF2), UINT64_C(0x4EC75B055518E141),+ UINT64_C(0x2FDA2DAE31263A8A), UINT64_C(0x40858AAD8F6A1439),+ UINT64_C(0x747A6D066610BE7E), UINT64_C(0x1B25CA05D85C90CD),+ UINT64_C(0x1C84A251B5E5EAF1), UINT64_C(0x73DB05520BA9C442),+ UINT64_C(0x4724E2F9E2D36E05), UINT64_C(0x287B45FA5C9F40B6),+ UINT64_C(0x92CC66A2704237FB), UINT64_C(0xFD93C1A1CE0E1948),+ UINT64_C(0xC96C260A2774B30F), UINT64_C(0xA633810999389DBC),+ UINT64_C(0xA192E95DF481E780), UINT64_C(0xCECD4E5E4ACDC933),+ UINT64_C(0xFA32A9F5A3B76374), UINT64_C(0x956D0EF61DFB4DC7),+ UINT64_C(0xF470785D79C5960C), UINT64_C(0x9B2FDF5EC789B8BF),+ UINT64_C(0xAFD038F52EF312F8), UINT64_C(0xC08F9FF690BF3C4B),+ UINT64_C(0xC72EF7A2FD064677), UINT64_C(0xA87150A1434A68C4),+ UINT64_C(0x9C8EB70AAA30C283), UINT64_C(0xF3D11009147CEC30),+ UINT64_C(0xDBAA55F348E3AC86), UINT64_C(0xB4F5F2F0F6AF8235),+ UINT64_C(0x800A155B1FD52872), UINT64_C(0xEF55B258A19906C1),+ UINT64_C(0xE8F4DA0CCC207CFD), UINT64_C(0x87AB7D0F726C524E),+ UINT64_C(0xB3549AA49B16F809), UINT64_C(0xDC0B3DA7255AD6BA),+ UINT64_C(0xBD164B0C41640D71), UINT64_C(0xD249EC0FFF2823C2),+ UINT64_C(0xE6B60BA416528985), UINT64_C(0x89E9ACA7A81EA736),+ UINT64_C(0x8E48C4F3C5A7DD0A), UINT64_C(0xE11763F07BEBF3B9),+ UINT64_C(0xD5E8845B929159FE), UINT64_C(0xBAB723582CDD774D),+ UINT64_C(0xA187C3EBCA2BB664), UINT64_C(0xCED864E8746798D7),+ UINT64_C(0xFA2783439D1D3290), UINT64_C(0x9578244023511C23),+ UINT64_C(0x92D94C144EE8661F), UINT64_C(0xFD86EB17F0A448AC),+ UINT64_C(0xC9790CBC19DEE2EB), UINT64_C(0xA626ABBFA792CC58),+ UINT64_C(0xC73BDD14C3AC1793), UINT64_C(0xA8647A177DE03920),+ UINT64_C(0x9C9B9DBC949A9367), UINT64_C(0xF3C43ABF2AD6BDD4),+ UINT64_C(0xF46552EB476FC7E8), UINT64_C(0x9B3AF5E8F923E95B),+ UINT64_C(0xAFC512431059431C), UINT64_C(0xC09AB540AE156DAF),+ UINT64_C(0xE8E1F0BAF28A2D19), UINT64_C(0x87BE57B94CC603AA),+ UINT64_C(0xB341B012A5BCA9ED), UINT64_C(0xDC1E17111BF0875E),+ UINT64_C(0xDBBF7F457649FD62), UINT64_C(0xB4E0D846C805D3D1),+ UINT64_C(0x801F3FED217F7996), UINT64_C(0xEF4098EE9F335725),+ UINT64_C(0x8E5DEE45FB0D8CEE), UINT64_C(0xE10249464541A25D),+ UINT64_C(0xD5FDAEEDAC3B081A), UINT64_C(0xBAA209EE127726A9),+ UINT64_C(0xBD0361BA7FCE5C95), UINT64_C(0xD25CC6B9C1827226),+ UINT64_C(0xE6A3211228F8D861), UINT64_C(0x89FC861196B4F6D2),+ UINT64_C(0x334BA549BA69819F), UINT64_C(0x5C14024A0425AF2C),+ UINT64_C(0x68EBE5E1ED5F056B), UINT64_C(0x07B442E253132BD8),+ UINT64_C(0x00152AB63EAA51E4), UINT64_C(0x6F4A8DB580E67F57),+ UINT64_C(0x5BB56A1E699CD510), UINT64_C(0x34EACD1DD7D0FBA3),+ UINT64_C(0x55F7BBB6B3EE2068), UINT64_C(0x3AA81CB50DA20EDB),+ UINT64_C(0x0E57FB1EE4D8A49C), UINT64_C(0x61085C1D5A948A2F),+ UINT64_C(0x66A93449372DF013), UINT64_C(0x09F6934A8961DEA0),+ UINT64_C(0x3D0974E1601B74E7), UINT64_C(0x5256D3E2DE575A54),+ UINT64_C(0x7A2D961882C81AE2), UINT64_C(0x1572311B3C843451),+ UINT64_C(0x218DD6B0D5FE9E16), UINT64_C(0x4ED271B36BB2B0A5),+ UINT64_C(0x497319E7060BCA99), UINT64_C(0x262CBEE4B847E42A),+ UINT64_C(0x12D3594F513D4E6D), UINT64_C(0x7D8CFE4CEF7160DE),+ UINT64_C(0x1C9188E78B4FBB15), UINT64_C(0x73CE2FE4350395A6),+ UINT64_C(0x4731C84FDC793FE1), UINT64_C(0x286E6F4C62351152),+ UINT64_C(0x2FCF07180F8C6B6E), UINT64_C(0x4090A01BB1C045DD),+ UINT64_C(0x746F47B058BAEF9A), UINT64_C(0x1B30E0B3E6F6C129),+ UINT64_C(0x420F87D795576CC9), UINT64_C(0x2D5020D42B1B427A),+ UINT64_C(0x19AFC77FC261E83D), UINT64_C(0x76F0607C7C2DC68E),+ UINT64_C(0x715108281194BCB2), UINT64_C(0x1E0EAF2BAFD89201),+ UINT64_C(0x2AF1488046A23846), UINT64_C(0x45AEEF83F8EE16F5),+ UINT64_C(0x24B399289CD0CD3E), UINT64_C(0x4BEC3E2B229CE38D),+ UINT64_C(0x7F13D980CBE649CA), UINT64_C(0x104C7E8375AA6779),+ UINT64_C(0x17ED16D718131D45), UINT64_C(0x78B2B1D4A65F33F6),+ UINT64_C(0x4C4D567F4F2599B1), UINT64_C(0x2312F17CF169B702),+ UINT64_C(0x0B69B486ADF6F7B4), UINT64_C(0x6436138513BAD907),+ UINT64_C(0x50C9F42EFAC07340), UINT64_C(0x3F96532D448C5DF3),+ UINT64_C(0x38373B79293527CF), UINT64_C(0x57689C7A9779097C),+ UINT64_C(0x63977BD17E03A33B), UINT64_C(0x0CC8DCD2C04F8D88),+ UINT64_C(0x6DD5AA79A4715643), UINT64_C(0x028A0D7A1A3D78F0),+ UINT64_C(0x3675EAD1F347D2B7), UINT64_C(0x592A4DD24D0BFC04),+ UINT64_C(0x5E8B258620B28638), UINT64_C(0x31D482859EFEA88B),+ UINT64_C(0x052B652E778402CC), UINT64_C(0x6A74C22DC9C82C7F),+ UINT64_C(0xD0C3E175E5155B32), UINT64_C(0xBF9C46765B597581),+ UINT64_C(0x8B63A1DDB223DFC6), UINT64_C(0xE43C06DE0C6FF175),+ UINT64_C(0xE39D6E8A61D68B49), UINT64_C(0x8CC2C989DF9AA5FA),+ UINT64_C(0xB83D2E2236E00FBD), UINT64_C(0xD762892188AC210E),+ UINT64_C(0xB67FFF8AEC92FAC5), UINT64_C(0xD920588952DED476),+ UINT64_C(0xEDDFBF22BBA47E31), UINT64_C(0x8280182105E85082),+ UINT64_C(0x8521707568512ABE), UINT64_C(0xEA7ED776D61D040D),+ UINT64_C(0xDE8130DD3F67AE4A), UINT64_C(0xB1DE97DE812B80F9),+ UINT64_C(0x99A5D224DDB4C04F), UINT64_C(0xF6FA752763F8EEFC),+ UINT64_C(0xC205928C8A8244BB), UINT64_C(0xAD5A358F34CE6A08),+ UINT64_C(0xAAFB5DDB59771034), UINT64_C(0xC5A4FAD8E73B3E87),+ UINT64_C(0xF15B1D730E4194C0), UINT64_C(0x9E04BA70B00DBA73),+ UINT64_C(0xFF19CCDBD43361B8), UINT64_C(0x90466BD86A7F4F0B),+ UINT64_C(0xA4B98C738305E54C), UINT64_C(0xCBE62B703D49CBFF),+ UINT64_C(0xCC47432450F0B1C3), UINT64_C(0xA318E427EEBC9F70),+ UINT64_C(0x97E7038C07C63537), UINT64_C(0xF8B8A48FB98A1B84),+ UINT64_C(0xE388443C5F7CDAAD), UINT64_C(0x8CD7E33FE130F41E),+ UINT64_C(0xB8280494084A5E59), UINT64_C(0xD777A397B60670EA),+ UINT64_C(0xD0D6CBC3DBBF0AD6), UINT64_C(0xBF896CC065F32465),+ UINT64_C(0x8B768B6B8C898E22), UINT64_C(0xE4292C6832C5A091),+ UINT64_C(0x85345AC356FB7B5A), UINT64_C(0xEA6BFDC0E8B755E9),+ UINT64_C(0xDE941A6B01CDFFAE), UINT64_C(0xB1CBBD68BF81D11D),+ UINT64_C(0xB66AD53CD238AB21), UINT64_C(0xD935723F6C748592),+ UINT64_C(0xEDCA9594850E2FD5), UINT64_C(0x829532973B420166),+ UINT64_C(0xAAEE776D67DD41D0), UINT64_C(0xC5B1D06ED9916F63),+ UINT64_C(0xF14E37C530EBC524), UINT64_C(0x9E1190C68EA7EB97),+ UINT64_C(0x99B0F892E31E91AB), UINT64_C(0xF6EF5F915D52BF18),+ UINT64_C(0xC210B83AB428155F), UINT64_C(0xAD4F1F390A643BEC),+ UINT64_C(0xCC5269926E5AE027), UINT64_C(0xA30DCE91D016CE94),+ UINT64_C(0x97F2293A396C64D3), UINT64_C(0xF8AD8E3987204A60),+ UINT64_C(0xFF0CE66DEA99305C), UINT64_C(0x9053416E54D51EEF),+ UINT64_C(0xA4ACA6C5BDAFB4A8), UINT64_C(0xCBF301C603E39A1B),+ UINT64_C(0x7144229E2F3EED56), UINT64_C(0x1E1B859D9172C3E5),+ UINT64_C(0x2AE46236780869A2), UINT64_C(0x45BBC535C6444711),+ UINT64_C(0x421AAD61ABFD3D2D), UINT64_C(0x2D450A6215B1139E),+ UINT64_C(0x19BAEDC9FCCBB9D9), UINT64_C(0x76E54ACA4287976A),+ UINT64_C(0x17F83C6126B94CA1), UINT64_C(0x78A79B6298F56212),+ UINT64_C(0x4C587CC9718FC855), UINT64_C(0x2307DBCACFC3E6E6),+ UINT64_C(0x24A6B39EA27A9CDA), UINT64_C(0x4BF9149D1C36B269),+ UINT64_C(0x7F06F336F54C182E), UINT64_C(0x105954354B00369D),+ UINT64_C(0x382211CF179F762B), UINT64_C(0x577DB6CCA9D35898),+ UINT64_C(0x6382516740A9F2DF), UINT64_C(0x0CDDF664FEE5DC6C),+ UINT64_C(0x0B7C9E30935CA650), UINT64_C(0x642339332D1088E3),+ UINT64_C(0x50DCDE98C46A22A4), UINT64_C(0x3F83799B7A260C17),+ UINT64_C(0x5E9E0F301E18D7DC), UINT64_C(0x31C1A833A054F96F),+ UINT64_C(0x053E4F98492E5328), UINT64_C(0x6A61E89BF7627D9B),+ UINT64_C(0x6DC080CF9ADB07A7), UINT64_C(0x029F27CC24972914),+ UINT64_C(0x3660C067CDED8353), UINT64_C(0x593F676473A1ADE0)+ }, {+ UINT64_C(0x0000000000000000), UINT64_C(0x0DF1D05C9279E954),+ UINT64_C(0x1AE2A1B924F3D2A9), UINT64_C(0x171371E5B68A3BFD),+ UINT64_C(0xB1DA4DDC62497DC1), UINT64_C(0xBC2B9D80F0309495),+ UINT64_C(0xAB38EC6546BAAF68), UINT64_C(0xA6C93C39D4C3463C),+ UINT64_C(0xE7AB9517EE3D2210), UINT64_C(0xEA5A454B7C44CB44),+ UINT64_C(0xFD4934AECACEF0B9), UINT64_C(0xF0B8E4F258B719ED),+ UINT64_C(0x5671D8CB8C745FD1), UINT64_C(0x5B8008971E0DB685),+ UINT64_C(0x4C937972A8878D78), UINT64_C(0x4162A92E3AFE642C),+ UINT64_C(0xCE572B2FDC7B4420), UINT64_C(0xC3A6FB734E02AD74),+ UINT64_C(0xD4B58A96F8889689), UINT64_C(0xD9445ACA6AF17FDD),+ UINT64_C(0x7F8D66F3BE3239E1), UINT64_C(0x727CB6AF2C4BD0B5),+ UINT64_C(0x656FC74A9AC1EB48), UINT64_C(0x689E171608B8021C),+ UINT64_C(0x29FCBE3832466630), UINT64_C(0x240D6E64A03F8F64),+ UINT64_C(0x331E1F8116B5B499), UINT64_C(0x3EEFCFDD84CC5DCD),+ UINT64_C(0x9826F3E4500F1BF1), UINT64_C(0x95D723B8C276F2A5),+ UINT64_C(0x82C4525D74FCC958), UINT64_C(0x8F358201E685200C),+ UINT64_C(0x9CAF565EB8F78840), UINT64_C(0x915E86022A8E6114),+ UINT64_C(0x864DF7E79C045AE9), UINT64_C(0x8BBC27BB0E7DB3BD),+ UINT64_C(0x2D751B82DABEF581), UINT64_C(0x2084CBDE48C71CD5),+ UINT64_C(0x3797BA3BFE4D2728), UINT64_C(0x3A666A676C34CE7C),+ UINT64_C(0x7B04C34956CAAA50), UINT64_C(0x76F51315C4B34304),+ UINT64_C(0x61E662F0723978F9), UINT64_C(0x6C17B2ACE04091AD),+ UINT64_C(0xCADE8E953483D791), UINT64_C(0xC72F5EC9A6FA3EC5),+ UINT64_C(0xD03C2F2C10700538), UINT64_C(0xDDCDFF708209EC6C),+ UINT64_C(0x52F87D71648CCC60), UINT64_C(0x5F09AD2DF6F52534),+ UINT64_C(0x481ADCC8407F1EC9), UINT64_C(0x45EB0C94D206F79D),+ UINT64_C(0xE32230AD06C5B1A1), UINT64_C(0xEED3E0F194BC58F5),+ UINT64_C(0xF9C0911422366308), UINT64_C(0xF4314148B04F8A5C),+ UINT64_C(0xB553E8668AB1EE70), UINT64_C(0xB8A2383A18C80724),+ UINT64_C(0xAFB149DFAE423CD9), UINT64_C(0xA24099833C3BD58D),+ UINT64_C(0x0489A5BAE8F893B1), UINT64_C(0x097875E67A817AE5),+ UINT64_C(0x1E6B0403CC0B4118), UINT64_C(0x139AD45F5E72A84C),+ UINT64_C(0x385FADBC70EF1181), UINT64_C(0x35AE7DE0E296F8D5),+ UINT64_C(0x22BD0C05541CC328), UINT64_C(0x2F4CDC59C6652A7C),+ UINT64_C(0x8985E06012A66C40), UINT64_C(0x8474303C80DF8514),+ UINT64_C(0x936741D93655BEE9), UINT64_C(0x9E969185A42C57BD),+ UINT64_C(0xDFF438AB9ED23391), UINT64_C(0xD205E8F70CABDAC5),+ UINT64_C(0xC5169912BA21E138), UINT64_C(0xC8E7494E2858086C),+ UINT64_C(0x6E2E7577FC9B4E50), UINT64_C(0x63DFA52B6EE2A704),+ UINT64_C(0x74CCD4CED8689CF9), UINT64_C(0x793D04924A1175AD),+ UINT64_C(0xF6088693AC9455A1), UINT64_C(0xFBF956CF3EEDBCF5),+ UINT64_C(0xECEA272A88678708), UINT64_C(0xE11BF7761A1E6E5C),+ UINT64_C(0x47D2CB4FCEDD2860), UINT64_C(0x4A231B135CA4C134),+ UINT64_C(0x5D306AF6EA2EFAC9), UINT64_C(0x50C1BAAA7857139D),+ UINT64_C(0x11A3138442A977B1), UINT64_C(0x1C52C3D8D0D09EE5),+ UINT64_C(0x0B41B23D665AA518), UINT64_C(0x06B06261F4234C4C),+ UINT64_C(0xA0795E5820E00A70), UINT64_C(0xAD888E04B299E324),+ UINT64_C(0xBA9BFFE10413D8D9), UINT64_C(0xB76A2FBD966A318D),+ UINT64_C(0xA4F0FBE2C81899C1), UINT64_C(0xA9012BBE5A617095),+ UINT64_C(0xBE125A5BECEB4B68), UINT64_C(0xB3E38A077E92A23C),+ UINT64_C(0x152AB63EAA51E400), UINT64_C(0x18DB666238280D54),+ UINT64_C(0x0FC817878EA236A9), UINT64_C(0x0239C7DB1CDBDFFD),+ UINT64_C(0x435B6EF52625BBD1), UINT64_C(0x4EAABEA9B45C5285),+ UINT64_C(0x59B9CF4C02D66978), UINT64_C(0x54481F1090AF802C),+ UINT64_C(0xF2812329446CC610), UINT64_C(0xFF70F375D6152F44),+ UINT64_C(0xE8638290609F14B9), UINT64_C(0xE59252CCF2E6FDED),+ UINT64_C(0x6AA7D0CD1463DDE1), UINT64_C(0x67560091861A34B5),+ UINT64_C(0x7045717430900F48), UINT64_C(0x7DB4A128A2E9E61C),+ UINT64_C(0xDB7D9D11762AA020), UINT64_C(0xD68C4D4DE4534974),+ UINT64_C(0xC19F3CA852D97289), UINT64_C(0xCC6EECF4C0A09BDD),+ UINT64_C(0x8D0C45DAFA5EFFF1), UINT64_C(0x80FD9586682716A5),+ UINT64_C(0x97EEE463DEAD2D58), UINT64_C(0x9A1F343F4CD4C40C),+ UINT64_C(0x3CD6080698178230), UINT64_C(0x3127D85A0A6E6B64),+ UINT64_C(0x2634A9BFBCE45099), UINT64_C(0x2BC579E32E9DB9CD),+ UINT64_C(0xF5A054D6CA71FB90), UINT64_C(0xF851848A580812C4),+ UINT64_C(0xEF42F56FEE822939), UINT64_C(0xE2B325337CFBC06D),+ UINT64_C(0x447A190AA8388651), UINT64_C(0x498BC9563A416F05),+ UINT64_C(0x5E98B8B38CCB54F8), UINT64_C(0x536968EF1EB2BDAC),+ UINT64_C(0x120BC1C1244CD980), UINT64_C(0x1FFA119DB63530D4),+ UINT64_C(0x08E9607800BF0B29), UINT64_C(0x0518B02492C6E27D),+ UINT64_C(0xA3D18C1D4605A441), UINT64_C(0xAE205C41D47C4D15),+ UINT64_C(0xB9332DA462F676E8), UINT64_C(0xB4C2FDF8F08F9FBC),+ UINT64_C(0x3BF77FF9160ABFB0), UINT64_C(0x3606AFA5847356E4),+ UINT64_C(0x2115DE4032F96D19), UINT64_C(0x2CE40E1CA080844D),+ UINT64_C(0x8A2D32257443C271), UINT64_C(0x87DCE279E63A2B25),+ UINT64_C(0x90CF939C50B010D8), UINT64_C(0x9D3E43C0C2C9F98C),+ UINT64_C(0xDC5CEAEEF8379DA0), UINT64_C(0xD1AD3AB26A4E74F4),+ UINT64_C(0xC6BE4B57DCC44F09), UINT64_C(0xCB4F9B0B4EBDA65D),+ UINT64_C(0x6D86A7329A7EE061), UINT64_C(0x6077776E08070935),+ UINT64_C(0x7764068BBE8D32C8), UINT64_C(0x7A95D6D72CF4DB9C),+ UINT64_C(0x690F0288728673D0), UINT64_C(0x64FED2D4E0FF9A84),+ UINT64_C(0x73EDA3315675A179), UINT64_C(0x7E1C736DC40C482D),+ UINT64_C(0xD8D54F5410CF0E11), UINT64_C(0xD5249F0882B6E745),+ UINT64_C(0xC237EEED343CDCB8), UINT64_C(0xCFC63EB1A64535EC),+ UINT64_C(0x8EA4979F9CBB51C0), UINT64_C(0x835547C30EC2B894),+ UINT64_C(0x94463626B8488369), UINT64_C(0x99B7E67A2A316A3D),+ UINT64_C(0x3F7EDA43FEF22C01), UINT64_C(0x328F0A1F6C8BC555),+ UINT64_C(0x259C7BFADA01FEA8), UINT64_C(0x286DABA6487817FC),+ UINT64_C(0xA75829A7AEFD37F0), UINT64_C(0xAAA9F9FB3C84DEA4),+ UINT64_C(0xBDBA881E8A0EE559), UINT64_C(0xB04B584218770C0D),+ UINT64_C(0x1682647BCCB44A31), UINT64_C(0x1B73B4275ECDA365),+ UINT64_C(0x0C60C5C2E8479898), UINT64_C(0x0191159E7A3E71CC),+ UINT64_C(0x40F3BCB040C015E0), UINT64_C(0x4D026CECD2B9FCB4),+ UINT64_C(0x5A111D096433C749), UINT64_C(0x57E0CD55F64A2E1D),+ UINT64_C(0xF129F16C22896821), UINT64_C(0xFCD82130B0F08175),+ UINT64_C(0xEBCB50D5067ABA88), UINT64_C(0xE63A8089940353DC),+ UINT64_C(0xCDFFF96ABA9EEA11), UINT64_C(0xC00E293628E70345),+ UINT64_C(0xD71D58D39E6D38B8), UINT64_C(0xDAEC888F0C14D1EC),+ UINT64_C(0x7C25B4B6D8D797D0), UINT64_C(0x71D464EA4AAE7E84),+ UINT64_C(0x66C7150FFC244579), UINT64_C(0x6B36C5536E5DAC2D),+ UINT64_C(0x2A546C7D54A3C801), UINT64_C(0x27A5BC21C6DA2155),+ UINT64_C(0x30B6CDC470501AA8), UINT64_C(0x3D471D98E229F3FC),+ UINT64_C(0x9B8E21A136EAB5C0), UINT64_C(0x967FF1FDA4935C94),+ UINT64_C(0x816C801812196769), UINT64_C(0x8C9D504480608E3D),+ UINT64_C(0x03A8D24566E5AE31), UINT64_C(0x0E590219F49C4765),+ UINT64_C(0x194A73FC42167C98), UINT64_C(0x14BBA3A0D06F95CC),+ UINT64_C(0xB2729F9904ACD3F0), UINT64_C(0xBF834FC596D53AA4),+ UINT64_C(0xA8903E20205F0159), UINT64_C(0xA561EE7CB226E80D),+ UINT64_C(0xE403475288D88C21), UINT64_C(0xE9F2970E1AA16575),+ UINT64_C(0xFEE1E6EBAC2B5E88), UINT64_C(0xF31036B73E52B7DC),+ UINT64_C(0x55D90A8EEA91F1E0), UINT64_C(0x5828DAD278E818B4),+ UINT64_C(0x4F3BAB37CE622349), UINT64_C(0x42CA7B6B5C1BCA1D),+ UINT64_C(0x5150AF3402696251), UINT64_C(0x5CA17F6890108B05),+ UINT64_C(0x4BB20E8D269AB0F8), UINT64_C(0x4643DED1B4E359AC),+ UINT64_C(0xE08AE2E860201F90), UINT64_C(0xED7B32B4F259F6C4),+ UINT64_C(0xFA68435144D3CD39), UINT64_C(0xF799930DD6AA246D),+ UINT64_C(0xB6FB3A23EC544041), UINT64_C(0xBB0AEA7F7E2DA915),+ UINT64_C(0xAC199B9AC8A792E8), UINT64_C(0xA1E84BC65ADE7BBC),+ UINT64_C(0x072177FF8E1D3D80), UINT64_C(0x0AD0A7A31C64D4D4),+ UINT64_C(0x1DC3D646AAEEEF29), UINT64_C(0x1032061A3897067D),+ UINT64_C(0x9F07841BDE122671), UINT64_C(0x92F654474C6BCF25),+ UINT64_C(0x85E525A2FAE1F4D8), UINT64_C(0x8814F5FE68981D8C),+ UINT64_C(0x2EDDC9C7BC5B5BB0), UINT64_C(0x232C199B2E22B2E4),+ UINT64_C(0x343F687E98A88919), UINT64_C(0x39CEB8220AD1604D),+ UINT64_C(0x78AC110C302F0461), UINT64_C(0x755DC150A256ED35),+ UINT64_C(0x624EB0B514DCD6C8), UINT64_C(0x6FBF60E986A53F9C),+ UINT64_C(0xC9765CD0526679A0), UINT64_C(0xC4878C8CC01F90F4),+ UINT64_C(0xD394FD697695AB09), UINT64_C(0xDE652D35E4EC425D)+ }, {+ UINT64_C(0x0000000000000000), UINT64_C(0xCB6D6A914AE10B3F),+ UINT64_C(0x96DBD42295C2177E), UINT64_C(0x5DB6BEB3DF231C41),+ UINT64_C(0x2CB7A9452A852FFC), UINT64_C(0xE7DAC3D4606424C3),+ UINT64_C(0xBA6C7D67BF473882), UINT64_C(0x710117F6F5A633BD),+ UINT64_C(0xDD705D247FA5876A), UINT64_C(0x161D37B535448C55),+ UINT64_C(0x4BAB8906EA679014), UINT64_C(0x80C6E397A0869B2B),+ UINT64_C(0xF1C7F4615520A896), UINT64_C(0x3AAA9EF01FC1A3A9),+ UINT64_C(0x671C2043C0E2BFE8), UINT64_C(0xAC714AD28A03B4D7),+ UINT64_C(0xBAE1BA48FE4A0FD5), UINT64_C(0x718CD0D9B4AB04EA),+ UINT64_C(0x2C3A6E6A6B8818AB), UINT64_C(0xE75704FB21691394),+ UINT64_C(0x9656130DD4CF2029), UINT64_C(0x5D3B799C9E2E2B16),+ UINT64_C(0x008DC72F410D3757), UINT64_C(0xCBE0ADBE0BEC3C68),+ UINT64_C(0x6791E76C81EF88BF), UINT64_C(0xACFC8DFDCB0E8380),+ UINT64_C(0xF14A334E142D9FC1), UINT64_C(0x3A2759DF5ECC94FE),+ UINT64_C(0x4B264E29AB6AA743), UINT64_C(0x804B24B8E18BAC7C),+ UINT64_C(0xDDFD9A0B3EA8B03D), UINT64_C(0x1690F09A7449BB02),+ UINT64_C(0xF1DD7B3ED73AC638), UINT64_C(0x3AB011AF9DDBCD07),+ UINT64_C(0x6706AF1C42F8D146), UINT64_C(0xAC6BC58D0819DA79),+ UINT64_C(0xDD6AD27BFDBFE9C4), UINT64_C(0x1607B8EAB75EE2FB),+ UINT64_C(0x4BB10659687DFEBA), UINT64_C(0x80DC6CC8229CF585),+ UINT64_C(0x2CAD261AA89F4152), UINT64_C(0xE7C04C8BE27E4A6D),+ UINT64_C(0xBA76F2383D5D562C), UINT64_C(0x711B98A977BC5D13),+ UINT64_C(0x001A8F5F821A6EAE), UINT64_C(0xCB77E5CEC8FB6591),+ UINT64_C(0x96C15B7D17D879D0), UINT64_C(0x5DAC31EC5D3972EF),+ UINT64_C(0x4B3CC1762970C9ED), UINT64_C(0x8051ABE76391C2D2),+ UINT64_C(0xDDE71554BCB2DE93), UINT64_C(0x168A7FC5F653D5AC),+ UINT64_C(0x678B683303F5E611), UINT64_C(0xACE602A24914ED2E),+ UINT64_C(0xF150BC119637F16F), UINT64_C(0x3A3DD680DCD6FA50),+ UINT64_C(0x964C9C5256D54E87), UINT64_C(0x5D21F6C31C3445B8),+ UINT64_C(0x00974870C31759F9), UINT64_C(0xCBFA22E189F652C6),+ UINT64_C(0xBAFB35177C50617B), UINT64_C(0x71965F8636B16A44),+ UINT64_C(0x2C20E135E9927605), UINT64_C(0xE74D8BA4A3737D3A),+ UINT64_C(0xE2BBF77CAE758C71), UINT64_C(0x29D69DEDE494874E),+ UINT64_C(0x7460235E3BB79B0F), UINT64_C(0xBF0D49CF71569030),+ UINT64_C(0xCE0C5E3984F0A38D), UINT64_C(0x056134A8CE11A8B2),+ UINT64_C(0x58D78A1B1132B4F3), UINT64_C(0x93BAE08A5BD3BFCC),+ UINT64_C(0x3FCBAA58D1D00B1B), UINT64_C(0xF4A6C0C99B310024),+ UINT64_C(0xA9107E7A44121C65), UINT64_C(0x627D14EB0EF3175A),+ UINT64_C(0x137C031DFB5524E7), UINT64_C(0xD811698CB1B42FD8),+ UINT64_C(0x85A7D73F6E973399), UINT64_C(0x4ECABDAE247638A6),+ UINT64_C(0x585A4D34503F83A4), UINT64_C(0x933727A51ADE889B),+ UINT64_C(0xCE819916C5FD94DA), UINT64_C(0x05ECF3878F1C9FE5),+ UINT64_C(0x74EDE4717ABAAC58), UINT64_C(0xBF808EE0305BA767),+ UINT64_C(0xE2363053EF78BB26), UINT64_C(0x295B5AC2A599B019),+ UINT64_C(0x852A10102F9A04CE), UINT64_C(0x4E477A81657B0FF1),+ UINT64_C(0x13F1C432BA5813B0), UINT64_C(0xD89CAEA3F0B9188F),+ UINT64_C(0xA99DB955051F2B32), UINT64_C(0x62F0D3C44FFE200D),+ UINT64_C(0x3F466D7790DD3C4C), UINT64_C(0xF42B07E6DA3C3773),+ UINT64_C(0x13668C42794F4A49), UINT64_C(0xD80BE6D333AE4176),+ UINT64_C(0x85BD5860EC8D5D37), UINT64_C(0x4ED032F1A66C5608),+ UINT64_C(0x3FD1250753CA65B5), UINT64_C(0xF4BC4F96192B6E8A),+ UINT64_C(0xA90AF125C60872CB), UINT64_C(0x62679BB48CE979F4),+ UINT64_C(0xCE16D16606EACD23), UINT64_C(0x057BBBF74C0BC61C),+ UINT64_C(0x58CD05449328DA5D), UINT64_C(0x93A06FD5D9C9D162),+ UINT64_C(0xE2A178232C6FE2DF), UINT64_C(0x29CC12B2668EE9E0),+ UINT64_C(0x747AAC01B9ADF5A1), UINT64_C(0xBF17C690F34CFE9E),+ UINT64_C(0xA987360A8705459C), UINT64_C(0x62EA5C9BCDE44EA3),+ UINT64_C(0x3F5CE22812C752E2), UINT64_C(0xF43188B9582659DD),+ UINT64_C(0x85309F4FAD806A60), UINT64_C(0x4E5DF5DEE761615F),+ UINT64_C(0x13EB4B6D38427D1E), UINT64_C(0xD88621FC72A37621),+ UINT64_C(0x74F76B2EF8A0C2F6), UINT64_C(0xBF9A01BFB241C9C9),+ UINT64_C(0xE22CBF0C6D62D588), UINT64_C(0x2941D59D2783DEB7),+ UINT64_C(0x5840C26BD225ED0A), UINT64_C(0x932DA8FA98C4E635),+ UINT64_C(0xCE9B164947E7FA74), UINT64_C(0x05F67CD80D06F14B),+ UINT64_C(0xC477EFF95CEB18E3), UINT64_C(0x0F1A8568160A13DC),+ UINT64_C(0x52AC3BDBC9290F9D), UINT64_C(0x99C1514A83C804A2),+ UINT64_C(0xE8C046BC766E371F), UINT64_C(0x23AD2C2D3C8F3C20),+ UINT64_C(0x7E1B929EE3AC2061), UINT64_C(0xB576F80FA94D2B5E),+ UINT64_C(0x1907B2DD234E9F89), UINT64_C(0xD26AD84C69AF94B6),+ UINT64_C(0x8FDC66FFB68C88F7), UINT64_C(0x44B10C6EFC6D83C8),+ UINT64_C(0x35B01B9809CBB075), UINT64_C(0xFEDD7109432ABB4A),+ UINT64_C(0xA36BCFBA9C09A70B), UINT64_C(0x6806A52BD6E8AC34),+ UINT64_C(0x7E9655B1A2A11736), UINT64_C(0xB5FB3F20E8401C09),+ UINT64_C(0xE84D819337630048), UINT64_C(0x2320EB027D820B77),+ UINT64_C(0x5221FCF4882438CA), UINT64_C(0x994C9665C2C533F5),+ UINT64_C(0xC4FA28D61DE62FB4), UINT64_C(0x0F9742475707248B),+ UINT64_C(0xA3E60895DD04905C), UINT64_C(0x688B620497E59B63),+ UINT64_C(0x353DDCB748C68722), UINT64_C(0xFE50B62602278C1D),+ UINT64_C(0x8F51A1D0F781BFA0), UINT64_C(0x443CCB41BD60B49F),+ UINT64_C(0x198A75F26243A8DE), UINT64_C(0xD2E71F6328A2A3E1),+ UINT64_C(0x35AA94C78BD1DEDB), UINT64_C(0xFEC7FE56C130D5E4),+ UINT64_C(0xA37140E51E13C9A5), UINT64_C(0x681C2A7454F2C29A),+ UINT64_C(0x191D3D82A154F127), UINT64_C(0xD2705713EBB5FA18),+ UINT64_C(0x8FC6E9A03496E659), UINT64_C(0x44AB83317E77ED66),+ UINT64_C(0xE8DAC9E3F47459B1), UINT64_C(0x23B7A372BE95528E),+ UINT64_C(0x7E011DC161B64ECF), UINT64_C(0xB56C77502B5745F0),+ UINT64_C(0xC46D60A6DEF1764D), UINT64_C(0x0F000A3794107D72),+ UINT64_C(0x52B6B4844B336133), UINT64_C(0x99DBDE1501D26A0C),+ UINT64_C(0x8F4B2E8F759BD10E), UINT64_C(0x4426441E3F7ADA31),+ UINT64_C(0x1990FAADE059C670), UINT64_C(0xD2FD903CAAB8CD4F),+ UINT64_C(0xA3FC87CA5F1EFEF2), UINT64_C(0x6891ED5B15FFF5CD),+ UINT64_C(0x352753E8CADCE98C), UINT64_C(0xFE4A3979803DE2B3),+ UINT64_C(0x523B73AB0A3E5664), UINT64_C(0x9956193A40DF5D5B),+ UINT64_C(0xC4E0A7899FFC411A), UINT64_C(0x0F8DCD18D51D4A25),+ UINT64_C(0x7E8CDAEE20BB7998), UINT64_C(0xB5E1B07F6A5A72A7),+ UINT64_C(0xE8570ECCB5796EE6), UINT64_C(0x233A645DFF9865D9),+ UINT64_C(0x26CC1885F29E9492), UINT64_C(0xEDA17214B87F9FAD),+ UINT64_C(0xB017CCA7675C83EC), UINT64_C(0x7B7AA6362DBD88D3),+ UINT64_C(0x0A7BB1C0D81BBB6E), UINT64_C(0xC116DB5192FAB051),+ UINT64_C(0x9CA065E24DD9AC10), UINT64_C(0x57CD0F730738A72F),+ UINT64_C(0xFBBC45A18D3B13F8), UINT64_C(0x30D12F30C7DA18C7),+ UINT64_C(0x6D67918318F90486), UINT64_C(0xA60AFB1252180FB9),+ UINT64_C(0xD70BECE4A7BE3C04), UINT64_C(0x1C668675ED5F373B),+ UINT64_C(0x41D038C6327C2B7A), UINT64_C(0x8ABD5257789D2045),+ UINT64_C(0x9C2DA2CD0CD49B47), UINT64_C(0x5740C85C46359078),+ UINT64_C(0x0AF676EF99168C39), UINT64_C(0xC19B1C7ED3F78706),+ UINT64_C(0xB09A0B882651B4BB), UINT64_C(0x7BF761196CB0BF84),+ UINT64_C(0x2641DFAAB393A3C5), UINT64_C(0xED2CB53BF972A8FA),+ UINT64_C(0x415DFFE973711C2D), UINT64_C(0x8A30957839901712),+ UINT64_C(0xD7862BCBE6B30B53), UINT64_C(0x1CEB415AAC52006C),+ UINT64_C(0x6DEA56AC59F433D1), UINT64_C(0xA6873C3D131538EE),+ UINT64_C(0xFB31828ECC3624AF), UINT64_C(0x305CE81F86D72F90),+ UINT64_C(0xD71163BB25A452AA), UINT64_C(0x1C7C092A6F455995),+ UINT64_C(0x41CAB799B06645D4), UINT64_C(0x8AA7DD08FA874EEB),+ UINT64_C(0xFBA6CAFE0F217D56), UINT64_C(0x30CBA06F45C07669),+ UINT64_C(0x6D7D1EDC9AE36A28), UINT64_C(0xA610744DD0026117),+ UINT64_C(0x0A613E9F5A01D5C0), UINT64_C(0xC10C540E10E0DEFF),+ UINT64_C(0x9CBAEABDCFC3C2BE), UINT64_C(0x57D7802C8522C981),+ UINT64_C(0x26D697DA7084FA3C), UINT64_C(0xEDBBFD4B3A65F103),+ UINT64_C(0xB00D43F8E546ED42), UINT64_C(0x7B602969AFA7E67D),+ UINT64_C(0x6DF0D9F3DBEE5D7F), UINT64_C(0xA69DB362910F5640),+ UINT64_C(0xFB2B0DD14E2C4A01), UINT64_C(0x3046674004CD413E),+ UINT64_C(0x414770B6F16B7283), UINT64_C(0x8A2A1A27BB8A79BC),+ UINT64_C(0xD79CA49464A965FD), UINT64_C(0x1CF1CE052E486EC2),+ UINT64_C(0xB08084D7A44BDA15), UINT64_C(0x7BEDEE46EEAAD12A),+ UINT64_C(0x265B50F53189CD6B), UINT64_C(0xED363A647B68C654),+ UINT64_C(0x9C372D928ECEF5E9), UINT64_C(0x575A4703C42FFED6),+ UINT64_C(0x0AECF9B01B0CE297), UINT64_C(0xC181932151EDE9A8)+ }, {+ UINT64_C(0x0000000000000000), UINT64_C(0xDCA12C225E8AEE1D),+ UINT64_C(0xB8435944BC14DD3B), UINT64_C(0x64E27566E29E3326),+ UINT64_C(0x7087B2887829BA77), UINT64_C(0xAC269EAA26A3546A),+ UINT64_C(0xC8C4EBCCC43D674C), UINT64_C(0x1465C7EE9AB78951),+ UINT64_C(0xE00E6511F15274EF), UINT64_C(0x3CAF4933AFD89AF2),+ UINT64_C(0x584D3C554D46A9D4), UINT64_C(0x84EC107713CC47C9),+ UINT64_C(0x9089D799897BCE98), UINT64_C(0x4C28FBBBD7F12085),+ UINT64_C(0x28CA8EDD356F13A3), UINT64_C(0xF46BA2FF6BE5FDBE),+ UINT64_C(0x4503C48DC90A304C), UINT64_C(0x99A2E8AF9780DE51),+ UINT64_C(0xFD409DC9751EED77), UINT64_C(0x21E1B1EB2B94036A),+ UINT64_C(0x35847605B1238A3B), UINT64_C(0xE9255A27EFA96426),+ UINT64_C(0x8DC72F410D375700), UINT64_C(0x5166036353BDB91D),+ UINT64_C(0xA50DA19C385844A3), UINT64_C(0x79AC8DBE66D2AABE),+ UINT64_C(0x1D4EF8D8844C9998), UINT64_C(0xC1EFD4FADAC67785),+ UINT64_C(0xD58A13144071FED4), UINT64_C(0x092B3F361EFB10C9),+ UINT64_C(0x6DC94A50FC6523EF), UINT64_C(0xB1686672A2EFCDF2),+ UINT64_C(0x8A06881B93156098), UINT64_C(0x56A7A439CD9F8E85),+ UINT64_C(0x3245D15F2F01BDA3), UINT64_C(0xEEE4FD7D718B53BE),+ UINT64_C(0xFA813A93EB3CDAEF), UINT64_C(0x262016B1B5B634F2),+ UINT64_C(0x42C263D7572807D4), UINT64_C(0x9E634FF509A2E9C9),+ UINT64_C(0x6A08ED0A62471477), UINT64_C(0xB6A9C1283CCDFA6A),+ UINT64_C(0xD24BB44EDE53C94C), UINT64_C(0x0EEA986C80D92751),+ UINT64_C(0x1A8F5F821A6EAE00), UINT64_C(0xC62E73A044E4401D),+ UINT64_C(0xA2CC06C6A67A733B), UINT64_C(0x7E6D2AE4F8F09D26),+ UINT64_C(0xCF054C965A1F50D4), UINT64_C(0x13A460B40495BEC9),+ UINT64_C(0x774615D2E60B8DEF), UINT64_C(0xABE739F0B88163F2),+ UINT64_C(0xBF82FE1E2236EAA3), UINT64_C(0x6323D23C7CBC04BE),+ UINT64_C(0x07C1A75A9E223798), UINT64_C(0xDB608B78C0A8D985),+ UINT64_C(0x2F0B2987AB4D243B), UINT64_C(0xF3AA05A5F5C7CA26),+ UINT64_C(0x974870C31759F900), UINT64_C(0x4BE95CE149D3171D),+ UINT64_C(0x5F8C9B0FD3649E4C), UINT64_C(0x832DB72D8DEE7051),+ UINT64_C(0xE7CFC24B6F704377), UINT64_C(0x3B6EEE6931FAAD6A),+ UINT64_C(0x91131E980D8418A2), UINT64_C(0x4DB232BA530EF6BF),+ UINT64_C(0x295047DCB190C599), UINT64_C(0xF5F16BFEEF1A2B84),+ UINT64_C(0xE194AC1075ADA2D5), UINT64_C(0x3D3580322B274CC8),+ UINT64_C(0x59D7F554C9B97FEE), UINT64_C(0x8576D976973391F3),+ UINT64_C(0x711D7B89FCD66C4D), UINT64_C(0xADBC57ABA25C8250),+ UINT64_C(0xC95E22CD40C2B176), UINT64_C(0x15FF0EEF1E485F6B),+ UINT64_C(0x019AC90184FFD63A), UINT64_C(0xDD3BE523DA753827),+ UINT64_C(0xB9D9904538EB0B01), UINT64_C(0x6578BC676661E51C),+ UINT64_C(0xD410DA15C48E28EE), UINT64_C(0x08B1F6379A04C6F3),+ UINT64_C(0x6C538351789AF5D5), UINT64_C(0xB0F2AF7326101BC8),+ UINT64_C(0xA497689DBCA79299), UINT64_C(0x783644BFE22D7C84),+ UINT64_C(0x1CD431D900B34FA2), UINT64_C(0xC0751DFB5E39A1BF),+ UINT64_C(0x341EBF0435DC5C01), UINT64_C(0xE8BF93266B56B21C),+ UINT64_C(0x8C5DE64089C8813A), UINT64_C(0x50FCCA62D7426F27),+ UINT64_C(0x44990D8C4DF5E676), UINT64_C(0x983821AE137F086B),+ UINT64_C(0xFCDA54C8F1E13B4D), UINT64_C(0x207B78EAAF6BD550),+ UINT64_C(0x1B1596839E91783A), UINT64_C(0xC7B4BAA1C01B9627),+ UINT64_C(0xA356CFC72285A501), UINT64_C(0x7FF7E3E57C0F4B1C),+ UINT64_C(0x6B92240BE6B8C24D), UINT64_C(0xB7330829B8322C50),+ UINT64_C(0xD3D17D4F5AAC1F76), UINT64_C(0x0F70516D0426F16B),+ UINT64_C(0xFB1BF3926FC30CD5), UINT64_C(0x27BADFB03149E2C8),+ UINT64_C(0x4358AAD6D3D7D1EE), UINT64_C(0x9FF986F48D5D3FF3),+ UINT64_C(0x8B9C411A17EAB6A2), UINT64_C(0x573D6D38496058BF),+ UINT64_C(0x33DF185EABFE6B99), UINT64_C(0xEF7E347CF5748584),+ UINT64_C(0x5E16520E579B4876), UINT64_C(0x82B77E2C0911A66B),+ UINT64_C(0xE6550B4AEB8F954D), UINT64_C(0x3AF42768B5057B50),+ UINT64_C(0x2E91E0862FB2F201), UINT64_C(0xF230CCA471381C1C),+ UINT64_C(0x96D2B9C293A62F3A), UINT64_C(0x4A7395E0CD2CC127),+ UINT64_C(0xBE18371FA6C93C99), UINT64_C(0x62B91B3DF843D284),+ UINT64_C(0x065B6E5B1ADDE1A2), UINT64_C(0xDAFA427944570FBF),+ UINT64_C(0xCE9F8597DEE086EE), UINT64_C(0x123EA9B5806A68F3),+ UINT64_C(0x76DCDCD362F45BD5), UINT64_C(0xAA7DF0F13C7EB5C8),+ UINT64_C(0xA739329F30A7E9D6), UINT64_C(0x7B981EBD6E2D07CB),+ UINT64_C(0x1F7A6BDB8CB334ED), UINT64_C(0xC3DB47F9D239DAF0),+ UINT64_C(0xD7BE8017488E53A1), UINT64_C(0x0B1FAC351604BDBC),+ UINT64_C(0x6FFDD953F49A8E9A), UINT64_C(0xB35CF571AA106087),+ UINT64_C(0x4737578EC1F59D39), UINT64_C(0x9B967BAC9F7F7324),+ UINT64_C(0xFF740ECA7DE14002), UINT64_C(0x23D522E8236BAE1F),+ UINT64_C(0x37B0E506B9DC274E), UINT64_C(0xEB11C924E756C953),+ UINT64_C(0x8FF3BC4205C8FA75), UINT64_C(0x535290605B421468),+ UINT64_C(0xE23AF612F9ADD99A), UINT64_C(0x3E9BDA30A7273787),+ UINT64_C(0x5A79AF5645B904A1), UINT64_C(0x86D883741B33EABC),+ UINT64_C(0x92BD449A818463ED), UINT64_C(0x4E1C68B8DF0E8DF0),+ UINT64_C(0x2AFE1DDE3D90BED6), UINT64_C(0xF65F31FC631A50CB),+ UINT64_C(0x0234930308FFAD75), UINT64_C(0xDE95BF2156754368),+ UINT64_C(0xBA77CA47B4EB704E), UINT64_C(0x66D6E665EA619E53),+ UINT64_C(0x72B3218B70D61702), UINT64_C(0xAE120DA92E5CF91F),+ UINT64_C(0xCAF078CFCCC2CA39), UINT64_C(0x165154ED92482424),+ UINT64_C(0x2D3FBA84A3B2894E), UINT64_C(0xF19E96A6FD386753),+ UINT64_C(0x957CE3C01FA65475), UINT64_C(0x49DDCFE2412CBA68),+ UINT64_C(0x5DB8080CDB9B3339), UINT64_C(0x8119242E8511DD24),+ UINT64_C(0xE5FB5148678FEE02), UINT64_C(0x395A7D6A3905001F),+ UINT64_C(0xCD31DF9552E0FDA1), UINT64_C(0x1190F3B70C6A13BC),+ UINT64_C(0x757286D1EEF4209A), UINT64_C(0xA9D3AAF3B07ECE87),+ UINT64_C(0xBDB66D1D2AC947D6), UINT64_C(0x6117413F7443A9CB),+ UINT64_C(0x05F5345996DD9AED), UINT64_C(0xD954187BC85774F0),+ UINT64_C(0x683C7E096AB8B902), UINT64_C(0xB49D522B3432571F),+ UINT64_C(0xD07F274DD6AC6439), UINT64_C(0x0CDE0B6F88268A24),+ UINT64_C(0x18BBCC8112910375), UINT64_C(0xC41AE0A34C1BED68),+ UINT64_C(0xA0F895C5AE85DE4E), UINT64_C(0x7C59B9E7F00F3053),+ UINT64_C(0x88321B189BEACDED), UINT64_C(0x5493373AC56023F0),+ UINT64_C(0x3071425C27FE10D6), UINT64_C(0xECD06E7E7974FECB),+ UINT64_C(0xF8B5A990E3C3779A), UINT64_C(0x241485B2BD499987),+ UINT64_C(0x40F6F0D45FD7AAA1), UINT64_C(0x9C57DCF6015D44BC),+ UINT64_C(0x362A2C073D23F174), UINT64_C(0xEA8B002563A91F69),+ UINT64_C(0x8E69754381372C4F), UINT64_C(0x52C85961DFBDC252),+ UINT64_C(0x46AD9E8F450A4B03), UINT64_C(0x9A0CB2AD1B80A51E),+ UINT64_C(0xFEEEC7CBF91E9638), UINT64_C(0x224FEBE9A7947825),+ UINT64_C(0xD6244916CC71859B), UINT64_C(0x0A85653492FB6B86),+ UINT64_C(0x6E671052706558A0), UINT64_C(0xB2C63C702EEFB6BD),+ UINT64_C(0xA6A3FB9EB4583FEC), UINT64_C(0x7A02D7BCEAD2D1F1),+ UINT64_C(0x1EE0A2DA084CE2D7), UINT64_C(0xC2418EF856C60CCA),+ UINT64_C(0x7329E88AF429C138), UINT64_C(0xAF88C4A8AAA32F25),+ UINT64_C(0xCB6AB1CE483D1C03), UINT64_C(0x17CB9DEC16B7F21E),+ UINT64_C(0x03AE5A028C007B4F), UINT64_C(0xDF0F7620D28A9552),+ UINT64_C(0xBBED03463014A674), UINT64_C(0x674C2F646E9E4869),+ UINT64_C(0x93278D9B057BB5D7), UINT64_C(0x4F86A1B95BF15BCA),+ UINT64_C(0x2B64D4DFB96F68EC), UINT64_C(0xF7C5F8FDE7E586F1),+ UINT64_C(0xE3A03F137D520FA0), UINT64_C(0x3F01133123D8E1BD),+ UINT64_C(0x5BE36657C146D29B), UINT64_C(0x87424A759FCC3C86),+ UINT64_C(0xBC2CA41CAE3691EC), UINT64_C(0x608D883EF0BC7FF1),+ UINT64_C(0x046FFD5812224CD7), UINT64_C(0xD8CED17A4CA8A2CA),+ UINT64_C(0xCCAB1694D61F2B9B), UINT64_C(0x100A3AB68895C586),+ UINT64_C(0x74E84FD06A0BF6A0), UINT64_C(0xA84963F2348118BD),+ UINT64_C(0x5C22C10D5F64E503), UINT64_C(0x8083ED2F01EE0B1E),+ UINT64_C(0xE4619849E3703838), UINT64_C(0x38C0B46BBDFAD625),+ UINT64_C(0x2CA57385274D5F74), UINT64_C(0xF0045FA779C7B169),+ UINT64_C(0x94E62AC19B59824F), UINT64_C(0x484706E3C5D36C52),+ UINT64_C(0xF92F6091673CA1A0), UINT64_C(0x258E4CB339B64FBD),+ UINT64_C(0x416C39D5DB287C9B), UINT64_C(0x9DCD15F785A29286),+ UINT64_C(0x89A8D2191F151BD7), UINT64_C(0x5509FE3B419FF5CA),+ UINT64_C(0x31EB8B5DA301C6EC), UINT64_C(0xED4AA77FFD8B28F1),+ UINT64_C(0x19210580966ED54F), UINT64_C(0xC58029A2C8E43B52),+ UINT64_C(0xA1625CC42A7A0874), UINT64_C(0x7DC370E674F0E669),+ UINT64_C(0x69A6B708EE476F38), UINT64_C(0xB5079B2AB0CD8125),+ UINT64_C(0xD1E5EE4C5253B203), UINT64_C(0x0D44C26E0CD95C1E)+ }+};
+ cbits/liblzma/check/crc64_table_le.h view
@@ -0,0 +1,521 @@+/* This file has been automatically generated by crc64_tablegen.c. */++const uint64_t lzma_crc64_table[4][256] = {+ {+ UINT64_C(0x0000000000000000), UINT64_C(0xB32E4CBE03A75F6F),+ UINT64_C(0xF4843657A840A05B), UINT64_C(0x47AA7AE9ABE7FF34),+ UINT64_C(0x7BD0C384FF8F5E33), UINT64_C(0xC8FE8F3AFC28015C),+ UINT64_C(0x8F54F5D357CFFE68), UINT64_C(0x3C7AB96D5468A107),+ UINT64_C(0xF7A18709FF1EBC66), UINT64_C(0x448FCBB7FCB9E309),+ UINT64_C(0x0325B15E575E1C3D), UINT64_C(0xB00BFDE054F94352),+ UINT64_C(0x8C71448D0091E255), UINT64_C(0x3F5F08330336BD3A),+ UINT64_C(0x78F572DAA8D1420E), UINT64_C(0xCBDB3E64AB761D61),+ UINT64_C(0x7D9BA13851336649), UINT64_C(0xCEB5ED8652943926),+ UINT64_C(0x891F976FF973C612), UINT64_C(0x3A31DBD1FAD4997D),+ UINT64_C(0x064B62BCAEBC387A), UINT64_C(0xB5652E02AD1B6715),+ UINT64_C(0xF2CF54EB06FC9821), UINT64_C(0x41E11855055BC74E),+ UINT64_C(0x8A3A2631AE2DDA2F), UINT64_C(0x39146A8FAD8A8540),+ UINT64_C(0x7EBE1066066D7A74), UINT64_C(0xCD905CD805CA251B),+ UINT64_C(0xF1EAE5B551A2841C), UINT64_C(0x42C4A90B5205DB73),+ UINT64_C(0x056ED3E2F9E22447), UINT64_C(0xB6409F5CFA457B28),+ UINT64_C(0xFB374270A266CC92), UINT64_C(0x48190ECEA1C193FD),+ UINT64_C(0x0FB374270A266CC9), UINT64_C(0xBC9D3899098133A6),+ UINT64_C(0x80E781F45DE992A1), UINT64_C(0x33C9CD4A5E4ECDCE),+ UINT64_C(0x7463B7A3F5A932FA), UINT64_C(0xC74DFB1DF60E6D95),+ UINT64_C(0x0C96C5795D7870F4), UINT64_C(0xBFB889C75EDF2F9B),+ UINT64_C(0xF812F32EF538D0AF), UINT64_C(0x4B3CBF90F69F8FC0),+ UINT64_C(0x774606FDA2F72EC7), UINT64_C(0xC4684A43A15071A8),+ UINT64_C(0x83C230AA0AB78E9C), UINT64_C(0x30EC7C140910D1F3),+ UINT64_C(0x86ACE348F355AADB), UINT64_C(0x3582AFF6F0F2F5B4),+ UINT64_C(0x7228D51F5B150A80), UINT64_C(0xC10699A158B255EF),+ UINT64_C(0xFD7C20CC0CDAF4E8), UINT64_C(0x4E526C720F7DAB87),+ UINT64_C(0x09F8169BA49A54B3), UINT64_C(0xBAD65A25A73D0BDC),+ UINT64_C(0x710D64410C4B16BD), UINT64_C(0xC22328FF0FEC49D2),+ UINT64_C(0x85895216A40BB6E6), UINT64_C(0x36A71EA8A7ACE989),+ UINT64_C(0x0ADDA7C5F3C4488E), UINT64_C(0xB9F3EB7BF06317E1),+ UINT64_C(0xFE5991925B84E8D5), UINT64_C(0x4D77DD2C5823B7BA),+ UINT64_C(0x64B62BCAEBC387A1), UINT64_C(0xD7986774E864D8CE),+ UINT64_C(0x90321D9D438327FA), UINT64_C(0x231C512340247895),+ UINT64_C(0x1F66E84E144CD992), UINT64_C(0xAC48A4F017EB86FD),+ UINT64_C(0xEBE2DE19BC0C79C9), UINT64_C(0x58CC92A7BFAB26A6),+ UINT64_C(0x9317ACC314DD3BC7), UINT64_C(0x2039E07D177A64A8),+ UINT64_C(0x67939A94BC9D9B9C), UINT64_C(0xD4BDD62ABF3AC4F3),+ UINT64_C(0xE8C76F47EB5265F4), UINT64_C(0x5BE923F9E8F53A9B),+ UINT64_C(0x1C4359104312C5AF), UINT64_C(0xAF6D15AE40B59AC0),+ UINT64_C(0x192D8AF2BAF0E1E8), UINT64_C(0xAA03C64CB957BE87),+ UINT64_C(0xEDA9BCA512B041B3), UINT64_C(0x5E87F01B11171EDC),+ UINT64_C(0x62FD4976457FBFDB), UINT64_C(0xD1D305C846D8E0B4),+ UINT64_C(0x96797F21ED3F1F80), UINT64_C(0x2557339FEE9840EF),+ UINT64_C(0xEE8C0DFB45EE5D8E), UINT64_C(0x5DA24145464902E1),+ UINT64_C(0x1A083BACEDAEFDD5), UINT64_C(0xA9267712EE09A2BA),+ UINT64_C(0x955CCE7FBA6103BD), UINT64_C(0x267282C1B9C65CD2),+ UINT64_C(0x61D8F8281221A3E6), UINT64_C(0xD2F6B4961186FC89),+ UINT64_C(0x9F8169BA49A54B33), UINT64_C(0x2CAF25044A02145C),+ UINT64_C(0x6B055FEDE1E5EB68), UINT64_C(0xD82B1353E242B407),+ UINT64_C(0xE451AA3EB62A1500), UINT64_C(0x577FE680B58D4A6F),+ UINT64_C(0x10D59C691E6AB55B), UINT64_C(0xA3FBD0D71DCDEA34),+ UINT64_C(0x6820EEB3B6BBF755), UINT64_C(0xDB0EA20DB51CA83A),+ UINT64_C(0x9CA4D8E41EFB570E), UINT64_C(0x2F8A945A1D5C0861),+ UINT64_C(0x13F02D374934A966), UINT64_C(0xA0DE61894A93F609),+ UINT64_C(0xE7741B60E174093D), UINT64_C(0x545A57DEE2D35652),+ UINT64_C(0xE21AC88218962D7A), UINT64_C(0x5134843C1B317215),+ UINT64_C(0x169EFED5B0D68D21), UINT64_C(0xA5B0B26BB371D24E),+ UINT64_C(0x99CA0B06E7197349), UINT64_C(0x2AE447B8E4BE2C26),+ UINT64_C(0x6D4E3D514F59D312), UINT64_C(0xDE6071EF4CFE8C7D),+ UINT64_C(0x15BB4F8BE788911C), UINT64_C(0xA6950335E42FCE73),+ UINT64_C(0xE13F79DC4FC83147), UINT64_C(0x521135624C6F6E28),+ UINT64_C(0x6E6B8C0F1807CF2F), UINT64_C(0xDD45C0B11BA09040),+ UINT64_C(0x9AEFBA58B0476F74), UINT64_C(0x29C1F6E6B3E0301B),+ UINT64_C(0xC96C5795D7870F42), UINT64_C(0x7A421B2BD420502D),+ UINT64_C(0x3DE861C27FC7AF19), UINT64_C(0x8EC62D7C7C60F076),+ UINT64_C(0xB2BC941128085171), UINT64_C(0x0192D8AF2BAF0E1E),+ UINT64_C(0x4638A2468048F12A), UINT64_C(0xF516EEF883EFAE45),+ UINT64_C(0x3ECDD09C2899B324), UINT64_C(0x8DE39C222B3EEC4B),+ UINT64_C(0xCA49E6CB80D9137F), UINT64_C(0x7967AA75837E4C10),+ UINT64_C(0x451D1318D716ED17), UINT64_C(0xF6335FA6D4B1B278),+ UINT64_C(0xB199254F7F564D4C), UINT64_C(0x02B769F17CF11223),+ UINT64_C(0xB4F7F6AD86B4690B), UINT64_C(0x07D9BA1385133664),+ UINT64_C(0x4073C0FA2EF4C950), UINT64_C(0xF35D8C442D53963F),+ UINT64_C(0xCF273529793B3738), UINT64_C(0x7C0979977A9C6857),+ UINT64_C(0x3BA3037ED17B9763), UINT64_C(0x888D4FC0D2DCC80C),+ UINT64_C(0x435671A479AAD56D), UINT64_C(0xF0783D1A7A0D8A02),+ UINT64_C(0xB7D247F3D1EA7536), UINT64_C(0x04FC0B4DD24D2A59),+ UINT64_C(0x3886B22086258B5E), UINT64_C(0x8BA8FE9E8582D431),+ UINT64_C(0xCC0284772E652B05), UINT64_C(0x7F2CC8C92DC2746A),+ UINT64_C(0x325B15E575E1C3D0), UINT64_C(0x8175595B76469CBF),+ UINT64_C(0xC6DF23B2DDA1638B), UINT64_C(0x75F16F0CDE063CE4),+ UINT64_C(0x498BD6618A6E9DE3), UINT64_C(0xFAA59ADF89C9C28C),+ UINT64_C(0xBD0FE036222E3DB8), UINT64_C(0x0E21AC88218962D7),+ UINT64_C(0xC5FA92EC8AFF7FB6), UINT64_C(0x76D4DE52895820D9),+ UINT64_C(0x317EA4BB22BFDFED), UINT64_C(0x8250E80521188082),+ UINT64_C(0xBE2A516875702185), UINT64_C(0x0D041DD676D77EEA),+ UINT64_C(0x4AAE673FDD3081DE), UINT64_C(0xF9802B81DE97DEB1),+ UINT64_C(0x4FC0B4DD24D2A599), UINT64_C(0xFCEEF8632775FAF6),+ UINT64_C(0xBB44828A8C9205C2), UINT64_C(0x086ACE348F355AAD),+ UINT64_C(0x34107759DB5DFBAA), UINT64_C(0x873E3BE7D8FAA4C5),+ UINT64_C(0xC094410E731D5BF1), UINT64_C(0x73BA0DB070BA049E),+ UINT64_C(0xB86133D4DBCC19FF), UINT64_C(0x0B4F7F6AD86B4690),+ UINT64_C(0x4CE50583738CB9A4), UINT64_C(0xFFCB493D702BE6CB),+ UINT64_C(0xC3B1F050244347CC), UINT64_C(0x709FBCEE27E418A3),+ UINT64_C(0x3735C6078C03E797), UINT64_C(0x841B8AB98FA4B8F8),+ UINT64_C(0xADDA7C5F3C4488E3), UINT64_C(0x1EF430E13FE3D78C),+ UINT64_C(0x595E4A08940428B8), UINT64_C(0xEA7006B697A377D7),+ UINT64_C(0xD60ABFDBC3CBD6D0), UINT64_C(0x6524F365C06C89BF),+ UINT64_C(0x228E898C6B8B768B), UINT64_C(0x91A0C532682C29E4),+ UINT64_C(0x5A7BFB56C35A3485), UINT64_C(0xE955B7E8C0FD6BEA),+ UINT64_C(0xAEFFCD016B1A94DE), UINT64_C(0x1DD181BF68BDCBB1),+ UINT64_C(0x21AB38D23CD56AB6), UINT64_C(0x9285746C3F7235D9),+ UINT64_C(0xD52F0E859495CAED), UINT64_C(0x6601423B97329582),+ UINT64_C(0xD041DD676D77EEAA), UINT64_C(0x636F91D96ED0B1C5),+ UINT64_C(0x24C5EB30C5374EF1), UINT64_C(0x97EBA78EC690119E),+ UINT64_C(0xAB911EE392F8B099), UINT64_C(0x18BF525D915FEFF6),+ UINT64_C(0x5F1528B43AB810C2), UINT64_C(0xEC3B640A391F4FAD),+ UINT64_C(0x27E05A6E926952CC), UINT64_C(0x94CE16D091CE0DA3),+ UINT64_C(0xD3646C393A29F297), UINT64_C(0x604A2087398EADF8),+ UINT64_C(0x5C3099EA6DE60CFF), UINT64_C(0xEF1ED5546E415390),+ UINT64_C(0xA8B4AFBDC5A6ACA4), UINT64_C(0x1B9AE303C601F3CB),+ UINT64_C(0x56ED3E2F9E224471), UINT64_C(0xE5C372919D851B1E),+ UINT64_C(0xA26908783662E42A), UINT64_C(0x114744C635C5BB45),+ UINT64_C(0x2D3DFDAB61AD1A42), UINT64_C(0x9E13B115620A452D),+ UINT64_C(0xD9B9CBFCC9EDBA19), UINT64_C(0x6A978742CA4AE576),+ UINT64_C(0xA14CB926613CF817), UINT64_C(0x1262F598629BA778),+ UINT64_C(0x55C88F71C97C584C), UINT64_C(0xE6E6C3CFCADB0723),+ UINT64_C(0xDA9C7AA29EB3A624), UINT64_C(0x69B2361C9D14F94B),+ UINT64_C(0x2E184CF536F3067F), UINT64_C(0x9D36004B35545910),+ UINT64_C(0x2B769F17CF112238), UINT64_C(0x9858D3A9CCB67D57),+ UINT64_C(0xDFF2A94067518263), UINT64_C(0x6CDCE5FE64F6DD0C),+ UINT64_C(0x50A65C93309E7C0B), UINT64_C(0xE388102D33392364),+ UINT64_C(0xA4226AC498DEDC50), UINT64_C(0x170C267A9B79833F),+ UINT64_C(0xDCD7181E300F9E5E), UINT64_C(0x6FF954A033A8C131),+ UINT64_C(0x28532E49984F3E05), UINT64_C(0x9B7D62F79BE8616A),+ UINT64_C(0xA707DB9ACF80C06D), UINT64_C(0x14299724CC279F02),+ UINT64_C(0x5383EDCD67C06036), UINT64_C(0xE0ADA17364673F59)+ }, {+ UINT64_C(0x0000000000000000), UINT64_C(0x54E979925CD0F10D),+ UINT64_C(0xA9D2F324B9A1E21A), UINT64_C(0xFD3B8AB6E5711317),+ UINT64_C(0xC17D4962DC4DDAB1), UINT64_C(0x959430F0809D2BBC),+ UINT64_C(0x68AFBA4665EC38AB), UINT64_C(0x3C46C3D4393CC9A6),+ UINT64_C(0x10223DEE1795ABE7), UINT64_C(0x44CB447C4B455AEA),+ UINT64_C(0xB9F0CECAAE3449FD), UINT64_C(0xED19B758F2E4B8F0),+ UINT64_C(0xD15F748CCBD87156), UINT64_C(0x85B60D1E9708805B),+ UINT64_C(0x788D87A87279934C), UINT64_C(0x2C64FE3A2EA96241),+ UINT64_C(0x20447BDC2F2B57CE), UINT64_C(0x74AD024E73FBA6C3),+ UINT64_C(0x899688F8968AB5D4), UINT64_C(0xDD7FF16ACA5A44D9),+ UINT64_C(0xE13932BEF3668D7F), UINT64_C(0xB5D04B2CAFB67C72),+ UINT64_C(0x48EBC19A4AC76F65), UINT64_C(0x1C02B80816179E68),+ UINT64_C(0x3066463238BEFC29), UINT64_C(0x648F3FA0646E0D24),+ UINT64_C(0x99B4B516811F1E33), UINT64_C(0xCD5DCC84DDCFEF3E),+ UINT64_C(0xF11B0F50E4F32698), UINT64_C(0xA5F276C2B823D795),+ UINT64_C(0x58C9FC745D52C482), UINT64_C(0x0C2085E60182358F),+ UINT64_C(0x4088F7B85E56AF9C), UINT64_C(0x14618E2A02865E91),+ UINT64_C(0xE95A049CE7F74D86), UINT64_C(0xBDB37D0EBB27BC8B),+ UINT64_C(0x81F5BEDA821B752D), UINT64_C(0xD51CC748DECB8420),+ UINT64_C(0x28274DFE3BBA9737), UINT64_C(0x7CCE346C676A663A),+ UINT64_C(0x50AACA5649C3047B), UINT64_C(0x0443B3C41513F576),+ UINT64_C(0xF9783972F062E661), UINT64_C(0xAD9140E0ACB2176C),+ UINT64_C(0x91D78334958EDECA), UINT64_C(0xC53EFAA6C95E2FC7),+ UINT64_C(0x380570102C2F3CD0), UINT64_C(0x6CEC098270FFCDDD),+ UINT64_C(0x60CC8C64717DF852), UINT64_C(0x3425F5F62DAD095F),+ UINT64_C(0xC91E7F40C8DC1A48), UINT64_C(0x9DF706D2940CEB45),+ UINT64_C(0xA1B1C506AD3022E3), UINT64_C(0xF558BC94F1E0D3EE),+ UINT64_C(0x086336221491C0F9), UINT64_C(0x5C8A4FB0484131F4),+ UINT64_C(0x70EEB18A66E853B5), UINT64_C(0x2407C8183A38A2B8),+ UINT64_C(0xD93C42AEDF49B1AF), UINT64_C(0x8DD53B3C839940A2),+ UINT64_C(0xB193F8E8BAA58904), UINT64_C(0xE57A817AE6757809),+ UINT64_C(0x18410BCC03046B1E), UINT64_C(0x4CA8725E5FD49A13),+ UINT64_C(0x8111EF70BCAD5F38), UINT64_C(0xD5F896E2E07DAE35),+ UINT64_C(0x28C31C54050CBD22), UINT64_C(0x7C2A65C659DC4C2F),+ UINT64_C(0x406CA61260E08589), UINT64_C(0x1485DF803C307484),+ UINT64_C(0xE9BE5536D9416793), UINT64_C(0xBD572CA48591969E),+ UINT64_C(0x9133D29EAB38F4DF), UINT64_C(0xC5DAAB0CF7E805D2),+ UINT64_C(0x38E121BA129916C5), UINT64_C(0x6C0858284E49E7C8),+ UINT64_C(0x504E9BFC77752E6E), UINT64_C(0x04A7E26E2BA5DF63),+ UINT64_C(0xF99C68D8CED4CC74), UINT64_C(0xAD75114A92043D79),+ UINT64_C(0xA15594AC938608F6), UINT64_C(0xF5BCED3ECF56F9FB),+ UINT64_C(0x088767882A27EAEC), UINT64_C(0x5C6E1E1A76F71BE1),+ UINT64_C(0x6028DDCE4FCBD247), UINT64_C(0x34C1A45C131B234A),+ UINT64_C(0xC9FA2EEAF66A305D), UINT64_C(0x9D135778AABAC150),+ UINT64_C(0xB177A9428413A311), UINT64_C(0xE59ED0D0D8C3521C),+ UINT64_C(0x18A55A663DB2410B), UINT64_C(0x4C4C23F46162B006),+ UINT64_C(0x700AE020585E79A0), UINT64_C(0x24E399B2048E88AD),+ UINT64_C(0xD9D81304E1FF9BBA), UINT64_C(0x8D316A96BD2F6AB7),+ UINT64_C(0xC19918C8E2FBF0A4), UINT64_C(0x9570615ABE2B01A9),+ UINT64_C(0x684BEBEC5B5A12BE), UINT64_C(0x3CA2927E078AE3B3),+ UINT64_C(0x00E451AA3EB62A15), UINT64_C(0x540D28386266DB18),+ UINT64_C(0xA936A28E8717C80F), UINT64_C(0xFDDFDB1CDBC73902),+ UINT64_C(0xD1BB2526F56E5B43), UINT64_C(0x85525CB4A9BEAA4E),+ UINT64_C(0x7869D6024CCFB959), UINT64_C(0x2C80AF90101F4854),+ UINT64_C(0x10C66C44292381F2), UINT64_C(0x442F15D675F370FF),+ UINT64_C(0xB9149F60908263E8), UINT64_C(0xEDFDE6F2CC5292E5),+ UINT64_C(0xE1DD6314CDD0A76A), UINT64_C(0xB5341A8691005667),+ UINT64_C(0x480F903074714570), UINT64_C(0x1CE6E9A228A1B47D),+ UINT64_C(0x20A02A76119D7DDB), UINT64_C(0x744953E44D4D8CD6),+ UINT64_C(0x8972D952A83C9FC1), UINT64_C(0xDD9BA0C0F4EC6ECC),+ UINT64_C(0xF1FF5EFADA450C8D), UINT64_C(0xA51627688695FD80),+ UINT64_C(0x582DADDE63E4EE97), UINT64_C(0x0CC4D44C3F341F9A),+ UINT64_C(0x308217980608D63C), UINT64_C(0x646B6E0A5AD82731),+ UINT64_C(0x9950E4BCBFA93426), UINT64_C(0xCDB99D2EE379C52B),+ UINT64_C(0x90FB71CAD654A0F5), UINT64_C(0xC41208588A8451F8),+ UINT64_C(0x392982EE6FF542EF), UINT64_C(0x6DC0FB7C3325B3E2),+ UINT64_C(0x518638A80A197A44), UINT64_C(0x056F413A56C98B49),+ UINT64_C(0xF854CB8CB3B8985E), UINT64_C(0xACBDB21EEF686953),+ UINT64_C(0x80D94C24C1C10B12), UINT64_C(0xD43035B69D11FA1F),+ UINT64_C(0x290BBF007860E908), UINT64_C(0x7DE2C69224B01805),+ UINT64_C(0x41A405461D8CD1A3), UINT64_C(0x154D7CD4415C20AE),+ UINT64_C(0xE876F662A42D33B9), UINT64_C(0xBC9F8FF0F8FDC2B4),+ UINT64_C(0xB0BF0A16F97FF73B), UINT64_C(0xE4567384A5AF0636),+ UINT64_C(0x196DF93240DE1521), UINT64_C(0x4D8480A01C0EE42C),+ UINT64_C(0x71C2437425322D8A), UINT64_C(0x252B3AE679E2DC87),+ UINT64_C(0xD810B0509C93CF90), UINT64_C(0x8CF9C9C2C0433E9D),+ UINT64_C(0xA09D37F8EEEA5CDC), UINT64_C(0xF4744E6AB23AADD1),+ UINT64_C(0x094FC4DC574BBEC6), UINT64_C(0x5DA6BD4E0B9B4FCB),+ UINT64_C(0x61E07E9A32A7866D), UINT64_C(0x350907086E777760),+ UINT64_C(0xC8328DBE8B066477), UINT64_C(0x9CDBF42CD7D6957A),+ UINT64_C(0xD073867288020F69), UINT64_C(0x849AFFE0D4D2FE64),+ UINT64_C(0x79A1755631A3ED73), UINT64_C(0x2D480CC46D731C7E),+ UINT64_C(0x110ECF10544FD5D8), UINT64_C(0x45E7B682089F24D5),+ UINT64_C(0xB8DC3C34EDEE37C2), UINT64_C(0xEC3545A6B13EC6CF),+ UINT64_C(0xC051BB9C9F97A48E), UINT64_C(0x94B8C20EC3475583),+ UINT64_C(0x698348B826364694), UINT64_C(0x3D6A312A7AE6B799),+ UINT64_C(0x012CF2FE43DA7E3F), UINT64_C(0x55C58B6C1F0A8F32),+ UINT64_C(0xA8FE01DAFA7B9C25), UINT64_C(0xFC177848A6AB6D28),+ UINT64_C(0xF037FDAEA72958A7), UINT64_C(0xA4DE843CFBF9A9AA),+ UINT64_C(0x59E50E8A1E88BABD), UINT64_C(0x0D0C771842584BB0),+ UINT64_C(0x314AB4CC7B648216), UINT64_C(0x65A3CD5E27B4731B),+ UINT64_C(0x989847E8C2C5600C), UINT64_C(0xCC713E7A9E159101),+ UINT64_C(0xE015C040B0BCF340), UINT64_C(0xB4FCB9D2EC6C024D),+ UINT64_C(0x49C73364091D115A), UINT64_C(0x1D2E4AF655CDE057),+ UINT64_C(0x216889226CF129F1), UINT64_C(0x7581F0B03021D8FC),+ UINT64_C(0x88BA7A06D550CBEB), UINT64_C(0xDC53039489803AE6),+ UINT64_C(0x11EA9EBA6AF9FFCD), UINT64_C(0x4503E72836290EC0),+ UINT64_C(0xB8386D9ED3581DD7), UINT64_C(0xECD1140C8F88ECDA),+ UINT64_C(0xD097D7D8B6B4257C), UINT64_C(0x847EAE4AEA64D471),+ UINT64_C(0x794524FC0F15C766), UINT64_C(0x2DAC5D6E53C5366B),+ UINT64_C(0x01C8A3547D6C542A), UINT64_C(0x5521DAC621BCA527),+ UINT64_C(0xA81A5070C4CDB630), UINT64_C(0xFCF329E2981D473D),+ UINT64_C(0xC0B5EA36A1218E9B), UINT64_C(0x945C93A4FDF17F96),+ UINT64_C(0x6967191218806C81), UINT64_C(0x3D8E608044509D8C),+ UINT64_C(0x31AEE56645D2A803), UINT64_C(0x65479CF41902590E),+ UINT64_C(0x987C1642FC734A19), UINT64_C(0xCC956FD0A0A3BB14),+ UINT64_C(0xF0D3AC04999F72B2), UINT64_C(0xA43AD596C54F83BF),+ UINT64_C(0x59015F20203E90A8), UINT64_C(0x0DE826B27CEE61A5),+ UINT64_C(0x218CD888524703E4), UINT64_C(0x7565A11A0E97F2E9),+ UINT64_C(0x885E2BACEBE6E1FE), UINT64_C(0xDCB7523EB73610F3),+ UINT64_C(0xE0F191EA8E0AD955), UINT64_C(0xB418E878D2DA2858),+ UINT64_C(0x492362CE37AB3B4F), UINT64_C(0x1DCA1B5C6B7BCA42),+ UINT64_C(0x5162690234AF5051), UINT64_C(0x058B1090687FA15C),+ UINT64_C(0xF8B09A268D0EB24B), UINT64_C(0xAC59E3B4D1DE4346),+ UINT64_C(0x901F2060E8E28AE0), UINT64_C(0xC4F659F2B4327BED),+ UINT64_C(0x39CDD344514368FA), UINT64_C(0x6D24AAD60D9399F7),+ UINT64_C(0x414054EC233AFBB6), UINT64_C(0x15A92D7E7FEA0ABB),+ UINT64_C(0xE892A7C89A9B19AC), UINT64_C(0xBC7BDE5AC64BE8A1),+ UINT64_C(0x803D1D8EFF772107), UINT64_C(0xD4D4641CA3A7D00A),+ UINT64_C(0x29EFEEAA46D6C31D), UINT64_C(0x7D0697381A063210),+ UINT64_C(0x712612DE1B84079F), UINT64_C(0x25CF6B4C4754F692),+ UINT64_C(0xD8F4E1FAA225E585), UINT64_C(0x8C1D9868FEF51488),+ UINT64_C(0xB05B5BBCC7C9DD2E), UINT64_C(0xE4B2222E9B192C23),+ UINT64_C(0x1989A8987E683F34), UINT64_C(0x4D60D10A22B8CE39),+ UINT64_C(0x61042F300C11AC78), UINT64_C(0x35ED56A250C15D75),+ UINT64_C(0xC8D6DC14B5B04E62), UINT64_C(0x9C3FA586E960BF6F),+ UINT64_C(0xA0796652D05C76C9), UINT64_C(0xF4901FC08C8C87C4),+ UINT64_C(0x09AB957669FD94D3), UINT64_C(0x5D42ECE4352D65DE)+ }, {+ UINT64_C(0x0000000000000000), UINT64_C(0x3F0BE14A916A6DCB),+ UINT64_C(0x7E17C29522D4DB96), UINT64_C(0x411C23DFB3BEB65D),+ UINT64_C(0xFC2F852A45A9B72C), UINT64_C(0xC3246460D4C3DAE7),+ UINT64_C(0x823847BF677D6CBA), UINT64_C(0xBD33A6F5F6170171),+ UINT64_C(0x6A87A57F245D70DD), UINT64_C(0x558C4435B5371D16),+ UINT64_C(0x149067EA0689AB4B), UINT64_C(0x2B9B86A097E3C680),+ UINT64_C(0x96A8205561F4C7F1), UINT64_C(0xA9A3C11FF09EAA3A),+ UINT64_C(0xE8BFE2C043201C67), UINT64_C(0xD7B4038AD24A71AC),+ UINT64_C(0xD50F4AFE48BAE1BA), UINT64_C(0xEA04ABB4D9D08C71),+ UINT64_C(0xAB18886B6A6E3A2C), UINT64_C(0x94136921FB0457E7),+ UINT64_C(0x2920CFD40D135696), UINT64_C(0x162B2E9E9C793B5D),+ UINT64_C(0x57370D412FC78D00), UINT64_C(0x683CEC0BBEADE0CB),+ UINT64_C(0xBF88EF816CE79167), UINT64_C(0x80830ECBFD8DFCAC),+ UINT64_C(0xC19F2D144E334AF1), UINT64_C(0xFE94CC5EDF59273A),+ UINT64_C(0x43A76AAB294E264B), UINT64_C(0x7CAC8BE1B8244B80),+ UINT64_C(0x3DB0A83E0B9AFDDD), UINT64_C(0x02BB49749AF09016),+ UINT64_C(0x38C63AD73E7BDDF1), UINT64_C(0x07CDDB9DAF11B03A),+ UINT64_C(0x46D1F8421CAF0667), UINT64_C(0x79DA19088DC56BAC),+ UINT64_C(0xC4E9BFFD7BD26ADD), UINT64_C(0xFBE25EB7EAB80716),+ UINT64_C(0xBAFE7D685906B14B), UINT64_C(0x85F59C22C86CDC80),+ UINT64_C(0x52419FA81A26AD2C), UINT64_C(0x6D4A7EE28B4CC0E7),+ UINT64_C(0x2C565D3D38F276BA), UINT64_C(0x135DBC77A9981B71),+ UINT64_C(0xAE6E1A825F8F1A00), UINT64_C(0x9165FBC8CEE577CB),+ UINT64_C(0xD079D8177D5BC196), UINT64_C(0xEF72395DEC31AC5D),+ UINT64_C(0xEDC9702976C13C4B), UINT64_C(0xD2C29163E7AB5180),+ UINT64_C(0x93DEB2BC5415E7DD), UINT64_C(0xACD553F6C57F8A16),+ UINT64_C(0x11E6F50333688B67), UINT64_C(0x2EED1449A202E6AC),+ UINT64_C(0x6FF1379611BC50F1), UINT64_C(0x50FAD6DC80D63D3A),+ UINT64_C(0x874ED556529C4C96), UINT64_C(0xB845341CC3F6215D),+ UINT64_C(0xF95917C370489700), UINT64_C(0xC652F689E122FACB),+ UINT64_C(0x7B61507C1735FBBA), UINT64_C(0x446AB136865F9671),+ UINT64_C(0x057692E935E1202C), UINT64_C(0x3A7D73A3A48B4DE7),+ UINT64_C(0x718C75AE7CF7BBE2), UINT64_C(0x4E8794E4ED9DD629),+ UINT64_C(0x0F9BB73B5E236074), UINT64_C(0x30905671CF490DBF),+ UINT64_C(0x8DA3F084395E0CCE), UINT64_C(0xB2A811CEA8346105),+ UINT64_C(0xF3B432111B8AD758), UINT64_C(0xCCBFD35B8AE0BA93),+ UINT64_C(0x1B0BD0D158AACB3F), UINT64_C(0x2400319BC9C0A6F4),+ UINT64_C(0x651C12447A7E10A9), UINT64_C(0x5A17F30EEB147D62),+ UINT64_C(0xE72455FB1D037C13), UINT64_C(0xD82FB4B18C6911D8),+ UINT64_C(0x9933976E3FD7A785), UINT64_C(0xA6387624AEBDCA4E),+ UINT64_C(0xA4833F50344D5A58), UINT64_C(0x9B88DE1AA5273793),+ UINT64_C(0xDA94FDC5169981CE), UINT64_C(0xE59F1C8F87F3EC05),+ UINT64_C(0x58ACBA7A71E4ED74), UINT64_C(0x67A75B30E08E80BF),+ UINT64_C(0x26BB78EF533036E2), UINT64_C(0x19B099A5C25A5B29),+ UINT64_C(0xCE049A2F10102A85), UINT64_C(0xF10F7B65817A474E),+ UINT64_C(0xB01358BA32C4F113), UINT64_C(0x8F18B9F0A3AE9CD8),+ UINT64_C(0x322B1F0555B99DA9), UINT64_C(0x0D20FE4FC4D3F062),+ UINT64_C(0x4C3CDD90776D463F), UINT64_C(0x73373CDAE6072BF4),+ UINT64_C(0x494A4F79428C6613), UINT64_C(0x7641AE33D3E60BD8),+ UINT64_C(0x375D8DEC6058BD85), UINT64_C(0x08566CA6F132D04E),+ UINT64_C(0xB565CA530725D13F), UINT64_C(0x8A6E2B19964FBCF4),+ UINT64_C(0xCB7208C625F10AA9), UINT64_C(0xF479E98CB49B6762),+ UINT64_C(0x23CDEA0666D116CE), UINT64_C(0x1CC60B4CF7BB7B05),+ UINT64_C(0x5DDA28934405CD58), UINT64_C(0x62D1C9D9D56FA093),+ UINT64_C(0xDFE26F2C2378A1E2), UINT64_C(0xE0E98E66B212CC29),+ UINT64_C(0xA1F5ADB901AC7A74), UINT64_C(0x9EFE4CF390C617BF),+ UINT64_C(0x9C4505870A3687A9), UINT64_C(0xA34EE4CD9B5CEA62),+ UINT64_C(0xE252C71228E25C3F), UINT64_C(0xDD592658B98831F4),+ UINT64_C(0x606A80AD4F9F3085), UINT64_C(0x5F6161E7DEF55D4E),+ UINT64_C(0x1E7D42386D4BEB13), UINT64_C(0x2176A372FC2186D8),+ UINT64_C(0xF6C2A0F82E6BF774), UINT64_C(0xC9C941B2BF019ABF),+ UINT64_C(0x88D5626D0CBF2CE2), UINT64_C(0xB7DE83279DD54129),+ UINT64_C(0x0AED25D26BC24058), UINT64_C(0x35E6C498FAA82D93),+ UINT64_C(0x74FAE74749169BCE), UINT64_C(0x4BF1060DD87CF605),+ UINT64_C(0xE318EB5CF9EF77C4), UINT64_C(0xDC130A1668851A0F),+ UINT64_C(0x9D0F29C9DB3BAC52), UINT64_C(0xA204C8834A51C199),+ UINT64_C(0x1F376E76BC46C0E8), UINT64_C(0x203C8F3C2D2CAD23),+ UINT64_C(0x6120ACE39E921B7E), UINT64_C(0x5E2B4DA90FF876B5),+ UINT64_C(0x899F4E23DDB20719), UINT64_C(0xB694AF694CD86AD2),+ UINT64_C(0xF7888CB6FF66DC8F), UINT64_C(0xC8836DFC6E0CB144),+ UINT64_C(0x75B0CB09981BB035), UINT64_C(0x4ABB2A430971DDFE),+ UINT64_C(0x0BA7099CBACF6BA3), UINT64_C(0x34ACE8D62BA50668),+ UINT64_C(0x3617A1A2B155967E), UINT64_C(0x091C40E8203FFBB5),+ UINT64_C(0x4800633793814DE8), UINT64_C(0x770B827D02EB2023),+ UINT64_C(0xCA382488F4FC2152), UINT64_C(0xF533C5C265964C99),+ UINT64_C(0xB42FE61DD628FAC4), UINT64_C(0x8B2407574742970F),+ UINT64_C(0x5C9004DD9508E6A3), UINT64_C(0x639BE59704628B68),+ UINT64_C(0x2287C648B7DC3D35), UINT64_C(0x1D8C270226B650FE),+ UINT64_C(0xA0BF81F7D0A1518F), UINT64_C(0x9FB460BD41CB3C44),+ UINT64_C(0xDEA84362F2758A19), UINT64_C(0xE1A3A228631FE7D2),+ UINT64_C(0xDBDED18BC794AA35), UINT64_C(0xE4D530C156FEC7FE),+ UINT64_C(0xA5C9131EE54071A3), UINT64_C(0x9AC2F254742A1C68),+ UINT64_C(0x27F154A1823D1D19), UINT64_C(0x18FAB5EB135770D2),+ UINT64_C(0x59E69634A0E9C68F), UINT64_C(0x66ED777E3183AB44),+ UINT64_C(0xB15974F4E3C9DAE8), UINT64_C(0x8E5295BE72A3B723),+ UINT64_C(0xCF4EB661C11D017E), UINT64_C(0xF045572B50776CB5),+ UINT64_C(0x4D76F1DEA6606DC4), UINT64_C(0x727D1094370A000F),+ UINT64_C(0x3361334B84B4B652), UINT64_C(0x0C6AD20115DEDB99),+ UINT64_C(0x0ED19B758F2E4B8F), UINT64_C(0x31DA7A3F1E442644),+ UINT64_C(0x70C659E0ADFA9019), UINT64_C(0x4FCDB8AA3C90FDD2),+ UINT64_C(0xF2FE1E5FCA87FCA3), UINT64_C(0xCDF5FF155BED9168),+ UINT64_C(0x8CE9DCCAE8532735), UINT64_C(0xB3E23D8079394AFE),+ UINT64_C(0x64563E0AAB733B52), UINT64_C(0x5B5DDF403A195699),+ UINT64_C(0x1A41FC9F89A7E0C4), UINT64_C(0x254A1DD518CD8D0F),+ UINT64_C(0x9879BB20EEDA8C7E), UINT64_C(0xA7725A6A7FB0E1B5),+ UINT64_C(0xE66E79B5CC0E57E8), UINT64_C(0xD96598FF5D643A23),+ UINT64_C(0x92949EF28518CC26), UINT64_C(0xAD9F7FB81472A1ED),+ UINT64_C(0xEC835C67A7CC17B0), UINT64_C(0xD388BD2D36A67A7B),+ UINT64_C(0x6EBB1BD8C0B17B0A), UINT64_C(0x51B0FA9251DB16C1),+ UINT64_C(0x10ACD94DE265A09C), UINT64_C(0x2FA73807730FCD57),+ UINT64_C(0xF8133B8DA145BCFB), UINT64_C(0xC718DAC7302FD130),+ UINT64_C(0x8604F9188391676D), UINT64_C(0xB90F185212FB0AA6),+ UINT64_C(0x043CBEA7E4EC0BD7), UINT64_C(0x3B375FED7586661C),+ UINT64_C(0x7A2B7C32C638D041), UINT64_C(0x45209D785752BD8A),+ UINT64_C(0x479BD40CCDA22D9C), UINT64_C(0x789035465CC84057),+ UINT64_C(0x398C1699EF76F60A), UINT64_C(0x0687F7D37E1C9BC1),+ UINT64_C(0xBBB45126880B9AB0), UINT64_C(0x84BFB06C1961F77B),+ UINT64_C(0xC5A393B3AADF4126), UINT64_C(0xFAA872F93BB52CED),+ UINT64_C(0x2D1C7173E9FF5D41), UINT64_C(0x121790397895308A),+ UINT64_C(0x530BB3E6CB2B86D7), UINT64_C(0x6C0052AC5A41EB1C),+ UINT64_C(0xD133F459AC56EA6D), UINT64_C(0xEE3815133D3C87A6),+ UINT64_C(0xAF2436CC8E8231FB), UINT64_C(0x902FD7861FE85C30),+ UINT64_C(0xAA52A425BB6311D7), UINT64_C(0x9559456F2A097C1C),+ UINT64_C(0xD44566B099B7CA41), UINT64_C(0xEB4E87FA08DDA78A),+ UINT64_C(0x567D210FFECAA6FB), UINT64_C(0x6976C0456FA0CB30),+ UINT64_C(0x286AE39ADC1E7D6D), UINT64_C(0x176102D04D7410A6),+ UINT64_C(0xC0D5015A9F3E610A), UINT64_C(0xFFDEE0100E540CC1),+ UINT64_C(0xBEC2C3CFBDEABA9C), UINT64_C(0x81C922852C80D757),+ UINT64_C(0x3CFA8470DA97D626), UINT64_C(0x03F1653A4BFDBBED),+ UINT64_C(0x42ED46E5F8430DB0), UINT64_C(0x7DE6A7AF6929607B),+ UINT64_C(0x7F5DEEDBF3D9F06D), UINT64_C(0x40560F9162B39DA6),+ UINT64_C(0x014A2C4ED10D2BFB), UINT64_C(0x3E41CD0440674630),+ UINT64_C(0x83726BF1B6704741), UINT64_C(0xBC798ABB271A2A8A),+ UINT64_C(0xFD65A96494A49CD7), UINT64_C(0xC26E482E05CEF11C),+ UINT64_C(0x15DA4BA4D78480B0), UINT64_C(0x2AD1AAEE46EEED7B),+ UINT64_C(0x6BCD8931F5505B26), UINT64_C(0x54C6687B643A36ED),+ UINT64_C(0xE9F5CE8E922D379C), UINT64_C(0xD6FE2FC403475A57),+ UINT64_C(0x97E20C1BB0F9EC0A), UINT64_C(0xA8E9ED51219381C1)+ }, {+ UINT64_C(0x0000000000000000), UINT64_C(0x1DEE8A5E222CA1DC),+ UINT64_C(0x3BDD14BC445943B8), UINT64_C(0x26339EE26675E264),+ UINT64_C(0x77BA297888B28770), UINT64_C(0x6A54A326AA9E26AC),+ UINT64_C(0x4C673DC4CCEBC4C8), UINT64_C(0x5189B79AEEC76514),+ UINT64_C(0xEF7452F111650EE0), UINT64_C(0xF29AD8AF3349AF3C),+ UINT64_C(0xD4A9464D553C4D58), UINT64_C(0xC947CC137710EC84),+ UINT64_C(0x98CE7B8999D78990), UINT64_C(0x8520F1D7BBFB284C),+ UINT64_C(0xA3136F35DD8ECA28), UINT64_C(0xBEFDE56BFFA26BF4),+ UINT64_C(0x4C300AC98DC40345), UINT64_C(0x51DE8097AFE8A299),+ UINT64_C(0x77ED1E75C99D40FD), UINT64_C(0x6A03942BEBB1E121),+ UINT64_C(0x3B8A23B105768435), UINT64_C(0x2664A9EF275A25E9),+ UINT64_C(0x0057370D412FC78D), UINT64_C(0x1DB9BD5363036651),+ UINT64_C(0xA34458389CA10DA5), UINT64_C(0xBEAAD266BE8DAC79),+ UINT64_C(0x98994C84D8F84E1D), UINT64_C(0x8577C6DAFAD4EFC1),+ UINT64_C(0xD4FE714014138AD5), UINT64_C(0xC910FB1E363F2B09),+ UINT64_C(0xEF2365FC504AC96D), UINT64_C(0xF2CDEFA2726668B1),+ UINT64_C(0x986015931B88068A), UINT64_C(0x858E9FCD39A4A756),+ UINT64_C(0xA3BD012F5FD14532), UINT64_C(0xBE538B717DFDE4EE),+ UINT64_C(0xEFDA3CEB933A81FA), UINT64_C(0xF234B6B5B1162026),+ UINT64_C(0xD4072857D763C242), UINT64_C(0xC9E9A209F54F639E),+ UINT64_C(0x771447620AED086A), UINT64_C(0x6AFACD3C28C1A9B6),+ UINT64_C(0x4CC953DE4EB44BD2), UINT64_C(0x5127D9806C98EA0E),+ UINT64_C(0x00AE6E1A825F8F1A), UINT64_C(0x1D40E444A0732EC6),+ UINT64_C(0x3B737AA6C606CCA2), UINT64_C(0x269DF0F8E42A6D7E),+ UINT64_C(0xD4501F5A964C05CF), UINT64_C(0xC9BE9504B460A413),+ UINT64_C(0xEF8D0BE6D2154677), UINT64_C(0xF26381B8F039E7AB),+ UINT64_C(0xA3EA36221EFE82BF), UINT64_C(0xBE04BC7C3CD22363),+ UINT64_C(0x9837229E5AA7C107), UINT64_C(0x85D9A8C0788B60DB),+ UINT64_C(0x3B244DAB87290B2F), UINT64_C(0x26CAC7F5A505AAF3),+ UINT64_C(0x00F95917C3704897), UINT64_C(0x1D17D349E15CE94B),+ UINT64_C(0x4C9E64D30F9B8C5F), UINT64_C(0x5170EE8D2DB72D83),+ UINT64_C(0x7743706F4BC2CFE7), UINT64_C(0x6AADFA3169EE6E3B),+ UINT64_C(0xA218840D981E1391), UINT64_C(0xBFF60E53BA32B24D),+ UINT64_C(0x99C590B1DC475029), UINT64_C(0x842B1AEFFE6BF1F5),+ UINT64_C(0xD5A2AD7510AC94E1), UINT64_C(0xC84C272B3280353D),+ UINT64_C(0xEE7FB9C954F5D759), UINT64_C(0xF391339776D97685),+ UINT64_C(0x4D6CD6FC897B1D71), UINT64_C(0x50825CA2AB57BCAD),+ UINT64_C(0x76B1C240CD225EC9), UINT64_C(0x6B5F481EEF0EFF15),+ UINT64_C(0x3AD6FF8401C99A01), UINT64_C(0x273875DA23E53BDD),+ UINT64_C(0x010BEB384590D9B9), UINT64_C(0x1CE5616667BC7865),+ UINT64_C(0xEE288EC415DA10D4), UINT64_C(0xF3C6049A37F6B108),+ UINT64_C(0xD5F59A785183536C), UINT64_C(0xC81B102673AFF2B0),+ UINT64_C(0x9992A7BC9D6897A4), UINT64_C(0x847C2DE2BF443678),+ UINT64_C(0xA24FB300D931D41C), UINT64_C(0xBFA1395EFB1D75C0),+ UINT64_C(0x015CDC3504BF1E34), UINT64_C(0x1CB2566B2693BFE8),+ UINT64_C(0x3A81C88940E65D8C), UINT64_C(0x276F42D762CAFC50),+ UINT64_C(0x76E6F54D8C0D9944), UINT64_C(0x6B087F13AE213898),+ UINT64_C(0x4D3BE1F1C854DAFC), UINT64_C(0x50D56BAFEA787B20),+ UINT64_C(0x3A78919E8396151B), UINT64_C(0x27961BC0A1BAB4C7),+ UINT64_C(0x01A58522C7CF56A3), UINT64_C(0x1C4B0F7CE5E3F77F),+ UINT64_C(0x4DC2B8E60B24926B), UINT64_C(0x502C32B8290833B7),+ UINT64_C(0x761FAC5A4F7DD1D3), UINT64_C(0x6BF126046D51700F),+ UINT64_C(0xD50CC36F92F31BFB), UINT64_C(0xC8E24931B0DFBA27),+ UINT64_C(0xEED1D7D3D6AA5843), UINT64_C(0xF33F5D8DF486F99F),+ UINT64_C(0xA2B6EA171A419C8B), UINT64_C(0xBF586049386D3D57),+ UINT64_C(0x996BFEAB5E18DF33), UINT64_C(0x848574F57C347EEF),+ UINT64_C(0x76489B570E52165E), UINT64_C(0x6BA611092C7EB782),+ UINT64_C(0x4D958FEB4A0B55E6), UINT64_C(0x507B05B56827F43A),+ UINT64_C(0x01F2B22F86E0912E), UINT64_C(0x1C1C3871A4CC30F2),+ UINT64_C(0x3A2FA693C2B9D296), UINT64_C(0x27C12CCDE095734A),+ UINT64_C(0x993CC9A61F3718BE), UINT64_C(0x84D243F83D1BB962),+ UINT64_C(0xA2E1DD1A5B6E5B06), UINT64_C(0xBF0F57447942FADA),+ UINT64_C(0xEE86E0DE97859FCE), UINT64_C(0xF3686A80B5A93E12),+ UINT64_C(0xD55BF462D3DCDC76), UINT64_C(0xC8B57E3CF1F07DAA),+ UINT64_C(0xD6E9A7309F3239A7), UINT64_C(0xCB072D6EBD1E987B),+ UINT64_C(0xED34B38CDB6B7A1F), UINT64_C(0xF0DA39D2F947DBC3),+ UINT64_C(0xA1538E481780BED7), UINT64_C(0xBCBD041635AC1F0B),+ UINT64_C(0x9A8E9AF453D9FD6F), UINT64_C(0x876010AA71F55CB3),+ UINT64_C(0x399DF5C18E573747), UINT64_C(0x24737F9FAC7B969B),+ UINT64_C(0x0240E17DCA0E74FF), UINT64_C(0x1FAE6B23E822D523),+ UINT64_C(0x4E27DCB906E5B037), UINT64_C(0x53C956E724C911EB),+ UINT64_C(0x75FAC80542BCF38F), UINT64_C(0x6814425B60905253),+ UINT64_C(0x9AD9ADF912F63AE2), UINT64_C(0x873727A730DA9B3E),+ UINT64_C(0xA104B94556AF795A), UINT64_C(0xBCEA331B7483D886),+ UINT64_C(0xED6384819A44BD92), UINT64_C(0xF08D0EDFB8681C4E),+ UINT64_C(0xD6BE903DDE1DFE2A), UINT64_C(0xCB501A63FC315FF6),+ UINT64_C(0x75ADFF0803933402), UINT64_C(0x6843755621BF95DE),+ UINT64_C(0x4E70EBB447CA77BA), UINT64_C(0x539E61EA65E6D666),+ UINT64_C(0x0217D6708B21B372), UINT64_C(0x1FF95C2EA90D12AE),+ UINT64_C(0x39CAC2CCCF78F0CA), UINT64_C(0x24244892ED545116),+ UINT64_C(0x4E89B2A384BA3F2D), UINT64_C(0x536738FDA6969EF1),+ UINT64_C(0x7554A61FC0E37C95), UINT64_C(0x68BA2C41E2CFDD49),+ UINT64_C(0x39339BDB0C08B85D), UINT64_C(0x24DD11852E241981),+ UINT64_C(0x02EE8F674851FBE5), UINT64_C(0x1F0005396A7D5A39),+ UINT64_C(0xA1FDE05295DF31CD), UINT64_C(0xBC136A0CB7F39011),+ UINT64_C(0x9A20F4EED1867275), UINT64_C(0x87CE7EB0F3AAD3A9),+ UINT64_C(0xD647C92A1D6DB6BD), UINT64_C(0xCBA943743F411761),+ UINT64_C(0xED9ADD965934F505), UINT64_C(0xF07457C87B1854D9),+ UINT64_C(0x02B9B86A097E3C68), UINT64_C(0x1F5732342B529DB4),+ UINT64_C(0x3964ACD64D277FD0), UINT64_C(0x248A26886F0BDE0C),+ UINT64_C(0x7503911281CCBB18), UINT64_C(0x68ED1B4CA3E01AC4),+ UINT64_C(0x4EDE85AEC595F8A0), UINT64_C(0x53300FF0E7B9597C),+ UINT64_C(0xEDCDEA9B181B3288), UINT64_C(0xF02360C53A379354),+ UINT64_C(0xD610FE275C427130), UINT64_C(0xCBFE74797E6ED0EC),+ UINT64_C(0x9A77C3E390A9B5F8), UINT64_C(0x879949BDB2851424),+ UINT64_C(0xA1AAD75FD4F0F640), UINT64_C(0xBC445D01F6DC579C),+ UINT64_C(0x74F1233D072C2A36), UINT64_C(0x691FA96325008BEA),+ UINT64_C(0x4F2C37814375698E), UINT64_C(0x52C2BDDF6159C852),+ UINT64_C(0x034B0A458F9EAD46), UINT64_C(0x1EA5801BADB20C9A),+ UINT64_C(0x38961EF9CBC7EEFE), UINT64_C(0x257894A7E9EB4F22),+ UINT64_C(0x9B8571CC164924D6), UINT64_C(0x866BFB923465850A),+ UINT64_C(0xA05865705210676E), UINT64_C(0xBDB6EF2E703CC6B2),+ UINT64_C(0xEC3F58B49EFBA3A6), UINT64_C(0xF1D1D2EABCD7027A),+ UINT64_C(0xD7E24C08DAA2E01E), UINT64_C(0xCA0CC656F88E41C2),+ UINT64_C(0x38C129F48AE82973), UINT64_C(0x252FA3AAA8C488AF),+ UINT64_C(0x031C3D48CEB16ACB), UINT64_C(0x1EF2B716EC9DCB17),+ UINT64_C(0x4F7B008C025AAE03), UINT64_C(0x52958AD220760FDF),+ UINT64_C(0x74A614304603EDBB), UINT64_C(0x69489E6E642F4C67),+ UINT64_C(0xD7B57B059B8D2793), UINT64_C(0xCA5BF15BB9A1864F),+ UINT64_C(0xEC686FB9DFD4642B), UINT64_C(0xF186E5E7FDF8C5F7),+ UINT64_C(0xA00F527D133FA0E3), UINT64_C(0xBDE1D8233113013F),+ UINT64_C(0x9BD246C15766E35B), UINT64_C(0x863CCC9F754A4287),+ UINT64_C(0xEC9136AE1CA42CBC), UINT64_C(0xF17FBCF03E888D60),+ UINT64_C(0xD74C221258FD6F04), UINT64_C(0xCAA2A84C7AD1CED8),+ UINT64_C(0x9B2B1FD69416ABCC), UINT64_C(0x86C59588B63A0A10),+ UINT64_C(0xA0F60B6AD04FE874), UINT64_C(0xBD188134F26349A8),+ UINT64_C(0x03E5645F0DC1225C), UINT64_C(0x1E0BEE012FED8380),+ UINT64_C(0x383870E3499861E4), UINT64_C(0x25D6FABD6BB4C038),+ UINT64_C(0x745F4D278573A52C), UINT64_C(0x69B1C779A75F04F0),+ UINT64_C(0x4F82599BC12AE694), UINT64_C(0x526CD3C5E3064748),+ UINT64_C(0xA0A13C6791602FF9), UINT64_C(0xBD4FB639B34C8E25),+ UINT64_C(0x9B7C28DBD5396C41), UINT64_C(0x8692A285F715CD9D),+ UINT64_C(0xD71B151F19D2A889), UINT64_C(0xCAF59F413BFE0955),+ UINT64_C(0xECC601A35D8BEB31), UINT64_C(0xF1288BFD7FA74AED),+ UINT64_C(0x4FD56E9680052119), UINT64_C(0x523BE4C8A22980C5),+ UINT64_C(0x74087A2AC45C62A1), UINT64_C(0x69E6F074E670C37D),+ UINT64_C(0x386F47EE08B7A669), UINT64_C(0x2581CDB02A9B07B5),+ UINT64_C(0x03B253524CEEE5D1), UINT64_C(0x1E5CD90C6EC2440D)+ }+};
+ cbits/liblzma/check/crc64_tablegen.c view
@@ -0,0 +1,88 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc64_tablegen.c+/// \brief Generate crc64_table_le.h and crc64_table_be.h+///+/// Compiling: gcc -std=c99 -o crc64_tablegen crc64_tablegen.c+/// Add -DWORDS_BIGENDIAN to generate big endian table.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include <stdio.h>+#include "../../common/tuklib_integer.h"+++static uint64_t crc64_table[4][256];+++extern void+init_crc64_table(void)+{+ static const uint64_t poly64 = UINT64_C(0xC96C5795D7870F42);++ for (size_t s = 0; s < 4; ++s) {+ for (size_t b = 0; b < 256; ++b) {+ uint64_t r = s == 0 ? b : crc64_table[s - 1][b];++ for (size_t i = 0; i < 8; ++i) {+ if (r & 1)+ r = (r >> 1) ^ poly64;+ else+ r >>= 1;+ }++ crc64_table[s][b] = r;+ }+ }++#ifdef WORDS_BIGENDIAN+ for (size_t s = 0; s < 4; ++s)+ for (size_t b = 0; b < 256; ++b)+ crc64_table[s][b] = bswap64(crc64_table[s][b]);+#endif++ return;+}+++static void+print_crc64_table(void)+{+ printf("/* This file has been automatically generated by "+ "crc64_tablegen.c. */\n\n"+ "const uint64_t lzma_crc64_table[4][256] = {\n\t{");++ for (size_t s = 0; s < 4; ++s) {+ for (size_t b = 0; b < 256; ++b) {+ if ((b % 2) == 0)+ printf("\n\t\t");++ printf("UINT64_C(0x%016" PRIX64 ")",+ crc64_table[s][b]);++ if (b != 255)+ printf(",%s", (b+1) % 2 == 0 ? "" : " ");+ }++ if (s == 3)+ printf("\n\t}\n};\n");+ else+ printf("\n\t}, {");+ }++ return;+}+++int+main(void)+{+ init_crc64_table();+ print_crc64_table();+ return 0;+}
+ cbits/liblzma/check/crc_macros.h view
@@ -0,0 +1,30 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file crc_macros.h+/// \brief Some endian-dependent macros for CRC32 and CRC64+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifdef WORDS_BIGENDIAN+# define A(x) ((x) >> 24)+# define B(x) (((x) >> 16) & 0xFF)+# define C(x) (((x) >> 8) & 0xFF)+# define D(x) ((x) & 0xFF)++# define S8(x) ((x) << 8)+# define S32(x) ((x) << 32)++#else+# define A(x) ((x) & 0xFF)+# define B(x) (((x) >> 8) & 0xFF)+# define C(x) (((x) >> 16) & 0xFF)+# define D(x) ((x) >> 24)++# define S8(x) ((x) >> 8)+# define S32(x) ((x) >> 32)+#endif
+ cbits/liblzma/check/sha256.c view
@@ -0,0 +1,196 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file sha256.c+/// \brief SHA-256+///+/// \todo Crypto++ has x86 ASM optimizations. They use SSE so if they+/// are imported to liblzma, SSE instructions need to be used+/// conditionally to keep the code working on older boxes.+//+// This code is based on the code found from 7-Zip, which has a modified+// version of the SHA-256 found from Crypto++ <http://www.cryptopp.com/>.+// The code was modified a little to fit into liblzma.+//+// Authors: Kevin Springle+// Wei Dai+// Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "check.h"++// 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));+}++#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)) + (y & z))++#define a(i) T[(0 - i) & 7]+#define b(i) T[(1 - i) & 7]+#define c(i) T[(2 - i) & 7]+#define d(i) T[(3 - i) & 7]+#define e(i) T[(4 - i) & 7]+#define f(i) T[(5 - i) & 7]+#define g(i) T[(6 - i) & 7]+#define h(i) T[(7 - i) & 7]++#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 ^ 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] = {+ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,+ 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,+ 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,+ 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,+ 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,+ 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,+ 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,+ 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,+ 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,+ 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,+ 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,+ 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,+ 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,+ 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,+ 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,+ 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,+};+++static void+transform(uint32_t state[8], const uint32_t data[16])+{+ uint32_t W[16];+ uint32_t T[8];++ // Copy state[] to working vars.+ memcpy(T, state, sizeof(T));++ // 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[].+ state[0] += a(0);+ state[1] += b(0);+ state[2] += c(0);+ state[3] += d(0);+ state[4] += e(0);+ state[5] += f(0);+ state[6] += g(0);+ state[7] += h(0);+}+++static void+process(lzma_check_state *check)+{+ transform(check->state.sha256.state, check->buffer.u32);+ return;+}+++extern void+lzma_sha256_init(lzma_check_state *check)+{+ static const uint32_t s[8] = {+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,+ };++ memcpy(check->state.sha256.state, s, sizeof(s));+ check->state.sha256.size = 0;++ return;+}+++extern void+lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)+{+ // Copy the input data into a properly aligned temporary buffer.+ // This way we can be called with arbitrarily sized buffers+ // (no need to be multiple of 64 bytes), and the code works also+ // on architectures that don't allow unaligned memory access.+ while (size > 0) {+ const size_t copy_start = check->state.sha256.size & 0x3F;+ size_t copy_size = 64 - copy_start;+ if (copy_size > size)+ copy_size = size;++ memcpy(check->buffer.u8 + copy_start, buf, copy_size);++ buf += copy_size;+ size -= copy_size;+ check->state.sha256.size += copy_size;++ if ((check->state.sha256.size & 0x3F) == 0)+ process(check);+ }++ return;+}+++extern void+lzma_sha256_finish(lzma_check_state *check)+{+ // Add padding as described in RFC 3174 (it describes SHA-1 but+ // the same padding style is used for SHA-256 too).+ size_t pos = check->state.sha256.size & 0x3F;+ check->buffer.u8[pos++] = 0x80;++ while (pos != 64 - 8) {+ if (pos == 64) {+ process(check);+ pos = 0;+ }++ check->buffer.u8[pos++] = 0x00;+ }++ // Convert the message size from bytes to bits.+ check->state.sha256.size *= 8;++ check->buffer.u64[(64 - 8) / 8] = conv64be(check->state.sha256.size);++ process(check);++ for (size_t i = 0; i < 8; ++i)+ check->buffer.u32[i] = conv32be(check->state.sha256.state[i]);++ return;+}
+ cbits/liblzma/common/alone_decoder.c view
@@ -0,0 +1,242 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file alone_decoder.c+/// \brief Decoder for LZMA_Alone files+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "alone_decoder.h"+#include "lzma_decoder.h"+#include "lz_decoder.h"+++typedef struct {+ lzma_next_coder next;++ enum {+ SEQ_PROPERTIES,+ SEQ_DICTIONARY_SIZE,+ SEQ_UNCOMPRESSED_SIZE,+ SEQ_CODER_INIT,+ SEQ_CODE,+ } sequence;++ /// If true, reject files that are unlikely to be .lzma files.+ /// If false, more non-.lzma files get accepted and will give+ /// LZMA_DATA_ERROR either immediately or after a few output bytes.+ bool picky;++ /// Position in the header fields+ size_t pos;++ /// Uncompressed size decoded from the header+ lzma_vli uncompressed_size;++ /// Memory usage limit+ uint64_t memlimit;++ /// Amount of memory actually needed (only an estimate)+ uint64_t memusage;++ /// Options decoded from the header needed to initialize+ /// the LZMA decoder+ lzma_options_lzma options;+} lzma_alone_coder;+++static lzma_ret+alone_decode(void *coder_ptr, const 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_alone_coder *coder = coder_ptr;++ while (*out_pos < out_size+ && (coder->sequence == SEQ_CODE || *in_pos < in_size))+ switch (coder->sequence) {+ case SEQ_PROPERTIES:+ if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))+ return LZMA_FORMAT_ERROR;++ coder->sequence = SEQ_DICTIONARY_SIZE;+ ++*in_pos;+ break;++ case SEQ_DICTIONARY_SIZE:+ coder->options.dict_size+ |= (size_t)(in[*in_pos]) << (coder->pos * 8);++ if (++coder->pos == 4) {+ if (coder->picky && coder->options.dict_size+ != UINT32_MAX) {+ // A hack to ditch tons of false positives:+ // We allow only dictionary sizes that are+ // 2^n or 2^n + 2^(n-1). LZMA_Alone created+ // only files with 2^n, but accepts any+ // dictionary size.+ uint32_t d = coder->options.dict_size - 1;+ d |= d >> 2;+ d |= d >> 3;+ d |= d >> 4;+ d |= d >> 8;+ d |= d >> 16;+ ++d;++ if (d != coder->options.dict_size)+ return LZMA_FORMAT_ERROR;+ }++ coder->pos = 0;+ coder->sequence = SEQ_UNCOMPRESSED_SIZE;+ }++ ++*in_pos;+ break;++ case SEQ_UNCOMPRESSED_SIZE:+ coder->uncompressed_size+ |= (lzma_vli)(in[*in_pos]) << (coder->pos * 8);+ ++*in_pos;+ if (++coder->pos < 8)+ break;++ // Another hack to ditch false positives: Assume that+ // if the uncompressed size is known, it must be less+ // than 256 GiB.+ if (coder->picky+ && coder->uncompressed_size != LZMA_VLI_UNKNOWN+ && coder->uncompressed_size+ >= (LZMA_VLI_C(1) << 38))+ return LZMA_FORMAT_ERROR;++ // Calculate the memory usage so that it is ready+ // for SEQ_CODER_INIT.+ coder->memusage = lzma_lzma_decoder_memusage(&coder->options)+ + LZMA_MEMUSAGE_BASE;++ coder->pos = 0;+ coder->sequence = SEQ_CODER_INIT;++ // Fall through++ case SEQ_CODER_INIT: {+ if (coder->memusage > coder->memlimit)+ return LZMA_MEMLIMIT_ERROR;++ lzma_filter_info filters[2] = {+ {+ .init = &lzma_lzma_decoder_init,+ .options = &coder->options,+ }, {+ .init = NULL,+ }+ };++ const lzma_ret ret = lzma_next_filter_init(&coder->next,+ allocator, filters);+ if (ret != LZMA_OK)+ return ret;++ // Use a hack to set the uncompressed size.+ lzma_lz_decoder_uncompressed(coder->next.coder,+ coder->uncompressed_size);++ coder->sequence = SEQ_CODE;+ break;+ }++ case SEQ_CODE: {+ return coder->next.code(coder->next.coder,+ allocator, in, in_pos, in_size,+ out, out_pos, out_size, action);+ }++ default:+ return LZMA_PROG_ERROR;+ }++ return LZMA_OK;+}+++static void+alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_alone_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage,+ uint64_t *old_memlimit, uint64_t new_memlimit)+{+ lzma_alone_coder *coder = coder_ptr;++ *memusage = coder->memusage;+ *old_memlimit = coder->memlimit;++ if (new_memlimit != 0) {+ if (new_memlimit < coder->memusage)+ return LZMA_MEMLIMIT_ERROR;++ coder->memlimit = new_memlimit;+ }++ return LZMA_OK;+}+++extern lzma_ret+lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ uint64_t memlimit, bool picky)+{+ lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);++ lzma_alone_coder *coder = next->coder;++ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &alone_decode;+ next->end = &alone_decoder_end;+ next->memconfig = &alone_decoder_memconfig;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ coder->sequence = SEQ_PROPERTIES;+ coder->picky = picky;+ coder->pos = 0;+ coder->options.dict_size = 0;+ coder->options.preset_dict = NULL;+ coder->options.preset_dict_size = 0;+ coder->uncompressed_size = 0;+ coder->memlimit = my_max(1, memlimit);+ coder->memusage = LZMA_MEMUSAGE_BASE;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)+{+ lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/alone_decoder.h view
@@ -0,0 +1,23 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file alone_decoder.h+/// \brief Decoder for LZMA_Alone files+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_ALONE_DECODER_H+#define LZMA_ALONE_DECODER_H++#include "common.h"+++extern lzma_ret lzma_alone_decoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ uint64_t memlimit, bool picky);++#endif
+ cbits/liblzma/common/alone_encoder.c view
@@ -0,0 +1,162 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file alone_encoder.c+/// \brief Encoder for LZMA_Alone files+//+// 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 "lzma_encoder.h"+++#define ALONE_HEADER_SIZE (1 + 4 + 8)+++typedef struct {+ lzma_next_coder next;++ enum {+ SEQ_HEADER,+ SEQ_CODE,+ } sequence;++ size_t header_pos;+ uint8_t header[ALONE_HEADER_SIZE];+} lzma_alone_coder;+++static lzma_ret+alone_encode(void *coder_ptr, const 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_alone_coder *coder = coder_ptr;++ while (*out_pos < out_size)+ switch (coder->sequence) {+ case SEQ_HEADER:+ lzma_bufcpy(coder->header, &coder->header_pos,+ ALONE_HEADER_SIZE,+ out, out_pos, out_size);+ if (coder->header_pos < ALONE_HEADER_SIZE)+ return LZMA_OK;++ coder->sequence = SEQ_CODE;+ break;++ case SEQ_CODE:+ return coder->next.code(coder->next.coder,+ allocator, in, in_pos, in_size,+ out, out_pos, out_size, action);++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++ return LZMA_OK;+}+++static void+alone_encoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_alone_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder, allocator);+ return;+}+++// At least for now, this is not used by any internal function.+static lzma_ret+alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_options_lzma *options)+{+ lzma_next_coder_init(&alone_encoder_init, next, allocator);++ lzma_alone_coder *coder = next->coder;++ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &alone_encode;+ next->end = &alone_encoder_end;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ // Basic initializations+ coder->sequence = SEQ_HEADER;+ coder->header_pos = 0;++ // Encode the header:+ // - Properties (1 byte)+ if (lzma_lzma_lclppb_encode(options, coder->header))+ return LZMA_OPTIONS_ERROR;++ // - Dictionary size (4 bytes)+ if (options->dict_size < LZMA_DICT_SIZE_MIN)+ return LZMA_OPTIONS_ERROR;++ // Round up to the next 2^n or 2^n + 2^(n - 1) depending on which+ // one is the next unless it is UINT32_MAX. While the header would+ // allow any 32-bit integer, we do this to keep the decoder of liblzma+ // accepting the resulting files.+ uint32_t d = options->dict_size - 1;+ d |= d >> 2;+ d |= d >> 3;+ d |= d >> 4;+ d |= d >> 8;+ d |= d >> 16;+ if (d != UINT32_MAX)+ ++d;++ write32le(coder->header + 1, d);++ // - Uncompressed size (always unknown and using EOPM)+ memset(coder->header + 1 + 4, 0xFF, 8);++ // Initialize the LZMA encoder.+ const lzma_filter_info filters[2] = {+ {+ .init = &lzma_lzma_encoder_init,+ .options = (void *)(options),+ }, {+ .init = NULL,+ }+ };++ return lzma_next_filter_init(&coder->next, allocator, filters);+}+++/*+extern lzma_ret+lzma_alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_options_alone *options)+{+ lzma_next_coder_init(&alone_encoder_init, next, allocator, options);+}+*/+++extern LZMA_API(lzma_ret)+lzma_alone_encoder(lzma_stream *strm, const lzma_options_lzma *options)+{+ lzma_next_strm_init(alone_encoder_init, strm, options);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/auto_decoder.c view
@@ -0,0 +1,195 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file auto_decoder.c+/// \brief Autodetect between .xz Stream and .lzma (LZMA_Alone) formats+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "stream_decoder.h"+#include "alone_decoder.h"+++typedef struct {+ /// Stream decoder or LZMA_Alone decoder+ lzma_next_coder next;++ uint64_t memlimit;+ uint32_t flags;++ enum {+ SEQ_INIT,+ SEQ_CODE,+ SEQ_FINISH,+ } sequence;+} lzma_auto_coder;+++static lzma_ret+auto_decode(void *coder_ptr, const 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_auto_coder *coder = coder_ptr;++ switch (coder->sequence) {+ case SEQ_INIT:+ if (*in_pos >= in_size)+ return LZMA_OK;++ // Update the sequence now, because we want to continue from+ // SEQ_CODE even if we return some LZMA_*_CHECK.+ coder->sequence = SEQ_CODE;++ // Detect the file format. For now this is simple, since if+ // it doesn't start with 0xFD (the first magic byte of the+ // new format), it has to be LZMA_Alone, or something that+ // we don't support at all.+ if (in[*in_pos] == 0xFD) {+ return_if_error(lzma_stream_decoder_init(+ &coder->next, allocator,+ coder->memlimit, coder->flags));+ } else {+ return_if_error(lzma_alone_decoder_init(&coder->next,+ allocator, coder->memlimit, true));++ // If the application wants to know about missing+ // integrity check or about the check in general, we+ // need to handle it here, because LZMA_Alone decoder+ // doesn't accept any flags.+ if (coder->flags & LZMA_TELL_NO_CHECK)+ return LZMA_NO_CHECK;++ if (coder->flags & LZMA_TELL_ANY_CHECK)+ return LZMA_GET_CHECK;+ }++ // Fall through++ case SEQ_CODE: {+ const lzma_ret ret = coder->next.code(+ coder->next.coder, allocator,+ in, in_pos, in_size,+ out, out_pos, out_size, action);+ if (ret != LZMA_STREAM_END+ || (coder->flags & LZMA_CONCATENATED) == 0)+ return ret;++ coder->sequence = SEQ_FINISH;+ }++ // Fall through++ case SEQ_FINISH:+ // When LZMA_DECODE_CONCATENATED was used and we were decoding+ // LZMA_Alone file, we need to check check that there is no+ // trailing garbage and wait for LZMA_FINISH.+ if (*in_pos < in_size)+ return LZMA_DATA_ERROR;++ return action == LZMA_FINISH ? LZMA_STREAM_END : LZMA_OK;++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }+}+++static void+auto_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_auto_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_check+auto_decoder_get_check(const void *coder_ptr)+{+ const lzma_auto_coder *coder = coder_ptr;++ // It is LZMA_Alone if get_check is NULL.+ return coder->next.get_check == NULL ? LZMA_CHECK_NONE+ : coder->next.get_check(coder->next.coder);+}+++static lzma_ret+auto_decoder_memconfig(void *coder_ptr, uint64_t *memusage,+ uint64_t *old_memlimit, uint64_t new_memlimit)+{+ lzma_auto_coder *coder = coder_ptr;++ lzma_ret ret;++ if (coder->next.memconfig != NULL) {+ ret = coder->next.memconfig(coder->next.coder,+ memusage, old_memlimit, new_memlimit);+ assert(*old_memlimit == coder->memlimit);+ } else {+ // No coder is configured yet. Use the base value as+ // the current memory usage.+ *memusage = LZMA_MEMUSAGE_BASE;+ *old_memlimit = coder->memlimit;++ ret = LZMA_OK;+ if (new_memlimit != 0 && new_memlimit < *memusage)+ ret = LZMA_MEMLIMIT_ERROR;+ }++ if (ret == LZMA_OK && new_memlimit != 0)+ coder->memlimit = new_memlimit;++ return ret;+}+++static lzma_ret+auto_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ uint64_t memlimit, uint32_t flags)+{+ lzma_next_coder_init(&auto_decoder_init, next, allocator);++ if (flags & ~LZMA_SUPPORTED_FLAGS)+ return LZMA_OPTIONS_ERROR;++ lzma_auto_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_auto_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &auto_decode;+ next->end = &auto_decoder_end;+ next->get_check = &auto_decoder_get_check;+ next->memconfig = &auto_decoder_memconfig;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ coder->memlimit = my_max(1, memlimit);+ coder->flags = flags;+ coder->sequence = SEQ_INIT;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_auto_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags)+{+ lzma_next_strm_init(auto_decoder_init, strm, memlimit, flags);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/block_buffer_decoder.c view
@@ -0,0 +1,80 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_buffer_decoder.c+/// \brief Single-call .xz Block decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "block_decoder.h"+++extern LZMA_API(lzma_ret)+lzma_block_buffer_decode(lzma_block *block, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ if (in_pos == NULL || (in == NULL && *in_pos != in_size)+ || *in_pos > in_size || out_pos == NULL+ || (out == NULL && *out_pos != out_size)+ || *out_pos > out_size)+ return LZMA_PROG_ERROR;++ // Initialize the Block decoder.+ lzma_next_coder block_decoder = LZMA_NEXT_CODER_INIT;+ lzma_ret ret = lzma_block_decoder_init(+ &block_decoder, allocator, block);++ if (ret == LZMA_OK) {+ // Save the positions so that we can restore them in case+ // an error occurs.+ const size_t in_start = *in_pos;+ const size_t out_start = *out_pos;++ // Do the actual decoding.+ ret = block_decoder.code(block_decoder.coder, allocator,+ in, in_pos, in_size, out, out_pos, out_size,+ LZMA_FINISH);++ if (ret == LZMA_STREAM_END) {+ ret = LZMA_OK;+ } else {+ if (ret == LZMA_OK) {+ // Either the input was truncated or the+ // output buffer was too small.+ assert(*in_pos == in_size+ || *out_pos == out_size);++ // If all the input was consumed, then the+ // input is truncated, even if the output+ // buffer is also full. This is because+ // processing the last byte of the Block+ // never produces output.+ //+ // NOTE: This assumption may break when new+ // filters are added, if the end marker of+ // the filter doesn't consume at least one+ // complete byte.+ if (*in_pos == in_size)+ ret = LZMA_DATA_ERROR;+ else+ ret = LZMA_BUF_ERROR;+ }++ // Restore the positions.+ *in_pos = in_start;+ *out_pos = out_start;+ }+ }++ // Free the decoder memory. This needs to be done even if+ // initialization fails, because the internal API doesn't+ // require the initialization function to free its memory on error.+ lzma_next_end(&block_decoder, allocator);++ return ret;+}
+ cbits/liblzma/common/block_buffer_encoder.c view
@@ -0,0 +1,337 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_buffer_encoder.c+/// \brief Single-call .xz Block encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "block_buffer_encoder.h"+#include "block_encoder.h"+#include "filter_encoder.h"+#include "lzma2_encoder.h"+#include "check.h"+++/// Estimate the maximum size of the Block Header and Check fields for+/// a Block that uses LZMA2 uncompressed chunks. We could use+/// lzma_block_header_size() but this is simpler.+///+/// Block Header Size + Block Flags + Compressed Size+/// + Uncompressed Size + Filter Flags for LZMA2 + CRC32 + Check+/// and round up to the next multiple of four to take Header Padding+/// into account.+#define HEADERS_BOUND ((1 + 1 + 2 * LZMA_VLI_BYTES_MAX + 3 + 4 \+ + LZMA_CHECK_SIZE_MAX + 3) & ~3)+++static uint64_t+lzma2_bound(uint64_t uncompressed_size)+{+ // Prevent integer overflow in overhead calculation.+ if (uncompressed_size > COMPRESSED_SIZE_MAX)+ return 0;++ // Calculate the exact overhead of the LZMA2 headers: Round+ // uncompressed_size up to the next multiple of LZMA2_CHUNK_MAX,+ // multiply by the size of per-chunk header, and add one byte for+ // the end marker.+ const uint64_t overhead = ((uncompressed_size + LZMA2_CHUNK_MAX - 1)+ / LZMA2_CHUNK_MAX)+ * LZMA2_HEADER_UNCOMPRESSED + 1;++ // Catch the possible integer overflow.+ if (COMPRESSED_SIZE_MAX - overhead < uncompressed_size)+ return 0;++ return uncompressed_size + overhead;+}+++extern uint64_t+lzma_block_buffer_bound64(uint64_t uncompressed_size)+{+ // If the data doesn't compress, we always use uncompressed+ // LZMA2 chunks.+ uint64_t lzma2_size = lzma2_bound(uncompressed_size);+ if (lzma2_size == 0)+ return 0;++ // Take Block Padding into account.+ lzma2_size = (lzma2_size + 3) & ~UINT64_C(3);++ // No risk of integer overflow because lzma2_bound() already takes+ // into account the size of the headers in the Block.+ return HEADERS_BOUND + lzma2_size;+}+++extern LZMA_API(size_t)+lzma_block_buffer_bound(size_t uncompressed_size)+{+ uint64_t ret = lzma_block_buffer_bound64(uncompressed_size);++#if SIZE_MAX < UINT64_MAX+ // Catch the possible integer overflow on 32-bit systems.+ if (ret > SIZE_MAX)+ return 0;+#endif++ return ret;+}+++static lzma_ret+block_encode_uncompressed(lzma_block *block, const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Use LZMA2 uncompressed chunks. We wouldn't need a dictionary at+ // all, but LZMA2 always requires a dictionary, so use the minimum+ // value to minimize memory usage of the decoder.+ lzma_options_lzma lzma2 = {+ .dict_size = LZMA_DICT_SIZE_MIN,+ };++ lzma_filter filters[2];+ filters[0].id = LZMA_FILTER_LZMA2;+ filters[0].options = &lzma2;+ filters[1].id = LZMA_VLI_UNKNOWN;++ // Set the above filter options to *block temporarily so that we can+ // encode the Block Header.+ lzma_filter *filters_orig = block->filters;+ block->filters = filters;++ if (lzma_block_header_size(block) != LZMA_OK) {+ block->filters = filters_orig;+ return LZMA_PROG_ERROR;+ }++ // Check that there's enough output space. The caller has already+ // set block->compressed_size to what lzma2_bound() has returned,+ // so we can reuse that value. We know that compressed_size is a+ // known valid VLI and header_size is a small value so their sum+ // will never overflow.+ assert(block->compressed_size == lzma2_bound(in_size));+ if (out_size - *out_pos+ < block->header_size + block->compressed_size) {+ block->filters = filters_orig;+ return LZMA_BUF_ERROR;+ }++ if (lzma_block_header_encode(block, out + *out_pos) != LZMA_OK) {+ block->filters = filters_orig;+ return LZMA_PROG_ERROR;+ }++ block->filters = filters_orig;+ *out_pos += block->header_size;++ // Encode the data using LZMA2 uncompressed chunks.+ size_t in_pos = 0;+ uint8_t control = 0x01; // Dictionary reset++ while (in_pos < in_size) {+ // Control byte: Indicate uncompressed chunk, of which+ // the first resets the dictionary.+ out[(*out_pos)++] = control;+ control = 0x02; // No dictionary reset++ // Size of the uncompressed chunk+ const size_t copy_size+ = my_min(in_size - in_pos, LZMA2_CHUNK_MAX);+ out[(*out_pos)++] = (copy_size - 1) >> 8;+ out[(*out_pos)++] = (copy_size - 1) & 0xFF;++ // The actual data+ assert(*out_pos + copy_size <= out_size);+ memcpy(out + *out_pos, in + in_pos, copy_size);++ in_pos += copy_size;+ *out_pos += copy_size;+ }++ // End marker+ out[(*out_pos)++] = 0x00;+ assert(*out_pos <= out_size);++ return LZMA_OK;+}+++static lzma_ret+block_encode_normal(lzma_block *block, const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Find out the size of the Block Header.+ return_if_error(lzma_block_header_size(block));++ // Reserve space for the Block Header and skip it for now.+ if (out_size - *out_pos <= block->header_size)+ return LZMA_BUF_ERROR;++ const size_t out_start = *out_pos;+ *out_pos += block->header_size;++ // Limit out_size so that we stop encoding if the output would grow+ // bigger than what uncompressed Block would be.+ if (out_size - *out_pos > block->compressed_size)+ out_size = *out_pos + block->compressed_size;++ // TODO: In many common cases this could be optimized to use+ // significantly less memory.+ lzma_next_coder raw_encoder = LZMA_NEXT_CODER_INIT;+ lzma_ret ret = lzma_raw_encoder_init(+ &raw_encoder, allocator, block->filters);++ if (ret == LZMA_OK) {+ size_t in_pos = 0;+ ret = raw_encoder.code(raw_encoder.coder, allocator,+ in, &in_pos, in_size, out, out_pos, out_size,+ LZMA_FINISH);+ }++ // NOTE: This needs to be run even if lzma_raw_encoder_init() failed.+ lzma_next_end(&raw_encoder, allocator);++ if (ret == LZMA_STREAM_END) {+ // Compression was successful. Write the Block Header.+ block->compressed_size+ = *out_pos - (out_start + block->header_size);+ ret = lzma_block_header_encode(block, out + out_start);+ if (ret != LZMA_OK)+ ret = LZMA_PROG_ERROR;++ } else if (ret == LZMA_OK) {+ // Output buffer became full.+ ret = LZMA_BUF_ERROR;+ }++ // Reset *out_pos if something went wrong.+ if (ret != LZMA_OK)+ *out_pos = out_start;++ return ret;+}+++static lzma_ret+block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size,+ bool try_to_compress)+{+ // Validate the arguments.+ if (block == NULL || (in == NULL && in_size != 0) || out == NULL+ || out_pos == NULL || *out_pos > out_size)+ return LZMA_PROG_ERROR;++ // The contents of the structure may depend on the version so+ // check the version before validating the contents of *block.+ if (block->version > 1)+ return LZMA_OPTIONS_ERROR;++ if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX+ || (try_to_compress && block->filters == NULL))+ return LZMA_PROG_ERROR;++ if (!lzma_check_is_supported(block->check))+ return LZMA_UNSUPPORTED_CHECK;++ // Size of a Block has to be a multiple of four, so limit the size+ // here already. This way we don't need to check it again when adding+ // Block Padding.+ out_size -= (out_size - *out_pos) & 3;++ // Get the size of the Check field.+ const size_t check_size = lzma_check_size(block->check);+ assert(check_size != UINT32_MAX);++ // Reserve space for the Check field.+ if (out_size - *out_pos <= check_size)+ return LZMA_BUF_ERROR;++ out_size -= check_size;++ // Initialize block->uncompressed_size and calculate the worst-case+ // value for block->compressed_size.+ block->uncompressed_size = in_size;+ block->compressed_size = lzma2_bound(in_size);+ if (block->compressed_size == 0)+ return LZMA_DATA_ERROR;++ // Do the actual compression.+ lzma_ret ret = LZMA_BUF_ERROR;+ if (try_to_compress)+ ret = block_encode_normal(block, allocator,+ in, in_size, out, out_pos, out_size);++ if (ret != LZMA_OK) {+ // If the error was something else than output buffer+ // becoming full, return the error now.+ if (ret != LZMA_BUF_ERROR)+ return ret;++ // The data was uncompressible (at least with the options+ // given to us) or the output buffer was too small. Use the+ // uncompressed chunks of LZMA2 to wrap the data into a valid+ // Block. If we haven't been given enough output space, even+ // this may fail.+ return_if_error(block_encode_uncompressed(block, in, in_size,+ out, out_pos, out_size));+ }++ assert(*out_pos <= out_size);++ // Block Padding. No buffer overflow here, because we already adjusted+ // out_size so that (out_size - out_start) is a multiple of four.+ // Thus, if the buffer is full, the loop body can never run.+ for (size_t i = (size_t)(block->compressed_size); i & 3; ++i) {+ assert(*out_pos < out_size);+ out[(*out_pos)++] = 0x00;+ }++ // If there's no Check field, we are done now.+ if (check_size > 0) {+ // Calculate the integrity check. We reserved space for+ // the Check field earlier so we don't need to check for+ // available output space here.+ lzma_check_state check;+ lzma_check_init(&check, block->check);+ lzma_check_update(&check, block->check, in, in_size);+ lzma_check_finish(&check, block->check);++ memcpy(block->raw_check, check.buffer.u8, check_size);+ memcpy(out + *out_pos, check.buffer.u8, check_size);+ *out_pos += check_size;+ }++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_block_buffer_encode(lzma_block *block, const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ return block_buffer_encode(block, allocator,+ in, in_size, out, out_pos, out_size, true);+}+++extern LZMA_API(lzma_ret)+lzma_block_uncomp_encode(lzma_block *block,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // It won't allocate any memory from heap so no need+ // for lzma_allocator.+ return block_buffer_encode(block, NULL,+ in, in_size, out, out_pos, out_size, false);+}
+ cbits/liblzma/common/block_buffer_encoder.h view
@@ -0,0 +1,24 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_buffer_encoder.h+/// \brief Single-call .xz Block encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_BLOCK_BUFFER_ENCODER_H+#define LZMA_BLOCK_BUFFER_ENCODER_H++#include "common.h"+++/// uint64_t version of lzma_block_buffer_bound(). It is used by+/// stream_encoder_mt.c. Probably the original lzma_block_buffer_bound()+/// should have been 64-bit, but fixing it would break the ABI.+extern uint64_t lzma_block_buffer_bound64(uint64_t uncompressed_size);++#endif
+ cbits/liblzma/common/block_decoder.c view
@@ -0,0 +1,257 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_decoder.c+/// \brief Decodes .xz Blocks+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "block_decoder.h"+#include "filter_decoder.h"+#include "check.h"+++typedef struct {+ enum {+ SEQ_CODE,+ SEQ_PADDING,+ SEQ_CHECK,+ } sequence;++ /// The filters in the chain; initialized with lzma_raw_decoder_init().+ lzma_next_coder next;++ /// Decoding options; we also write Compressed Size and Uncompressed+ /// Size back to this structure when the decoding has been finished.+ lzma_block *block;++ /// Compressed Size calculated while decoding+ lzma_vli compressed_size;++ /// Uncompressed Size calculated while decoding+ lzma_vli uncompressed_size;++ /// Maximum allowed Compressed Size; this takes into account the+ /// size of the Block Header and Check fields when Compressed Size+ /// is unknown.+ lzma_vli compressed_limit;++ /// Position when reading the Check field+ size_t check_pos;++ /// Check of the uncompressed data+ lzma_check_state check;++ /// True if the integrity check won't be calculated and verified.+ bool ignore_check;+} lzma_block_coder;+++static inline bool+update_size(lzma_vli *size, lzma_vli add, lzma_vli limit)+{+ if (limit > LZMA_VLI_MAX)+ limit = LZMA_VLI_MAX;++ if (limit < *size || limit - *size < add)+ return true;++ *size += add;++ return false;+}+++static inline bool+is_size_valid(lzma_vli size, lzma_vli reference)+{+ return reference == LZMA_VLI_UNKNOWN || reference == size;+}+++static lzma_ret+block_decode(void *coder_ptr, const 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_block_coder *coder = coder_ptr;++ switch (coder->sequence) {+ case SEQ_CODE: {+ const size_t in_start = *in_pos;+ const size_t out_start = *out_pos;++ const lzma_ret ret = coder->next.code(coder->next.coder,+ allocator, in, in_pos, in_size,+ out, out_pos, out_size, action);++ const size_t in_used = *in_pos - in_start;+ const size_t out_used = *out_pos - out_start;++ // NOTE: We compare to compressed_limit here, which prevents+ // the total size of the Block growing past LZMA_VLI_MAX.+ if (update_size(&coder->compressed_size, in_used,+ coder->compressed_limit)+ || update_size(&coder->uncompressed_size,+ out_used,+ coder->block->uncompressed_size))+ return LZMA_DATA_ERROR;++ if (!coder->ignore_check)+ lzma_check_update(&coder->check, coder->block->check,+ out + out_start, out_used);++ if (ret != LZMA_STREAM_END)+ return ret;++ // Compressed and Uncompressed Sizes are now at their final+ // values. Verify that they match the values given to us.+ if (!is_size_valid(coder->compressed_size,+ coder->block->compressed_size)+ || !is_size_valid(coder->uncompressed_size,+ coder->block->uncompressed_size))+ return LZMA_DATA_ERROR;++ // Copy the values into coder->block. The caller+ // may use this information to construct Index.+ coder->block->compressed_size = coder->compressed_size;+ coder->block->uncompressed_size = coder->uncompressed_size;++ coder->sequence = SEQ_PADDING;+ }++ // Fall through++ case SEQ_PADDING:+ // Compressed Data is padded to a multiple of four bytes.+ while (coder->compressed_size & 3) {+ if (*in_pos >= in_size)+ return LZMA_OK;++ // We use compressed_size here just get the Padding+ // right. The actual Compressed Size was stored to+ // coder->block already, and won't be modified by+ // us anymore.+ ++coder->compressed_size;++ if (in[(*in_pos)++] != 0x00)+ return LZMA_DATA_ERROR;+ }++ if (coder->block->check == LZMA_CHECK_NONE)+ return LZMA_STREAM_END;++ if (!coder->ignore_check)+ lzma_check_finish(&coder->check, coder->block->check);++ coder->sequence = SEQ_CHECK;++ // Fall through++ case SEQ_CHECK: {+ const size_t check_size = lzma_check_size(coder->block->check);+ lzma_bufcpy(in, in_pos, in_size, coder->block->raw_check,+ &coder->check_pos, check_size);+ if (coder->check_pos < check_size)+ return LZMA_OK;++ // Validate the Check only if we support it.+ // coder->check.buffer may be uninitialized+ // when the Check ID is not supported.+ if (!coder->ignore_check+ && lzma_check_is_supported(coder->block->check)+ && memcmp(coder->block->raw_check,+ coder->check.buffer.u8,+ check_size) != 0)+ return LZMA_DATA_ERROR;++ return LZMA_STREAM_END;+ }+ }++ return LZMA_PROG_ERROR;+}+++static void+block_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_block_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder, allocator);+ return;+}+++extern lzma_ret+lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ lzma_block *block)+{+ lzma_next_coder_init(&lzma_block_decoder_init, next, allocator);++ // Validate the options. lzma_block_unpadded_size() does that for us+ // except for Uncompressed Size and filters. Filters are validated+ // by the raw decoder.+ if (lzma_block_unpadded_size(block) == 0+ || !lzma_vli_is_valid(block->uncompressed_size))+ return LZMA_PROG_ERROR;++ // Allocate *next->coder if needed.+ lzma_block_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_block_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &block_decode;+ next->end = &block_decoder_end;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ // Basic initializations+ coder->sequence = SEQ_CODE;+ coder->block = block;+ coder->compressed_size = 0;+ coder->uncompressed_size = 0;++ // If Compressed Size is not known, we calculate the maximum allowed+ // value so that encoded size of the Block (including Block Padding)+ // is still a valid VLI and a multiple of four.+ coder->compressed_limit+ = block->compressed_size == LZMA_VLI_UNKNOWN+ ? (LZMA_VLI_MAX & ~LZMA_VLI_C(3))+ - block->header_size+ - lzma_check_size(block->check)+ : block->compressed_size;++ // Initialize the check. It's caller's problem if the Check ID is not+ // supported, and the Block decoder cannot verify the Check field.+ // Caller can test lzma_check_is_supported(block->check).+ coder->check_pos = 0;+ lzma_check_init(&coder->check, block->check);++ coder->ignore_check = block->version >= 1+ ? block->ignore_check : false;++ // Initialize the filter chain.+ return lzma_raw_decoder_init(&coder->next, allocator,+ block->filters);+}+++extern LZMA_API(lzma_ret)+lzma_block_decoder(lzma_stream *strm, lzma_block *block)+{+ lzma_next_strm_init(lzma_block_decoder_init, strm, block);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/block_decoder.h view
@@ -0,0 +1,22 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_decoder.h+/// \brief Decodes .xz Blocks+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_BLOCK_DECODER_H+#define LZMA_BLOCK_DECODER_H++#include "common.h"+++extern lzma_ret lzma_block_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator, lzma_block *block);++#endif
+ cbits/liblzma/common/block_encoder.c view
@@ -0,0 +1,223 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_encoder.c+/// \brief Encodes .xz Blocks+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "block_encoder.h"+#include "filter_encoder.h"+#include "check.h"+++typedef struct {+ /// The filters in the chain; initialized with lzma_raw_decoder_init().+ lzma_next_coder next;++ /// Encoding options; we also write Unpadded Size, Compressed Size,+ /// and Uncompressed Size back to this structure when the encoding+ /// has been finished.+ lzma_block *block;++ enum {+ SEQ_CODE,+ SEQ_PADDING,+ SEQ_CHECK,+ } sequence;++ /// Compressed Size calculated while encoding+ lzma_vli compressed_size;++ /// Uncompressed Size calculated while encoding+ lzma_vli uncompressed_size;++ /// Position in the Check field+ size_t pos;++ /// Check of the uncompressed data+ lzma_check_state check;+} lzma_block_coder;+++static lzma_ret+block_encode(void *coder_ptr, const 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_block_coder *coder = coder_ptr;++ // Check that our amount of input stays in proper limits.+ if (LZMA_VLI_MAX - coder->uncompressed_size < in_size - *in_pos)+ return LZMA_DATA_ERROR;++ switch (coder->sequence) {+ case SEQ_CODE: {+ const size_t in_start = *in_pos;+ const size_t out_start = *out_pos;++ const lzma_ret ret = coder->next.code(coder->next.coder,+ allocator, in, in_pos, in_size,+ out, out_pos, out_size, action);++ const size_t in_used = *in_pos - in_start;+ const size_t out_used = *out_pos - out_start;++ if (COMPRESSED_SIZE_MAX - coder->compressed_size < out_used)+ return LZMA_DATA_ERROR;++ coder->compressed_size += out_used;++ // No need to check for overflow because we have already+ // checked it at the beginning of this function.+ coder->uncompressed_size += in_used;++ lzma_check_update(&coder->check, coder->block->check,+ in + in_start, in_used);++ if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)+ return ret;++ assert(*in_pos == in_size);+ assert(action == LZMA_FINISH);++ // Copy the values into coder->block. The caller+ // may use this information to construct Index.+ coder->block->compressed_size = coder->compressed_size;+ coder->block->uncompressed_size = coder->uncompressed_size;++ coder->sequence = SEQ_PADDING;+ }++ // Fall through++ case SEQ_PADDING:+ // Pad Compressed Data to a multiple of four bytes. We can+ // use coder->compressed_size for this since we don't need+ // it for anything else anymore.+ while (coder->compressed_size & 3) {+ if (*out_pos >= out_size)+ return LZMA_OK;++ out[*out_pos] = 0x00;+ ++*out_pos;+ ++coder->compressed_size;+ }++ if (coder->block->check == LZMA_CHECK_NONE)+ return LZMA_STREAM_END;++ lzma_check_finish(&coder->check, coder->block->check);++ coder->sequence = SEQ_CHECK;++ // Fall through++ case SEQ_CHECK: {+ const size_t check_size = lzma_check_size(coder->block->check);+ lzma_bufcpy(coder->check.buffer.u8, &coder->pos, check_size,+ out, out_pos, out_size);+ if (coder->pos < check_size)+ return LZMA_OK;++ memcpy(coder->block->raw_check, coder->check.buffer.u8,+ check_size);+ return LZMA_STREAM_END;+ }+ }++ return LZMA_PROG_ERROR;+}+++static void+block_encoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_block_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+block_encoder_update(void *coder_ptr, const lzma_allocator *allocator,+ const lzma_filter *filters lzma_attribute((__unused__)),+ const lzma_filter *reversed_filters)+{+ lzma_block_coder *coder = coder_ptr;++ if (coder->sequence != SEQ_CODE)+ return LZMA_PROG_ERROR;++ return lzma_next_filter_update(+ &coder->next, allocator, reversed_filters);+}+++extern lzma_ret+lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ lzma_block *block)+{+ lzma_next_coder_init(&lzma_block_encoder_init, next, allocator);++ if (block == NULL)+ return LZMA_PROG_ERROR;++ // The contents of the structure may depend on the version so+ // check the version first.+ if (block->version > 1)+ return LZMA_OPTIONS_ERROR;++ // If the Check ID is not supported, we cannot calculate the check and+ // thus not create a proper Block.+ if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX)+ return LZMA_PROG_ERROR;++ if (!lzma_check_is_supported(block->check))+ return LZMA_UNSUPPORTED_CHECK;++ // Allocate and initialize *next->coder if needed.+ lzma_block_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_block_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &block_encode;+ next->end = &block_encoder_end;+ next->update = &block_encoder_update;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ // Basic initializations+ coder->sequence = SEQ_CODE;+ coder->block = block;+ coder->compressed_size = 0;+ coder->uncompressed_size = 0;+ coder->pos = 0;++ // Initialize the check+ lzma_check_init(&coder->check, block->check);++ // Initialize the requested filters.+ return lzma_raw_encoder_init(&coder->next, allocator, block->filters);+}+++extern LZMA_API(lzma_ret)+lzma_block_encoder(lzma_stream *strm, lzma_block *block)+{+ lzma_next_strm_init(lzma_block_encoder_init, strm, block);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/block_encoder.h view
@@ -0,0 +1,47 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_encoder.h+/// \brief Encodes .xz Blocks+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_BLOCK_ENCODER_H+#define LZMA_BLOCK_ENCODER_H++#include "common.h"+++/// \brief Biggest Compressed Size value that the Block encoder supports+///+/// The maximum size of a single Block is limited by the maximum size of+/// a Stream, which in theory is 2^63 - 3 bytes (i.e. LZMA_VLI_MAX - 3).+/// While the size is really big and no one should hit it in practice, we+/// take it into account in some places anyway to catch some errors e.g. if+/// application passes insanely big value to some function.+///+/// We could take into account the headers etc. to determine the exact+/// maximum size of the Compressed Data field, but the complexity would give+/// us nothing useful. Instead, limit the size of Compressed Data so that+/// even with biggest possible Block Header and Check fields the total+/// encoded size of the Block stays as a valid VLI. This doesn't guarantee+/// that the size of the Stream doesn't grow too big, but that problem is+/// taken care outside the Block handling code.+///+/// ~LZMA_VLI_C(3) is to guarantee that if we need padding at the end of+/// the Compressed Data field, it will still stay in the proper limit.+///+/// This constant is in this file because it is needed in both+/// block_encoder.c and block_buffer_encoder.c.+#define COMPRESSED_SIZE_MAX ((LZMA_VLI_MAX - LZMA_BLOCK_HEADER_SIZE_MAX \+ - LZMA_CHECK_SIZE_MAX) & ~LZMA_VLI_C(3))+++extern lzma_ret lzma_block_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator, lzma_block *block);++#endif
+ cbits/liblzma/common/block_header_decoder.c view
@@ -0,0 +1,124 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_header_decoder.c+/// \brief Decodes Block Header from .xz files+//+// 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 "check.h"+++static void+free_properties(lzma_block *block, const lzma_allocator *allocator)+{+ // Free allocated filter options. The last array member is not+ // touched after the initialization in the beginning of+ // lzma_block_header_decode(), so we don't need to touch that here.+ for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i) {+ lzma_free(block->filters[i].options, allocator);+ block->filters[i].id = LZMA_VLI_UNKNOWN;+ block->filters[i].options = NULL;+ }++ return;+}+++extern LZMA_API(lzma_ret)+lzma_block_header_decode(lzma_block *block,+ const lzma_allocator *allocator, const uint8_t *in)+{+ // NOTE: We consider the header to be corrupt not only when the+ // CRC32 doesn't match, but also when variable-length integers+ // are invalid or over 63 bits, or if the header is too small+ // to contain the claimed information.++ // Initialize the filter options array. This way the caller can+ // safely free() the options even if an error occurs in this function.+ for (size_t i = 0; i <= LZMA_FILTERS_MAX; ++i) {+ block->filters[i].id = LZMA_VLI_UNKNOWN;+ block->filters[i].options = NULL;+ }++ // 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.+ if (lzma_block_header_size_decode(in[0]) != block->header_size+ || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)+ return LZMA_PROG_ERROR;++ // Exclude the CRC32 field.+ const size_t in_size = block->header_size - 4;++ // Verify CRC32+ if (lzma_crc32(in, in_size, 0) != read32le(in + in_size))+ return LZMA_DATA_ERROR;++ // Check for unsupported flags.+ if (in[1] & 0x3C)+ return LZMA_OPTIONS_ERROR;++ // Start after the Block Header Size and Block Flags fields.+ size_t in_pos = 2;++ // Compressed Size+ if (in[1] & 0x40) {+ return_if_error(lzma_vli_decode(&block->compressed_size,+ NULL, in, &in_pos, in_size));++ // Validate Compressed Size. This checks that it isn't zero+ // and that the total size of the Block is a valid VLI.+ if (lzma_block_unpadded_size(block) == 0)+ return LZMA_DATA_ERROR;+ } else {+ block->compressed_size = LZMA_VLI_UNKNOWN;+ }++ // Uncompressed Size+ if (in[1] & 0x80)+ return_if_error(lzma_vli_decode(&block->uncompressed_size,+ NULL, in, &in_pos, in_size));+ else+ block->uncompressed_size = LZMA_VLI_UNKNOWN;++ // Filter Flags+ const size_t filter_count = (in[1] & 3U) + 1;+ for (size_t i = 0; i < filter_count; ++i) {+ const lzma_ret ret = lzma_filter_flags_decode(+ &block->filters[i], allocator,+ in, &in_pos, in_size);+ if (ret != LZMA_OK) {+ free_properties(block, allocator);+ return ret;+ }+ }++ // Padding+ while (in_pos < in_size) {+ if (in[in_pos++] != 0x00) {+ free_properties(block, allocator);++ // Possibly some new field present so use+ // LZMA_OPTIONS_ERROR instead of LZMA_DATA_ERROR.+ return LZMA_OPTIONS_ERROR;+ }+ }++ return LZMA_OK;+}
+ cbits/liblzma/common/block_header_encoder.c view
@@ -0,0 +1,132 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_header_encoder.c+/// \brief Encodes Block Header for .xz files+//+// 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 "check.h"+++extern LZMA_API(lzma_ret)+lzma_block_header_size(lzma_block *block)+{+ if (block->version > 1)+ return LZMA_OPTIONS_ERROR;++ // Block Header Size + Block Flags + CRC32.+ uint32_t size = 1 + 1 + 4;++ // Compressed Size+ if (block->compressed_size != LZMA_VLI_UNKNOWN) {+ const uint32_t add = lzma_vli_size(block->compressed_size);+ if (add == 0 || block->compressed_size == 0)+ return LZMA_PROG_ERROR;++ size += add;+ }++ // Uncompressed Size+ if (block->uncompressed_size != LZMA_VLI_UNKNOWN) {+ const uint32_t add = lzma_vli_size(block->uncompressed_size);+ if (add == 0)+ return LZMA_PROG_ERROR;++ size += add;+ }++ // List of Filter Flags+ if (block->filters == NULL || block->filters[0].id == LZMA_VLI_UNKNOWN)+ return LZMA_PROG_ERROR;++ for (size_t i = 0; block->filters[i].id != LZMA_VLI_UNKNOWN; ++i) {+ // Don't allow too many filters.+ if (i == LZMA_FILTERS_MAX)+ return LZMA_PROG_ERROR;++ uint32_t add;+ return_if_error(lzma_filter_flags_size(&add,+ block->filters + i));++ size += add;+ }++ // Pad to a multiple of four bytes.+ block->header_size = (size + 3) & ~UINT32_C(3);++ // NOTE: We don't verify that the encoded size of the Block stays+ // within limits. This is because it is possible that we are called+ // with exaggerated Compressed Size (e.g. LZMA_VLI_MAX) to reserve+ // space for Block Header, and later called again with lower,+ // real values.++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_block_header_encode(const lzma_block *block, uint8_t *out)+{+ // Validate everything but filters.+ if (lzma_block_unpadded_size(block) == 0+ || !lzma_vli_is_valid(block->uncompressed_size))+ return LZMA_PROG_ERROR;++ // Indicate the size of the buffer _excluding_ the CRC32 field.+ const size_t out_size = block->header_size - 4;++ // Store the Block Header Size.+ out[0] = out_size / 4;++ // We write Block Flags in pieces.+ out[1] = 0x00;+ size_t out_pos = 2;++ // Compressed Size+ if (block->compressed_size != LZMA_VLI_UNKNOWN) {+ return_if_error(lzma_vli_encode(block->compressed_size, NULL,+ out, &out_pos, out_size));++ out[1] |= 0x40;+ }++ // Uncompressed Size+ if (block->uncompressed_size != LZMA_VLI_UNKNOWN) {+ return_if_error(lzma_vli_encode(block->uncompressed_size, NULL,+ out, &out_pos, out_size));++ out[1] |= 0x80;+ }++ // Filter Flags+ if (block->filters == NULL || block->filters[0].id == LZMA_VLI_UNKNOWN)+ return LZMA_PROG_ERROR;++ size_t filter_count = 0;+ do {+ // There can be a maximum of four filters.+ if (filter_count == LZMA_FILTERS_MAX)+ return LZMA_PROG_ERROR;++ return_if_error(lzma_filter_flags_encode(+ block->filters + filter_count,+ out, &out_pos, out_size));++ } while (block->filters[++filter_count].id != LZMA_VLI_UNKNOWN);++ out[1] |= filter_count - 1;++ // Padding+ memzero(out + out_pos, out_size - out_pos);++ // CRC32+ write32le(out + out_size, lzma_crc32(out, out_size, 0));++ return LZMA_OK;+}
+ cbits/liblzma/common/block_util.c view
@@ -0,0 +1,90 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file block_util.c+/// \brief Utility functions to handle lzma_block+//+// 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 "index.h"+++extern LZMA_API(lzma_ret)+lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size)+{+ // Validate everything but Uncompressed Size and filters.+ if (lzma_block_unpadded_size(block) == 0)+ return LZMA_PROG_ERROR;++ const uint32_t container_size = block->header_size+ + lzma_check_size(block->check);++ // Validate that Compressed Size will be greater than zero.+ if (unpadded_size <= container_size)+ return LZMA_DATA_ERROR;++ // Calculate what Compressed Size is supposed to be.+ // If Compressed Size was present in Block Header,+ // compare that the new value matches it.+ const lzma_vli compressed_size = unpadded_size - container_size;+ if (block->compressed_size != LZMA_VLI_UNKNOWN+ && block->compressed_size != compressed_size)+ return LZMA_DATA_ERROR;++ block->compressed_size = compressed_size;++ return LZMA_OK;+}+++extern LZMA_API(lzma_vli)+lzma_block_unpadded_size(const lzma_block *block)+{+ // Validate the values that we are interested in i.e. all but+ // Uncompressed Size and the filters.+ //+ // 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 > 1+ || block->header_size < LZMA_BLOCK_HEADER_SIZE_MIN+ || block->header_size > LZMA_BLOCK_HEADER_SIZE_MAX+ || (block->header_size & 3)+ || !lzma_vli_is_valid(block->compressed_size)+ || block->compressed_size == 0+ || (unsigned int)(block->check) > LZMA_CHECK_ID_MAX)+ return 0;++ // If Compressed Size is unknown, return that we cannot know+ // size of the Block either.+ if (block->compressed_size == LZMA_VLI_UNKNOWN)+ return LZMA_VLI_UNKNOWN;++ // Calculate Unpadded Size and validate it.+ const lzma_vli unpadded_size = block->compressed_size+ + block->header_size+ + lzma_check_size(block->check);++ assert(unpadded_size >= UNPADDED_SIZE_MIN);+ if (unpadded_size > UNPADDED_SIZE_MAX)+ return 0;++ return unpadded_size;+}+++extern LZMA_API(lzma_vli)+lzma_block_total_size(const lzma_block *block)+{+ lzma_vli unpadded_size = lzma_block_unpadded_size(block);++ if (unpadded_size != LZMA_VLI_UNKNOWN)+ unpadded_size = vli_ceil4(unpadded_size);++ return unpadded_size;+}
+ cbits/liblzma/common/common.c view
@@ -0,0 +1,449 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file common.c+/// \brief Common functions needed in many places in liblzma+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++/////////////+// Version //+/////////////++extern LZMA_API(uint32_t)+lzma_version_number(void)+{+ return LZMA_VERSION;+}+++extern LZMA_API(const char *)+lzma_version_string(void)+{+ return LZMA_VERSION_STRING;+}+++///////////////////////+// Memory allocation //+///////////////////////++extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)+lzma_alloc(size_t size, const lzma_allocator *allocator)+{+ // Some malloc() 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);+ else+ ptr = malloc(size);++ return ptr;+}+++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)+{+ if (allocator != NULL && allocator->free != NULL)+ allocator->free(allocator->opaque, ptr);+ else+ free(ptr);++ return;+}+++//////////+// Misc //+//////////++extern size_t+lzma_bufcpy(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)+{+ const size_t in_avail = in_size - *in_pos;+ const size_t out_avail = out_size - *out_pos;+ const size_t copy_size = my_min(in_avail, out_avail);++ // Call memcpy() only if there is something to copy. If there is+ // nothing to copy, in or out might be NULL and then the memcpy()+ // call would trigger undefined behavior.+ if (copy_size > 0)+ memcpy(out + *out_pos, in + *in_pos, copy_size);++ *in_pos += copy_size;+ *out_pos += copy_size;++ return copy_size;+}+++extern lzma_ret+lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ lzma_next_coder_init(filters[0].init, next, allocator);+ next->id = filters[0].id;+ return filters[0].init == NULL+ ? LZMA_OK : filters[0].init(next, allocator, filters);+}+++extern lzma_ret+lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *reversed_filters)+{+ // Check that the application isn't trying to change the Filter ID.+ // End of filters is indicated with LZMA_VLI_UNKNOWN in both+ // reversed_filters[0].id and next->id.+ if (reversed_filters[0].id != next->id)+ return LZMA_PROG_ERROR;++ if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)+ return LZMA_OK;++ assert(next->update != NULL);+ return next->update(next->coder, allocator, NULL, reversed_filters);+}+++extern void+lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)+{+ if (next->init != (uintptr_t)(NULL)) {+ // To avoid tiny end functions that simply call+ // lzma_free(coder, allocator), we allow leaving next->end+ // NULL and call lzma_free() here.+ if (next->end != NULL)+ next->end(next->coder, allocator);+ else+ lzma_free(next->coder, allocator);++ // Reset the variables so the we don't accidentally think+ // that it is an already initialized coder.+ *next = LZMA_NEXT_CODER_INIT;+ }++ return;+}+++//////////////////////////////////////+// External to internal API wrapper //+//////////////////////////////////////++extern lzma_ret+lzma_strm_init(lzma_stream *strm)+{+ if (strm == NULL)+ return LZMA_PROG_ERROR;++ if (strm->internal == NULL) {+ strm->internal = lzma_alloc(sizeof(lzma_internal),+ strm->allocator);+ if (strm->internal == NULL)+ return LZMA_MEM_ERROR;++ strm->internal->next = LZMA_NEXT_CODER_INIT;+ }++ memzero(strm->internal->supported_actions,+ sizeof(strm->internal->supported_actions));+ strm->internal->sequence = ISEQ_RUN;+ strm->internal->allow_buf_error = false;++ strm->total_in = 0;+ strm->total_out = 0;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_code(lzma_stream *strm, lzma_action action)+{+ // Sanity checks+ if ((strm->next_in == NULL && strm->avail_in != 0)+ || (strm->next_out == NULL && strm->avail_out != 0)+ || strm->internal == NULL+ || strm->internal->next.code == NULL+ || (unsigned int)(action) > LZMA_ACTION_MAX+ || !strm->internal->supported_actions[action])+ return LZMA_PROG_ERROR;++ // Check if unsupported members have been set to non-zero or non-NULL,+ // which would indicate that some new feature is wanted.+ if (strm->reserved_ptr1 != NULL+ || strm->reserved_ptr2 != NULL+ || strm->reserved_ptr3 != NULL+ || strm->reserved_ptr4 != NULL+ || strm->reserved_int1 != 0+ || strm->reserved_int2 != 0+ || strm->reserved_int3 != 0+ || strm->reserved_int4 != 0+ || strm->reserved_enum1 != LZMA_RESERVED_ENUM+ || strm->reserved_enum2 != LZMA_RESERVED_ENUM)+ return LZMA_OPTIONS_ERROR;++ switch (strm->internal->sequence) {+ case ISEQ_RUN:+ switch (action) {+ case LZMA_RUN:+ break;++ case LZMA_SYNC_FLUSH:+ strm->internal->sequence = ISEQ_SYNC_FLUSH;+ break;++ case LZMA_FULL_FLUSH:+ strm->internal->sequence = ISEQ_FULL_FLUSH;+ break;++ case LZMA_FINISH:+ strm->internal->sequence = ISEQ_FINISH;+ break;++ case LZMA_FULL_BARRIER:+ strm->internal->sequence = ISEQ_FULL_BARRIER;+ break;+ }++ break;++ case ISEQ_SYNC_FLUSH:+ // The same action must be used until we return+ // LZMA_STREAM_END, and the amount of input must not change.+ if (action != LZMA_SYNC_FLUSH+ || strm->internal->avail_in != strm->avail_in)+ return LZMA_PROG_ERROR;++ break;++ case ISEQ_FULL_FLUSH:+ if (action != LZMA_FULL_FLUSH+ || strm->internal->avail_in != strm->avail_in)+ return LZMA_PROG_ERROR;++ break;++ case ISEQ_FINISH:+ if (action != LZMA_FINISH+ || strm->internal->avail_in != strm->avail_in)+ return LZMA_PROG_ERROR;++ break;++ case ISEQ_FULL_BARRIER:+ if (action != LZMA_FULL_BARRIER+ || strm->internal->avail_in != strm->avail_in)+ return LZMA_PROG_ERROR;++ break;++ case ISEQ_END:+ return LZMA_STREAM_END;++ case ISEQ_ERROR:+ default:+ return LZMA_PROG_ERROR;+ }++ size_t in_pos = 0;+ size_t out_pos = 0;+ lzma_ret ret = strm->internal->next.code(+ strm->internal->next.coder, strm->allocator,+ strm->next_in, &in_pos, strm->avail_in,+ strm->next_out, &out_pos, strm->avail_out, action);++ strm->next_in += in_pos;+ strm->avail_in -= in_pos;+ strm->total_in += in_pos;++ strm->next_out += out_pos;+ strm->avail_out -= out_pos;+ strm->total_out += out_pos;++ strm->internal->avail_in = strm->avail_in;++ // Cast is needed to silence a warning about LZMA_TIMED_OUT, which+ // isn't part of lzma_ret enumeration.+ switch ((unsigned int)(ret)) {+ case LZMA_OK:+ // Don't return LZMA_BUF_ERROR when it happens the first time.+ // This is to avoid returning LZMA_BUF_ERROR when avail_out+ // was zero but still there was no more data left to written+ // to next_out.+ if (out_pos == 0 && in_pos == 0) {+ if (strm->internal->allow_buf_error)+ ret = LZMA_BUF_ERROR;+ else+ strm->internal->allow_buf_error = true;+ } else {+ strm->internal->allow_buf_error = false;+ }+ break;++ case LZMA_TIMED_OUT:+ strm->internal->allow_buf_error = false;+ ret = LZMA_OK;+ break;++ case LZMA_STREAM_END:+ if (strm->internal->sequence == ISEQ_SYNC_FLUSH+ || strm->internal->sequence == ISEQ_FULL_FLUSH+ || strm->internal->sequence+ == ISEQ_FULL_BARRIER)+ strm->internal->sequence = ISEQ_RUN;+ else+ strm->internal->sequence = ISEQ_END;++ // Fall through++ case LZMA_NO_CHECK:+ case LZMA_UNSUPPORTED_CHECK:+ case LZMA_GET_CHECK:+ case LZMA_MEMLIMIT_ERROR:+ // Something else than LZMA_OK, but not a fatal error,+ // that is, coding may be continued (except if ISEQ_END).+ strm->internal->allow_buf_error = false;+ break;++ default:+ // All the other errors are fatal; coding cannot be continued.+ assert(ret != LZMA_BUF_ERROR);+ strm->internal->sequence = ISEQ_ERROR;+ break;+ }++ return ret;+}+++extern LZMA_API(void)+lzma_end(lzma_stream *strm)+{+ if (strm != NULL && strm->internal != NULL) {+ lzma_next_end(&strm->internal->next, strm->allocator);+ lzma_free(strm->internal, strm->allocator);+ strm->internal = NULL;+ }++ return;+}+++extern LZMA_API(void)+lzma_get_progress(lzma_stream *strm,+ uint64_t *progress_in, uint64_t *progress_out)+{+ if (strm->internal->next.get_progress != NULL) {+ strm->internal->next.get_progress(strm->internal->next.coder,+ progress_in, progress_out);+ } else {+ *progress_in = strm->total_in;+ *progress_out = strm->total_out;+ }++ return;+}+++extern LZMA_API(lzma_check)+lzma_get_check(const lzma_stream *strm)+{+ // Return LZMA_CHECK_NONE if we cannot know the check type.+ // It's a bug in the application if this happens.+ if (strm->internal->next.get_check == NULL)+ return LZMA_CHECK_NONE;++ return strm->internal->next.get_check(strm->internal->next.coder);+}+++extern LZMA_API(uint64_t)+lzma_memusage(const lzma_stream *strm)+{+ uint64_t memusage;+ uint64_t old_memlimit;++ if (strm == NULL || strm->internal == NULL+ || strm->internal->next.memconfig == NULL+ || strm->internal->next.memconfig(+ strm->internal->next.coder,+ &memusage, &old_memlimit, 0) != LZMA_OK)+ return 0;++ return memusage;+}+++extern LZMA_API(uint64_t)+lzma_memlimit_get(const lzma_stream *strm)+{+ uint64_t old_memlimit;+ uint64_t memusage;++ if (strm == NULL || strm->internal == NULL+ || strm->internal->next.memconfig == NULL+ || strm->internal->next.memconfig(+ strm->internal->next.coder,+ &memusage, &old_memlimit, 0) != LZMA_OK)+ return 0;++ return old_memlimit;+}+++extern LZMA_API(lzma_ret)+lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)+{+ // Dummy variables to simplify memconfig functions+ uint64_t old_memlimit;+ uint64_t memusage;++ if (strm == NULL || strm->internal == NULL+ || strm->internal->next.memconfig == NULL)+ return LZMA_PROG_ERROR;++ // Zero is a special value that cannot be used as an actual limit.+ // If 0 was specified, use 1 instead.+ if (new_memlimit == 0)+ new_memlimit = 1;++ return strm->internal->next.memconfig(strm->internal->next.coder,+ &memusage, &old_memlimit, new_memlimit);+}
+ cbits/liblzma/common/common.h view
@@ -0,0 +1,314 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file common.h+/// \brief Definitions common to the whole liblzma library+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_COMMON_H+#define LZMA_COMMON_H++#include "sysdefs.h"+#include "mythread.h"+#include "tuklib_integer.h"++#if defined(_WIN32) || defined(__CYGWIN__)+# ifdef DLL_EXPORT+# define LZMA_API_EXPORT __declspec(dllexport)+# else+# define LZMA_API_EXPORT+# endif+// Don't use ifdef or defined() below.+#elif HAVE_VISIBILITY+# define LZMA_API_EXPORT __attribute__((__visibility__("default")))+#else+# define LZMA_API_EXPORT+#endif++#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL++#include "lzma.h"++// These allow helping the compiler in some often-executed branches, whose+// result is almost always the same.+#ifdef __GNUC__+# define likely(expr) __builtin_expect(expr, true)+# define unlikely(expr) __builtin_expect(expr, false)+#else+# define likely(expr) (expr)+# define unlikely(expr) (expr)+#endif+++/// Size of temporary buffers needed in some filters+#define LZMA_BUFFER_SIZE 4096+++/// Maximum number of worker threads within one multithreaded component.+/// The limit exists solely to make it simpler to prevent integer overflows+/// when allocating structures etc. This should be big enough for now...+/// the code won't scale anywhere close to this number anyway.+#define LZMA_THREADS_MAX 16384+++/// Starting value for memory usage estimates. Instead of calculating size+/// of _every_ structure and taking into account malloc() overhead etc., we+/// add a base size to all memory usage estimates. It's not very accurate+/// but should be easily good enough.+#define LZMA_MEMUSAGE_BASE (UINT64_C(1) << 15)++/// Start of internal Filter ID space. These IDs must never be used+/// in Streams.+#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)+++/// Supported flags that can be passed to lzma_stream_decoder()+/// or lzma_auto_decoder().+#define LZMA_SUPPORTED_FLAGS \+ ( LZMA_TELL_NO_CHECK \+ | LZMA_TELL_UNSUPPORTED_CHECK \+ | LZMA_TELL_ANY_CHECK \+ | LZMA_IGNORE_CHECK \+ | LZMA_CONCATENATED )+++/// Largest valid lzma_action value as unsigned integer.+#define LZMA_ACTION_MAX ((unsigned int)(LZMA_FULL_BARRIER))+++/// Special return value (lzma_ret) to indicate that a timeout was reached+/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to+/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because+/// there's no need to have it in the public API.+#define LZMA_TIMED_OUT 32+++typedef struct lzma_next_coder_s lzma_next_coder;++typedef struct lzma_filter_info_s lzma_filter_info;+++/// Type of a function used to initialize a filter encoder or decoder+typedef lzma_ret (*lzma_init_function)(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters);++/// Type of a function to do some kind of coding work (filters, Stream,+/// Block encoders/decoders etc.). Some special coders use don't use both+/// input and output buffers, but for simplicity they still use this same+/// function prototype.+typedef lzma_ret (*lzma_code_function)(+ void *coder, const 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);++/// Type of a function to free the memory allocated for the coder+typedef void (*lzma_end_function)(+ void *coder, const lzma_allocator *allocator);+++/// Raw coder validates and converts an array of lzma_filter structures to+/// an array of lzma_filter_info structures. This array is used with+/// lzma_next_filter_init to initialize the filter chain.+struct lzma_filter_info_s {+ /// Filter ID. This is used only by the encoder+ /// with lzma_filters_update().+ lzma_vli id;++ /// Pointer to function used to initialize the filter.+ /// This is NULL to indicate end of array.+ lzma_init_function init;++ /// Pointer to filter's options structure+ void *options;+};+++/// Hold data and function pointers of the next filter in the chain.+struct lzma_next_coder_s {+ /// Pointer to coder-specific data+ void *coder;++ /// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't+ /// point to a filter coder.+ lzma_vli id;++ /// "Pointer" to init function. This is never called here.+ /// We need only to detect if we are initializing a coder+ /// that was allocated earlier. See lzma_next_coder_init and+ /// lzma_next_strm_init macros in this file.+ uintptr_t init;++ /// Pointer to function to do the actual coding+ lzma_code_function code;++ /// Pointer to function to free lzma_next_coder.coder. This can+ /// be NULL; in that case, lzma_free is called to free+ /// lzma_next_coder.coder.+ lzma_end_function end;++ /// Pointer to a function to get progress information. If this is NULL,+ /// lzma_stream.total_in and .total_out are used instead.+ void (*get_progress)(void *coder,+ uint64_t *progress_in, uint64_t *progress_out);++ /// Pointer to function to return the type of the integrity check.+ /// Most coders won't support this.+ lzma_check (*get_check)(const void *coder);++ /// Pointer to function to get and/or change the memory usage limit.+ /// If new_memlimit == 0, the limit is not changed.+ lzma_ret (*memconfig)(void *coder, uint64_t *memusage,+ uint64_t *old_memlimit, uint64_t new_memlimit);++ /// Update the filter-specific options or the whole filter chain+ /// in the encoder.+ lzma_ret (*update)(void *coder, const lzma_allocator *allocator,+ const lzma_filter *filters,+ const lzma_filter *reversed_filters);+};+++/// Macro to initialize lzma_next_coder structure+#define LZMA_NEXT_CODER_INIT \+ (lzma_next_coder){ \+ .coder = NULL, \+ .init = (uintptr_t)(NULL), \+ .id = LZMA_VLI_UNKNOWN, \+ .code = NULL, \+ .end = NULL, \+ .get_progress = NULL, \+ .get_check = NULL, \+ .memconfig = NULL, \+ .update = NULL, \+ }+++/// Internal data for lzma_strm_init, lzma_code, and lzma_end. A pointer to+/// this is stored in lzma_stream.+struct lzma_internal_s {+ /// The actual coder that should do something useful+ lzma_next_coder next;++ /// Track the state of the coder. This is used to validate arguments+ /// so that the actual coders can rely on e.g. that LZMA_SYNC_FLUSH+ /// is used on every call to lzma_code until next.code has returned+ /// LZMA_STREAM_END.+ enum {+ ISEQ_RUN,+ ISEQ_SYNC_FLUSH,+ ISEQ_FULL_FLUSH,+ ISEQ_FINISH,+ ISEQ_FULL_BARRIER,+ ISEQ_END,+ ISEQ_ERROR,+ } sequence;++ /// A copy of lzma_stream avail_in. This is used to verify that the+ /// amount of input doesn't change once e.g. LZMA_FINISH has been+ /// used.+ size_t avail_in;++ /// Indicates which lzma_action values are allowed by next.code.+ bool supported_actions[LZMA_ACTION_MAX + 1];++ /// If true, lzma_code will return LZMA_BUF_ERROR if no progress was+ /// made (no input consumed and no output produced by next.code).+ bool allow_buf_error;+};+++/// Allocates memory+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);+++/// Allocates strm->internal if it is NULL, and initializes *strm and+/// strm->internal. This function is only called via lzma_next_strm_init macro.+extern lzma_ret lzma_strm_init(lzma_stream *strm);++/// Initializes the next filter in the chain, if any. This takes care of+/// freeing the memory of previously initialized filter if it is different+/// than the filter being initialized now. This way the actual filter+/// initialization functions don't need to use lzma_next_coder_init macro.+extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++/// Update the next filter in the chain, if any. This checks that+/// the application is not trying to change the Filter IDs.+extern lzma_ret lzma_next_filter_update(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *reversed_filters);++/// Frees the memory allocated for next->coder either using next->end or,+/// if next->end is NULL, using lzma_free.+extern void lzma_next_end(lzma_next_coder *next,+ const lzma_allocator *allocator);+++/// Copy as much data as possible from in[] to out[] and update *in_pos+/// and *out_pos accordingly. Returns the number of bytes copied.+extern size_t lzma_bufcpy(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);+++/// \brief Return if expression doesn't evaluate to LZMA_OK+///+/// There are several situations where we want to return immediately+/// with the value of expr if it isn't LZMA_OK. This macro shortens+/// the code a little.+#define return_if_error(expr) \+do { \+ const lzma_ret ret_ = (expr); \+ if (ret_ != LZMA_OK) \+ return ret_; \+} while (0)+++/// If next isn't already initialized, free the previous coder. Then mark+/// that next is _possibly_ initialized for the coder using this macro.+/// "Possibly" means that if e.g. allocation of next->coder fails, the+/// structure isn't actually initialized for this coder, but leaving+/// next->init to func is still OK.+#define lzma_next_coder_init(func, next, allocator) \+do { \+ if ((uintptr_t)(func) != (next)->init) \+ lzma_next_end(next, allocator); \+ (next)->init = (uintptr_t)(func); \+} while (0)+++/// Initializes lzma_strm and calls func() to initialize strm->internal->next.+/// (The function being called will use lzma_next_coder_init()). If+/// initialization fails, memory that wasn't freed by func() is freed+/// along strm->internal.+#define lzma_next_strm_init(func, strm, ...) \+do { \+ return_if_error(lzma_strm_init(strm)); \+ const lzma_ret ret_ = func(&(strm)->internal->next, \+ (strm)->allocator, __VA_ARGS__); \+ if (ret_ != LZMA_OK) { \+ lzma_end(strm); \+ return ret_; \+ } \+} while (0)++#endif
+ cbits/liblzma/common/easy_buffer_encoder.c view
@@ -0,0 +1,27 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file easy_buffer_encoder.c+/// \brief Easy single-call .xz Stream encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "easy_preset.h"+++extern LZMA_API(lzma_ret)+lzma_easy_buffer_encode(uint32_t preset, lzma_check check,+ const lzma_allocator *allocator, const uint8_t *in,+ size_t in_size, uint8_t *out, size_t *out_pos, size_t out_size)+{+ lzma_options_easy opt_easy;+ if (lzma_easy_preset(&opt_easy, preset))+ return LZMA_OPTIONS_ERROR;++ return lzma_stream_buffer_encode(opt_easy.filters, check,+ allocator, in, in_size, out, out_pos, out_size);+}
+ cbits/liblzma/common/easy_decoder_memusage.c view
@@ -0,0 +1,24 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file easy_decoder_memusage.c+/// \brief Decoder memory usage calculation to match easy encoder presets+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "easy_preset.h"+++extern LZMA_API(uint64_t)+lzma_easy_decoder_memusage(uint32_t preset)+{+ lzma_options_easy opt_easy;+ if (lzma_easy_preset(&opt_easy, preset))+ return UINT32_MAX;++ return lzma_raw_decoder_memusage(opt_easy.filters);+}
+ cbits/liblzma/common/easy_encoder.c view
@@ -0,0 +1,24 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file easy_encoder.c+/// \brief Easy .xz Stream encoder initialization+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "easy_preset.h"+++extern LZMA_API(lzma_ret)+lzma_easy_encoder(lzma_stream *strm, uint32_t preset, lzma_check check)+{+ lzma_options_easy opt_easy;+ if (lzma_easy_preset(&opt_easy, preset))+ return LZMA_OPTIONS_ERROR;++ return lzma_stream_encoder(strm, opt_easy.filters, check);+}
+ cbits/liblzma/common/easy_encoder_memusage.c view
@@ -0,0 +1,24 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file easy_encoder_memusage.c+/// \brief Easy .xz Stream encoder memory usage calculation+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "easy_preset.h"+++extern LZMA_API(uint64_t)+lzma_easy_encoder_memusage(uint32_t preset)+{+ lzma_options_easy opt_easy;+ if (lzma_easy_preset(&opt_easy, preset))+ return UINT32_MAX;++ return lzma_raw_encoder_memusage(opt_easy.filters);+}
+ cbits/liblzma/common/easy_preset.c view
@@ -0,0 +1,27 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file easy_preset.c+/// \brief Preset handling for easy encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "easy_preset.h"+++extern bool+lzma_easy_preset(lzma_options_easy *opt_easy, uint32_t preset)+{+ if (lzma_lzma_preset(&opt_easy->opt_lzma, preset))+ return true;++ opt_easy->filters[0].id = LZMA_FILTER_LZMA2;+ opt_easy->filters[0].options = &opt_easy->opt_lzma;+ opt_easy->filters[1].id = LZMA_VLI_UNKNOWN;++ return false;+}
+ cbits/liblzma/common/easy_preset.h view
@@ -0,0 +1,32 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file easy_preset.h+/// \brief Preset handling for easy encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++typedef struct {+ /// We need to keep the filters array available in case+ /// LZMA_FULL_FLUSH is used.+ lzma_filter filters[LZMA_FILTERS_MAX + 1];++ /// Options for LZMA2+ lzma_options_lzma opt_lzma;++ // Options for more filters can be added later, so this struct+ // is not ready to be put into the public API.++} lzma_options_easy;+++/// Set *easy to the settings given by the preset. Returns true on error,+/// false on success.+extern bool lzma_easy_preset(lzma_options_easy *easy, uint32_t preset);
+ cbits/liblzma/common/filter_buffer_decoder.c view
@@ -0,0 +1,88 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_buffer_decoder.c+/// \brief Single-call raw decoding+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_decoder.h"+++extern LZMA_API(lzma_ret)+lzma_raw_buffer_decode(+ const lzma_filter *filters, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Validate what isn't validated later in filter_common.c.+ if (in == NULL || in_pos == NULL || *in_pos > in_size || out == NULL+ || out_pos == NULL || *out_pos > out_size)+ return LZMA_PROG_ERROR;++ // Initialize the decoer.+ lzma_next_coder next = LZMA_NEXT_CODER_INIT;+ return_if_error(lzma_raw_decoder_init(&next, allocator, filters));++ // Store the positions so that we can restore them if something+ // goes wrong.+ const size_t in_start = *in_pos;+ const size_t out_start = *out_pos;++ // Do the actual decoding and free decoder's memory.+ lzma_ret ret = next.code(next.coder, allocator, in, in_pos, in_size,+ out, out_pos, out_size, LZMA_FINISH);++ if (ret == LZMA_STREAM_END) {+ ret = LZMA_OK;+ } else {+ if (ret == LZMA_OK) {+ // Either the input was truncated or the+ // output buffer was too small.+ assert(*in_pos == in_size || *out_pos == out_size);++ if (*in_pos != in_size) {+ // Since input wasn't consumed completely,+ // the output buffer became full and is+ // too small.+ ret = LZMA_BUF_ERROR;++ } else if (*out_pos != out_size) {+ // Since output didn't became full, the input+ // has to be truncated.+ ret = LZMA_DATA_ERROR;++ } else {+ // All the input was consumed and output+ // buffer is full. Now we don't immediately+ // know the reason for the error. Try+ // decoding one more byte. If it succeeds,+ // then the output buffer was too small. If+ // we cannot get a new output byte, the input+ // is truncated.+ uint8_t tmp[1];+ size_t tmp_pos = 0;+ (void)next.code(next.coder, allocator,+ in, in_pos, in_size,+ tmp, &tmp_pos, 1, LZMA_FINISH);++ if (tmp_pos == 1)+ ret = LZMA_BUF_ERROR;+ else+ ret = LZMA_DATA_ERROR;+ }+ }++ // Restore the positions.+ *in_pos = in_start;+ *out_pos = out_start;+ }++ lzma_next_end(&next, allocator);++ return ret;+}
+ cbits/liblzma/common/filter_buffer_encoder.c view
@@ -0,0 +1,55 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_buffer_encoder.c+/// \brief Single-call raw encoding+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_encoder.h"+++extern LZMA_API(lzma_ret)+lzma_raw_buffer_encode(+ const lzma_filter *filters, const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Validate what isn't validated later in filter_common.c.+ if ((in == NULL && in_size != 0) || out == NULL+ || out_pos == NULL || *out_pos > out_size)+ return LZMA_PROG_ERROR;++ // Initialize the encoder+ lzma_next_coder next = LZMA_NEXT_CODER_INIT;+ return_if_error(lzma_raw_encoder_init(&next, allocator, filters));++ // Store the output position so that we can restore it if+ // something goes wrong.+ const size_t out_start = *out_pos;++ // Do the actual encoding and free coder's memory.+ size_t in_pos = 0;+ lzma_ret ret = next.code(next.coder, allocator, in, &in_pos, in_size,+ out, out_pos, out_size, LZMA_FINISH);+ lzma_next_end(&next, allocator);++ if (ret == LZMA_STREAM_END) {+ ret = LZMA_OK;+ } else {+ if (ret == LZMA_OK) {+ // Output buffer was too small.+ assert(*out_pos == out_size);+ ret = LZMA_BUF_ERROR;+ }++ // Restore the output position.+ *out_pos = out_start;+ }++ return ret;+}
+ cbits/liblzma/common/filter_common.c view
@@ -0,0 +1,337 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_common.c+/// \brief Filter-specific stuff common for both encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_common.h"+++static const struct {+ /// Filter ID+ lzma_vli id;++ /// Size of the filter-specific options structure+ size_t options_size;++ /// True if it is OK to use this filter as non-last filter in+ /// the chain.+ bool non_last_ok;++ /// True if it is OK to use this filter as the last filter in+ /// the chain.+ bool last_ok;++ /// True if the filter may change the size of the data (that is, the+ /// amount of encoded output can be different than the amount of+ /// uncompressed input).+ bool changes_size;++} features[] = {+#if defined (HAVE_ENCODER_LZMA1) || defined(HAVE_DECODER_LZMA1)+ {+ .id = LZMA_FILTER_LZMA1,+ .options_size = sizeof(lzma_options_lzma),+ .non_last_ok = false,+ .last_ok = true,+ .changes_size = true,+ },+#endif+#if defined(HAVE_ENCODER_LZMA2) || defined(HAVE_DECODER_LZMA2)+ {+ .id = LZMA_FILTER_LZMA2,+ .options_size = sizeof(lzma_options_lzma),+ .non_last_ok = false,+ .last_ok = true,+ .changes_size = true,+ },+#endif+#if defined(HAVE_ENCODER_X86) || defined(HAVE_DECODER_X86)+ {+ .id = LZMA_FILTER_X86,+ .options_size = sizeof(lzma_options_bcj),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+#if defined(HAVE_ENCODER_POWERPC) || defined(HAVE_DECODER_POWERPC)+ {+ .id = LZMA_FILTER_POWERPC,+ .options_size = sizeof(lzma_options_bcj),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+#if defined(HAVE_ENCODER_IA64) || defined(HAVE_DECODER_IA64)+ {+ .id = LZMA_FILTER_IA64,+ .options_size = sizeof(lzma_options_bcj),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+#if defined(HAVE_ENCODER_ARM) || defined(HAVE_DECODER_ARM)+ {+ .id = LZMA_FILTER_ARM,+ .options_size = sizeof(lzma_options_bcj),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+#if defined(HAVE_ENCODER_ARMTHUMB) || defined(HAVE_DECODER_ARMTHUMB)+ {+ .id = LZMA_FILTER_ARMTHUMB,+ .options_size = sizeof(lzma_options_bcj),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+#if defined(HAVE_ENCODER_SPARC) || defined(HAVE_DECODER_SPARC)+ {+ .id = LZMA_FILTER_SPARC,+ .options_size = sizeof(lzma_options_bcj),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+#if defined(HAVE_ENCODER_DELTA) || defined(HAVE_DECODER_DELTA)+ {+ .id = LZMA_FILTER_DELTA,+ .options_size = sizeof(lzma_options_delta),+ .non_last_ok = true,+ .last_ok = false,+ .changes_size = false,+ },+#endif+ {+ .id = LZMA_VLI_UNKNOWN+ }+};+++extern LZMA_API(lzma_ret)+lzma_filters_copy(const lzma_filter *src, lzma_filter *dest,+ const lzma_allocator *allocator)+{+ if (src == NULL || dest == NULL)+ return LZMA_PROG_ERROR;++ lzma_ret ret;+ size_t i;+ for (i = 0; src[i].id != LZMA_VLI_UNKNOWN; ++i) {+ // There must be a maximum of four filters plus+ // the array terminator.+ if (i == LZMA_FILTERS_MAX) {+ ret = LZMA_OPTIONS_ERROR;+ goto error;+ }++ dest[i].id = src[i].id;++ if (src[i].options == NULL) {+ dest[i].options = NULL;+ } else {+ // See if the filter is supported only when the+ // options is not NULL. This might be convenient+ // sometimes if the app is actually copying only+ // a partial filter chain with a place holder ID.+ //+ // When options is not NULL, the Filter ID must be+ // supported by us, because otherwise we don't know+ // how big the options are.+ size_t j;+ for (j = 0; src[i].id != features[j].id; ++j) {+ if (features[j].id == LZMA_VLI_UNKNOWN) {+ ret = LZMA_OPTIONS_ERROR;+ goto error;+ }+ }++ // Allocate and copy the options.+ dest[i].options = lzma_alloc(features[j].options_size,+ allocator);+ if (dest[i].options == NULL) {+ ret = LZMA_MEM_ERROR;+ goto error;+ }++ memcpy(dest[i].options, src[i].options,+ features[j].options_size);+ }+ }++ // Terminate the filter array.+ assert(i <= LZMA_FILTERS_MAX + 1);+ dest[i].id = LZMA_VLI_UNKNOWN;+ dest[i].options = NULL;++ return LZMA_OK;++error:+ // Free the options which we have already allocated.+ while (i-- > 0) {+ lzma_free(dest[i].options, allocator);+ dest[i].options = NULL;+ }++ return ret;+}+++static lzma_ret+validate_chain(const lzma_filter *filters, size_t *count)+{+ // There must be at least one filter.+ if (filters == NULL || filters[0].id == LZMA_VLI_UNKNOWN)+ return LZMA_PROG_ERROR;++ // Number of non-last filters that may change the size of the data+ // significantly (that is, more than 1-2 % or so).+ size_t changes_size_count = 0;++ // True if it is OK to add a new filter after the current filter.+ bool non_last_ok = true;++ // True if the last filter in the given chain is actually usable as+ // the last filter. Only filters that support embedding End of Payload+ // Marker can be used as the last filter in the chain.+ bool last_ok = false;++ size_t i = 0;+ do {+ size_t j;+ for (j = 0; filters[i].id != features[j].id; ++j)+ if (features[j].id == LZMA_VLI_UNKNOWN)+ return LZMA_OPTIONS_ERROR;++ // If the previous filter in the chain cannot be a non-last+ // filter, the chain is invalid.+ if (!non_last_ok)+ return LZMA_OPTIONS_ERROR;++ non_last_ok = features[j].non_last_ok;+ last_ok = features[j].last_ok;+ changes_size_count += features[j].changes_size;++ } while (filters[++i].id != LZMA_VLI_UNKNOWN);++ // There must be 1-4 filters. The last filter must be usable as+ // the last filter in the chain. A maximum of three filters are+ // allowed to change the size of the data.+ if (i > LZMA_FILTERS_MAX || !last_ok || changes_size_count > 3)+ return LZMA_OPTIONS_ERROR;++ *count = i;+ return LZMA_OK;+}+++extern lzma_ret+lzma_raw_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *options,+ lzma_filter_find coder_find, bool is_encoder)+{+ // Do some basic validation and get the number of filters.+ size_t count;+ return_if_error(validate_chain(options, &count));++ // Set the filter functions and copy the options pointer.+ lzma_filter_info filters[LZMA_FILTERS_MAX + 1];+ if (is_encoder) {+ for (size_t i = 0; i < count; ++i) {+ // The order of the filters is reversed in the+ // encoder. It allows more efficient handling+ // of the uncompressed data.+ const size_t j = count - i - 1;++ const lzma_filter_coder *const fc+ = coder_find(options[i].id);+ if (fc == NULL || fc->init == NULL)+ return LZMA_OPTIONS_ERROR;++ filters[j].id = options[i].id;+ filters[j].init = fc->init;+ filters[j].options = options[i].options;+ }+ } else {+ for (size_t i = 0; i < count; ++i) {+ const lzma_filter_coder *const fc+ = coder_find(options[i].id);+ if (fc == NULL || fc->init == NULL)+ return LZMA_OPTIONS_ERROR;++ filters[i].id = options[i].id;+ filters[i].init = fc->init;+ filters[i].options = options[i].options;+ }+ }++ // Terminate the array.+ filters[count].id = LZMA_VLI_UNKNOWN;+ filters[count].init = NULL;++ // Initialize the filters.+ const lzma_ret ret = lzma_next_filter_init(next, allocator, filters);+ if (ret != LZMA_OK)+ lzma_next_end(next, allocator);++ return ret;+}+++extern uint64_t+lzma_raw_coder_memusage(lzma_filter_find coder_find,+ const lzma_filter *filters)+{+ // The chain has to have at least one filter.+ {+ size_t tmp;+ if (validate_chain(filters, &tmp) != LZMA_OK)+ return UINT64_MAX;+ }++ uint64_t total = 0;+ size_t i = 0;++ do {+ const lzma_filter_coder *const fc+ = coder_find(filters[i].id);+ if (fc == NULL)+ return UINT64_MAX; // Unsupported Filter ID++ if (fc->memusage == NULL) {+ // This filter doesn't have a function to calculate+ // the memory usage and validate the options. Such+ // filters need only little memory, so we use 1 KiB+ // as a good estimate. They also accept all possible+ // options, so there's no need to worry about lack+ // of validation.+ total += 1024;+ } else {+ // Call the filter-specific memory usage calculation+ // function.+ const uint64_t usage+ = fc->memusage(filters[i].options);+ if (usage == UINT64_MAX)+ return UINT64_MAX; // Invalid options++ total += usage;+ }+ } while (filters[++i].id != LZMA_VLI_UNKNOWN);++ // Add some fixed amount of extra. It's to compensate memory usage+ // of Stream, Block etc. coders, malloc() overhead, stack etc.+ return total + LZMA_MEMUSAGE_BASE;+}
+ cbits/liblzma/common/filter_common.h view
@@ -0,0 +1,48 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_common.h+/// \brief Filter-specific stuff common for both encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_FILTER_COMMON_H+#define LZMA_FILTER_COMMON_H++#include "common.h"+++/// Both lzma_filter_encoder and lzma_filter_decoder begin with these members.+typedef struct {+ /// Filter ID+ lzma_vli id;++ /// Initializes the filter encoder and calls lzma_next_filter_init()+ /// for filters + 1.+ lzma_init_function init;++ /// Calculates memory usage of the encoder. If the options are+ /// invalid, UINT64_MAX is returned.+ uint64_t (*memusage)(const void *options);++} lzma_filter_coder;+++typedef const lzma_filter_coder *(*lzma_filter_find)(lzma_vli id);+++extern lzma_ret lzma_raw_coder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *filters,+ lzma_filter_find coder_find, bool is_encoder);+++extern uint64_t lzma_raw_coder_memusage(lzma_filter_find coder_find,+ const lzma_filter *filters);+++#endif
+ cbits/liblzma/common/filter_decoder.c view
@@ -0,0 +1,184 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_decoder.c+/// \brief Filter ID mapping to filter-specific functions+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_decoder.h"+#include "filter_common.h"+#include "lzma_decoder.h"+#include "lzma2_decoder.h"+#include "simple_decoder.h"+#include "delta_decoder.h"+++typedef struct {+ /// Filter ID+ lzma_vli id;++ /// Initializes the filter encoder and calls lzma_next_filter_init()+ /// for filters + 1.+ lzma_init_function init;++ /// Calculates memory usage of the encoder. If the options are+ /// invalid, UINT64_MAX is returned.+ uint64_t (*memusage)(const void *options);++ /// Decodes Filter Properties.+ ///+ /// \return - LZMA_OK: Properties decoded successfully.+ /// - LZMA_OPTIONS_ERROR: Unsupported properties+ /// - LZMA_MEM_ERROR: Memory allocation failed.+ lzma_ret (*props_decode)(+ void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size);++} lzma_filter_decoder;+++static const lzma_filter_decoder decoders[] = {+#ifdef HAVE_DECODER_LZMA1+ {+ .id = LZMA_FILTER_LZMA1,+ .init = &lzma_lzma_decoder_init,+ .memusage = &lzma_lzma_decoder_memusage,+ .props_decode = &lzma_lzma_props_decode,+ },+#endif+#ifdef HAVE_DECODER_LZMA2+ {+ .id = LZMA_FILTER_LZMA2,+ .init = &lzma_lzma2_decoder_init,+ .memusage = &lzma_lzma2_decoder_memusage,+ .props_decode = &lzma_lzma2_props_decode,+ },+#endif+#ifdef HAVE_DECODER_X86+ {+ .id = LZMA_FILTER_X86,+ .init = &lzma_simple_x86_decoder_init,+ .memusage = NULL,+ .props_decode = &lzma_simple_props_decode,+ },+#endif+#ifdef HAVE_DECODER_POWERPC+ {+ .id = LZMA_FILTER_POWERPC,+ .init = &lzma_simple_powerpc_decoder_init,+ .memusage = NULL,+ .props_decode = &lzma_simple_props_decode,+ },+#endif+#ifdef HAVE_DECODER_IA64+ {+ .id = LZMA_FILTER_IA64,+ .init = &lzma_simple_ia64_decoder_init,+ .memusage = NULL,+ .props_decode = &lzma_simple_props_decode,+ },+#endif+#ifdef HAVE_DECODER_ARM+ {+ .id = LZMA_FILTER_ARM,+ .init = &lzma_simple_arm_decoder_init,+ .memusage = NULL,+ .props_decode = &lzma_simple_props_decode,+ },+#endif+#ifdef HAVE_DECODER_ARMTHUMB+ {+ .id = LZMA_FILTER_ARMTHUMB,+ .init = &lzma_simple_armthumb_decoder_init,+ .memusage = NULL,+ .props_decode = &lzma_simple_props_decode,+ },+#endif+#ifdef HAVE_DECODER_SPARC+ {+ .id = LZMA_FILTER_SPARC,+ .init = &lzma_simple_sparc_decoder_init,+ .memusage = NULL,+ .props_decode = &lzma_simple_props_decode,+ },+#endif+#ifdef HAVE_DECODER_DELTA+ {+ .id = LZMA_FILTER_DELTA,+ .init = &lzma_delta_decoder_init,+ .memusage = &lzma_delta_coder_memusage,+ .props_decode = &lzma_delta_props_decode,+ },+#endif+};+++static const lzma_filter_decoder *+decoder_find(lzma_vli id)+{+ for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i)+ if (decoders[i].id == id)+ return decoders + i;++ return NULL;+}+++extern LZMA_API(lzma_bool)+lzma_filter_decoder_is_supported(lzma_vli id)+{+ return decoder_find(id) != NULL;+}+++extern lzma_ret+lzma_raw_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *options)+{+ return lzma_raw_coder_init(next, allocator,+ options, (lzma_filter_find)(&decoder_find), false);+}+++extern LZMA_API(lzma_ret)+lzma_raw_decoder(lzma_stream *strm, const lzma_filter *options)+{+ lzma_next_strm_init(lzma_raw_decoder_init, strm, options);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}+++extern LZMA_API(uint64_t)+lzma_raw_decoder_memusage(const lzma_filter *filters)+{+ return lzma_raw_coder_memusage(+ (lzma_filter_find)(&decoder_find), filters);+}+++extern LZMA_API(lzma_ret)+lzma_properties_decode(lzma_filter *filter, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size)+{+ // Make it always NULL so that the caller can always safely free() it.+ filter->options = NULL;++ const lzma_filter_decoder *const fd = decoder_find(filter->id);+ if (fd == NULL)+ return LZMA_OPTIONS_ERROR;++ if (fd->props_decode == NULL)+ return props_size == 0 ? LZMA_OK : LZMA_OPTIONS_ERROR;++ return fd->props_decode(+ &filter->options, allocator, props, props_size);+}
+ cbits/liblzma/common/filter_decoder.h view
@@ -0,0 +1,23 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_decoder.h+/// \brief Filter ID mapping to filter-specific functions+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_FILTER_DECODER_H+#define LZMA_FILTER_DECODER_H++#include "common.h"+++extern lzma_ret lzma_raw_decoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *options);++#endif
+ cbits/liblzma/common/filter_encoder.c view
@@ -0,0 +1,286 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_decoder.c+/// \brief Filter ID mapping to filter-specific functions+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_encoder.h"+#include "filter_common.h"+#include "lzma_encoder.h"+#include "lzma2_encoder.h"+#include "simple_encoder.h"+#include "delta_encoder.h"+++typedef struct {+ /// Filter ID+ lzma_vli id;++ /// Initializes the filter encoder and calls lzma_next_filter_init()+ /// for filters + 1.+ lzma_init_function init;++ /// Calculates memory usage of the encoder. If the options are+ /// invalid, UINT64_MAX is returned.+ uint64_t (*memusage)(const void *options);++ /// Calculates the recommended Uncompressed Size for .xz Blocks to+ /// which the input data can be split to make multithreaded+ /// encoding possible. If this is NULL, it is assumed that+ /// the encoder is fast enough with single thread.+ uint64_t (*block_size)(const void *options);++ /// Tells the size of the Filter Properties field. If options are+ /// invalid, UINT32_MAX is returned. If this is NULL, props_size_fixed+ /// is used.+ lzma_ret (*props_size_get)(uint32_t *size, const void *options);+ uint32_t props_size_fixed;++ /// Encodes Filter Properties.+ ///+ /// \return - LZMA_OK: Properties encoded successfully.+ /// - LZMA_OPTIONS_ERROR: Unsupported options+ /// - LZMA_PROG_ERROR: Invalid options or not enough+ /// output space+ lzma_ret (*props_encode)(const void *options, uint8_t *out);++} lzma_filter_encoder;+++static const lzma_filter_encoder encoders[] = {+#ifdef HAVE_ENCODER_LZMA1+ {+ .id = LZMA_FILTER_LZMA1,+ .init = &lzma_lzma_encoder_init,+ .memusage = &lzma_lzma_encoder_memusage,+ .block_size = NULL, // FIXME+ .props_size_get = NULL,+ .props_size_fixed = 5,+ .props_encode = &lzma_lzma_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_LZMA2+ {+ .id = LZMA_FILTER_LZMA2,+ .init = &lzma_lzma2_encoder_init,+ .memusage = &lzma_lzma2_encoder_memusage,+ .block_size = &lzma_lzma2_block_size, // FIXME+ .props_size_get = NULL,+ .props_size_fixed = 1,+ .props_encode = &lzma_lzma2_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_X86+ {+ .id = LZMA_FILTER_X86,+ .init = &lzma_simple_x86_encoder_init,+ .memusage = NULL,+ .block_size = NULL,+ .props_size_get = &lzma_simple_props_size,+ .props_encode = &lzma_simple_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_POWERPC+ {+ .id = LZMA_FILTER_POWERPC,+ .init = &lzma_simple_powerpc_encoder_init,+ .memusage = NULL,+ .block_size = NULL,+ .props_size_get = &lzma_simple_props_size,+ .props_encode = &lzma_simple_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_IA64+ {+ .id = LZMA_FILTER_IA64,+ .init = &lzma_simple_ia64_encoder_init,+ .memusage = NULL,+ .block_size = NULL,+ .props_size_get = &lzma_simple_props_size,+ .props_encode = &lzma_simple_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_ARM+ {+ .id = LZMA_FILTER_ARM,+ .init = &lzma_simple_arm_encoder_init,+ .memusage = NULL,+ .block_size = NULL,+ .props_size_get = &lzma_simple_props_size,+ .props_encode = &lzma_simple_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_ARMTHUMB+ {+ .id = LZMA_FILTER_ARMTHUMB,+ .init = &lzma_simple_armthumb_encoder_init,+ .memusage = NULL,+ .block_size = NULL,+ .props_size_get = &lzma_simple_props_size,+ .props_encode = &lzma_simple_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_SPARC+ {+ .id = LZMA_FILTER_SPARC,+ .init = &lzma_simple_sparc_encoder_init,+ .memusage = NULL,+ .block_size = NULL,+ .props_size_get = &lzma_simple_props_size,+ .props_encode = &lzma_simple_props_encode,+ },+#endif+#ifdef HAVE_ENCODER_DELTA+ {+ .id = LZMA_FILTER_DELTA,+ .init = &lzma_delta_encoder_init,+ .memusage = &lzma_delta_coder_memusage,+ .block_size = NULL,+ .props_size_get = NULL,+ .props_size_fixed = 1,+ .props_encode = &lzma_delta_props_encode,+ },+#endif+};+++static const lzma_filter_encoder *+encoder_find(lzma_vli id)+{+ for (size_t i = 0; i < ARRAY_SIZE(encoders); ++i)+ if (encoders[i].id == id)+ return encoders + i;++ return NULL;+}+++extern LZMA_API(lzma_bool)+lzma_filter_encoder_is_supported(lzma_vli id)+{+ return encoder_find(id) != NULL;+}+++extern LZMA_API(lzma_ret)+lzma_filters_update(lzma_stream *strm, const lzma_filter *filters)+{+ if (strm->internal->next.update == NULL)+ return LZMA_PROG_ERROR;++ // Validate the filter chain.+ if (lzma_raw_encoder_memusage(filters) == UINT64_MAX)+ return LZMA_OPTIONS_ERROR;++ // The actual filter chain in the encoder is reversed. Some things+ // still want the normal order chain, so we provide both.+ size_t count = 1;+ while (filters[count].id != LZMA_VLI_UNKNOWN)+ ++count;++ lzma_filter reversed_filters[LZMA_FILTERS_MAX + 1];+ for (size_t i = 0; i < count; ++i)+ reversed_filters[count - i - 1] = filters[i];++ reversed_filters[count].id = LZMA_VLI_UNKNOWN;++ return strm->internal->next.update(strm->internal->next.coder,+ strm->allocator, filters, reversed_filters);+}+++extern lzma_ret+lzma_raw_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *options)+{+ return lzma_raw_coder_init(next, allocator,+ options, (lzma_filter_find)(&encoder_find), true);+}+++extern LZMA_API(lzma_ret)+lzma_raw_encoder(lzma_stream *strm, const lzma_filter *options)+{+ lzma_next_strm_init(lzma_raw_coder_init, strm, options,+ (lzma_filter_find)(&encoder_find), true);++ 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;+}+++extern LZMA_API(uint64_t)+lzma_raw_encoder_memusage(const lzma_filter *filters)+{+ return lzma_raw_coder_memusage(+ (lzma_filter_find)(&encoder_find), filters);+}+++extern uint64_t+lzma_mt_block_size(const lzma_filter *filters)+{+ uint64_t max = 0;++ for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {+ const lzma_filter_encoder *const fe+ = encoder_find(filters[i].id);+ if (fe->block_size != NULL) {+ const uint64_t size+ = fe->block_size(filters[i].options);+ if (size == 0)+ return 0;++ if (size > max)+ max = size;+ }+ }++ return max;+}+++extern LZMA_API(lzma_ret)+lzma_properties_size(uint32_t *size, const lzma_filter *filter)+{+ const lzma_filter_encoder *const fe = encoder_find(filter->id);+ if (fe == NULL) {+ // Unknown filter - if the Filter ID is a proper VLI,+ // return LZMA_OPTIONS_ERROR instead of LZMA_PROG_ERROR,+ // because it's possible that we just don't have support+ // compiled in for the requested filter.+ return filter->id <= LZMA_VLI_MAX+ ? LZMA_OPTIONS_ERROR : LZMA_PROG_ERROR;+ }++ if (fe->props_size_get == NULL) {+ // No props_size_get() function, use props_size_fixed.+ *size = fe->props_size_fixed;+ return LZMA_OK;+ }++ return fe->props_size_get(size, filter->options);+}+++extern LZMA_API(lzma_ret)+lzma_properties_encode(const lzma_filter *filter, uint8_t *props)+{+ const lzma_filter_encoder *const fe = encoder_find(filter->id);+ if (fe == NULL)+ return LZMA_PROG_ERROR;++ if (fe->props_encode == NULL)+ return LZMA_OK;++ return fe->props_encode(filter->options, props);+}
+ cbits/liblzma/common/filter_encoder.h view
@@ -0,0 +1,27 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_encoder.c+/// \brief Filter ID mapping to filter-specific functions+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_FILTER_ENCODER_H+#define LZMA_FILTER_ENCODER_H++#include "common.h"+++// FIXME: Might become a part of the public API.+extern uint64_t lzma_mt_block_size(const lzma_filter *filters);+++extern lzma_ret lzma_raw_encoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *filters);++#endif
+ cbits/liblzma/common/filter_flags_decoder.c view
@@ -0,0 +1,46 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_flags_decoder.c+/// \brief Decodes a Filter Flags field+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_decoder.h"+++extern LZMA_API(lzma_ret)+lzma_filter_flags_decode(+ lzma_filter *filter, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size)+{+ // Set the pointer to NULL so the caller can always safely free it.+ filter->options = NULL;++ // Filter ID+ return_if_error(lzma_vli_decode(&filter->id, NULL,+ in, in_pos, in_size));++ if (filter->id >= LZMA_FILTER_RESERVED_START)+ return LZMA_DATA_ERROR;++ // Size of Properties+ lzma_vli props_size;+ return_if_error(lzma_vli_decode(&props_size, NULL,+ in, in_pos, in_size));++ // Filter Properties+ if (in_size - *in_pos < props_size)+ return LZMA_DATA_ERROR;++ const lzma_ret ret = lzma_properties_decode(+ filter, allocator, in + *in_pos, props_size);++ *in_pos += props_size;++ return ret;+}
+ cbits/liblzma/common/filter_flags_encoder.c view
@@ -0,0 +1,56 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file filter_flags_encoder.c+/// \brief Encodes a Filter Flags field+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_encoder.h"+++extern LZMA_API(lzma_ret)+lzma_filter_flags_size(uint32_t *size, const lzma_filter *filter)+{+ if (filter->id >= LZMA_FILTER_RESERVED_START)+ return LZMA_PROG_ERROR;++ return_if_error(lzma_properties_size(size, filter));++ *size += lzma_vli_size(filter->id) + lzma_vli_size(*size);++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_filter_flags_encode(const lzma_filter *filter,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Filter ID+ if (filter->id >= LZMA_FILTER_RESERVED_START)+ return LZMA_PROG_ERROR;++ return_if_error(lzma_vli_encode(filter->id, NULL,+ out, out_pos, out_size));++ // Size of Properties+ uint32_t props_size;+ return_if_error(lzma_properties_size(&props_size, filter));+ return_if_error(lzma_vli_encode(props_size, NULL,+ out, out_pos, out_size));++ // Filter Properties+ if (out_size - *out_pos < props_size)+ return LZMA_PROG_ERROR;++ return_if_error(lzma_properties_encode(filter, out + *out_pos));++ *out_pos += props_size;++ return LZMA_OK;+}
+ cbits/liblzma/common/hardware_cputhreads.c view
@@ -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();+}
+ cbits/liblzma/common/hardware_physmem.c view
@@ -0,0 +1,25 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file hardware_physmem.c+/// \brief Get the total amount of physical memory (RAM)+//+// Author: Jonathan Nieder+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"++#include "tuklib_physmem.h"+++extern LZMA_API(uint64_t)+lzma_physmem(void)+{+ // It is simpler to make lzma_physmem() a wrapper for+ // tuklib_physmem() than to hack appropriate symbol visibility+ // support for the tuklib modules.+ return tuklib_physmem();+}
+ cbits/liblzma/common/index.c view
@@ -0,0 +1,1250 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file index.c+/// \brief Handling of .xz Indexes and some other Stream information+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "index.h"+#include "stream_flags_common.h"+++/// \brief How many Records to allocate at once+///+/// This should be big enough to avoid making lots of tiny allocations+/// but small enough to avoid too much unused memory at once.+#define INDEX_GROUP_SIZE 512+++/// \brief How many Records can be allocated at once at maximum+#define PREALLOC_MAX ((SIZE_MAX - sizeof(index_group)) / sizeof(index_record))+++/// \brief Base structure for index_stream and index_group structures+typedef struct index_tree_node_s index_tree_node;+struct index_tree_node_s {+ /// Uncompressed start offset of this Stream (relative to the+ /// beginning of the file) or Block (relative to the beginning+ /// of the Stream)+ lzma_vli uncompressed_base;++ /// Compressed start offset of this Stream or Block+ lzma_vli compressed_base;++ index_tree_node *parent;+ index_tree_node *left;+ index_tree_node *right;+};+++/// \brief AVL tree to hold index_stream or index_group structures+typedef struct {+ /// Root node+ index_tree_node *root;++ /// Leftmost node. Since the tree will be filled sequentially,+ /// this won't change after the first node has been added to+ /// the tree.+ index_tree_node *leftmost;++ /// The rightmost node in the tree. Since the tree is filled+ /// sequentially, this is always the node where to add the new data.+ index_tree_node *rightmost;++ /// Number of nodes in the tree+ uint32_t count;++} index_tree;+++typedef struct {+ lzma_vli uncompressed_sum;+ lzma_vli unpadded_sum;+} index_record;+++typedef struct {+ /// Every Record group is part of index_stream.groups tree.+ index_tree_node node;++ /// Number of Blocks in this Stream before this group.+ lzma_vli number_base;++ /// Number of Records that can be put in records[].+ size_t allocated;++ /// Index of the last Record in use.+ size_t last;++ /// The sizes in this array are stored as cumulative sums relative+ /// to the beginning of the Stream. This makes it possible to+ /// use binary search in lzma_index_locate().+ ///+ /// Note that the cumulative summing is done specially for+ /// unpadded_sum: The previous value is rounded up to the next+ /// multiple of four before adding the Unpadded Size of the new+ /// Block. The total encoded size of the Blocks in the Stream+ /// is records[last].unpadded_sum in the last Record group of+ /// the Stream.+ ///+ /// For example, if the Unpadded Sizes are 39, 57, and 81, the+ /// stored values are 39, 97 (40 + 57), and 181 (100 + 181).+ /// The total encoded size of these Blocks is 184.+ ///+ /// This is a flexible array, because it makes easy to optimize+ /// memory usage in case someone concatenates many Streams that+ /// have only one or few Blocks.+ index_record records[];++} index_group;+++typedef struct {+ /// Every index_stream is a node in the tree of Streams.+ index_tree_node node;++ /// Number of this Stream (first one is 1)+ uint32_t number;++ /// Total number of Blocks before this Stream+ lzma_vli block_number_base;++ /// Record groups of this Stream are stored in a tree.+ /// It's a T-tree with AVL-tree balancing. There are+ /// INDEX_GROUP_SIZE Records per node by default.+ /// This keeps the number of memory allocations reasonable+ /// and finding a Record is fast.+ index_tree groups;++ /// Number of Records in this Stream+ lzma_vli record_count;++ /// Size of the List of Records field in this Stream. This is used+ /// together with record_count to calculate the size of the Index+ /// field and thus the total size of the Stream.+ lzma_vli index_list_size;++ /// Stream Flags of this Stream. This is meaningful only if+ /// the Stream Flags have been told us with lzma_index_stream_flags().+ /// Initially stream_flags.version is set to UINT32_MAX to indicate+ /// that the Stream Flags are unknown.+ lzma_stream_flags stream_flags;++ /// Amount of Stream Padding after this Stream. This defaults to+ /// zero and can be set with lzma_index_stream_padding().+ lzma_vli stream_padding;++} index_stream;+++struct lzma_index_s {+ /// AVL-tree containing the Stream(s). Often there is just one+ /// Stream, but using a tree keeps lookups fast even when there+ /// are many concatenated Streams.+ index_tree streams;++ /// Uncompressed size of all the Blocks in the Stream(s)+ lzma_vli uncompressed_size;++ /// Total size of all the Blocks in the Stream(s)+ lzma_vli total_size;++ /// Total number of Records in all Streams in this lzma_index+ lzma_vli record_count;++ /// Size of the List of Records field if all the Streams in this+ /// lzma_index were packed into a single Stream (makes it simpler to+ /// take many .xz files and combine them into a single Stream).+ ///+ /// This value together with record_count is needed to calculate+ /// Backward Size that is stored into Stream Footer.+ lzma_vli index_list_size;++ /// How many Records to allocate at once in lzma_index_append().+ /// This defaults to INDEX_GROUP_SIZE but can be overridden with+ /// lzma_index_prealloc().+ size_t prealloc;++ /// Bitmask indicating what integrity check types have been used+ /// as set by lzma_index_stream_flags(). The bit of the last Stream+ /// is not included here, since it is possible to change it by+ /// calling lzma_index_stream_flags() again.+ uint32_t checks;+};+++static void+index_tree_init(index_tree *tree)+{+ tree->root = NULL;+ tree->leftmost = NULL;+ tree->rightmost = NULL;+ tree->count = 0;+ return;+}+++/// Helper for index_tree_end()+static void+index_tree_node_end(index_tree_node *node, const lzma_allocator *allocator,+ void (*free_func)(void *node, const lzma_allocator *allocator))+{+ // The tree won't ever be very huge, so recursion should be fine.+ // 20 levels in the tree is likely quite a lot already in practice.+ if (node->left != NULL)+ index_tree_node_end(node->left, allocator, free_func);++ if (node->right != NULL)+ index_tree_node_end(node->right, allocator, free_func);++ free_func(node, allocator);+ return;+}+++/// Free the memory allocated for a tree. Each node is freed using the+/// given free_func which is either &lzma_free or &index_stream_end.+/// The latter is used to free the Record groups from each index_stream+/// before freeing the index_stream itself.+static void+index_tree_end(index_tree *tree, const lzma_allocator *allocator,+ void (*free_func)(void *node, const lzma_allocator *allocator))+{+ assert(free_func != NULL);++ if (tree->root != NULL)+ index_tree_node_end(tree->root, allocator, free_func);++ return;+}+++/// Add a new node to the tree. node->uncompressed_base and+/// node->compressed_base must have been set by the caller already.+static void+index_tree_append(index_tree *tree, index_tree_node *node)+{+ node->parent = tree->rightmost;+ node->left = NULL;+ node->right = NULL;++ ++tree->count;++ // Handle the special case of adding the first node.+ if (tree->root == NULL) {+ tree->root = node;+ tree->leftmost = node;+ tree->rightmost = node;+ return;+ }++ // The tree is always filled sequentially.+ assert(tree->rightmost->uncompressed_base <= node->uncompressed_base);+ assert(tree->rightmost->compressed_base < node->compressed_base);++ // Add the new node after the rightmost node. It's the correct+ // place due to the reason above.+ tree->rightmost->right = node;+ tree->rightmost = node;++ // Balance the AVL-tree if needed. We don't need to keep the balance+ // factors in nodes, because we always fill the tree sequentially,+ // and thus know the state of the tree just by looking at the node+ // count. From the node count we can calculate how many steps to go+ // up in the tree to find the rotation root.+ uint32_t up = tree->count ^ (UINT32_C(1) << bsr32(tree->count));+ if (up != 0) {+ // Locate the root node for the rotation.+ up = ctz32(tree->count) + 2;+ do {+ node = node->parent;+ } while (--up > 0);++ // Rotate left using node as the rotation root.+ index_tree_node *pivot = node->right;++ if (node->parent == NULL) {+ tree->root = pivot;+ } else {+ assert(node->parent->right == node);+ node->parent->right = pivot;+ }++ pivot->parent = node->parent;++ node->right = pivot->left;+ if (node->right != NULL)+ node->right->parent = node;++ pivot->left = node;+ node->parent = pivot;+ }++ return;+}+++/// Get the next node in the tree. Return NULL if there are no more nodes.+static void *+index_tree_next(const index_tree_node *node)+{+ if (node->right != NULL) {+ node = node->right;+ while (node->left != NULL)+ node = node->left;++ return (void *)(node);+ }++ while (node->parent != NULL && node->parent->right == node)+ node = node->parent;++ return (void *)(node->parent);+}+++/// Locate a node that contains the given uncompressed offset. It is+/// caller's job to check that target is not bigger than the uncompressed+/// size of the tree (the last node would be returned in that case still).+static void *+index_tree_locate(const index_tree *tree, lzma_vli target)+{+ const index_tree_node *result = NULL;+ const index_tree_node *node = tree->root;++ assert(tree->leftmost == NULL+ || tree->leftmost->uncompressed_base == 0);++ // Consecutive nodes may have the same uncompressed_base.+ // We must pick the rightmost one.+ while (node != NULL) {+ if (node->uncompressed_base > target) {+ node = node->left;+ } else {+ result = node;+ node = node->right;+ }+ }++ return (void *)(result);+}+++/// Allocate and initialize a new Stream using the given base offsets.+static index_stream *+index_stream_init(lzma_vli compressed_base, lzma_vli uncompressed_base,+ uint32_t stream_number, lzma_vli block_number_base,+ const lzma_allocator *allocator)+{+ index_stream *s = lzma_alloc(sizeof(index_stream), allocator);+ if (s == NULL)+ return NULL;++ s->node.uncompressed_base = uncompressed_base;+ s->node.compressed_base = compressed_base;+ s->node.parent = NULL;+ s->node.left = NULL;+ s->node.right = NULL;++ s->number = stream_number;+ s->block_number_base = block_number_base;++ index_tree_init(&s->groups);++ s->record_count = 0;+ s->index_list_size = 0;+ s->stream_flags.version = UINT32_MAX;+ s->stream_padding = 0;++ return s;+}+++/// Free the memory allocated for a Stream and its Record groups.+static void+index_stream_end(void *node, const lzma_allocator *allocator)+{+ index_stream *s = node;+ index_tree_end(&s->groups, allocator, &lzma_free);+ lzma_free(s, allocator);+ return;+}+++static lzma_index *+index_init_plain(const lzma_allocator *allocator)+{+ lzma_index *i = lzma_alloc(sizeof(lzma_index), allocator);+ if (i != NULL) {+ index_tree_init(&i->streams);+ i->uncompressed_size = 0;+ i->total_size = 0;+ i->record_count = 0;+ i->index_list_size = 0;+ i->prealloc = INDEX_GROUP_SIZE;+ i->checks = 0;+ }++ return i;+}+++extern LZMA_API(lzma_index *)+lzma_index_init(const lzma_allocator *allocator)+{+ lzma_index *i = index_init_plain(allocator);+ if (i == NULL)+ return NULL;++ index_stream *s = index_stream_init(0, 0, 1, 0, allocator);+ if (s == NULL) {+ lzma_free(i, allocator);+ return NULL;+ }++ index_tree_append(&i->streams, &s->node);++ return i;+}+++extern LZMA_API(void)+lzma_index_end(lzma_index *i, const lzma_allocator *allocator)+{+ // NOTE: If you modify this function, check also the bottom+ // of lzma_index_cat().+ if (i != NULL) {+ index_tree_end(&i->streams, allocator, &index_stream_end);+ lzma_free(i, allocator);+ }++ return;+}+++extern void+lzma_index_prealloc(lzma_index *i, lzma_vli records)+{+ if (records > PREALLOC_MAX)+ records = PREALLOC_MAX;++ i->prealloc = (size_t)(records);+ return;+}+++extern LZMA_API(uint64_t)+lzma_index_memusage(lzma_vli streams, lzma_vli blocks)+{+ // This calculates an upper bound that is only a little bit+ // bigger than the exact maximum memory usage with the given+ // parameters.++ // Typical malloc() overhead is 2 * sizeof(void *) but we take+ // a little bit extra just in case. Using LZMA_MEMUSAGE_BASE+ // instead would give too inaccurate estimate.+ const size_t alloc_overhead = 4 * sizeof(void *);++ // Amount of memory needed for each Stream base structures.+ // We assume that every Stream has at least one Block and+ // thus at least one group.+ const size_t stream_base = sizeof(index_stream)+ + sizeof(index_group) + 2 * alloc_overhead;++ // Amount of memory needed per group.+ const size_t group_base = sizeof(index_group)+ + INDEX_GROUP_SIZE * sizeof(index_record)+ + alloc_overhead;++ // Number of groups. There may actually be more, but that overhead+ // has been taken into account in stream_base already.+ const lzma_vli groups+ = (blocks + INDEX_GROUP_SIZE - 1) / INDEX_GROUP_SIZE;++ // Memory used by index_stream and index_group structures.+ const uint64_t streams_mem = streams * stream_base;+ const uint64_t groups_mem = groups * group_base;++ // Memory used by the base structure.+ const uint64_t index_base = sizeof(lzma_index) + alloc_overhead;++ // Validate the arguments and catch integer overflows.+ // Maximum number of Streams is "only" UINT32_MAX, because+ // that limit is used by the tree containing the Streams.+ const uint64_t limit = UINT64_MAX - index_base;+ if (streams == 0 || streams > UINT32_MAX || blocks > LZMA_VLI_MAX+ || streams > limit / stream_base+ || groups > limit / group_base+ || limit - streams_mem < groups_mem)+ return UINT64_MAX;++ return index_base + streams_mem + groups_mem;+}+++extern LZMA_API(uint64_t)+lzma_index_memused(const lzma_index *i)+{+ return lzma_index_memusage(i->streams.count, i->record_count);+}+++extern LZMA_API(lzma_vli)+lzma_index_block_count(const lzma_index *i)+{+ return i->record_count;+}+++extern LZMA_API(lzma_vli)+lzma_index_stream_count(const lzma_index *i)+{+ return i->streams.count;+}+++extern LZMA_API(lzma_vli)+lzma_index_size(const lzma_index *i)+{+ return index_size(i->record_count, i->index_list_size);+}+++extern LZMA_API(lzma_vli)+lzma_index_total_size(const lzma_index *i)+{+ return i->total_size;+}+++extern LZMA_API(lzma_vli)+lzma_index_stream_size(const lzma_index *i)+{+ // Stream Header + Blocks + Index + Stream Footer+ return LZMA_STREAM_HEADER_SIZE + i->total_size+ + index_size(i->record_count, i->index_list_size)+ + LZMA_STREAM_HEADER_SIZE;+}+++static lzma_vli+index_file_size(lzma_vli compressed_base, lzma_vli unpadded_sum,+ lzma_vli record_count, lzma_vli index_list_size,+ lzma_vli stream_padding)+{+ // Earlier Streams and Stream Paddings + Stream Header+ // + Blocks + Index + Stream Footer + Stream Padding+ //+ // This might go over LZMA_VLI_MAX due to too big unpadded_sum+ // when this function is used in lzma_index_append().+ lzma_vli file_size = compressed_base + 2 * LZMA_STREAM_HEADER_SIZE+ + stream_padding + vli_ceil4(unpadded_sum);+ if (file_size > LZMA_VLI_MAX)+ return LZMA_VLI_UNKNOWN;++ // The same applies here.+ file_size += index_size(record_count, index_list_size);+ if (file_size > LZMA_VLI_MAX)+ return LZMA_VLI_UNKNOWN;++ return file_size;+}+++extern LZMA_API(lzma_vli)+lzma_index_file_size(const lzma_index *i)+{+ const index_stream *s = (const index_stream *)(i->streams.rightmost);+ const index_group *g = (const index_group *)(s->groups.rightmost);+ return index_file_size(s->node.compressed_base,+ g == NULL ? 0 : g->records[g->last].unpadded_sum,+ s->record_count, s->index_list_size,+ s->stream_padding);+}+++extern LZMA_API(lzma_vli)+lzma_index_uncompressed_size(const lzma_index *i)+{+ return i->uncompressed_size;+}+++extern LZMA_API(uint32_t)+lzma_index_checks(const lzma_index *i)+{+ uint32_t checks = i->checks;++ // Get the type of the Check of the last Stream too.+ const index_stream *s = (const index_stream *)(i->streams.rightmost);+ if (s->stream_flags.version != UINT32_MAX)+ checks |= UINT32_C(1) << s->stream_flags.check;++ return checks;+}+++extern uint32_t+lzma_index_padding_size(const lzma_index *i)+{+ return (LZMA_VLI_C(4) - index_size_unpadded(+ i->record_count, i->index_list_size)) & 3;+}+++extern LZMA_API(lzma_ret)+lzma_index_stream_flags(lzma_index *i, const lzma_stream_flags *stream_flags)+{+ if (i == NULL || stream_flags == NULL)+ return LZMA_PROG_ERROR;++ // Validate the Stream Flags.+ return_if_error(lzma_stream_flags_compare(+ stream_flags, stream_flags));++ index_stream *s = (index_stream *)(i->streams.rightmost);+ s->stream_flags = *stream_flags;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_stream_padding(lzma_index *i, lzma_vli stream_padding)+{+ if (i == NULL || stream_padding > LZMA_VLI_MAX+ || (stream_padding & 3) != 0)+ return LZMA_PROG_ERROR;++ index_stream *s = (index_stream *)(i->streams.rightmost);++ // Check that the new value won't make the file grow too big.+ const lzma_vli old_stream_padding = s->stream_padding;+ s->stream_padding = 0;+ if (lzma_index_file_size(i) + stream_padding > LZMA_VLI_MAX) {+ s->stream_padding = old_stream_padding;+ return LZMA_DATA_ERROR;+ }++ s->stream_padding = stream_padding;+ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_append(lzma_index *i, const lzma_allocator *allocator,+ lzma_vli unpadded_size, lzma_vli uncompressed_size)+{+ // Validate.+ if (i == NULL || unpadded_size < UNPADDED_SIZE_MIN+ || unpadded_size > UNPADDED_SIZE_MAX+ || uncompressed_size > LZMA_VLI_MAX)+ return LZMA_PROG_ERROR;++ index_stream *s = (index_stream *)(i->streams.rightmost);+ index_group *g = (index_group *)(s->groups.rightmost);++ const lzma_vli compressed_base = g == NULL ? 0+ : vli_ceil4(g->records[g->last].unpadded_sum);+ const lzma_vli uncompressed_base = g == NULL ? 0+ : g->records[g->last].uncompressed_sum;+ const uint32_t index_list_size_add = lzma_vli_size(unpadded_size)+ + lzma_vli_size(uncompressed_size);++ // Check that the file size will stay within limits.+ if (index_file_size(s->node.compressed_base,+ compressed_base + unpadded_size, s->record_count + 1,+ s->index_list_size + index_list_size_add,+ s->stream_padding) == LZMA_VLI_UNKNOWN)+ return LZMA_DATA_ERROR;++ // The size of the Index field must not exceed the maximum value+ // that can be stored in the Backward Size field.+ if (index_size(i->record_count + 1,+ i->index_list_size + index_list_size_add)+ > LZMA_BACKWARD_SIZE_MAX)+ return LZMA_DATA_ERROR;++ if (g != NULL && g->last + 1 < g->allocated) {+ // There is space in the last group at least for one Record.+ ++g->last;+ } else {+ // We need to allocate a new group.+ g = lzma_alloc(sizeof(index_group)+ + i->prealloc * sizeof(index_record),+ allocator);+ if (g == NULL)+ return LZMA_MEM_ERROR;++ g->last = 0;+ g->allocated = i->prealloc;++ // Reset prealloc so that if the application happens to+ // add new Records, the allocation size will be sane.+ i->prealloc = INDEX_GROUP_SIZE;++ // Set the start offsets of this group.+ g->node.uncompressed_base = uncompressed_base;+ g->node.compressed_base = compressed_base;+ g->number_base = s->record_count + 1;++ // Add the new group to the Stream.+ index_tree_append(&s->groups, &g->node);+ }++ // Add the new Record to the group.+ g->records[g->last].uncompressed_sum+ = uncompressed_base + uncompressed_size;+ g->records[g->last].unpadded_sum+ = compressed_base + unpadded_size;++ // Update the totals.+ ++s->record_count;+ s->index_list_size += index_list_size_add;++ i->total_size += vli_ceil4(unpadded_size);+ i->uncompressed_size += uncompressed_size;+ ++i->record_count;+ i->index_list_size += index_list_size_add;++ return LZMA_OK;+}+++/// Structure to pass info to index_cat_helper()+typedef struct {+ /// Uncompressed size of the destination+ lzma_vli uncompressed_size;++ /// Compressed file size of the destination+ lzma_vli file_size;++ /// Same as above but for Block numbers+ lzma_vli block_number_add;++ /// Number of Streams that were in the destination index before we+ /// started appending new Streams from the source index. This is+ /// used to fix the Stream numbering.+ uint32_t stream_number_add;++ /// Destination index' Stream tree+ index_tree *streams;++} index_cat_info;+++/// Add the Stream nodes from the source index to dest using recursion.+/// Simplest iterative traversal of the source tree wouldn't work, because+/// we update the pointers in nodes when moving them to the destination tree.+static void+index_cat_helper(const index_cat_info *info, index_stream *this)+{+ index_stream *left = (index_stream *)(this->node.left);+ index_stream *right = (index_stream *)(this->node.right);++ if (left != NULL)+ index_cat_helper(info, left);++ this->node.uncompressed_base += info->uncompressed_size;+ this->node.compressed_base += info->file_size;+ this->number += info->stream_number_add;+ this->block_number_base += info->block_number_add;+ index_tree_append(info->streams, &this->node);++ if (right != NULL)+ index_cat_helper(info, right);++ return;+}+++extern LZMA_API(lzma_ret)+lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src,+ const lzma_allocator *allocator)+{+ const lzma_vli dest_file_size = lzma_index_file_size(dest);++ // Check that we don't exceed the file size limits.+ if (dest_file_size + lzma_index_file_size(src) > LZMA_VLI_MAX+ || dest->uncompressed_size + src->uncompressed_size+ > LZMA_VLI_MAX)+ return LZMA_DATA_ERROR;++ // Check that the encoded size of the combined lzma_indexes stays+ // within limits. In theory, this should be done only if we know+ // that the user plans to actually combine the Streams and thus+ // construct a single Index (probably rare). However, exceeding+ // this limit is quite theoretical, so we do this check always+ // to simplify things elsewhere.+ {+ const lzma_vli dest_size = index_size_unpadded(+ dest->record_count, dest->index_list_size);+ const lzma_vli src_size = index_size_unpadded(+ src->record_count, src->index_list_size);+ if (vli_ceil4(dest_size + src_size) > LZMA_BACKWARD_SIZE_MAX)+ return LZMA_DATA_ERROR;+ }++ // Optimize the last group to minimize memory usage. Allocation has+ // to be done before modifying dest or src.+ {+ index_stream *s = (index_stream *)(dest->streams.rightmost);+ index_group *g = (index_group *)(s->groups.rightmost);+ if (g != NULL && g->last + 1 < g->allocated) {+ assert(g->node.left == NULL);+ assert(g->node.right == NULL);++ index_group *newg = lzma_alloc(sizeof(index_group)+ + (g->last + 1)+ * sizeof(index_record),+ allocator);+ if (newg == NULL)+ return LZMA_MEM_ERROR;++ newg->node = g->node;+ newg->allocated = g->last + 1;+ newg->last = g->last;+ newg->number_base = g->number_base;++ memcpy(newg->records, g->records, newg->allocated+ * sizeof(index_record));++ if (g->node.parent != NULL) {+ assert(g->node.parent->right == &g->node);+ g->node.parent->right = &newg->node;+ }++ if (s->groups.leftmost == &g->node) {+ assert(s->groups.root == &g->node);+ s->groups.leftmost = &newg->node;+ s->groups.root = &newg->node;+ }++ assert(s->groups.rightmost == &g->node);+ s->groups.rightmost = &newg->node;++ lzma_free(g, allocator);++ // NOTE: newg isn't leaked here because+ // newg == (void *)&newg->node.+ }+ }++ // Add all the Streams from src to dest. Update the base offsets+ // of each Stream from src.+ const index_cat_info info = {+ .uncompressed_size = dest->uncompressed_size,+ .file_size = dest_file_size,+ .stream_number_add = dest->streams.count,+ .block_number_add = dest->record_count,+ .streams = &dest->streams,+ };+ index_cat_helper(&info, (index_stream *)(src->streams.root));++ // Update info about all the combined Streams.+ dest->uncompressed_size += src->uncompressed_size;+ dest->total_size += src->total_size;+ dest->record_count += src->record_count;+ dest->index_list_size += src->index_list_size;+ dest->checks = lzma_index_checks(dest) | src->checks;++ // There's nothing else left in src than the base structure.+ lzma_free(src, allocator);++ return LZMA_OK;+}+++/// Duplicate an index_stream.+static index_stream *+index_dup_stream(const index_stream *src, const lzma_allocator *allocator)+{+ // Catch a somewhat theoretical integer overflow.+ if (src->record_count > PREALLOC_MAX)+ return NULL;++ // Allocate and initialize a new Stream.+ index_stream *dest = index_stream_init(src->node.compressed_base,+ src->node.uncompressed_base, src->number,+ src->block_number_base, allocator);+ if (dest == NULL)+ return NULL;++ // Copy the overall information.+ dest->record_count = src->record_count;+ dest->index_list_size = src->index_list_size;+ dest->stream_flags = src->stream_flags;+ dest->stream_padding = src->stream_padding;++ // Return if there are no groups to duplicate.+ if (src->groups.leftmost == NULL)+ return dest;++ // Allocate memory for the Records. We put all the Records into+ // a single group. It's simplest and also tends to make+ // lzma_index_locate() a little bit faster with very big Indexes.+ index_group *destg = lzma_alloc(sizeof(index_group)+ + src->record_count * sizeof(index_record),+ allocator);+ if (destg == NULL) {+ index_stream_end(dest, allocator);+ return NULL;+ }++ // Initialize destg.+ destg->node.uncompressed_base = 0;+ destg->node.compressed_base = 0;+ destg->number_base = 1;+ destg->allocated = src->record_count;+ destg->last = src->record_count - 1;++ // Go through all the groups in src and copy the Records into destg.+ const index_group *srcg = (const index_group *)(src->groups.leftmost);+ size_t i = 0;+ do {+ memcpy(destg->records + i, srcg->records,+ (srcg->last + 1) * sizeof(index_record));+ i += srcg->last + 1;+ srcg = index_tree_next(&srcg->node);+ } while (srcg != NULL);++ assert(i == destg->allocated);++ // Add the group to the new Stream.+ index_tree_append(&dest->groups, &destg->node);++ return dest;+}+++extern LZMA_API(lzma_index *)+lzma_index_dup(const lzma_index *src, const lzma_allocator *allocator)+{+ // Allocate the base structure (no initial Stream).+ lzma_index *dest = index_init_plain(allocator);+ if (dest == NULL)+ return NULL;++ // Copy the totals.+ dest->uncompressed_size = src->uncompressed_size;+ dest->total_size = src->total_size;+ dest->record_count = src->record_count;+ dest->index_list_size = src->index_list_size;++ // Copy the Streams and the groups in them.+ const index_stream *srcstream+ = (const index_stream *)(src->streams.leftmost);+ do {+ index_stream *deststream = index_dup_stream(+ srcstream, allocator);+ if (deststream == NULL) {+ lzma_index_end(dest, allocator);+ return NULL;+ }++ index_tree_append(&dest->streams, &deststream->node);++ srcstream = index_tree_next(&srcstream->node);+ } while (srcstream != NULL);++ return dest;+}+++/// Indexing for lzma_index_iter.internal[]+enum {+ ITER_INDEX,+ ITER_STREAM,+ ITER_GROUP,+ ITER_RECORD,+ ITER_METHOD,+};+++/// Values for lzma_index_iter.internal[ITER_METHOD].s+enum {+ ITER_METHOD_NORMAL,+ ITER_METHOD_NEXT,+ ITER_METHOD_LEFTMOST,+};+++static void+iter_set_info(lzma_index_iter *iter)+{+ const lzma_index *i = iter->internal[ITER_INDEX].p;+ const index_stream *stream = iter->internal[ITER_STREAM].p;+ const index_group *group = iter->internal[ITER_GROUP].p;+ const size_t record = iter->internal[ITER_RECORD].s;++ // lzma_index_iter.internal must not contain a pointer to the last+ // group in the index, because that may be reallocated by+ // lzma_index_cat().+ if (group == NULL) {+ // There are no groups.+ assert(stream->groups.root == NULL);+ iter->internal[ITER_METHOD].s = ITER_METHOD_LEFTMOST;++ } else if (i->streams.rightmost != &stream->node+ || stream->groups.rightmost != &group->node) {+ // The group is not not the last group in the index.+ iter->internal[ITER_METHOD].s = ITER_METHOD_NORMAL;++ } else if (stream->groups.leftmost != &group->node) {+ // The group isn't the only group in the Stream, thus we+ // know that it must have a parent group i.e. it's not+ // the root node.+ assert(stream->groups.root != &group->node);+ assert(group->node.parent->right == &group->node);+ iter->internal[ITER_METHOD].s = ITER_METHOD_NEXT;+ iter->internal[ITER_GROUP].p = group->node.parent;++ } else {+ // The Stream has only one group.+ assert(stream->groups.root == &group->node);+ assert(group->node.parent == NULL);+ iter->internal[ITER_METHOD].s = ITER_METHOD_LEFTMOST;+ iter->internal[ITER_GROUP].p = NULL;+ }++ // NOTE: lzma_index_iter.stream.number is lzma_vli but we use uint32_t+ // internally.+ iter->stream.number = stream->number;+ iter->stream.block_count = stream->record_count;+ iter->stream.compressed_offset = stream->node.compressed_base;+ iter->stream.uncompressed_offset = stream->node.uncompressed_base;++ // iter->stream.flags will be NULL if the Stream Flags haven't been+ // set with lzma_index_stream_flags().+ iter->stream.flags = stream->stream_flags.version == UINT32_MAX+ ? NULL : &stream->stream_flags;+ iter->stream.padding = stream->stream_padding;++ if (stream->groups.rightmost == NULL) {+ // Stream has no Blocks.+ iter->stream.compressed_size = index_size(0, 0)+ + 2 * LZMA_STREAM_HEADER_SIZE;+ iter->stream.uncompressed_size = 0;+ } else {+ const index_group *g = (const index_group *)(+ stream->groups.rightmost);++ // Stream Header + Stream Footer + Index + Blocks+ iter->stream.compressed_size = 2 * LZMA_STREAM_HEADER_SIZE+ + index_size(stream->record_count,+ stream->index_list_size)+ + vli_ceil4(g->records[g->last].unpadded_sum);+ iter->stream.uncompressed_size+ = g->records[g->last].uncompressed_sum;+ }++ if (group != NULL) {+ iter->block.number_in_stream = group->number_base + record;+ iter->block.number_in_file = iter->block.number_in_stream+ + stream->block_number_base;++ iter->block.compressed_stream_offset+ = record == 0 ? group->node.compressed_base+ : vli_ceil4(group->records[+ record - 1].unpadded_sum);+ iter->block.uncompressed_stream_offset+ = record == 0 ? group->node.uncompressed_base+ : group->records[record - 1].uncompressed_sum;++ iter->block.uncompressed_size+ = group->records[record].uncompressed_sum+ - iter->block.uncompressed_stream_offset;+ iter->block.unpadded_size+ = group->records[record].unpadded_sum+ - iter->block.compressed_stream_offset;+ iter->block.total_size = vli_ceil4(iter->block.unpadded_size);++ iter->block.compressed_stream_offset+ += LZMA_STREAM_HEADER_SIZE;++ iter->block.compressed_file_offset+ = iter->block.compressed_stream_offset+ + iter->stream.compressed_offset;+ iter->block.uncompressed_file_offset+ = iter->block.uncompressed_stream_offset+ + iter->stream.uncompressed_offset;+ }++ return;+}+++extern LZMA_API(void)+lzma_index_iter_init(lzma_index_iter *iter, const lzma_index *i)+{+ iter->internal[ITER_INDEX].p = i;+ lzma_index_iter_rewind(iter);+ return;+}+++extern LZMA_API(void)+lzma_index_iter_rewind(lzma_index_iter *iter)+{+ iter->internal[ITER_STREAM].p = NULL;+ iter->internal[ITER_GROUP].p = NULL;+ iter->internal[ITER_RECORD].s = 0;+ iter->internal[ITER_METHOD].s = ITER_METHOD_NORMAL;+ return;+}+++extern LZMA_API(lzma_bool)+lzma_index_iter_next(lzma_index_iter *iter, lzma_index_iter_mode mode)+{+ // Catch unsupported mode values.+ if ((unsigned int)(mode) > LZMA_INDEX_ITER_NONEMPTY_BLOCK)+ return true;++ const lzma_index *i = iter->internal[ITER_INDEX].p;+ const index_stream *stream = iter->internal[ITER_STREAM].p;+ const index_group *group = NULL;+ size_t record = iter->internal[ITER_RECORD].s;++ // If we are being asked for the next Stream, leave group to NULL+ // so that the rest of the this function thinks that this Stream+ // has no groups and will thus go to the next Stream.+ if (mode != LZMA_INDEX_ITER_STREAM) {+ // Get the pointer to the current group. See iter_set_inf()+ // for explanation.+ switch (iter->internal[ITER_METHOD].s) {+ case ITER_METHOD_NORMAL:+ group = iter->internal[ITER_GROUP].p;+ break;++ case ITER_METHOD_NEXT:+ group = index_tree_next(iter->internal[ITER_GROUP].p);+ break;++ case ITER_METHOD_LEFTMOST:+ group = (const index_group *)(+ stream->groups.leftmost);+ break;+ }+ }++again:+ if (stream == NULL) {+ // We at the beginning of the lzma_index.+ // Locate the first Stream.+ stream = (const index_stream *)(i->streams.leftmost);+ if (mode >= LZMA_INDEX_ITER_BLOCK) {+ // Since we are being asked to return information+ // about the first a Block, skip Streams that have+ // no Blocks.+ while (stream->groups.leftmost == NULL) {+ stream = index_tree_next(&stream->node);+ if (stream == NULL)+ return true;+ }+ }++ // Start from the first Record in the Stream.+ group = (const index_group *)(stream->groups.leftmost);+ record = 0;++ } else if (group != NULL && record < group->last) {+ // The next Record is in the same group.+ ++record;++ } else {+ // This group has no more Records or this Stream has+ // no Blocks at all.+ record = 0;++ // If group is not NULL, this Stream has at least one Block+ // and thus at least one group. Find the next group.+ if (group != NULL)+ group = index_tree_next(&group->node);++ if (group == NULL) {+ // This Stream has no more Records. Find the next+ // Stream. If we are being asked to return information+ // about a Block, we skip empty Streams.+ do {+ stream = index_tree_next(&stream->node);+ if (stream == NULL)+ return true;+ } while (mode >= LZMA_INDEX_ITER_BLOCK+ && stream->groups.leftmost == NULL);++ group = (const index_group *)(+ stream->groups.leftmost);+ }+ }++ if (mode == LZMA_INDEX_ITER_NONEMPTY_BLOCK) {+ // We need to look for the next Block again if this Block+ // is empty.+ if (record == 0) {+ if (group->node.uncompressed_base+ == group->records[0].uncompressed_sum)+ goto again;+ } else if (group->records[record - 1].uncompressed_sum+ == group->records[record].uncompressed_sum) {+ goto again;+ }+ }++ iter->internal[ITER_STREAM].p = stream;+ iter->internal[ITER_GROUP].p = group;+ iter->internal[ITER_RECORD].s = record;++ iter_set_info(iter);++ return false;+}+++extern LZMA_API(lzma_bool)+lzma_index_iter_locate(lzma_index_iter *iter, lzma_vli target)+{+ const lzma_index *i = iter->internal[ITER_INDEX].p;++ // If the target is past the end of the file, return immediately.+ if (i->uncompressed_size <= target)+ return true;++ // Locate the Stream containing the target offset.+ const index_stream *stream = index_tree_locate(&i->streams, target);+ assert(stream != NULL);+ target -= stream->node.uncompressed_base;++ // Locate the group containing the target offset.+ const index_group *group = index_tree_locate(&stream->groups, target);+ assert(group != NULL);++ // Use binary search to locate the exact Record. It is the first+ // Record whose uncompressed_sum is greater than target.+ // This is because we want the rightmost Record that fullfills the+ // search criterion. It is possible that there are empty Blocks;+ // we don't want to return them.+ size_t left = 0;+ size_t right = group->last;++ while (left < right) {+ const size_t pos = left + (right - left) / 2;+ if (group->records[pos].uncompressed_sum <= target)+ left = pos + 1;+ else+ right = pos;+ }++ iter->internal[ITER_STREAM].p = stream;+ iter->internal[ITER_GROUP].p = group;+ iter->internal[ITER_RECORD].s = left;++ iter_set_info(iter);++ return false;+}
+ cbits/liblzma/common/index.h view
@@ -0,0 +1,73 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file index.h+/// \brief Handling of Index+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_INDEX_H+#define LZMA_INDEX_H++#include "common.h"+++/// Minimum Unpadded Size+#define UNPADDED_SIZE_MIN LZMA_VLI_C(5)++/// Maximum Unpadded Size+#define UNPADDED_SIZE_MAX (LZMA_VLI_MAX & ~LZMA_VLI_C(3))+++/// Get the size of the Index Padding field. This is needed by Index encoder+/// and decoder, but applications should have no use for this.+extern uint32_t lzma_index_padding_size(const lzma_index *i);+++/// Set for how many Records to allocate memory the next time+/// lzma_index_append() needs to allocate space for a new Record.+/// This is used only by the Index decoder.+extern void lzma_index_prealloc(lzma_index *i, lzma_vli records);+++/// Round the variable-length integer to the next multiple of four.+static inline lzma_vli+vli_ceil4(lzma_vli vli)+{+ assert(vli <= LZMA_VLI_MAX);+ return (vli + 3) & ~LZMA_VLI_C(3);+}+++/// Calculate the size of the Index field excluding Index Padding+static inline lzma_vli+index_size_unpadded(lzma_vli count, lzma_vli index_list_size)+{+ // Index Indicator + Number of Records + List of Records + CRC32+ return 1 + lzma_vli_size(count) + index_list_size + 4;+}+++/// Calculate the size of the Index field including Index Padding+static inline lzma_vli+index_size(lzma_vli count, lzma_vli index_list_size)+{+ return vli_ceil4(index_size_unpadded(count, index_list_size));+}+++/// Calculate the total size of the Stream+static inline lzma_vli+index_stream_size(lzma_vli blocks_size,+ lzma_vli count, lzma_vli index_list_size)+{+ return LZMA_STREAM_HEADER_SIZE + blocks_size+ + index_size(count, index_list_size)+ + LZMA_STREAM_HEADER_SIZE;+}++#endif
+ cbits/liblzma/common/index_decoder.c view
@@ -0,0 +1,352 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file index_decoder.c+/// \brief Decodes the Index field+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "index.h"+#include "check.h"+++typedef struct {+ enum {+ SEQ_INDICATOR,+ SEQ_COUNT,+ SEQ_MEMUSAGE,+ SEQ_UNPADDED,+ SEQ_UNCOMPRESSED,+ SEQ_PADDING_INIT,+ SEQ_PADDING,+ SEQ_CRC32,+ } sequence;++ /// Memory usage limit+ uint64_t memlimit;++ /// Target Index+ lzma_index *index;++ /// Pointer give by the application, which is set after+ /// successful decoding.+ lzma_index **index_ptr;++ /// Number of Records left to decode.+ lzma_vli count;++ /// The most recent Unpadded Size field+ lzma_vli unpadded_size;++ /// The most recent Uncompressed Size field+ lzma_vli uncompressed_size;++ /// Position in integers+ size_t pos;++ /// CRC32 of the List of Records field+ uint32_t crc32;+} lzma_index_coder;+++static lzma_ret+index_decode(void *coder_ptr, const lzma_allocator *allocator,+ const uint8_t *restrict in, size_t *restrict in_pos,+ size_t in_size,+ uint8_t *restrict out lzma_attribute((__unused__)),+ size_t *restrict out_pos lzma_attribute((__unused__)),+ size_t out_size lzma_attribute((__unused__)),+ lzma_action action lzma_attribute((__unused__)))+{+ lzma_index_coder *coder = coder_ptr;++ // Similar optimization as in index_encoder.c+ const size_t in_start = *in_pos;+ lzma_ret ret = LZMA_OK;++ while (*in_pos < in_size)+ switch (coder->sequence) {+ case SEQ_INDICATOR:+ // Return LZMA_DATA_ERROR instead of e.g. LZMA_PROG_ERROR or+ // LZMA_FORMAT_ERROR, because a typical usage case for Index+ // decoder is when parsing the Stream backwards. If seeking+ // backward from the Stream Footer gives us something that+ // doesn't begin with Index Indicator, the file is considered+ // corrupt, not "programming error" or "unrecognized file+ // format". One could argue that the application should+ // verify the Index Indicator before trying to decode the+ // Index, but well, I suppose it is simpler this way.+ if (in[(*in_pos)++] != 0x00)+ return LZMA_DATA_ERROR;++ coder->sequence = SEQ_COUNT;+ break;++ case SEQ_COUNT:+ ret = lzma_vli_decode(&coder->count, &coder->pos,+ in, in_pos, in_size);+ if (ret != LZMA_STREAM_END)+ goto out;++ coder->pos = 0;+ coder->sequence = SEQ_MEMUSAGE;++ // Fall through++ case SEQ_MEMUSAGE:+ if (lzma_index_memusage(1, coder->count) > coder->memlimit) {+ ret = LZMA_MEMLIMIT_ERROR;+ goto out;+ }++ // Tell the Index handling code how many Records this+ // Index has to allow it to allocate memory more efficiently.+ lzma_index_prealloc(coder->index, coder->count);++ ret = LZMA_OK;+ coder->sequence = coder->count == 0+ ? SEQ_PADDING_INIT : SEQ_UNPADDED;+ break;++ case SEQ_UNPADDED:+ case SEQ_UNCOMPRESSED: {+ lzma_vli *size = coder->sequence == SEQ_UNPADDED+ ? &coder->unpadded_size+ : &coder->uncompressed_size;++ ret = lzma_vli_decode(size, &coder->pos,+ in, in_pos, in_size);+ if (ret != LZMA_STREAM_END)+ goto out;++ ret = LZMA_OK;+ coder->pos = 0;++ if (coder->sequence == SEQ_UNPADDED) {+ // Validate that encoded Unpadded Size isn't too small+ // or too big.+ if (coder->unpadded_size < UNPADDED_SIZE_MIN+ || coder->unpadded_size+ > UNPADDED_SIZE_MAX)+ return LZMA_DATA_ERROR;++ coder->sequence = SEQ_UNCOMPRESSED;+ } else {+ // Add the decoded Record to the Index.+ return_if_error(lzma_index_append(+ coder->index, allocator,+ coder->unpadded_size,+ coder->uncompressed_size));++ // Check if this was the last Record.+ coder->sequence = --coder->count == 0+ ? SEQ_PADDING_INIT+ : SEQ_UNPADDED;+ }++ break;+ }++ case SEQ_PADDING_INIT:+ coder->pos = lzma_index_padding_size(coder->index);+ coder->sequence = SEQ_PADDING;++ // Fall through++ case SEQ_PADDING:+ if (coder->pos > 0) {+ --coder->pos;+ if (in[(*in_pos)++] != 0x00)+ return LZMA_DATA_ERROR;++ break;+ }++ // Finish the CRC32 calculation.+ coder->crc32 = lzma_crc32(in + in_start,+ *in_pos - in_start, coder->crc32);++ coder->sequence = SEQ_CRC32;++ // Fall through++ case SEQ_CRC32:+ do {+ if (*in_pos == in_size)+ return LZMA_OK;++ if (((coder->crc32 >> (coder->pos * 8)) & 0xFF)+ != in[(*in_pos)++])+ return LZMA_DATA_ERROR;++ } while (++coder->pos < 4);++ // Decoding was successful, now we can let the application+ // see the decoded Index.+ *coder->index_ptr = coder->index;++ // Make index NULL so we don't free it unintentionally.+ coder->index = NULL;++ return LZMA_STREAM_END;++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++out:+ // Update the CRC32,+ coder->crc32 = lzma_crc32(in + in_start,+ *in_pos - in_start, coder->crc32);++ return ret;+}+++static void+index_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_index_coder *coder = coder_ptr;+ lzma_index_end(coder->index, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+index_decoder_memconfig(void *coder_ptr, uint64_t *memusage,+ uint64_t *old_memlimit, uint64_t new_memlimit)+{+ lzma_index_coder *coder = coder_ptr;++ *memusage = lzma_index_memusage(1, coder->count);+ *old_memlimit = coder->memlimit;++ if (new_memlimit != 0) {+ if (new_memlimit < *memusage)+ return LZMA_MEMLIMIT_ERROR;++ coder->memlimit = new_memlimit;+ }++ return LZMA_OK;+}+++static lzma_ret+index_decoder_reset(lzma_index_coder *coder, const lzma_allocator *allocator,+ lzma_index **i, uint64_t memlimit)+{+ // Remember the pointer given by the application. We will set it+ // to point to the decoded Index only if decoding is successful.+ // Before that, keep it NULL so that applications can always safely+ // pass it to lzma_index_end() no matter did decoding succeed or not.+ coder->index_ptr = i;+ *i = NULL;++ // We always allocate a new lzma_index.+ coder->index = lzma_index_init(allocator);+ if (coder->index == NULL)+ return LZMA_MEM_ERROR;++ // Initialize the rest.+ coder->sequence = SEQ_INDICATOR;+ coder->memlimit = my_max(1, memlimit);+ coder->count = 0; // Needs to be initialized due to _memconfig().+ coder->pos = 0;+ coder->crc32 = 0;++ return LZMA_OK;+}+++static lzma_ret+index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ lzma_index **i, uint64_t memlimit)+{+ lzma_next_coder_init(&index_decoder_init, next, allocator);++ if (i == NULL)+ return LZMA_PROG_ERROR;++ lzma_index_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_index_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &index_decode;+ next->end = &index_decoder_end;+ next->memconfig = &index_decoder_memconfig;+ coder->index = NULL;+ } else {+ lzma_index_end(coder->index, allocator);+ }++ return index_decoder_reset(coder, allocator, i, memlimit);+}+++extern LZMA_API(lzma_ret)+lzma_index_decoder(lzma_stream *strm, lzma_index **i, uint64_t memlimit)+{+ lzma_next_strm_init(index_decoder_init, strm, i, memlimit);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit,+ const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size)+{+ // Sanity checks+ if (i == NULL || memlimit == NULL+ || in == NULL || in_pos == NULL || *in_pos > in_size)+ return LZMA_PROG_ERROR;++ // Initialize the decoder.+ lzma_index_coder coder;+ return_if_error(index_decoder_reset(&coder, allocator, i, *memlimit));++ // Store the input start position so that we can restore it in case+ // of an error.+ const size_t in_start = *in_pos;++ // Do the actual decoding.+ lzma_ret ret = index_decode(&coder, allocator, in, in_pos, in_size,+ NULL, NULL, 0, LZMA_RUN);++ if (ret == LZMA_STREAM_END) {+ ret = LZMA_OK;+ } else {+ // Something went wrong, free the Index structure and restore+ // the input position.+ lzma_index_end(coder.index, allocator);+ *in_pos = in_start;++ if (ret == LZMA_OK) {+ // The input is truncated or otherwise corrupt.+ // Use LZMA_DATA_ERROR instead of LZMA_BUF_ERROR+ // like lzma_vli_decode() does in single-call mode.+ ret = LZMA_DATA_ERROR;++ } else if (ret == LZMA_MEMLIMIT_ERROR) {+ // Tell the caller how much memory would have+ // been needed.+ *memlimit = lzma_index_memusage(1, coder.count);+ }+ }++ return ret;+}
+ cbits/liblzma/common/index_encoder.c view
@@ -0,0 +1,256 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file index_encoder.c+/// \brief Encodes the Index field+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "index_encoder.h"+#include "index.h"+#include "check.h"+++typedef struct {+ enum {+ SEQ_INDICATOR,+ SEQ_COUNT,+ SEQ_UNPADDED,+ SEQ_UNCOMPRESSED,+ SEQ_NEXT,+ SEQ_PADDING,+ SEQ_CRC32,+ } sequence;++ /// Index being encoded+ const lzma_index *index;++ /// Iterator for the Index being encoded+ lzma_index_iter iter;++ /// Position in integers+ size_t pos;++ /// CRC32 of the List of Records field+ uint32_t crc32;+} lzma_index_coder;+++static lzma_ret+index_encode(void *coder_ptr,+ const lzma_allocator *allocator lzma_attribute((__unused__)),+ const uint8_t *restrict in lzma_attribute((__unused__)),+ size_t *restrict in_pos lzma_attribute((__unused__)),+ size_t in_size lzma_attribute((__unused__)),+ uint8_t *restrict out, size_t *restrict out_pos,+ size_t out_size,+ lzma_action action lzma_attribute((__unused__)))+{+ lzma_index_coder *coder = coder_ptr;++ // Position where to start calculating CRC32. The idea is that we+ // need to call lzma_crc32() only once per call to index_encode().+ const size_t out_start = *out_pos;++ // Return value to use if we return at the end of this function.+ // We use "goto out" to jump out of the while-switch construct+ // instead of returning directly, because that way we don't need+ // to copypaste the lzma_crc32() call to many places.+ lzma_ret ret = LZMA_OK;++ while (*out_pos < out_size)+ switch (coder->sequence) {+ case SEQ_INDICATOR:+ out[*out_pos] = 0x00;+ ++*out_pos;+ coder->sequence = SEQ_COUNT;+ break;++ case SEQ_COUNT: {+ const lzma_vli count = lzma_index_block_count(coder->index);+ ret = lzma_vli_encode(count, &coder->pos,+ out, out_pos, out_size);+ if (ret != LZMA_STREAM_END)+ goto out;++ ret = LZMA_OK;+ coder->pos = 0;+ coder->sequence = SEQ_NEXT;+ break;+ }++ case SEQ_NEXT:+ if (lzma_index_iter_next(+ &coder->iter, LZMA_INDEX_ITER_BLOCK)) {+ // Get the size of the Index Padding field.+ coder->pos = lzma_index_padding_size(coder->index);+ assert(coder->pos <= 3);+ coder->sequence = SEQ_PADDING;+ break;+ }++ coder->sequence = SEQ_UNPADDED;++ // Fall through++ case SEQ_UNPADDED:+ case SEQ_UNCOMPRESSED: {+ const lzma_vli size = coder->sequence == SEQ_UNPADDED+ ? coder->iter.block.unpadded_size+ : coder->iter.block.uncompressed_size;++ ret = lzma_vli_encode(size, &coder->pos,+ out, out_pos, out_size);+ if (ret != LZMA_STREAM_END)+ goto out;++ ret = LZMA_OK;+ coder->pos = 0;++ // Advance to SEQ_UNCOMPRESSED or SEQ_NEXT.+ ++coder->sequence;+ break;+ }++ case SEQ_PADDING:+ if (coder->pos > 0) {+ --coder->pos;+ out[(*out_pos)++] = 0x00;+ break;+ }++ // Finish the CRC32 calculation.+ coder->crc32 = lzma_crc32(out + out_start,+ *out_pos - out_start, coder->crc32);++ coder->sequence = SEQ_CRC32;++ // Fall through++ case SEQ_CRC32:+ // We don't use the main loop, because we don't want+ // coder->crc32 to be touched anymore.+ do {+ if (*out_pos == out_size)+ return LZMA_OK;++ out[*out_pos] = (coder->crc32 >> (coder->pos * 8))+ & 0xFF;+ ++*out_pos;++ } while (++coder->pos < 4);++ return LZMA_STREAM_END;++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++out:+ // Update the CRC32.+ coder->crc32 = lzma_crc32(out + out_start,+ *out_pos - out_start, coder->crc32);++ return ret;+}+++static void+index_encoder_end(void *coder, const lzma_allocator *allocator)+{+ lzma_free(coder, allocator);+ return;+}+++static void+index_encoder_reset(lzma_index_coder *coder, const lzma_index *i)+{+ lzma_index_iter_init(&coder->iter, i);++ coder->sequence = SEQ_INDICATOR;+ coder->index = i;+ coder->pos = 0;+ coder->crc32 = 0;++ return;+}+++extern lzma_ret+lzma_index_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_index *i)+{+ lzma_next_coder_init(&lzma_index_encoder_init, next, allocator);++ if (i == NULL)+ return LZMA_PROG_ERROR;++ if (next->coder == NULL) {+ next->coder = lzma_alloc(sizeof(lzma_index_coder), allocator);+ if (next->coder == NULL)+ return LZMA_MEM_ERROR;++ next->code = &index_encode;+ next->end = &index_encoder_end;+ }++ index_encoder_reset(next->coder, i);++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_encoder(lzma_stream *strm, const lzma_index *i)+{+ lzma_next_strm_init(lzma_index_encoder_init, strm, i);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_buffer_encode(const lzma_index *i,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Validate the arguments.+ if (i == NULL || out == NULL || out_pos == NULL || *out_pos > out_size)+ return LZMA_PROG_ERROR;++ // Don't try to encode if there's not enough output space.+ if (out_size - *out_pos < lzma_index_size(i))+ return LZMA_BUF_ERROR;++ // The Index encoder needs just one small data structure so we can+ // allocate it on stack.+ lzma_index_coder coder;+ index_encoder_reset(&coder, i);++ // Do the actual encoding. This should never fail, but store+ // the original *out_pos just in case.+ const size_t out_start = *out_pos;+ lzma_ret ret = index_encode(&coder, NULL, NULL, NULL, 0,+ out, out_pos, out_size, LZMA_RUN);++ if (ret == LZMA_STREAM_END) {+ ret = LZMA_OK;+ } else {+ // We should never get here, but just in case, restore the+ // output position and set the error accordingly if something+ // goes wrong and debugging isn't enabled.+ assert(0);+ *out_pos = out_start;+ ret = LZMA_PROG_ERROR;+ }++ return ret;+}
+ cbits/liblzma/common/index_encoder.h view
@@ -0,0 +1,23 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file index_encoder.h+/// \brief Encodes the Index field+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_INDEX_ENCODER_H+#define LZMA_INDEX_ENCODER_H++#include "common.h"+++extern lzma_ret lzma_index_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator, const lzma_index *i);+++#endif
+ cbits/liblzma/common/index_hash.c view
@@ -0,0 +1,334 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file index_hash.c+/// \brief Validates Index by using a hash function+//+// 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 "index.h"+#include "check.h"+++typedef struct {+ /// Sum of the Block sizes (including Block Padding)+ lzma_vli blocks_size;++ /// Sum of the Uncompressed Size fields+ lzma_vli uncompressed_size;++ /// Number of Records+ lzma_vli count;++ /// Size of the List of Index Records as bytes+ lzma_vli index_list_size;++ /// Check calculated from Unpadded Sizes and Uncompressed Sizes.+ lzma_check_state check;++} lzma_index_hash_info;+++struct lzma_index_hash_s {+ enum {+ SEQ_BLOCK,+ SEQ_COUNT,+ SEQ_UNPADDED,+ SEQ_UNCOMPRESSED,+ SEQ_PADDING_INIT,+ SEQ_PADDING,+ SEQ_CRC32,+ } sequence;++ /// Information collected while decoding the actual Blocks.+ lzma_index_hash_info blocks;++ /// Information collected from the Index field.+ lzma_index_hash_info records;++ /// Number of Records not fully decoded+ lzma_vli remaining;++ /// Unpadded Size currently being read from an Index Record.+ lzma_vli unpadded_size;++ /// Uncompressed Size currently being read from an Index Record.+ lzma_vli uncompressed_size;++ /// Position in variable-length integers when decoding them from+ /// the List of Records.+ size_t pos;++ /// CRC32 of the Index+ uint32_t crc32;+};+++extern LZMA_API(lzma_index_hash *)+lzma_index_hash_init(lzma_index_hash *index_hash,+ const lzma_allocator *allocator)+{+ if (index_hash == NULL) {+ index_hash = lzma_alloc(sizeof(lzma_index_hash), allocator);+ if (index_hash == NULL)+ return NULL;+ }++ index_hash->sequence = SEQ_BLOCK;+ index_hash->blocks.blocks_size = 0;+ index_hash->blocks.uncompressed_size = 0;+ index_hash->blocks.count = 0;+ index_hash->blocks.index_list_size = 0;+ index_hash->records.blocks_size = 0;+ index_hash->records.uncompressed_size = 0;+ index_hash->records.count = 0;+ index_hash->records.index_list_size = 0;+ index_hash->unpadded_size = 0;+ index_hash->uncompressed_size = 0;+ index_hash->pos = 0;+ index_hash->crc32 = 0;++ // These cannot fail because LZMA_CHECK_BEST is known to be supported.+ (void)lzma_check_init(&index_hash->blocks.check, LZMA_CHECK_BEST);+ (void)lzma_check_init(&index_hash->records.check, LZMA_CHECK_BEST);++ return index_hash;+}+++extern LZMA_API(void)+lzma_index_hash_end(lzma_index_hash *index_hash,+ const lzma_allocator *allocator)+{+ lzma_free(index_hash, allocator);+ return;+}+++extern LZMA_API(lzma_vli)+lzma_index_hash_size(const lzma_index_hash *index_hash)+{+ // Get the size of the Index from ->blocks instead of ->records for+ // cases where application wants to know the Index Size before+ // decoding the Index.+ return index_size(index_hash->blocks.count,+ index_hash->blocks.index_list_size);+}+++/// Updates the sizes and the hash without any validation.+static lzma_ret+hash_append(lzma_index_hash_info *info, lzma_vli unpadded_size,+ lzma_vli uncompressed_size)+{+ info->blocks_size += vli_ceil4(unpadded_size);+ info->uncompressed_size += uncompressed_size;+ info->index_list_size += lzma_vli_size(unpadded_size)+ + lzma_vli_size(uncompressed_size);+ ++info->count;++ const lzma_vli sizes[2] = { unpadded_size, uncompressed_size };+ lzma_check_update(&info->check, LZMA_CHECK_BEST,+ (const uint8_t *)(sizes), sizeof(sizes));++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_hash_append(lzma_index_hash *index_hash, lzma_vli unpadded_size,+ lzma_vli uncompressed_size)+{+ // Validate the arguments.+ if (index_hash->sequence != SEQ_BLOCK+ || unpadded_size < UNPADDED_SIZE_MIN+ || unpadded_size > UNPADDED_SIZE_MAX+ || uncompressed_size > LZMA_VLI_MAX)+ return LZMA_PROG_ERROR;++ // Update the hash.+ return_if_error(hash_append(&index_hash->blocks,+ unpadded_size, uncompressed_size));++ // Validate the properties of *info are still in allowed limits.+ if (index_hash->blocks.blocks_size > LZMA_VLI_MAX+ || index_hash->blocks.uncompressed_size > LZMA_VLI_MAX+ || index_size(index_hash->blocks.count,+ index_hash->blocks.index_list_size)+ > LZMA_BACKWARD_SIZE_MAX+ || index_stream_size(index_hash->blocks.blocks_size,+ index_hash->blocks.count,+ index_hash->blocks.index_list_size)+ > LZMA_VLI_MAX)+ return LZMA_DATA_ERROR;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_index_hash_decode(lzma_index_hash *index_hash, const uint8_t *in,+ size_t *in_pos, size_t in_size)+{+ // Catch zero input buffer here, because in contrast to Index encoder+ // and decoder functions, applications call this function directly+ // instead of via lzma_code(), which does the buffer checking.+ if (*in_pos >= in_size)+ return LZMA_BUF_ERROR;++ // NOTE: This function has many similarities to index_encode() and+ // index_decode() functions found from index_encoder.c and+ // index_decoder.c. See the comments especially in index_encoder.c.+ const size_t in_start = *in_pos;+ lzma_ret ret = LZMA_OK;++ while (*in_pos < in_size)+ switch (index_hash->sequence) {+ case SEQ_BLOCK:+ // Check the Index Indicator is present.+ if (in[(*in_pos)++] != 0x00)+ return LZMA_DATA_ERROR;++ index_hash->sequence = SEQ_COUNT;+ break;++ case SEQ_COUNT: {+ ret = lzma_vli_decode(&index_hash->remaining,+ &index_hash->pos, in, in_pos, in_size);+ if (ret != LZMA_STREAM_END)+ goto out;++ // The count must match the count of the Blocks decoded.+ if (index_hash->remaining != index_hash->blocks.count)+ return LZMA_DATA_ERROR;++ ret = LZMA_OK;+ index_hash->pos = 0;++ // Handle the special case when there are no Blocks.+ index_hash->sequence = index_hash->remaining == 0+ ? SEQ_PADDING_INIT : SEQ_UNPADDED;+ break;+ }++ case SEQ_UNPADDED:+ case SEQ_UNCOMPRESSED: {+ lzma_vli *size = index_hash->sequence == SEQ_UNPADDED+ ? &index_hash->unpadded_size+ : &index_hash->uncompressed_size;++ ret = lzma_vli_decode(size, &index_hash->pos,+ in, in_pos, in_size);+ if (ret != LZMA_STREAM_END)+ goto out;++ ret = LZMA_OK;+ index_hash->pos = 0;++ if (index_hash->sequence == SEQ_UNPADDED) {+ if (index_hash->unpadded_size < UNPADDED_SIZE_MIN+ || index_hash->unpadded_size+ > UNPADDED_SIZE_MAX)+ return LZMA_DATA_ERROR;++ index_hash->sequence = SEQ_UNCOMPRESSED;+ } else {+ // Update the hash.+ return_if_error(hash_append(&index_hash->records,+ index_hash->unpadded_size,+ index_hash->uncompressed_size));++ // Verify that we don't go over the known sizes. Note+ // that this validation is simpler than the one used+ // in lzma_index_hash_append(), because here we know+ // that values in index_hash->blocks are already+ // validated and we are fine as long as we don't+ // exceed them in index_hash->records.+ if (index_hash->blocks.blocks_size+ < index_hash->records.blocks_size+ || index_hash->blocks.uncompressed_size+ < index_hash->records.uncompressed_size+ || index_hash->blocks.index_list_size+ < index_hash->records.index_list_size)+ return LZMA_DATA_ERROR;++ // Check if this was the last Record.+ index_hash->sequence = --index_hash->remaining == 0+ ? SEQ_PADDING_INIT : SEQ_UNPADDED;+ }++ break;+ }++ case SEQ_PADDING_INIT:+ index_hash->pos = (LZMA_VLI_C(4) - index_size_unpadded(+ index_hash->records.count,+ index_hash->records.index_list_size)) & 3;+ index_hash->sequence = SEQ_PADDING;++ // Fall through++ case SEQ_PADDING:+ if (index_hash->pos > 0) {+ --index_hash->pos;+ if (in[(*in_pos)++] != 0x00)+ return LZMA_DATA_ERROR;++ break;+ }++ // Compare the sizes.+ if (index_hash->blocks.blocks_size+ != index_hash->records.blocks_size+ || index_hash->blocks.uncompressed_size+ != index_hash->records.uncompressed_size+ || index_hash->blocks.index_list_size+ != index_hash->records.index_list_size)+ return LZMA_DATA_ERROR;++ // Finish the hashes and compare them.+ lzma_check_finish(&index_hash->blocks.check, LZMA_CHECK_BEST);+ lzma_check_finish(&index_hash->records.check, LZMA_CHECK_BEST);+ if (memcmp(index_hash->blocks.check.buffer.u8,+ index_hash->records.check.buffer.u8,+ lzma_check_size(LZMA_CHECK_BEST)) != 0)+ return LZMA_DATA_ERROR;++ // Finish the CRC32 calculation.+ index_hash->crc32 = lzma_crc32(in + in_start,+ *in_pos - in_start, index_hash->crc32);++ index_hash->sequence = SEQ_CRC32;++ // Fall through++ case SEQ_CRC32:+ do {+ if (*in_pos == in_size)+ return LZMA_OK;++ if (((index_hash->crc32 >> (index_hash->pos * 8))+ & 0xFF) != in[(*in_pos)++])+ return LZMA_DATA_ERROR;++ } while (++index_hash->pos < 4);++ return LZMA_STREAM_END;++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++out:+ // Update the CRC32,+ index_hash->crc32 = lzma_crc32(in + in_start,+ *in_pos - in_start, index_hash->crc32);++ return ret;+}
+ cbits/liblzma/common/memcmplen.h view
@@ -0,0 +1,164 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \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+++/// 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.+///+/// \note LZMA_MEMCMPLEN_EXTRA defines how many extra bytes may be read.+/// It's rounded up to 2^n. This extra amount needs to be+/// allocated in the buffers being used. It needs to be+/// initialized too to keep Valgrind quiet.+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().+#define LZMA_MEMCMPLEN_EXTRA 8+ while (len < limit) {+ const uint64_t x = read64ne(buf1 + len) - read64ne(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.+# define LZMA_MEMCMPLEN_EXTRA 16+ 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) {+ len += ctz32(x);+ return my_min(len, limit);+ }++ len += 16;+ }++ return limit;++#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && !defined(WORDS_BIGENDIAN)+ // Generic 32-bit little endian method+# define LZMA_MEMCMPLEN_EXTRA 4+ while (len < limit) {+ uint32_t x = read32ne(buf1 + len) - read32ne(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+# define LZMA_MEMCMPLEN_EXTRA 4+ while (len < limit) {+ uint32_t x = read32ne(buf1 + len) ^ read32ne(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.+# define LZMA_MEMCMPLEN_EXTRA 0+ while (len < limit && buf1[len] == buf2[len])+ ++len;++ return len;+#endif+}++#endif
+ cbits/liblzma/common/outqueue.c view
@@ -0,0 +1,184 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file outqueue.c+/// \brief Output queue handling in multithreaded coding+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "outqueue.h"+++/// This is to ease integer overflow checking: We may allocate up to+/// 2 * LZMA_THREADS_MAX buffers and we need some extra memory for other+/// data structures (that's the second /2).+#define BUF_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX / 2 / 2)+++static lzma_ret+get_options(uint64_t *bufs_alloc_size, uint32_t *bufs_count,+ uint64_t buf_size_max, uint32_t threads)+{+ if (threads > LZMA_THREADS_MAX || buf_size_max > BUF_SIZE_MAX)+ return LZMA_OPTIONS_ERROR;++ // The number of buffers is twice the number of threads.+ // This wastes RAM but keeps the threads busy when buffers+ // finish out of order.+ //+ // NOTE: If this is changed, update BUF_SIZE_MAX too.+ *bufs_count = threads * 2;+ *bufs_alloc_size = *bufs_count * buf_size_max;++ return LZMA_OK;+}+++extern uint64_t+lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads)+{+ uint64_t bufs_alloc_size;+ uint32_t bufs_count;++ if (get_options(&bufs_alloc_size, &bufs_count, buf_size_max, threads)+ != LZMA_OK)+ return UINT64_MAX;++ return sizeof(lzma_outq) + bufs_count * sizeof(lzma_outbuf)+ + bufs_alloc_size;+}+++extern lzma_ret+lzma_outq_init(lzma_outq *outq, const lzma_allocator *allocator,+ uint64_t buf_size_max, uint32_t threads)+{+ uint64_t bufs_alloc_size;+ uint32_t bufs_count;++ // Set bufs_count and bufs_alloc_size.+ return_if_error(get_options(&bufs_alloc_size, &bufs_count,+ buf_size_max, threads));++ // Allocate memory if needed.+ if (outq->buf_size_max != buf_size_max+ || outq->bufs_allocated != bufs_count) {+ lzma_outq_end(outq, allocator);++#if SIZE_MAX < UINT64_MAX+ if (bufs_alloc_size > SIZE_MAX)+ return LZMA_MEM_ERROR;+#endif++ outq->bufs = lzma_alloc(bufs_count * sizeof(lzma_outbuf),+ allocator);+ outq->bufs_mem = lzma_alloc((size_t)(bufs_alloc_size),+ allocator);++ if (outq->bufs == NULL || outq->bufs_mem == NULL) {+ lzma_outq_end(outq, allocator);+ return LZMA_MEM_ERROR;+ }+ }++ // Initialize the rest of the main structure. Initialization of+ // outq->bufs[] is done when they are actually needed.+ outq->buf_size_max = (size_t)(buf_size_max);+ outq->bufs_allocated = bufs_count;+ outq->bufs_pos = 0;+ outq->bufs_used = 0;+ outq->read_pos = 0;++ return LZMA_OK;+}+++extern void+lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator)+{+ lzma_free(outq->bufs, allocator);+ outq->bufs = NULL;++ lzma_free(outq->bufs_mem, allocator);+ outq->bufs_mem = NULL;++ return;+}+++extern lzma_outbuf *+lzma_outq_get_buf(lzma_outq *outq)+{+ // Caller must have checked it with lzma_outq_has_buf().+ assert(outq->bufs_used < outq->bufs_allocated);++ // Initialize the new buffer.+ lzma_outbuf *buf = &outq->bufs[outq->bufs_pos];+ buf->buf = outq->bufs_mem + outq->bufs_pos * outq->buf_size_max;+ buf->size = 0;+ buf->finished = false;++ // Update the queue state.+ if (++outq->bufs_pos == outq->bufs_allocated)+ outq->bufs_pos = 0;++ ++outq->bufs_used;++ return buf;+}+++extern bool+lzma_outq_is_readable(const lzma_outq *outq)+{+ uint32_t i = outq->bufs_pos - outq->bufs_used;+ if (outq->bufs_pos < outq->bufs_used)+ i += outq->bufs_allocated;++ return outq->bufs[i].finished;+}+++extern lzma_ret+lzma_outq_read(lzma_outq *restrict outq, uint8_t *restrict out,+ size_t *restrict out_pos, size_t out_size,+ lzma_vli *restrict unpadded_size,+ lzma_vli *restrict uncompressed_size)+{+ // There must be at least one buffer from which to read.+ if (outq->bufs_used == 0)+ return LZMA_OK;++ // Get the buffer.+ uint32_t i = outq->bufs_pos - outq->bufs_used;+ if (outq->bufs_pos < outq->bufs_used)+ i += outq->bufs_allocated;++ lzma_outbuf *buf = &outq->bufs[i];++ // If it isn't finished yet, we cannot read from it.+ if (!buf->finished)+ return LZMA_OK;++ // Copy from the buffer to output.+ lzma_bufcpy(buf->buf, &outq->read_pos, buf->size,+ out, out_pos, out_size);++ // Return if we didn't get all the data from the buffer.+ if (outq->read_pos < buf->size)+ return LZMA_OK;++ // The buffer was finished. Tell the caller its size information.+ *unpadded_size = buf->unpadded_size;+ *uncompressed_size = buf->uncompressed_size;++ // Free this buffer for further use.+ --outq->bufs_used;+ outq->read_pos = 0;++ return LZMA_STREAM_END;+}
+ cbits/liblzma/common/outqueue.h view
@@ -0,0 +1,156 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file outqueue.h+/// \brief Output queue handling in multithreaded coding+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++/// Output buffer for a single thread+typedef struct {+ /// Pointer to the output buffer of lzma_outq.buf_size_max bytes+ uint8_t *buf;++ /// Amount of data written to buf+ size_t size;++ /// Additional size information+ lzma_vli unpadded_size;+ lzma_vli uncompressed_size;++ /// True when no more data will be written into this buffer.+ ///+ /// \note This is read by another thread and thus access+ /// to this variable needs a mutex.+ bool finished;++} lzma_outbuf;+++typedef struct {+ /// Array of buffers that are used cyclically.+ lzma_outbuf *bufs;++ /// Memory allocated for all the buffers+ uint8_t *bufs_mem;++ /// Amount of buffer space available in each buffer+ size_t buf_size_max;++ /// Number of buffers allocated+ uint32_t bufs_allocated;++ /// Position in the bufs array. The next buffer to be taken+ /// into use is bufs[bufs_pos].+ uint32_t bufs_pos;++ /// Number of buffers in use+ uint32_t bufs_used;++ /// Position in the buffer in lzma_outq_read()+ size_t read_pos;++} lzma_outq;+++/**+ * \brief Calculate the memory usage of an output queue+ *+ * \return Approximate memory usage in bytes or UINT64_MAX on error.+ */+extern uint64_t lzma_outq_memusage(uint64_t buf_size_max, uint32_t threads);+++/// \brief Initialize an output queue+///+/// \param outq Pointer to an output queue. Before calling+/// this function the first time, *outq should+/// have been zeroed with memzero() so that this+/// function knows that there are no previous+/// allocations to free.+/// \param allocator Pointer to allocator or NULL+/// \param buf_size_max Maximum amount of data that a single buffer+/// in the queue may need to store.+/// \param threads Number of buffers that may be in use+/// concurrently. Note that more than this number+/// of buffers will actually get allocated to+/// improve performance when buffers finish+/// out of order.+///+/// \return - LZMA_OK+/// - LZMA_MEM_ERROR+///+extern lzma_ret lzma_outq_init(+ lzma_outq *outq, const lzma_allocator *allocator,+ uint64_t buf_size_max, uint32_t threads);+++/// \brief Free the memory associated with the output queue+extern void lzma_outq_end(lzma_outq *outq, const lzma_allocator *allocator);+++/// \brief Get a new buffer+///+/// lzma_outq_has_buf() must be used to check that there is a buffer+/// available before calling lzma_outq_get_buf().+///+extern lzma_outbuf *lzma_outq_get_buf(lzma_outq *outq);+++/// \brief Test if there is data ready to be read+///+/// Call to this function must be protected with the same mutex that+/// is used to protect lzma_outbuf.finished.+///+extern bool lzma_outq_is_readable(const lzma_outq *outq);+++/// \brief Read finished data+///+/// \param outq Pointer to an output queue+/// \param out Beginning of the output buffer+/// \param out_pos The next byte will be written to+/// out[*out_pos].+/// \param out_size Size of the out buffer; the first byte into+/// which no data is written to is out[out_size].+/// \param unpadded_size Unpadded Size from the Block encoder+/// \param uncompressed_size Uncompressed Size from the Block encoder+///+/// \return - LZMA: All OK. Either no data was available or the buffer+/// being read didn't become empty yet.+/// - LZMA_STREAM_END: The buffer being read was finished.+/// *unpadded_size and *uncompressed_size were set.+///+/// \note This reads lzma_outbuf.finished variables and thus call+/// to this function needs to be protected with a mutex.+///+extern lzma_ret lzma_outq_read(lzma_outq *restrict outq,+ uint8_t *restrict out, size_t *restrict out_pos,+ size_t out_size, lzma_vli *restrict unpadded_size,+ lzma_vli *restrict uncompressed_size);+++/// \brief Test if there is at least one buffer free+///+/// This must be used before getting a new buffer with lzma_outq_get_buf().+///+static inline bool+lzma_outq_has_buf(const lzma_outq *outq)+{+ return outq->bufs_used < outq->bufs_allocated;+}+++/// \brief Test if the queue is completely empty+static inline bool+lzma_outq_is_empty(const lzma_outq *outq)+{+ return outq->bufs_used == 0;+}
+ cbits/liblzma/common/stream_buffer_decoder.c view
@@ -0,0 +1,91 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_buffer_decoder.c+/// \brief Single-call .xz Stream decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "stream_decoder.h"+++extern LZMA_API(lzma_ret)+lzma_stream_buffer_decode(uint64_t *memlimit, uint32_t flags,+ const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ // Sanity checks+ if (in_pos == NULL || (in == NULL && *in_pos != in_size)+ || *in_pos > in_size || out_pos == NULL+ || (out == NULL && *out_pos != out_size)+ || *out_pos > out_size)+ return LZMA_PROG_ERROR;++ // Catch flags that are not allowed in buffer-to-buffer decoding.+ if (flags & LZMA_TELL_ANY_CHECK)+ return LZMA_PROG_ERROR;++ // Initialize the Stream decoder.+ // TODO: We need something to tell the decoder that it can use the+ // output buffer as workspace, and thus save significant amount of RAM.+ lzma_next_coder stream_decoder = LZMA_NEXT_CODER_INIT;+ lzma_ret ret = lzma_stream_decoder_init(+ &stream_decoder, allocator, *memlimit, flags);++ if (ret == LZMA_OK) {+ // Save the positions so that we can restore them in case+ // an error occurs.+ const size_t in_start = *in_pos;+ const size_t out_start = *out_pos;++ // Do the actual decoding.+ ret = stream_decoder.code(stream_decoder.coder, allocator,+ in, in_pos, in_size, out, out_pos, out_size,+ LZMA_FINISH);++ if (ret == LZMA_STREAM_END) {+ ret = LZMA_OK;+ } else {+ // Something went wrong, restore the positions.+ *in_pos = in_start;+ *out_pos = out_start;++ if (ret == LZMA_OK) {+ // Either the input was truncated or the+ // output buffer was too small.+ assert(*in_pos == in_size+ || *out_pos == out_size);++ // If all the input was consumed, then the+ // input is truncated, even if the output+ // buffer is also full. This is because+ // processing the last byte of the Stream+ // never produces output.+ if (*in_pos == in_size)+ ret = LZMA_DATA_ERROR;+ else+ ret = LZMA_BUF_ERROR;++ } else if (ret == LZMA_MEMLIMIT_ERROR) {+ // Let the caller know how much memory would+ // have been needed.+ uint64_t memusage;+ (void)stream_decoder.memconfig(+ stream_decoder.coder,+ memlimit, &memusage, 0);+ }+ }+ }++ // Free the decoder memory. This needs to be done even if+ // initialization fails, because the internal API doesn't+ // require the initialization function to free its memory on error.+ lzma_next_end(&stream_decoder, allocator);++ return ret;+}
+ cbits/liblzma/common/stream_buffer_encoder.c view
@@ -0,0 +1,141 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_buffer_encoder.c+/// \brief Single-call .xz Stream encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "index.h"+++/// Maximum size of Index that has exactly one Record.+/// Index Indicator + Number of Records + Record + CRC32 rounded up to+/// the next multiple of four.+#define INDEX_BOUND ((1 + 1 + 2 * LZMA_VLI_BYTES_MAX + 4 + 3) & ~3)++/// Stream Header, Stream Footer, and Index+#define HEADERS_BOUND (2 * LZMA_STREAM_HEADER_SIZE + INDEX_BOUND)+++extern LZMA_API(size_t)+lzma_stream_buffer_bound(size_t uncompressed_size)+{+ // Get the maximum possible size of a Block.+ const size_t block_bound = lzma_block_buffer_bound(uncompressed_size);+ if (block_bound == 0)+ return 0;++ // Catch the possible integer overflow and also prevent the size of+ // the Stream exceeding LZMA_VLI_MAX (theoretically possible on+ // 64-bit systems).+ if (my_min(SIZE_MAX, LZMA_VLI_MAX) - block_bound < HEADERS_BOUND)+ return 0;++ return block_bound + HEADERS_BOUND;+}+++extern LZMA_API(lzma_ret)+lzma_stream_buffer_encode(lzma_filter *filters, lzma_check check,+ const lzma_allocator *allocator,+ const uint8_t *in, size_t in_size,+ uint8_t *out, size_t *out_pos_ptr, size_t out_size)+{+ // Sanity checks+ if (filters == NULL || (unsigned int)(check) > LZMA_CHECK_ID_MAX+ || (in == NULL && in_size != 0) || out == NULL+ || out_pos_ptr == NULL || *out_pos_ptr > out_size)+ return LZMA_PROG_ERROR;++ if (!lzma_check_is_supported(check))+ return LZMA_UNSUPPORTED_CHECK;++ // Note for the paranoids: Index encoder prevents the Stream from+ // getting too big and still being accepted with LZMA_OK, and Block+ // encoder catches if the input is too big. So we don't need to+ // separately check if the buffers are too big.++ // Use a local copy. We update *out_pos_ptr only if everything+ // succeeds.+ size_t out_pos = *out_pos_ptr;++ // Check that there's enough space for both Stream Header and+ // Stream Footer.+ if (out_size - out_pos <= 2 * LZMA_STREAM_HEADER_SIZE)+ return LZMA_BUF_ERROR;++ // Reserve space for Stream Footer so we don't need to check for+ // available space again before encoding Stream Footer.+ out_size -= LZMA_STREAM_HEADER_SIZE;++ // Encode the Stream Header.+ lzma_stream_flags stream_flags = {+ .version = 0,+ .check = check,+ };++ if (lzma_stream_header_encode(&stream_flags, out + out_pos)+ != LZMA_OK)+ return LZMA_PROG_ERROR;++ out_pos += LZMA_STREAM_HEADER_SIZE;++ // Encode a Block but only if there is at least one byte of input.+ lzma_block block = {+ .version = 0,+ .check = check,+ .filters = filters,+ };++ if (in_size > 0)+ return_if_error(lzma_block_buffer_encode(&block, allocator,+ in, in_size, out, &out_pos, out_size));++ // Index+ {+ // Create an Index. It will have one Record if there was+ // at least one byte of input to encode. Otherwise the+ // Index will be empty.+ lzma_index *i = lzma_index_init(allocator);+ if (i == NULL)+ return LZMA_MEM_ERROR;++ lzma_ret ret = LZMA_OK;++ if (in_size > 0)+ ret = lzma_index_append(i, allocator,+ lzma_block_unpadded_size(&block),+ block.uncompressed_size);++ // If adding the Record was successful, encode the Index+ // and get its size which will be stored into Stream Footer.+ if (ret == LZMA_OK) {+ ret = lzma_index_buffer_encode(+ i, out, &out_pos, out_size);++ stream_flags.backward_size = lzma_index_size(i);+ }++ lzma_index_end(i, allocator);++ if (ret != LZMA_OK)+ return ret;+ }++ // Stream Footer. We have already reserved space for this.+ if (lzma_stream_footer_encode(&stream_flags, out + out_pos)+ != LZMA_OK)+ return LZMA_PROG_ERROR;++ out_pos += LZMA_STREAM_HEADER_SIZE;++ // Everything went fine, make the new output position available+ // to the application.+ *out_pos_ptr = out_pos;+ return LZMA_OK;+}
+ cbits/liblzma/common/stream_decoder.c view
@@ -0,0 +1,467 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_decoder.c+/// \brief Decodes .xz Streams+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "stream_decoder.h"+#include "block_decoder.h"+++typedef struct {+ enum {+ SEQ_STREAM_HEADER,+ SEQ_BLOCK_HEADER,+ SEQ_BLOCK,+ SEQ_INDEX,+ SEQ_STREAM_FOOTER,+ SEQ_STREAM_PADDING,+ } sequence;++ /// Block or Metadata decoder. This takes little memory and the same+ /// data structure can be used to decode every Block Header, so it's+ /// a good idea to have a separate lzma_next_coder structure for it.+ lzma_next_coder block_decoder;++ /// Block options decoded by the Block Header decoder and used by+ /// the Block decoder.+ lzma_block block_options;++ /// Stream Flags from Stream Header+ lzma_stream_flags stream_flags;++ /// Index is hashed so that it can be compared to the sizes of Blocks+ /// with O(1) memory usage.+ lzma_index_hash *index_hash;++ /// Memory usage limit+ uint64_t memlimit;++ /// Amount of memory actually needed (only an estimate)+ uint64_t memusage;++ /// If true, LZMA_NO_CHECK is returned if the Stream has+ /// no integrity check.+ bool tell_no_check;++ /// If true, LZMA_UNSUPPORTED_CHECK is returned if the Stream has+ /// an integrity check that isn't supported by this liblzma build.+ bool tell_unsupported_check;++ /// 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+ /// in the middle of a Stream, and possible Stream Padding is a+ /// multiple of four bytes.+ bool concatenated;++ /// When decoding concatenated Streams, this is true as long as we+ /// are decoding the first Stream. This is needed to avoid misleading+ /// LZMA_FORMAT_ERROR in case the later Streams don't have valid magic+ /// bytes.+ bool first_stream;++ /// Write position in buffer[] and position in Stream Padding+ size_t pos;++ /// Buffer to hold Stream Header, Block Header, and Stream Footer.+ /// Block Header has biggest maximum size.+ uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];+} lzma_stream_coder;+++static lzma_ret+stream_decoder_reset(lzma_stream_coder *coder, const lzma_allocator *allocator)+{+ // Initialize the Index hash used to verify the Index.+ coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator);+ if (coder->index_hash == NULL)+ return LZMA_MEM_ERROR;++ // Reset the rest of the variables.+ coder->sequence = SEQ_STREAM_HEADER;+ coder->pos = 0;++ return LZMA_OK;+}+++static lzma_ret+stream_decode(void *coder_ptr, const 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_stream_coder *coder = coder_ptr;++ // When decoding the actual Block, it may be able to produce more+ // output even if we don't give it any new input.+ while (true)+ switch (coder->sequence) {+ case SEQ_STREAM_HEADER: {+ // Copy the Stream Header to the internal buffer.+ lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,+ LZMA_STREAM_HEADER_SIZE);++ // Return if we didn't get the whole Stream Header yet.+ if (coder->pos < LZMA_STREAM_HEADER_SIZE)+ return LZMA_OK;++ coder->pos = 0;++ // Decode the Stream Header.+ const lzma_ret ret = lzma_stream_header_decode(+ &coder->stream_flags, coder->buffer);+ if (ret != LZMA_OK)+ return ret == LZMA_FORMAT_ERROR && !coder->first_stream+ ? LZMA_DATA_ERROR : ret;++ // If we are decoding concatenated Streams, and the later+ // Streams have invalid Header Magic Bytes, we give+ // LZMA_DATA_ERROR instead of LZMA_FORMAT_ERROR.+ coder->first_stream = false;++ // Copy the type of the Check so that Block Header and Block+ // decoders see it.+ coder->block_options.check = coder->stream_flags.check;++ // Even if we return LZMA_*_CHECK below, we want+ // to continue from Block Header decoding.+ coder->sequence = SEQ_BLOCK_HEADER;++ // Detect if there's no integrity check or if it is+ // unsupported if those were requested by the application.+ if (coder->tell_no_check && coder->stream_flags.check+ == LZMA_CHECK_NONE)+ return LZMA_NO_CHECK;++ if (coder->tell_unsupported_check+ && !lzma_check_is_supported(+ coder->stream_flags.check))+ return LZMA_UNSUPPORTED_CHECK;++ if (coder->tell_any_check)+ return LZMA_GET_CHECK;+ }++ // Fall through++ case SEQ_BLOCK_HEADER: {+ if (*in_pos >= in_size)+ return LZMA_OK;++ if (coder->pos == 0) {+ // Detect if it's Index.+ if (in[*in_pos] == 0x00) {+ coder->sequence = SEQ_INDEX;+ break;+ }++ // Calculate the size of the Block Header. Note that+ // Block Header decoder wants to see this byte too+ // so don't advance *in_pos.+ coder->block_options.header_size+ = lzma_block_header_size_decode(+ in[*in_pos]);+ }++ // Copy the Block Header to the internal buffer.+ lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,+ coder->block_options.header_size);++ // Return if we didn't get the whole Block Header yet.+ if (coder->pos < coder->block_options.header_size)+ return LZMA_OK;++ coder->pos = 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+ // we don't need to do it here.+ lzma_filter filters[LZMA_FILTERS_MAX + 1];+ coder->block_options.filters = filters;++ // Decode the Block Header.+ 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;++ if (memusage == UINT64_MAX) {+ // One or more unknown Filter IDs.+ ret = LZMA_OPTIONS_ERROR;+ } else {+ // Now we can set coder->memusage since we know that+ // the filter chain is valid. We don't want+ // lzma_memusage() to return UINT64_MAX in case of+ // invalid filter chain.+ coder->memusage = memusage;++ if (memusage > coder->memlimit) {+ // The chain would need too much memory.+ ret = LZMA_MEMLIMIT_ERROR;+ } else {+ // Memory usage is OK.+ // Initialize the Block decoder.+ ret = lzma_block_decoder_init(+ &coder->block_decoder,+ allocator,+ &coder->block_options);+ }+ }++ // Free the allocated filter options since they are needed+ // only to initialize the Block decoder.+ for (size_t i = 0; i < LZMA_FILTERS_MAX; ++i)+ lzma_free(filters[i].options, allocator);++ coder->block_options.filters = NULL;++ // Check if memory usage calculation and Block enocoder+ // initialization succeeded.+ if (ret != LZMA_OK)+ return ret;++ coder->sequence = SEQ_BLOCK;+ }++ // Fall through++ case SEQ_BLOCK: {+ const lzma_ret ret = coder->block_decoder.code(+ coder->block_decoder.coder, allocator,+ in, in_pos, in_size, out, out_pos, out_size,+ action);++ if (ret != LZMA_STREAM_END)+ return ret;++ // Block decoded successfully. Add the new size pair to+ // the Index hash.+ return_if_error(lzma_index_hash_append(coder->index_hash,+ lzma_block_unpadded_size(+ &coder->block_options),+ coder->block_options.uncompressed_size));++ coder->sequence = SEQ_BLOCK_HEADER;+ break;+ }++ case SEQ_INDEX: {+ // If we don't have any input, don't call+ // lzma_index_hash_decode() since it would return+ // LZMA_BUF_ERROR, which we must not do here.+ if (*in_pos >= in_size)+ return LZMA_OK;++ // Decode the Index and compare it to the hash calculated+ // from the sizes of the Blocks (if any).+ const lzma_ret ret = lzma_index_hash_decode(coder->index_hash,+ in, in_pos, in_size);+ if (ret != LZMA_STREAM_END)+ return ret;++ coder->sequence = SEQ_STREAM_FOOTER;+ }++ // Fall through++ case SEQ_STREAM_FOOTER: {+ // Copy the Stream Footer to the internal buffer.+ lzma_bufcpy(in, in_pos, in_size, coder->buffer, &coder->pos,+ LZMA_STREAM_HEADER_SIZE);++ // Return if we didn't get the whole Stream Footer yet.+ if (coder->pos < LZMA_STREAM_HEADER_SIZE)+ return LZMA_OK;++ coder->pos = 0;++ // Decode the Stream Footer. The decoder gives+ // LZMA_FORMAT_ERROR if the magic bytes don't match,+ // so convert that return code to LZMA_DATA_ERROR.+ lzma_stream_flags footer_flags;+ const lzma_ret ret = lzma_stream_footer_decode(+ &footer_flags, coder->buffer);+ if (ret != LZMA_OK)+ return ret == LZMA_FORMAT_ERROR+ ? LZMA_DATA_ERROR : ret;++ // Check that Index Size stored in the Stream Footer matches+ // the real size of the Index field.+ if (lzma_index_hash_size(coder->index_hash)+ != footer_flags.backward_size)+ return LZMA_DATA_ERROR;++ // Compare that the Stream Flags fields are identical in+ // both Stream Header and Stream Footer.+ return_if_error(lzma_stream_flags_compare(+ &coder->stream_flags, &footer_flags));++ if (!coder->concatenated)+ return LZMA_STREAM_END;++ coder->sequence = SEQ_STREAM_PADDING;+ }++ // Fall through++ case SEQ_STREAM_PADDING:+ assert(coder->concatenated);++ // Skip over possible Stream Padding.+ while (true) {+ if (*in_pos >= in_size) {+ // Unless LZMA_FINISH was used, we cannot+ // know if there's more input coming later.+ if (action != LZMA_FINISH)+ return LZMA_OK;++ // Stream Padding must be a multiple of+ // four bytes.+ return coder->pos == 0+ ? LZMA_STREAM_END+ : LZMA_DATA_ERROR;+ }++ // If the byte is not zero, it probably indicates+ // beginning of a new Stream (or the file is corrupt).+ if (in[*in_pos] != 0x00)+ break;++ ++*in_pos;+ coder->pos = (coder->pos + 1) & 3;+ }++ // Stream Padding must be a multiple of four bytes (empty+ // Stream Padding is OK).+ if (coder->pos != 0) {+ ++*in_pos;+ return LZMA_DATA_ERROR;+ }++ // Prepare to decode the next Stream.+ return_if_error(stream_decoder_reset(coder, allocator));+ break;++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++ // Never reached+}+++static void+stream_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_stream_coder *coder = coder_ptr;+ lzma_next_end(&coder->block_decoder, allocator);+ lzma_index_hash_end(coder->index_hash, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_check+stream_decoder_get_check(const void *coder_ptr)+{+ const lzma_stream_coder *coder = coder_ptr;+ return coder->stream_flags.check;+}+++static lzma_ret+stream_decoder_memconfig(void *coder_ptr, uint64_t *memusage,+ uint64_t *old_memlimit, uint64_t new_memlimit)+{+ lzma_stream_coder *coder = coder_ptr;++ *memusage = coder->memusage;+ *old_memlimit = coder->memlimit;++ if (new_memlimit != 0) {+ if (new_memlimit < coder->memusage)+ return LZMA_MEMLIMIT_ERROR;++ coder->memlimit = new_memlimit;+ }++ return LZMA_OK;+}+++extern lzma_ret+lzma_stream_decoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ uint64_t memlimit, uint32_t flags)+{+ lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);++ if (flags & ~LZMA_SUPPORTED_FLAGS)+ return LZMA_OPTIONS_ERROR;++ lzma_stream_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &stream_decode;+ next->end = &stream_decoder_end;+ next->get_check = &stream_decoder_get_check;+ next->memconfig = &stream_decoder_memconfig;++ coder->block_decoder = LZMA_NEXT_CODER_INIT;+ coder->index_hash = NULL;+ }++ coder->memlimit = my_max(1, memlimit);+ coder->memusage = LZMA_MEMUSAGE_BASE;+ coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0;+ coder->tell_unsupported_check+ = (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0;+ coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;+ coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0;+ coder->concatenated = (flags & LZMA_CONCATENATED) != 0;+ coder->first_stream = true;++ return stream_decoder_reset(coder, allocator);+}+++extern LZMA_API(lzma_ret)+lzma_stream_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags)+{+ lzma_next_strm_init(lzma_stream_decoder_init, strm, memlimit, flags);++ strm->internal->supported_actions[LZMA_RUN] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/stream_decoder.h view
@@ -0,0 +1,22 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_decoder.h+/// \brief Decodes .xz Streams+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_STREAM_DECODER_H+#define LZMA_STREAM_DECODER_H++#include "common.h"++extern lzma_ret lzma_stream_decoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ uint64_t memlimit, uint32_t flags);++#endif
+ cbits/liblzma/common/stream_encoder.c view
@@ -0,0 +1,340 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_encoder.c+/// \brief Encodes .xz Streams+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "block_encoder.h"+#include "index_encoder.h"+++typedef struct {+ enum {+ SEQ_STREAM_HEADER,+ SEQ_BLOCK_INIT,+ SEQ_BLOCK_HEADER,+ SEQ_BLOCK_ENCODE,+ SEQ_INDEX_ENCODE,+ SEQ_STREAM_FOOTER,+ } sequence;++ /// True if Block encoder has been initialized by+ /// stream_encoder_init() or stream_encoder_update()+ /// and thus doesn't need to be initialized in stream_encode().+ bool block_encoder_is_initialized;++ /// Block+ lzma_next_coder block_encoder;++ /// Options for the Block encoder+ lzma_block block_options;++ /// The filter chain currently in use+ lzma_filter filters[LZMA_FILTERS_MAX + 1];++ /// Index encoder. This is separate from Block encoder, because this+ /// doesn't take much memory, and when encoding multiple Streams+ /// with the same encoding options we avoid reallocating memory.+ lzma_next_coder index_encoder;++ /// Index to hold sizes of the Blocks+ lzma_index *index;++ /// Read position in buffer[]+ size_t buffer_pos;++ /// Total number of bytes in buffer[]+ size_t buffer_size;++ /// Buffer to hold Stream Header, Block Header, and Stream Footer.+ /// Block Header has biggest maximum size.+ uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];+} lzma_stream_coder;+++static lzma_ret+block_encoder_init(lzma_stream_coder *coder, const lzma_allocator *allocator)+{+ // Prepare the Block options. Even though Block encoder doesn't need+ // compressed_size, uncompressed_size, and header_size to be+ // initialized, it is a good idea to do it here, because this way+ // we catch if someone gave us Filter ID that cannot be used in+ // Blocks/Streams.+ coder->block_options.compressed_size = LZMA_VLI_UNKNOWN;+ coder->block_options.uncompressed_size = LZMA_VLI_UNKNOWN;++ return_if_error(lzma_block_header_size(&coder->block_options));++ // Initialize the actual Block encoder.+ return lzma_block_encoder_init(&coder->block_encoder, allocator,+ &coder->block_options);+}+++static lzma_ret+stream_encode(void *coder_ptr, const 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_stream_coder *coder = coder_ptr;++ // Main loop+ while (*out_pos < out_size)+ switch (coder->sequence) {+ case SEQ_STREAM_HEADER:+ case SEQ_BLOCK_HEADER:+ case SEQ_STREAM_FOOTER:+ lzma_bufcpy(coder->buffer, &coder->buffer_pos,+ coder->buffer_size, out, out_pos, out_size);+ if (coder->buffer_pos < coder->buffer_size)+ return LZMA_OK;++ if (coder->sequence == SEQ_STREAM_FOOTER)+ return LZMA_STREAM_END;++ coder->buffer_pos = 0;+ ++coder->sequence;+ break;++ case SEQ_BLOCK_INIT: {+ if (*in_pos == in_size) {+ // If we are requested to flush or finish the current+ // Block, return LZMA_STREAM_END immediately since+ // there's nothing to do.+ if (action != LZMA_FINISH)+ return action == LZMA_RUN+ ? LZMA_OK : LZMA_STREAM_END;++ // The application had used LZMA_FULL_FLUSH to finish+ // the previous Block, but now wants to finish without+ // encoding new data, or it is simply creating an+ // empty Stream with no Blocks.+ //+ // Initialize the Index encoder, and continue to+ // actually encoding the Index.+ return_if_error(lzma_index_encoder_init(+ &coder->index_encoder, allocator,+ coder->index));+ coder->sequence = SEQ_INDEX_ENCODE;+ break;+ }++ // Initialize the Block encoder unless it was already+ // initialized by stream_encoder_init() or+ // stream_encoder_update().+ if (!coder->block_encoder_is_initialized)+ return_if_error(block_encoder_init(coder, allocator));++ // Make it false so that we don't skip the initialization+ // with the next Block.+ coder->block_encoder_is_initialized = false;++ // Encode the Block Header. This shouldn't fail since we have+ // already initialized the Block encoder.+ if (lzma_block_header_encode(&coder->block_options,+ coder->buffer) != LZMA_OK)+ return LZMA_PROG_ERROR;++ coder->buffer_size = coder->block_options.header_size;+ coder->sequence = SEQ_BLOCK_HEADER;+ break;+ }++ case SEQ_BLOCK_ENCODE: {+ static const lzma_action convert[LZMA_ACTION_MAX + 1] = {+ LZMA_RUN,+ LZMA_SYNC_FLUSH,+ LZMA_FINISH,+ LZMA_FINISH,+ LZMA_FINISH,+ };++ const lzma_ret ret = coder->block_encoder.code(+ coder->block_encoder.coder, allocator,+ in, in_pos, in_size,+ out, out_pos, out_size, convert[action]);+ if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)+ return ret;++ // Add a new Index Record.+ const lzma_vli unpadded_size = lzma_block_unpadded_size(+ &coder->block_options);+ assert(unpadded_size != 0);+ return_if_error(lzma_index_append(coder->index, allocator,+ unpadded_size,+ coder->block_options.uncompressed_size));++ coder->sequence = SEQ_BLOCK_INIT;+ break;+ }++ case SEQ_INDEX_ENCODE: {+ // Call the Index encoder. It doesn't take any input, so+ // those pointers can be NULL.+ const lzma_ret ret = coder->index_encoder.code(+ coder->index_encoder.coder, allocator,+ NULL, NULL, 0,+ out, out_pos, out_size, LZMA_RUN);+ if (ret != LZMA_STREAM_END)+ return ret;++ // Encode the Stream Footer into coder->buffer.+ const lzma_stream_flags stream_flags = {+ .version = 0,+ .backward_size = lzma_index_size(coder->index),+ .check = coder->block_options.check,+ };++ if (lzma_stream_footer_encode(&stream_flags, coder->buffer)+ != LZMA_OK)+ return LZMA_PROG_ERROR;++ coder->buffer_size = LZMA_STREAM_HEADER_SIZE;+ coder->sequence = SEQ_STREAM_FOOTER;+ break;+ }++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++ return LZMA_OK;+}+++static void+stream_encoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_stream_coder *coder = coder_ptr;++ lzma_next_end(&coder->block_encoder, allocator);+ lzma_next_end(&coder->index_encoder, allocator);+ lzma_index_end(coder->index, allocator);++ for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)+ lzma_free(coder->filters[i].options, allocator);++ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+stream_encoder_update(void *coder_ptr, const lzma_allocator *allocator,+ const lzma_filter *filters,+ const lzma_filter *reversed_filters)+{+ lzma_stream_coder *coder = coder_ptr;++ if (coder->sequence <= SEQ_BLOCK_INIT) {+ // There is no incomplete Block waiting to be finished,+ // thus we can change the whole filter chain. Start by+ // trying to initialize the Block encoder with the new+ // chain. This way we detect if the chain is valid.+ coder->block_encoder_is_initialized = false;+ coder->block_options.filters = (lzma_filter *)(filters);+ const lzma_ret ret = block_encoder_init(coder, allocator);+ coder->block_options.filters = coder->filters;+ if (ret != LZMA_OK)+ return ret;++ coder->block_encoder_is_initialized = true;++ } else if (coder->sequence <= SEQ_BLOCK_ENCODE) {+ // We are in the middle of a Block. Try to update only+ // the filter-specific options.+ return_if_error(coder->block_encoder.update(+ coder->block_encoder.coder, allocator,+ filters, reversed_filters));+ } else {+ // Trying to update the filter chain when we are already+ // encoding Index or Stream Footer.+ return LZMA_PROG_ERROR;+ }++ // Free the copy of the old chain and make a copy of the new chain.+ for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)+ lzma_free(coder->filters[i].options, allocator);++ return lzma_filters_copy(filters, coder->filters, allocator);+}+++static lzma_ret+stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter *filters, lzma_check check)+{+ lzma_next_coder_init(&stream_encoder_init, next, allocator);++ if (filters == NULL)+ return LZMA_PROG_ERROR;++ lzma_stream_coder *coder = next->coder;++ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &stream_encode;+ next->end = &stream_encoder_end;+ next->update = &stream_encoder_update;++ coder->filters[0].id = LZMA_VLI_UNKNOWN;+ coder->block_encoder = LZMA_NEXT_CODER_INIT;+ coder->index_encoder = LZMA_NEXT_CODER_INIT;+ coder->index = NULL;+ }++ // Basic initializations+ coder->sequence = SEQ_STREAM_HEADER;+ coder->block_options.version = 0;+ coder->block_options.check = check;++ // Initialize the Index+ lzma_index_end(coder->index, allocator);+ coder->index = lzma_index_init(allocator);+ if (coder->index == NULL)+ return LZMA_MEM_ERROR;++ // Encode the Stream Header+ lzma_stream_flags stream_flags = {+ .version = 0,+ .check = check,+ };+ return_if_error(lzma_stream_header_encode(+ &stream_flags, coder->buffer));++ coder->buffer_pos = 0;+ coder->buffer_size = LZMA_STREAM_HEADER_SIZE;++ // Initialize the Block encoder. This way we detect unsupported+ // filter chains when initializing the Stream encoder instead of+ // giving an error after Stream Header has already written out.+ return stream_encoder_update(coder, allocator, filters, NULL);+}+++extern LZMA_API(lzma_ret)+lzma_stream_encoder(lzma_stream *strm,+ const lzma_filter *filters, lzma_check check)+{+ lzma_next_strm_init(stream_encoder_init, strm, filters, check);++ 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_FULL_BARRIER] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}
+ cbits/liblzma/common/stream_encoder_mt.c view
@@ -0,0 +1,1143 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_encoder_mt.c+/// \brief Multithreaded .xz Stream encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "filter_encoder.h"+#include "easy_preset.h"+#include "block_encoder.h"+#include "block_buffer_encoder.h"+#include "index_encoder.h"+#include "outqueue.h"+++/// Maximum supported block size. This makes it simpler to prevent integer+/// overflows if we are given unusually large block size.+#define BLOCK_SIZE_MAX (UINT64_MAX / LZMA_THREADS_MAX)+++typedef enum {+ /// Waiting for work.+ THR_IDLE,++ /// Encoding is in progress.+ THR_RUN,++ /// Encoding is in progress but no more input data will+ /// be read.+ THR_FINISH,++ /// The main thread wants the thread to stop whatever it was doing+ /// but not exit.+ THR_STOP,++ /// The main thread wants the thread to exit. We could use+ /// cancellation but since there's stopped anyway, this is lazier.+ THR_EXIT,++} worker_state;++typedef struct lzma_stream_coder_s lzma_stream_coder;++typedef struct worker_thread_s worker_thread;+struct worker_thread_s {+ worker_state state;++ /// Input buffer of coder->block_size bytes. The main thread will+ /// put new input into this and update in_size accordingly. Once+ /// no more input is coming, state will be set to THR_FINISH.+ uint8_t *in;++ /// Amount of data available in the input buffer. This is modified+ /// only by the main thread.+ size_t in_size;++ /// Output buffer for this thread. This is set by the main+ /// thread every time a new Block is started with this thread+ /// structure.+ lzma_outbuf *outbuf;++ /// Pointer to the main structure is needed when putting this+ /// thread back to the stack of free threads.+ lzma_stream_coder *coder;++ /// The allocator is set by the main thread. Since a copy of the+ /// pointer is kept here, the application must not change the+ /// allocator before calling lzma_end().+ const lzma_allocator *allocator;++ /// Amount of uncompressed data that has already been compressed.+ uint64_t progress_in;++ /// Amount of compressed data that is ready.+ uint64_t progress_out;++ /// Block encoder+ lzma_next_coder block_encoder;++ /// Compression options for this Block+ lzma_block block_options;++ /// Next structure in the stack of free worker threads.+ worker_thread *next;++ mythread_mutex mutex;+ mythread_cond cond;++ /// The ID of this thread is used to join the thread+ /// when it's not needed anymore.+ mythread thread_id;+};+++struct lzma_stream_coder_s {+ enum {+ SEQ_STREAM_HEADER,+ SEQ_BLOCK,+ SEQ_INDEX,+ SEQ_STREAM_FOOTER,+ } sequence;++ /// Start a new Block every block_size bytes of input unless+ /// LZMA_FULL_FLUSH or LZMA_FULL_BARRIER is used earlier.+ size_t block_size;++ /// The filter chain currently in use+ lzma_filter filters[LZMA_FILTERS_MAX + 1];+++ /// Index to hold sizes of the Blocks+ lzma_index *index;++ /// Index encoder+ lzma_next_coder index_encoder;+++ /// Stream Flags for encoding the Stream Header and Stream Footer.+ lzma_stream_flags stream_flags;++ /// Buffer to hold Stream Header and Stream Footer.+ uint8_t header[LZMA_STREAM_HEADER_SIZE];++ /// Read position in header[]+ size_t header_pos;+++ /// Output buffer queue for compressed data+ lzma_outq outq;+++ /// Maximum wait time if cannot use all the input and cannot+ /// fill the output buffer. This is in milliseconds.+ uint32_t timeout;+++ /// Error code from a worker thread+ lzma_ret thread_error;++ /// Array of allocated thread-specific structures+ worker_thread *threads;++ /// Number of structures in "threads" above. This is also the+ /// number of threads that will be created at maximum.+ uint32_t threads_max;++ /// Number of thread structures that have been initialized, and+ /// thus the number of worker threads actually created so far.+ uint32_t threads_initialized;++ /// Stack of free threads. When a thread finishes, it puts itself+ /// back into this stack. This starts as empty because threads+ /// are created only when actually needed.+ worker_thread *threads_free;++ /// The most recent worker thread to which the main thread writes+ /// the new input from the application.+ worker_thread *thr;+++ /// Amount of uncompressed data in Blocks that have already+ /// been finished.+ uint64_t progress_in;++ /// Amount of compressed data in Stream Header + Blocks that+ /// have already been finished.+ uint64_t progress_out;+++ mythread_mutex mutex;+ mythread_cond cond;+};+++/// Tell the main thread that something has gone wrong.+static void+worker_error(worker_thread *thr, lzma_ret ret)+{+ assert(ret != LZMA_OK);+ assert(ret != LZMA_STREAM_END);++ mythread_sync(thr->coder->mutex) {+ if (thr->coder->thread_error == LZMA_OK)+ thr->coder->thread_error = ret;++ mythread_cond_signal(&thr->coder->cond);+ }++ return;+}+++static worker_state+worker_encode(worker_thread *thr, worker_state state)+{+ assert(thr->progress_in == 0);+ assert(thr->progress_out == 0);++ // Set the Block options.+ thr->block_options = (lzma_block){+ .version = 0,+ .check = thr->coder->stream_flags.check,+ .compressed_size = thr->coder->outq.buf_size_max,+ .uncompressed_size = thr->coder->block_size,++ // TODO: To allow changing the filter chain, the filters+ // array must be copied to each worker_thread.+ .filters = thr->coder->filters,+ };++ // Calculate maximum size of the Block Header. This amount is+ // reserved in the beginning of the buffer so that Block Header+ // along with Compressed Size and Uncompressed Size can be+ // written there.+ lzma_ret ret = lzma_block_header_size(&thr->block_options);+ if (ret != LZMA_OK) {+ worker_error(thr, ret);+ return THR_STOP;+ }++ // Initialize the Block encoder.+ ret = lzma_block_encoder_init(&thr->block_encoder,+ thr->allocator, &thr->block_options);+ if (ret != LZMA_OK) {+ worker_error(thr, ret);+ return THR_STOP;+ }++ size_t in_pos = 0;+ size_t in_size = 0;++ thr->outbuf->size = thr->block_options.header_size;+ const size_t out_size = thr->coder->outq.buf_size_max;++ do {+ mythread_sync(thr->mutex) {+ // Store in_pos and out_pos into *thr so that+ // an application may read them via+ // lzma_get_progress() to get progress information.+ //+ // NOTE: These aren't updated when the encoding+ // finishes. Instead, the final values are taken+ // later from thr->outbuf.+ thr->progress_in = in_pos;+ thr->progress_out = thr->outbuf->size;++ while (in_size == thr->in_size+ && thr->state == THR_RUN)+ mythread_cond_wait(&thr->cond, &thr->mutex);++ state = thr->state;+ in_size = thr->in_size;+ }++ // Return if we were asked to stop or exit.+ if (state >= THR_STOP)+ return state;++ lzma_action action = state == THR_FINISH+ ? LZMA_FINISH : LZMA_RUN;++ // Limit the amount of input given to the Block encoder+ // at once. This way this thread can react fairly quickly+ // if the main thread wants us to stop or exit.+ static const size_t in_chunk_max = 16384;+ size_t in_limit = in_size;+ if (in_size - in_pos > in_chunk_max) {+ in_limit = in_pos + in_chunk_max;+ action = LZMA_RUN;+ }++ ret = thr->block_encoder.code(+ thr->block_encoder.coder, thr->allocator,+ thr->in, &in_pos, in_limit, thr->outbuf->buf,+ &thr->outbuf->size, out_size, action);+ } while (ret == LZMA_OK && thr->outbuf->size < out_size);++ switch (ret) {+ case LZMA_STREAM_END:+ assert(state == THR_FINISH);++ // Encode the Block Header. By doing it after+ // the compression, we can store the Compressed Size+ // and Uncompressed Size fields.+ ret = lzma_block_header_encode(&thr->block_options,+ thr->outbuf->buf);+ if (ret != LZMA_OK) {+ worker_error(thr, ret);+ return THR_STOP;+ }++ break;++ case LZMA_OK:+ // The data was incompressible. Encode it using uncompressed+ // LZMA2 chunks.+ //+ // First wait that we have gotten all the input.+ mythread_sync(thr->mutex) {+ while (thr->state == THR_RUN)+ mythread_cond_wait(&thr->cond, &thr->mutex);++ state = thr->state;+ in_size = thr->in_size;+ }++ if (state >= THR_STOP)+ return state;++ // Do the encoding. This takes care of the Block Header too.+ thr->outbuf->size = 0;+ ret = lzma_block_uncomp_encode(&thr->block_options,+ thr->in, in_size, thr->outbuf->buf,+ &thr->outbuf->size, out_size);++ // It shouldn't fail.+ if (ret != LZMA_OK) {+ worker_error(thr, LZMA_PROG_ERROR);+ return THR_STOP;+ }++ break;++ default:+ worker_error(thr, ret);+ return THR_STOP;+ }++ // Set the size information that will be read by the main thread+ // to write the Index field.+ thr->outbuf->unpadded_size+ = lzma_block_unpadded_size(&thr->block_options);+ assert(thr->outbuf->unpadded_size != 0);+ thr->outbuf->uncompressed_size = thr->block_options.uncompressed_size;++ return THR_FINISH;+}+++static MYTHREAD_RET_TYPE+worker_start(void *thr_ptr)+{+ worker_thread *thr = thr_ptr;+ worker_state state = THR_IDLE; // Init to silence a warning++ while (true) {+ // Wait for work.+ mythread_sync(thr->mutex) {+ while (true) {+ // The thread is already idle so if we are+ // requested to stop, just set the state.+ if (thr->state == THR_STOP) {+ thr->state = THR_IDLE;+ mythread_cond_signal(&thr->cond);+ }++ state = thr->state;+ if (state != THR_IDLE)+ break;++ mythread_cond_wait(&thr->cond, &thr->mutex);+ }+ }++ assert(state != THR_IDLE);+ assert(state != THR_STOP);++ if (state <= THR_FINISH)+ state = worker_encode(thr, state);++ if (state == THR_EXIT)+ break;++ // Mark the thread as idle unless the main thread has+ // told us to exit. Signal is needed for the case+ // where the main thread is waiting for the threads to stop.+ mythread_sync(thr->mutex) {+ if (thr->state != THR_EXIT) {+ thr->state = THR_IDLE;+ mythread_cond_signal(&thr->cond);+ }+ }++ mythread_sync(thr->coder->mutex) {+ // Mark the output buffer as finished if+ // no errors occurred.+ thr->outbuf->finished = state == THR_FINISH;++ // Update the main progress info.+ thr->coder->progress_in+ += thr->outbuf->uncompressed_size;+ thr->coder->progress_out += thr->outbuf->size;+ thr->progress_in = 0;+ thr->progress_out = 0;++ // Return this thread to the stack of free threads.+ thr->next = thr->coder->threads_free;+ thr->coder->threads_free = thr;++ mythread_cond_signal(&thr->coder->cond);+ }+ }++ // Exiting, free the resources.+ mythread_mutex_destroy(&thr->mutex);+ mythread_cond_destroy(&thr->cond);++ lzma_next_end(&thr->block_encoder, thr->allocator);+ lzma_free(thr->in, thr->allocator);+ return MYTHREAD_RET_VALUE;+}+++/// Make the threads stop but not exit. Optionally wait for them to stop.+static void+threads_stop(lzma_stream_coder *coder, bool wait_for_threads)+{+ // Tell the threads to stop.+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {+ mythread_sync(coder->threads[i].mutex) {+ coder->threads[i].state = THR_STOP;+ mythread_cond_signal(&coder->threads[i].cond);+ }+ }++ if (!wait_for_threads)+ return;++ // Wait for the threads to settle in the idle state.+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {+ mythread_sync(coder->threads[i].mutex) {+ while (coder->threads[i].state != THR_IDLE)+ mythread_cond_wait(&coder->threads[i].cond,+ &coder->threads[i].mutex);+ }+ }++ return;+}+++/// Stop the threads and free the resources associated with them.+/// Wait until the threads have exited.+static void+threads_end(lzma_stream_coder *coder, const lzma_allocator *allocator)+{+ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {+ mythread_sync(coder->threads[i].mutex) {+ coder->threads[i].state = THR_EXIT;+ mythread_cond_signal(&coder->threads[i].cond);+ }+ }++ for (uint32_t i = 0; i < coder->threads_initialized; ++i) {+ int ret = mythread_join(coder->threads[i].thread_id);+ assert(ret == 0);+ (void)ret;+ }++ lzma_free(coder->threads, allocator);+ return;+}+++/// Initialize a new worker_thread structure and create a new thread.+static lzma_ret+initialize_new_thread(lzma_stream_coder *coder,+ const lzma_allocator *allocator)+{+ worker_thread *thr = &coder->threads[coder->threads_initialized];++ thr->in = lzma_alloc(coder->block_size, allocator);+ if (thr->in == NULL)+ return LZMA_MEM_ERROR;++ if (mythread_mutex_init(&thr->mutex))+ goto error_mutex;++ if (mythread_cond_init(&thr->cond))+ goto error_cond;++ thr->state = THR_IDLE;+ thr->allocator = allocator;+ thr->coder = coder;+ thr->progress_in = 0;+ thr->progress_out = 0;+ thr->block_encoder = LZMA_NEXT_CODER_INIT;++ if (mythread_create(&thr->thread_id, &worker_start, thr))+ goto error_thread;++ ++coder->threads_initialized;+ coder->thr = thr;++ return LZMA_OK;++error_thread:+ mythread_cond_destroy(&thr->cond);++error_cond:+ mythread_mutex_destroy(&thr->mutex);++error_mutex:+ lzma_free(thr->in, allocator);+ return LZMA_MEM_ERROR;+}+++static lzma_ret+get_thread(lzma_stream_coder *coder, const lzma_allocator *allocator)+{+ // If there are no free output subqueues, there is no+ // point to try getting a thread.+ if (!lzma_outq_has_buf(&coder->outq))+ return LZMA_OK;++ // If there is a free structure on the stack, use it.+ mythread_sync(coder->mutex) {+ if (coder->threads_free != NULL) {+ coder->thr = coder->threads_free;+ coder->threads_free = coder->threads_free->next;+ }+ }++ if (coder->thr == NULL) {+ // If there are no uninitialized structures left, return.+ if (coder->threads_initialized == coder->threads_max)+ return LZMA_OK;++ // Initialize a new thread.+ return_if_error(initialize_new_thread(coder, allocator));+ }++ // Reset the parts of the thread state that have to be done+ // in the main thread.+ mythread_sync(coder->thr->mutex) {+ coder->thr->state = THR_RUN;+ coder->thr->in_size = 0;+ coder->thr->outbuf = lzma_outq_get_buf(&coder->outq);+ mythread_cond_signal(&coder->thr->cond);+ }++ return LZMA_OK;+}+++static lzma_ret+stream_encode_in(lzma_stream_coder *coder, const lzma_allocator *allocator,+ const uint8_t *restrict in, size_t *restrict in_pos,+ size_t in_size, lzma_action action)+{+ while (*in_pos < in_size+ || (coder->thr != NULL && action != LZMA_RUN)) {+ if (coder->thr == NULL) {+ // Get a new thread.+ const lzma_ret ret = get_thread(coder, allocator);+ if (coder->thr == NULL)+ return ret;+ }++ // Copy the input data to thread's buffer.+ size_t thr_in_size = coder->thr->in_size;+ lzma_bufcpy(in, in_pos, in_size, coder->thr->in,+ &thr_in_size, coder->block_size);++ // Tell the Block encoder to finish if+ // - it has got block_size bytes of input; or+ // - all input was used and LZMA_FINISH, LZMA_FULL_FLUSH,+ // or LZMA_FULL_BARRIER was used.+ //+ // TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.+ const bool finish = thr_in_size == coder->block_size+ || (*in_pos == in_size && action != LZMA_RUN);++ bool block_error = false;++ mythread_sync(coder->thr->mutex) {+ if (coder->thr->state == THR_IDLE) {+ // Something has gone wrong with the Block+ // encoder. It has set coder->thread_error+ // which we will read a few lines later.+ block_error = true;+ } else {+ // Tell the Block encoder its new amount+ // of input and update the state if needed.+ coder->thr->in_size = thr_in_size;++ if (finish)+ coder->thr->state = THR_FINISH;++ mythread_cond_signal(&coder->thr->cond);+ }+ }++ if (block_error) {+ lzma_ret ret;++ mythread_sync(coder->mutex) {+ ret = coder->thread_error;+ }++ return ret;+ }++ if (finish)+ coder->thr = NULL;+ }++ return LZMA_OK;+}+++/// Wait until more input can be consumed, more output can be read, or+/// an optional timeout is reached.+static bool+wait_for_work(lzma_stream_coder *coder, mythread_condtime *wait_abs,+ bool *has_blocked, bool has_input)+{+ if (coder->timeout != 0 && !*has_blocked) {+ // Every time when stream_encode_mt() is called via+ // lzma_code(), *has_blocked starts as false. We set it+ // to true here and calculate the absolute time when+ // we must return if there's nothing to do.+ //+ // The idea of *has_blocked is to avoid unneeded calls+ // to mythread_condtime_set(), which may do a syscall+ // depending on the operating system.+ *has_blocked = true;+ mythread_condtime_set(wait_abs, &coder->cond, coder->timeout);+ }++ bool timed_out = false;++ mythread_sync(coder->mutex) {+ // There are four things that we wait. If one of them+ // becomes possible, we return.+ // - If there is input left, we need to get a free+ // worker thread and an output buffer for it.+ // - Data ready to be read from the output queue.+ // - A worker thread indicates an error.+ // - Time out occurs.+ while ((!has_input || coder->threads_free == NULL+ || !lzma_outq_has_buf(&coder->outq))+ && !lzma_outq_is_readable(&coder->outq)+ && coder->thread_error == LZMA_OK+ && !timed_out) {+ if (coder->timeout != 0)+ timed_out = mythread_cond_timedwait(+ &coder->cond, &coder->mutex,+ wait_abs) != 0;+ else+ mythread_cond_wait(&coder->cond,+ &coder->mutex);+ }+ }++ return timed_out;+}+++static lzma_ret+stream_encode_mt(void *coder_ptr, const 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_stream_coder *coder = coder_ptr;++ switch (coder->sequence) {+ case SEQ_STREAM_HEADER:+ lzma_bufcpy(coder->header, &coder->header_pos,+ sizeof(coder->header),+ out, out_pos, out_size);+ if (coder->header_pos < sizeof(coder->header))+ return LZMA_OK;++ coder->header_pos = 0;+ coder->sequence = SEQ_BLOCK;++ // Fall through++ case SEQ_BLOCK: {+ // Initialized to silence warnings.+ lzma_vli unpadded_size = 0;+ lzma_vli uncompressed_size = 0;+ lzma_ret ret = LZMA_OK;++ // These are for wait_for_work().+ bool has_blocked = false;+ mythread_condtime wait_abs;++ while (true) {+ mythread_sync(coder->mutex) {+ // Check for Block encoder errors.+ ret = coder->thread_error;+ if (ret != LZMA_OK) {+ assert(ret != LZMA_STREAM_END);+ break; // Break out of mythread_sync.+ }++ // Try to read compressed data to out[].+ ret = lzma_outq_read(&coder->outq,+ out, out_pos, out_size,+ &unpadded_size,+ &uncompressed_size);+ }++ if (ret == LZMA_STREAM_END) {+ // End of Block. Add it to the Index.+ ret = lzma_index_append(coder->index,+ allocator, unpadded_size,+ uncompressed_size);++ // If we didn't fill the output buffer yet,+ // try to read more data. Maybe the next+ // outbuf has been finished already too.+ if (*out_pos < out_size)+ continue;+ }++ if (ret != LZMA_OK) {+ // coder->thread_error was set or+ // lzma_index_append() failed.+ threads_stop(coder, false);+ return ret;+ }++ // Try to give uncompressed data to a worker thread.+ ret = stream_encode_in(coder, allocator,+ in, in_pos, in_size, action);+ if (ret != LZMA_OK) {+ threads_stop(coder, false);+ return ret;+ }++ // See if we should wait or return.+ //+ // TODO: LZMA_SYNC_FLUSH and LZMA_SYNC_BARRIER.+ if (*in_pos == in_size) {+ // LZMA_RUN: More data is probably coming+ // so return to let the caller fill the+ // input buffer.+ if (action == LZMA_RUN)+ return LZMA_OK;++ // LZMA_FULL_BARRIER: The same as with+ // LZMA_RUN but tell the caller that the+ // barrier was completed.+ if (action == LZMA_FULL_BARRIER)+ return LZMA_STREAM_END;++ // Finishing or flushing isn't completed until+ // all input data has been encoded and copied+ // to the output buffer.+ if (lzma_outq_is_empty(&coder->outq)) {+ // LZMA_FINISH: Continue to encode+ // the Index field.+ if (action == LZMA_FINISH)+ break;++ // LZMA_FULL_FLUSH: Return to tell+ // the caller that flushing was+ // completed.+ if (action == LZMA_FULL_FLUSH)+ return LZMA_STREAM_END;+ }+ }++ // Return if there is no output space left.+ // This check must be done after testing the input+ // buffer, because we might want to use a different+ // return code.+ if (*out_pos == out_size)+ return LZMA_OK;++ // Neither in nor out has been used completely.+ // Wait until there's something we can do.+ if (wait_for_work(coder, &wait_abs, &has_blocked,+ *in_pos < in_size))+ return LZMA_TIMED_OUT;+ }++ // All Blocks have been encoded and the threads have stopped.+ // Prepare to encode the Index field.+ return_if_error(lzma_index_encoder_init(+ &coder->index_encoder, allocator,+ coder->index));+ coder->sequence = SEQ_INDEX;++ // Update the progress info to take the Index and+ // Stream Footer into account. Those are very fast to encode+ // so in terms of progress information they can be thought+ // to be ready to be copied out.+ coder->progress_out += lzma_index_size(coder->index)+ + LZMA_STREAM_HEADER_SIZE;+ }++ // Fall through++ case SEQ_INDEX: {+ // Call the Index encoder. It doesn't take any input, so+ // those pointers can be NULL.+ const lzma_ret ret = coder->index_encoder.code(+ coder->index_encoder.coder, allocator,+ NULL, NULL, 0,+ out, out_pos, out_size, LZMA_RUN);+ if (ret != LZMA_STREAM_END)+ return ret;++ // Encode the Stream Footer into coder->buffer.+ coder->stream_flags.backward_size+ = lzma_index_size(coder->index);+ if (lzma_stream_footer_encode(&coder->stream_flags,+ coder->header) != LZMA_OK)+ return LZMA_PROG_ERROR;++ coder->sequence = SEQ_STREAM_FOOTER;+ }++ // Fall through++ case SEQ_STREAM_FOOTER:+ lzma_bufcpy(coder->header, &coder->header_pos,+ sizeof(coder->header),+ out, out_pos, out_size);+ return coder->header_pos < sizeof(coder->header)+ ? LZMA_OK : LZMA_STREAM_END;+ }++ assert(0);+ return LZMA_PROG_ERROR;+}+++static void+stream_encoder_mt_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_stream_coder *coder = coder_ptr;++ // Threads must be killed before the output queue can be freed.+ threads_end(coder, allocator);+ lzma_outq_end(&coder->outq, allocator);++ for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)+ lzma_free(coder->filters[i].options, allocator);++ lzma_next_end(&coder->index_encoder, allocator);+ lzma_index_end(coder->index, allocator);++ mythread_cond_destroy(&coder->cond);+ mythread_mutex_destroy(&coder->mutex);++ lzma_free(coder, allocator);+ return;+}+++/// Options handling for lzma_stream_encoder_mt_init() and+/// lzma_stream_encoder_mt_memusage()+static lzma_ret+get_options(const lzma_mt *options, lzma_options_easy *opt_easy,+ const lzma_filter **filters, uint64_t *block_size,+ uint64_t *outbuf_size_max)+{+ // Validate some of the options.+ if (options == NULL)+ return LZMA_PROG_ERROR;++ if (options->flags != 0 || options->threads == 0+ || options->threads > LZMA_THREADS_MAX)+ return LZMA_OPTIONS_ERROR;++ if (options->filters != NULL) {+ // Filter chain was given, use it as is.+ *filters = options->filters;+ } else {+ // Use a preset.+ if (lzma_easy_preset(opt_easy, options->preset))+ return LZMA_OPTIONS_ERROR;++ *filters = opt_easy->filters;+ }++ // Block size+ if (options->block_size > 0) {+ if (options->block_size > BLOCK_SIZE_MAX)+ return LZMA_OPTIONS_ERROR;++ *block_size = options->block_size;+ } else {+ // Determine the Block size from the filter chain.+ *block_size = lzma_mt_block_size(*filters);+ if (*block_size == 0)+ return LZMA_OPTIONS_ERROR;++ assert(*block_size <= BLOCK_SIZE_MAX);+ }++ // Calculate the maximum amount output that a single output buffer+ // may need to hold. This is the same as the maximum total size of+ // a Block.+ *outbuf_size_max = lzma_block_buffer_bound64(*block_size);+ if (*outbuf_size_max == 0)+ return LZMA_MEM_ERROR;++ return LZMA_OK;+}+++static void+get_progress(void *coder_ptr, uint64_t *progress_in, uint64_t *progress_out)+{+ lzma_stream_coder *coder = coder_ptr;++ // Lock coder->mutex to prevent finishing threads from moving their+ // progress info from the worker_thread structure to lzma_stream_coder.+ mythread_sync(coder->mutex) {+ *progress_in = coder->progress_in;+ *progress_out = coder->progress_out;++ for (size_t i = 0; i < coder->threads_initialized; ++i) {+ mythread_sync(coder->threads[i].mutex) {+ *progress_in += coder->threads[i].progress_in;+ *progress_out += coder->threads[i]+ .progress_out;+ }+ }+ }++ return;+}+++static lzma_ret+stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_mt *options)+{+ lzma_next_coder_init(&stream_encoder_mt_init, next, allocator);++ // Get the filter chain.+ lzma_options_easy easy;+ const lzma_filter *filters;+ uint64_t block_size;+ uint64_t outbuf_size_max;+ return_if_error(get_options(options, &easy, &filters,+ &block_size, &outbuf_size_max));++#if SIZE_MAX < UINT64_MAX+ if (block_size > SIZE_MAX)+ return LZMA_MEM_ERROR;+#endif++ // Validate the filter chain so that we can give an error in this+ // function instead of delaying it to the first call to lzma_code().+ // The memory usage calculation verifies the filter chain as+ // a side effect so we take advantage of that.+ if (lzma_raw_encoder_memusage(filters) == UINT64_MAX)+ return LZMA_OPTIONS_ERROR;++ // Validate the Check ID.+ if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)+ return LZMA_PROG_ERROR;++ if (!lzma_check_is_supported(options->check))+ return LZMA_UNSUPPORTED_CHECK;++ // Allocate and initialize the base structure if needed.+ lzma_stream_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;++ // For the mutex and condition variable initializations+ // the error handling has to be done here because+ // stream_encoder_mt_end() doesn't know if they have+ // already been initialized or not.+ if (mythread_mutex_init(&coder->mutex)) {+ lzma_free(coder, allocator);+ next->coder = NULL;+ return LZMA_MEM_ERROR;+ }++ if (mythread_cond_init(&coder->cond)) {+ mythread_mutex_destroy(&coder->mutex);+ lzma_free(coder, allocator);+ next->coder = NULL;+ return LZMA_MEM_ERROR;+ }++ next->code = &stream_encode_mt;+ next->end = &stream_encoder_mt_end;+ next->get_progress = &get_progress;+// next->update = &stream_encoder_mt_update;++ coder->filters[0].id = LZMA_VLI_UNKNOWN;+ coder->index_encoder = LZMA_NEXT_CODER_INIT;+ coder->index = NULL;+ memzero(&coder->outq, sizeof(coder->outq));+ coder->threads = NULL;+ coder->threads_max = 0;+ coder->threads_initialized = 0;+ }++ // Basic initializations+ coder->sequence = SEQ_STREAM_HEADER;+ coder->block_size = (size_t)(block_size);+ coder->thread_error = LZMA_OK;+ coder->thr = NULL;++ // Allocate the thread-specific base structures.+ assert(options->threads > 0);+ if (coder->threads_max != options->threads) {+ threads_end(coder, allocator);++ coder->threads = NULL;+ coder->threads_max = 0;++ coder->threads_initialized = 0;+ coder->threads_free = NULL;++ coder->threads = lzma_alloc(+ options->threads * sizeof(worker_thread),+ allocator);+ if (coder->threads == NULL)+ return LZMA_MEM_ERROR;++ coder->threads_max = options->threads;+ } else {+ // Reuse the old structures and threads. Tell the running+ // threads to stop and wait until they have stopped.+ threads_stop(coder, true);+ }++ // Output queue+ return_if_error(lzma_outq_init(&coder->outq, allocator,+ outbuf_size_max, options->threads));++ // Timeout+ coder->timeout = options->timeout;++ // Free the old filter chain and copy the new one.+ for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)+ lzma_free(coder->filters[i].options, allocator);++ return_if_error(lzma_filters_copy(+ filters, coder->filters, allocator));++ // Index+ lzma_index_end(coder->index, allocator);+ coder->index = lzma_index_init(allocator);+ if (coder->index == NULL)+ return LZMA_MEM_ERROR;++ // Stream Header+ coder->stream_flags.version = 0;+ coder->stream_flags.check = options->check;+ return_if_error(lzma_stream_header_encode(+ &coder->stream_flags, coder->header));++ coder->header_pos = 0;++ // Progress info+ coder->progress_in = 0;+ coder->progress_out = LZMA_STREAM_HEADER_SIZE;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_stream_encoder_mt(lzma_stream *strm, const lzma_mt *options)+{+ lzma_next_strm_init(stream_encoder_mt_init, strm, options);++ 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_FULL_BARRIER] = true;+ strm->internal->supported_actions[LZMA_FINISH] = true;++ return LZMA_OK;+}+++// This function name is a monster but it's consistent with the older+// monster names. :-( 31 chars is the max that C99 requires so in that+// sense it's not too long. ;-)+extern LZMA_API(uint64_t)+lzma_stream_encoder_mt_memusage(const lzma_mt *options)+{+ lzma_options_easy easy;+ const lzma_filter *filters;+ uint64_t block_size;+ uint64_t outbuf_size_max;++ if (get_options(options, &easy, &filters, &block_size,+ &outbuf_size_max) != LZMA_OK)+ return UINT64_MAX;++ // Memory usage of the input buffers+ const uint64_t inbuf_memusage = options->threads * block_size;++ // Memory usage of the filter encoders+ uint64_t filters_memusage = lzma_raw_encoder_memusage(filters);+ if (filters_memusage == UINT64_MAX)+ return UINT64_MAX;++ filters_memusage *= options->threads;++ // Memory usage of the output queue+ const uint64_t outq_memusage = lzma_outq_memusage(+ outbuf_size_max, options->threads);+ if (outq_memusage == UINT64_MAX)+ return UINT64_MAX;++ // Sum them with overflow checking.+ uint64_t total_memusage = LZMA_MEMUSAGE_BASE+ + sizeof(lzma_stream_coder)+ + options->threads * sizeof(worker_thread);++ if (UINT64_MAX - total_memusage < inbuf_memusage)+ return UINT64_MAX;++ total_memusage += inbuf_memusage;++ if (UINT64_MAX - total_memusage < filters_memusage)+ return UINT64_MAX;++ total_memusage += filters_memusage;++ if (UINT64_MAX - total_memusage < outq_memusage)+ return UINT64_MAX;++ return total_memusage + outq_memusage;+}
+ cbits/liblzma/common/stream_flags_common.c view
@@ -0,0 +1,47 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_flags_common.c+/// \brief Common stuff for Stream flags coders+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "stream_flags_common.h"+++const uint8_t lzma_header_magic[6] = { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00 };+const uint8_t lzma_footer_magic[2] = { 0x59, 0x5A };+++extern LZMA_API(lzma_ret)+lzma_stream_flags_compare(+ const lzma_stream_flags *a, const lzma_stream_flags *b)+{+ // We can compare only version 0 structures.+ if (a->version != 0 || b->version != 0)+ return LZMA_OPTIONS_ERROR;++ // Check type+ if ((unsigned int)(a->check) > LZMA_CHECK_ID_MAX+ || (unsigned int)(b->check) > LZMA_CHECK_ID_MAX)+ return LZMA_PROG_ERROR;++ if (a->check != b->check)+ return LZMA_DATA_ERROR;++ // Backward Sizes are compared only if they are known in both.+ if (a->backward_size != LZMA_VLI_UNKNOWN+ && b->backward_size != LZMA_VLI_UNKNOWN) {+ if (!is_backward_size_valid(a) || !is_backward_size_valid(b))+ return LZMA_PROG_ERROR;++ if (a->backward_size != b->backward_size)+ return LZMA_DATA_ERROR;+ }++ return LZMA_OK;+}
+ cbits/liblzma/common/stream_flags_common.h view
@@ -0,0 +1,33 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_flags_common.h+/// \brief Common stuff for Stream flags coders+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_STREAM_FLAGS_COMMON_H+#define LZMA_STREAM_FLAGS_COMMON_H++#include "common.h"++/// Size of the Stream Flags field+#define LZMA_STREAM_FLAGS_SIZE 2++extern const uint8_t lzma_header_magic[6];+extern const uint8_t lzma_footer_magic[2];+++static inline bool+is_backward_size_valid(const lzma_stream_flags *options)+{+ return options->backward_size >= LZMA_BACKWARD_SIZE_MIN+ && options->backward_size <= LZMA_BACKWARD_SIZE_MAX+ && (options->backward_size & 3) == 0;+}++#endif
+ cbits/liblzma/common/stream_flags_decoder.c view
@@ -0,0 +1,82 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_flags_decoder.c+/// \brief Decodes Stream Header and Stream Footer from .xz files+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "stream_flags_common.h"+++static bool+stream_flags_decode(lzma_stream_flags *options, const uint8_t *in)+{+ // Reserved bits must be unset.+ if (in[0] != 0x00 || (in[1] & 0xF0))+ return true;++ options->version = 0;+ options->check = in[1] & 0x0F;++ return false;+}+++extern LZMA_API(lzma_ret)+lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in)+{+ // Magic+ if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0)+ return LZMA_FORMAT_ERROR;++ // Verify the CRC32 so we can distinguish between corrupt+ // and unsupported files.+ const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic),+ LZMA_STREAM_FLAGS_SIZE, 0);+ if (crc != read32le(in + sizeof(lzma_header_magic)+ + LZMA_STREAM_FLAGS_SIZE))+ return LZMA_DATA_ERROR;++ // Stream Flags+ if (stream_flags_decode(options, in + sizeof(lzma_header_magic)))+ return LZMA_OPTIONS_ERROR;++ // Set Backward Size to indicate unknown value. That way+ // lzma_stream_flags_compare() can be used to compare Stream Header+ // and Stream Footer while keeping it useful also for comparing+ // two Stream Footers.+ options->backward_size = LZMA_VLI_UNKNOWN;++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in)+{+ // Magic+ if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE,+ lzma_footer_magic, sizeof(lzma_footer_magic)) != 0)+ return LZMA_FORMAT_ERROR;++ // CRC32+ const uint32_t crc = lzma_crc32(in + sizeof(uint32_t),+ sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0);+ if (crc != read32le(in))+ return LZMA_DATA_ERROR;++ // Stream Flags+ if (stream_flags_decode(options, in + sizeof(uint32_t) * 2))+ return LZMA_OPTIONS_ERROR;++ // Backward Size+ options->backward_size = read32le(in + sizeof(uint32_t));+ options->backward_size = (options->backward_size + 1) * 4;++ return LZMA_OK;+}
+ cbits/liblzma/common/stream_flags_encoder.c view
@@ -0,0 +1,86 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file stream_flags_encoder.c+/// \brief Encodes Stream Header and Stream Footer for .xz files+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "stream_flags_common.h"+++static bool+stream_flags_encode(const lzma_stream_flags *options, uint8_t *out)+{+ if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)+ return true;++ out[0] = 0x00;+ out[1] = options->check;++ return false;+}+++extern LZMA_API(lzma_ret)+lzma_stream_header_encode(const lzma_stream_flags *options, uint8_t *out)+{+ assert(sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE+ + 4 == LZMA_STREAM_HEADER_SIZE);++ if (options->version != 0)+ return LZMA_OPTIONS_ERROR;++ // Magic+ memcpy(out, lzma_header_magic, sizeof(lzma_header_magic));++ // Stream Flags+ if (stream_flags_encode(options, out + sizeof(lzma_header_magic)))+ return LZMA_PROG_ERROR;++ // CRC32 of the Stream Header+ const uint32_t crc = lzma_crc32(out + sizeof(lzma_header_magic),+ LZMA_STREAM_FLAGS_SIZE, 0);++ write32le(out + sizeof(lzma_header_magic) + LZMA_STREAM_FLAGS_SIZE,+ crc);++ return LZMA_OK;+}+++extern LZMA_API(lzma_ret)+lzma_stream_footer_encode(const lzma_stream_flags *options, uint8_t *out)+{+ assert(2 * 4 + LZMA_STREAM_FLAGS_SIZE + sizeof(lzma_footer_magic)+ == LZMA_STREAM_HEADER_SIZE);++ if (options->version != 0)+ return LZMA_OPTIONS_ERROR;++ // Backward Size+ if (!is_backward_size_valid(options))+ return LZMA_PROG_ERROR;++ write32le(out + 4, options->backward_size / 4 - 1);++ // Stream Flags+ if (stream_flags_encode(options, out + 2 * 4))+ return LZMA_PROG_ERROR;++ // CRC32+ const uint32_t crc = lzma_crc32(+ out + 4, 4 + LZMA_STREAM_FLAGS_SIZE, 0);++ write32le(out, crc);++ // Magic+ memcpy(out + 2 * 4 + LZMA_STREAM_FLAGS_SIZE,+ lzma_footer_magic, sizeof(lzma_footer_magic));++ return LZMA_OK;+}
+ cbits/liblzma/common/vli_decoder.c view
@@ -0,0 +1,86 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file vli_decoder.c+/// \brief Decodes variable-length integers+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++extern LZMA_API(lzma_ret)+lzma_vli_decode(lzma_vli *restrict vli, size_t *vli_pos,+ const uint8_t *restrict in, size_t *restrict in_pos,+ size_t in_size)+{+ // If we haven't been given vli_pos, work in single-call mode.+ size_t vli_pos_internal = 0;+ if (vli_pos == NULL) {+ vli_pos = &vli_pos_internal;+ *vli = 0;++ // If there's no input, use LZMA_DATA_ERROR. This way it is+ // easy to decode VLIs from buffers that have known size,+ // and get the correct error code in case the buffer is+ // too short.+ if (*in_pos >= in_size)+ return LZMA_DATA_ERROR;++ } else {+ // Initialize *vli when starting to decode a new integer.+ if (*vli_pos == 0)+ *vli = 0;++ // Validate the arguments.+ if (*vli_pos >= LZMA_VLI_BYTES_MAX+ || (*vli >> (*vli_pos * 7)) != 0)+ return LZMA_PROG_ERROR;;++ if (*in_pos >= in_size)+ return LZMA_BUF_ERROR;+ }++ do {+ // Read the next byte. Use a temporary variable so that we+ // can update *in_pos immediately.+ const uint8_t byte = in[*in_pos];+ ++*in_pos;++ // Add the newly read byte to *vli.+ *vli += (lzma_vli)(byte & 0x7F) << (*vli_pos * 7);+ ++*vli_pos;++ // Check if this is the last byte of a multibyte integer.+ if ((byte & 0x80) == 0) {+ // We don't allow using variable-length integers as+ // padding i.e. the encoding must use the most the+ // compact form.+ if (byte == 0x00 && *vli_pos > 1)+ return LZMA_DATA_ERROR;++ return vli_pos == &vli_pos_internal+ ? LZMA_OK : LZMA_STREAM_END;+ }++ // There is at least one more byte coming. If we have already+ // read maximum number of bytes, the integer is considered+ // corrupt.+ //+ // If we need bigger integers in future, old versions liblzma+ // will confusingly indicate the file being corrupt instead of+ // unsupported. I suppose it's still better this way, because+ // in the foreseeable future (writing this in 2008) the only+ // reason why files would appear having over 63-bit integers+ // is that the files are simply corrupt.+ if (*vli_pos == LZMA_VLI_BYTES_MAX)+ return LZMA_DATA_ERROR;++ } while (*in_pos < in_size);++ return vli_pos == &vli_pos_internal ? LZMA_DATA_ERROR : LZMA_OK;+}
+ cbits/liblzma/common/vli_encoder.c view
@@ -0,0 +1,69 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file vli_encoder.c+/// \brief Encodes variable-length integers+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++extern LZMA_API(lzma_ret)+lzma_vli_encode(lzma_vli vli, size_t *vli_pos,+ uint8_t *restrict out, size_t *restrict out_pos,+ size_t out_size)+{+ // If we haven't been given vli_pos, work in single-call mode.+ size_t vli_pos_internal = 0;+ if (vli_pos == NULL) {+ vli_pos = &vli_pos_internal;++ // In single-call mode, we expect that the caller has+ // reserved enough output space.+ if (*out_pos >= out_size)+ return LZMA_PROG_ERROR;+ } else {+ // This never happens when we are called by liblzma, but+ // may happen if called directly from an application.+ if (*out_pos >= out_size)+ return LZMA_BUF_ERROR;+ }++ // Validate the arguments.+ if (*vli_pos >= LZMA_VLI_BYTES_MAX || vli > LZMA_VLI_MAX)+ return LZMA_PROG_ERROR;++ // Shift vli so that the next bits to encode are the lowest. In+ // single-call mode this never changes vli since *vli_pos is zero.+ vli >>= *vli_pos * 7;++ // Write the non-last bytes in a loop.+ while (vli >= 0x80) {+ // We don't need *vli_pos during this function call anymore,+ // but update it here so that it is ready if we need to+ // return before the whole integer has been decoded.+ ++*vli_pos;+ assert(*vli_pos < LZMA_VLI_BYTES_MAX);++ // Write the next byte.+ out[*out_pos] = (uint8_t)(vli) | 0x80;+ vli >>= 7;++ if (++*out_pos == out_size)+ return vli_pos == &vli_pos_internal+ ? LZMA_PROG_ERROR : LZMA_OK;+ }++ // Write the last byte.+ out[*out_pos] = (uint8_t)(vli);+ ++*out_pos;+ ++*vli_pos;++ return vli_pos == &vli_pos_internal ? LZMA_OK : LZMA_STREAM_END;++}
+ cbits/liblzma/common/vli_size.c view
@@ -0,0 +1,30 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file vli_size.c+/// \brief Calculates the encoded size of a variable-length integer+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++extern LZMA_API(uint32_t)+lzma_vli_size(lzma_vli vli)+{+ if (vli > LZMA_VLI_MAX)+ return 0;++ uint32_t i = 0;+ do {+ vli >>= 7;+ ++i;+ } while (vli != 0);++ assert(i <= LZMA_VLI_BYTES_MAX);+ return i;+}
+ cbits/liblzma/delta/delta_common.c view
@@ -0,0 +1,73 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_common.c+/// \brief Common stuff for Delta encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "delta_common.h"+#include "delta_private.h"+++static void+delta_coder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_delta_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder, allocator);+ return;+}+++extern lzma_ret+lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ // Allocate memory for the decoder if needed.+ lzma_delta_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_delta_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;++ // End function is the same for encoder and decoder.+ next->end = &delta_coder_end;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ // Validate the options.+ if (lzma_delta_coder_memusage(filters[0].options) == UINT64_MAX)+ return LZMA_OPTIONS_ERROR;++ // Set the delta distance.+ const lzma_options_delta *opt = filters[0].options;+ coder->distance = opt->dist;++ // Initialize the rest of the variables.+ coder->pos = 0;+ memzero(coder->history, LZMA_DELTA_DIST_MAX);++ // Initialize the next decoder in the chain, if any.+ return lzma_next_filter_init(&coder->next, allocator, filters + 1);+}+++extern uint64_t+lzma_delta_coder_memusage(const void *options)+{+ const lzma_options_delta *opt = options;++ if (opt == NULL || opt->type != LZMA_DELTA_TYPE_BYTE+ || opt->dist < LZMA_DELTA_DIST_MIN+ || opt->dist > LZMA_DELTA_DIST_MAX)+ return UINT64_MAX;++ return sizeof(lzma_delta_coder);+}
+ cbits/liblzma/delta/delta_common.h view
@@ -0,0 +1,20 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_common.h+/// \brief Common stuff for Delta encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_DELTA_COMMON_H+#define LZMA_DELTA_COMMON_H++#include "common.h"++extern uint64_t lzma_delta_coder_memusage(const void *options);++#endif
+ cbits/liblzma/delta/delta_decoder.c view
@@ -0,0 +1,78 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_decoder.c+/// \brief Delta filter decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "delta_decoder.h"+#include "delta_private.h"+++static void+decode_buffer(lzma_delta_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(void *coder_ptr, const 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_delta_coder *coder = coder_ptr;++ assert(coder->next.code != NULL);++ const size_t out_start = *out_pos;++ const lzma_ret ret = coder->next.code(coder->next.coder, allocator,+ in, in_pos, in_size, out, out_pos, out_size,+ action);++ decode_buffer(coder, out + out_start, *out_pos - out_start);++ return ret;+}+++extern lzma_ret+lzma_delta_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ next->code = &delta_decode;+ return lzma_delta_coder_init(next, allocator, filters);+}+++extern lzma_ret+lzma_delta_props_decode(void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size)+{+ if (props_size != 1)+ return LZMA_OPTIONS_ERROR;++ lzma_options_delta *opt+ = lzma_alloc(sizeof(lzma_options_delta), allocator);+ if (opt == NULL)+ return LZMA_MEM_ERROR;++ opt->type = LZMA_DELTA_TYPE_BYTE;+ opt->dist = props[0] + 1U;++ *options = opt;++ return LZMA_OK;+}
+ cbits/liblzma/delta/delta_decoder.h view
@@ -0,0 +1,26 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_decoder.h+/// \brief Delta filter decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_DELTA_DECODER_H+#define LZMA_DELTA_DECODER_H++#include "delta_common.h"++extern lzma_ret lzma_delta_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_delta_props_decode(+ void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size);++#endif
+ cbits/liblzma/delta/delta_encoder.c view
@@ -0,0 +1,125 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_encoder.c+/// \brief Delta filter encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "delta_encoder.h"+#include "delta_private.h"+++/// Copies and encodes the data at the same time. This is used when Delta+/// is the first filter in the chain (and thus the last filter in the+/// encoder's filter stack).+static void+copy_and_encode(lzma_delta_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 the last filter+/// in the chain (and thus non-last filter in the encoder's filter stack).+static void+encode_in_place(lzma_delta_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(void *coder_ptr, const 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_delta_coder *coder = coder_ptr;++ 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 = my_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;+}+++static lzma_ret+delta_encoder_update(void *coder_ptr, const lzma_allocator *allocator,+ const lzma_filter *filters_null lzma_attribute((__unused__)),+ const lzma_filter *reversed_filters)+{+ lzma_delta_coder *coder = coder_ptr;++ // Delta doesn't and will never support changing the options in+ // the middle of encoding. If the app tries to change them, we+ // simply ignore them.+ return lzma_next_filter_update(+ &coder->next, allocator, reversed_filters + 1);+}+++extern lzma_ret+lzma_delta_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ next->code = &delta_encode;+ next->update = &delta_encoder_update;+ return lzma_delta_coder_init(next, allocator, filters);+}+++extern lzma_ret+lzma_delta_props_encode(const void *options, uint8_t *out)+{+ // The caller must have already validated the options, so it's+ // LZMA_PROG_ERROR if they are invalid.+ if (lzma_delta_coder_memusage(options) == UINT64_MAX)+ return LZMA_PROG_ERROR;++ const lzma_options_delta *opt = options;+ out[0] = opt->dist - LZMA_DELTA_DIST_MIN;++ return LZMA_OK;+}
+ cbits/liblzma/delta/delta_encoder.h view
@@ -0,0 +1,24 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_encoder.h+/// \brief Delta filter encoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_DELTA_ENCODER_H+#define LZMA_DELTA_ENCODER_H++#include "delta_common.h"++extern lzma_ret lzma_delta_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_delta_props_encode(const void *options, uint8_t *out);++#endif
+ cbits/liblzma/delta/delta_private.h view
@@ -0,0 +1,37 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file delta_private.h+/// \brief Private common stuff for Delta encoder and decoder+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_DELTA_PRIVATE_H+#define LZMA_DELTA_PRIVATE_H++#include "delta_common.h"++typedef struct {+ /// Next coder in the chain+ lzma_next_coder next;++ /// Delta distance+ size_t distance;++ /// Position in history[]+ uint8_t pos;++ /// Buffer to hold history of the original data+ uint8_t history[LZMA_DELTA_DIST_MAX];+} lzma_delta_coder;+++extern lzma_ret lzma_delta_coder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters);++#endif
+ cbits/liblzma/lz/lz_decoder.c view
@@ -0,0 +1,311 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lz_decoder.c+/// \brief LZ out window+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++// liblzma supports multiple LZ77-based filters. The LZ part is shared+// between these filters. The LZ code takes care of dictionary handling+// and passing the data between filters in the chain. The filter-specific+// part decodes from the input buffer to the dictionary.+++#include "lz_decoder.h"+++typedef struct {+ /// Dictionary (history buffer)+ lzma_dict dict;++ /// The actual LZ-based decoder e.g. LZMA+ lzma_lz_decoder lz;++ /// Next filter in the chain, if any. Note that LZMA and LZMA2 are+ /// only allowed as the last filter, but the long-range filter in+ /// future can be in the middle of the chain.+ lzma_next_coder next;++ /// True if the next filter in the chain has returned LZMA_STREAM_END.+ bool next_finished;++ /// True if the LZ decoder (e.g. LZMA) has detected end of payload+ /// marker. This may become true before next_finished becomes true.+ bool this_finished;++ /// Temporary buffer needed when the LZ-based filter is not the last+ /// filter in the chain. The output of the next filter is first+ /// decoded into buffer[], which is then used as input for the actual+ /// LZ-based decoder.+ struct {+ size_t pos;+ size_t size;+ uint8_t buffer[LZMA_BUFFER_SIZE];+ } temp;+} lzma_coder;+++static void+lz_decoder_reset(lzma_coder *coder)+{+ coder->dict.pos = 0;+ coder->dict.full = 0;+ coder->dict.buf[coder->dict.size - 1] = '\0';+ coder->dict.need_reset = false;+ return;+}+++static lzma_ret+decode_buffer(lzma_coder *coder,+ 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)+{+ while (true) {+ // Wrap the dictionary if needed.+ if (coder->dict.pos == coder->dict.size)+ coder->dict.pos = 0;++ // Store the current dictionary position. It is needed to know+ // where to start copying to the out[] buffer.+ const size_t dict_start = coder->dict.pos;++ // Calculate how much we allow coder->lz.code() to decode.+ // It must not decode past the end of the dictionary+ // buffer, and we don't want it to decode more than is+ // actually needed to fill the out[] buffer.+ coder->dict.limit = coder->dict.pos+ + my_min(out_size - *out_pos,+ coder->dict.size - coder->dict.pos);++ // Call the coder->lz.code() to do the actual decoding.+ const lzma_ret ret = coder->lz.code(+ coder->lz.coder, &coder->dict,+ in, in_pos, in_size);++ // Copy the decoded data from the dictionary to the out[]+ // buffer. Do it conditionally because out can be NULL+ // (in which case copy_size is always 0). Calling memcpy()+ // with a null-pointer is undefined even if the third+ // argument is 0.+ const size_t copy_size = coder->dict.pos - dict_start;+ assert(copy_size <= out_size - *out_pos);++ if (copy_size > 0)+ memcpy(out + *out_pos, coder->dict.buf + dict_start,+ copy_size);++ *out_pos += copy_size;++ // Reset the dictionary if so requested by coder->lz.code().+ if (coder->dict.need_reset) {+ lz_decoder_reset(coder);++ // Since we reset dictionary, we don't check if+ // dictionary became full.+ if (ret != LZMA_OK || *out_pos == out_size)+ return ret;+ } else {+ // Return if everything got decoded or an error+ // occurred, or if there's no more data to decode.+ //+ // Note that detecting if there's something to decode+ // is done by looking if dictionary become full+ // instead of looking if *in_pos == in_size. This+ // is because it is possible that all the input was+ // consumed already but some data is pending to be+ // written to the dictionary.+ if (ret != LZMA_OK || *out_pos == out_size+ || coder->dict.pos < coder->dict.size)+ return ret;+ }+ }+}+++static lzma_ret+lz_decode(void *coder_ptr, const 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_coder *coder = coder_ptr;++ if (coder->next.code == NULL)+ return decode_buffer(coder, in, in_pos, in_size,+ out, out_pos, out_size);++ // We aren't the last coder in the chain, we need to decode+ // our input to a temporary buffer.+ while (*out_pos < out_size) {+ // Fill the temporary buffer if it is empty.+ if (!coder->next_finished+ && coder->temp.pos == coder->temp.size) {+ coder->temp.pos = 0;+ coder->temp.size = 0;++ const lzma_ret ret = coder->next.code(+ coder->next.coder,+ allocator, in, in_pos, in_size,+ coder->temp.buffer, &coder->temp.size,+ LZMA_BUFFER_SIZE, action);++ if (ret == LZMA_STREAM_END)+ coder->next_finished = true;+ else if (ret != LZMA_OK || coder->temp.size == 0)+ return ret;+ }++ if (coder->this_finished) {+ if (coder->temp.size != 0)+ return LZMA_DATA_ERROR;++ if (coder->next_finished)+ return LZMA_STREAM_END;++ return LZMA_OK;+ }++ const lzma_ret ret = decode_buffer(coder, coder->temp.buffer,+ &coder->temp.pos, coder->temp.size,+ out, out_pos, out_size);++ if (ret == LZMA_STREAM_END)+ coder->this_finished = true;+ else if (ret != LZMA_OK)+ return ret;+ else if (coder->next_finished && *out_pos < out_size)+ return LZMA_DATA_ERROR;+ }++ return LZMA_OK;+}+++static void+lz_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_coder *coder = coder_ptr;++ lzma_next_end(&coder->next, allocator);+ lzma_free(coder->dict.buf, allocator);++ if (coder->lz.end != NULL)+ coder->lz.end(coder->lz.coder, allocator);+ else+ lzma_free(coder->lz.coder, allocator);++ lzma_free(coder, allocator);+ return;+}+++extern lzma_ret+lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters,+ lzma_ret (*lz_init)(lzma_lz_decoder *lz,+ const lzma_allocator *allocator, const void *options,+ lzma_lz_options *lz_options))+{+ // Allocate the base structure if it isn't already allocated.+ lzma_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &lz_decode;+ next->end = &lz_decoder_end;++ coder->dict.buf = NULL;+ coder->dict.size = 0;+ coder->lz = LZMA_LZ_DECODER_INIT;+ coder->next = LZMA_NEXT_CODER_INIT;+ }++ // Allocate and initialize the LZ-based decoder. It will also give+ // us the dictionary size.+ lzma_lz_options lz_options;+ return_if_error(lz_init(&coder->lz, allocator,+ filters[0].options, &lz_options));++ // If the dictionary size is very small, increase it to 4096 bytes.+ // This is to prevent constant wrapping of the dictionary, which+ // would slow things down. The downside is that since we don't check+ // separately for the real dictionary size, we may happily accept+ // corrupt files.+ if (lz_options.dict_size < 4096)+ lz_options.dict_size = 4096;++ // Make dictionary size a multiple of 16. Some LZ-based decoders like+ // LZMA use the lowest bits lzma_dict.pos to know the alignment of the+ // data. Aligned buffer is also good when memcpying from the+ // dictionary to the output buffer, since applications are+ // recommended to give aligned buffers to liblzma.+ //+ // Avoid integer overflow.+ if (lz_options.dict_size > SIZE_MAX - 15)+ return LZMA_MEM_ERROR;++ lz_options.dict_size = (lz_options.dict_size + 15) & ~((size_t)(15));++ // Allocate and initialize the dictionary.+ if (coder->dict.size != lz_options.dict_size) {+ lzma_free(coder->dict.buf, allocator);+ coder->dict.buf+ = lzma_alloc(lz_options.dict_size, allocator);+ if (coder->dict.buf == NULL)+ return LZMA_MEM_ERROR;++ coder->dict.size = lz_options.dict_size;+ }++ lz_decoder_reset(next->coder);++ // Use the preset dictionary if it was given to us.+ if (lz_options.preset_dict != NULL+ && lz_options.preset_dict_size > 0) {+ // If the preset dictionary is bigger than the actual+ // dictionary, copy only the tail.+ const size_t copy_size = my_min(lz_options.preset_dict_size,+ lz_options.dict_size);+ const size_t offset = lz_options.preset_dict_size - copy_size;+ memcpy(coder->dict.buf, lz_options.preset_dict + offset,+ copy_size);+ coder->dict.pos = copy_size;+ coder->dict.full = copy_size;+ }++ // Miscellaneous initializations+ coder->next_finished = false;+ coder->this_finished = false;+ coder->temp.pos = 0;+ coder->temp.size = 0;++ // Initialize the next filter in the chain, if any.+ return lzma_next_filter_init(&coder->next, allocator, filters + 1);+}+++extern uint64_t+lzma_lz_decoder_memusage(size_t dictionary_size)+{+ return sizeof(lzma_coder) + (uint64_t)(dictionary_size);+}+++extern void+lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)+{+ lzma_coder *coder = coder_ptr;+ coder->lz.set_uncompressed(coder->lz.coder, uncompressed_size);+}
+ cbits/liblzma/lz/lz_decoder.h view
@@ -0,0 +1,234 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lz_decoder.h+/// \brief LZ out window+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZ_DECODER_H+#define LZMA_LZ_DECODER_H++#include "common.h"+++typedef struct {+ /// Pointer to the dictionary buffer. It can be an allocated buffer+ /// internal to liblzma, or it can a be a buffer given by the+ /// application when in single-call mode (not implemented yet).+ uint8_t *buf;++ /// Write position in dictionary. The next byte will be written to+ /// buf[pos].+ size_t pos;++ /// Indicates how full the dictionary is. This is used by+ /// dict_is_distance_valid() to detect corrupt files that would+ /// read beyond the beginning of the dictionary.+ size_t full;++ /// Write limit+ size_t limit;++ /// Size of the dictionary+ size_t size;++ /// True when dictionary should be reset before decoding more data.+ bool need_reset;++} lzma_dict;+++typedef struct {+ size_t dict_size;+ const uint8_t *preset_dict;+ size_t preset_dict_size;+} lzma_lz_options;+++typedef struct {+ /// Data specific to the LZ-based decoder+ void *coder;++ /// Function to decode from in[] to *dict+ lzma_ret (*code)(void *coder,+ lzma_dict *restrict dict, const uint8_t *restrict in,+ size_t *restrict in_pos, size_t in_size);++ void (*reset)(void *coder, const void *options);++ /// Set the uncompressed size+ void (*set_uncompressed)(void *coder, lzma_vli uncompressed_size);++ /// Free allocated resources+ void (*end)(void *coder, const lzma_allocator *allocator);++} lzma_lz_decoder;+++#define LZMA_LZ_DECODER_INIT \+ (lzma_lz_decoder){ \+ .coder = NULL, \+ .code = NULL, \+ .reset = NULL, \+ .set_uncompressed = NULL, \+ .end = NULL, \+ }+++extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters,+ lzma_ret (*lz_init)(lzma_lz_decoder *lz,+ const lzma_allocator *allocator, const void *options,+ lzma_lz_options *lz_options));++extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size);++extern void lzma_lz_decoder_uncompressed(+ void *coder, lzma_vli uncompressed_size);+++//////////////////////+// Inline functions //+//////////////////////++/// Get a byte from the history buffer.+static inline uint8_t+dict_get(const lzma_dict *const dict, const uint32_t distance)+{+ return dict->buf[dict->pos - distance - 1+ + (distance < dict->pos ? 0 : dict->size)];+}+++/// Test if dictionary is empty.+static inline bool+dict_is_empty(const lzma_dict *const dict)+{+ return dict->full == 0;+}+++/// Validate the match distance+static inline bool+dict_is_distance_valid(const lzma_dict *const dict, const size_t distance)+{+ return dict->full > distance;+}+++/// Repeat *len bytes at distance.+static inline bool+dict_repeat(lzma_dict *dict, uint32_t distance, uint32_t *len)+{+ // Don't write past the end of the dictionary.+ const size_t dict_avail = dict->limit - dict->pos;+ uint32_t left = my_min(dict_avail, *len);+ *len -= left;++ // Repeat a block of data from the history. Because memcpy() is faster+ // than copying byte by byte in a loop, the copying process gets split+ // into three cases.+ if (distance < left) {+ // Source and target areas overlap, thus we can't use+ // memcpy() nor even memmove() safely.+ do {+ dict->buf[dict->pos] = dict_get(dict, distance);+ ++dict->pos;+ } while (--left > 0);++ } else if (distance < dict->pos) {+ // The easiest and fastest case+ memcpy(dict->buf + dict->pos,+ dict->buf + dict->pos - distance - 1,+ left);+ dict->pos += left;++ } else {+ // The bigger the dictionary, the more rare this+ // case occurs. We need to "wrap" the dict, thus+ // we might need two memcpy() to copy all the data.+ assert(dict->full == dict->size);+ const uint32_t copy_pos+ = dict->pos - distance - 1 + dict->size;+ uint32_t copy_size = dict->size - copy_pos;++ if (copy_size < left) {+ memmove(dict->buf + dict->pos, dict->buf + copy_pos,+ copy_size);+ dict->pos += copy_size;+ copy_size = left - copy_size;+ memcpy(dict->buf + dict->pos, dict->buf, copy_size);+ dict->pos += copy_size;+ } else {+ memmove(dict->buf + dict->pos, dict->buf + copy_pos,+ left);+ dict->pos += left;+ }+ }++ // Update how full the dictionary is.+ if (dict->full < dict->pos)+ dict->full = dict->pos;++ return unlikely(*len != 0);+}+++/// Puts one byte into the dictionary. Returns true if the dictionary was+/// already full and the byte couldn't be added.+static inline bool+dict_put(lzma_dict *dict, uint8_t byte)+{+ if (unlikely(dict->pos == dict->limit))+ return true;++ dict->buf[dict->pos++] = byte;++ if (dict->pos > dict->full)+ dict->full = dict->pos;++ return false;+}+++/// Copies arbitrary amount of data into the dictionary.+static inline void+dict_write(lzma_dict *restrict dict, const uint8_t *restrict in,+ size_t *restrict in_pos, size_t in_size,+ size_t *restrict left)+{+ // NOTE: If we are being given more data than the size of the+ // dictionary, it could be possible to optimize the LZ decoder+ // so that not everything needs to go through the dictionary.+ // This shouldn't be very common thing in practice though, and+ // the slowdown of one extra memcpy() isn't bad compared to how+ // much time it would have taken if the data were compressed.++ if (in_size - *in_pos > *left)+ in_size = *in_pos + *left;++ *left -= lzma_bufcpy(in, in_pos, in_size,+ dict->buf, &dict->pos, dict->limit);++ if (dict->pos > dict->full)+ dict->full = dict->pos;++ return;+}+++static inline void+dict_reset(lzma_dict *dict)+{+ dict->need_reset = true;+ return;+}++#endif
+ cbits/liblzma/lz/lz_encoder.c view
@@ -0,0 +1,616 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lz_encoder.c+/// \brief LZ in window+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lz_encoder.h"+#include "lz_encoder_hash.h"++// See lz_encoder_hash.h. This is a bit hackish but avoids making+// endianness a conditional in makefiles.+#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)+# include "lz_encoder_hash_table.h"+#endif++#include "memcmplen.h"+++typedef struct {+ /// LZ-based encoder e.g. LZMA+ lzma_lz_encoder lz;++ /// History buffer and match finder+ lzma_mf mf;++ /// Next coder in the chain+ lzma_next_coder next;+} lzma_coder;+++/// \brief Moves the data in the input window to free space for new data+///+/// mf->buffer is a sliding input window, which keeps mf->keep_size_before+/// bytes of input history available all the time. Now and then we need to+/// "slide" the buffer to make space for the new data to the end of the+/// buffer. At the same time, data older than keep_size_before is dropped.+///+static void+move_window(lzma_mf *mf)+{+ // Align the move to a multiple of 16 bytes. Some LZ-based encoders+ // like LZMA use the lowest bits of mf->read_pos to know the+ // alignment of the uncompressed data. We also get better speed+ // for memmove() with aligned buffers.+ assert(mf->read_pos > mf->keep_size_before);+ const uint32_t move_offset+ = (mf->read_pos - mf->keep_size_before) & ~UINT32_C(15);++ assert(mf->write_pos > move_offset);+ const size_t move_size = mf->write_pos - move_offset;++ assert(move_offset + move_size <= mf->size);++ memmove(mf->buffer, mf->buffer + move_offset, move_size);++ mf->offset += move_offset;+ mf->read_pos -= move_offset;+ mf->read_limit -= move_offset;+ mf->write_pos -= move_offset;++ return;+}+++/// \brief Tries to fill the input window (mf->buffer)+///+/// If we are the last encoder in the chain, our input data is in in[].+/// Otherwise we call the next filter in the chain to process in[] and+/// write its output to mf->buffer.+///+/// This function must not be called once it has returned LZMA_STREAM_END.+///+static lzma_ret+fill_window(lzma_coder *coder, const lzma_allocator *allocator,+ const uint8_t *in, size_t *in_pos, size_t in_size,+ lzma_action action)+{+ assert(coder->mf.read_pos <= coder->mf.write_pos);++ // Move the sliding window if needed.+ if (coder->mf.read_pos >= coder->mf.size - coder->mf.keep_size_after)+ move_window(&coder->mf);++ // Maybe this is ugly, but lzma_mf uses uint32_t for most things+ // (which I find cleanest), but we need size_t here when filling+ // the history window.+ size_t write_pos = coder->mf.write_pos;+ lzma_ret ret;+ if (coder->next.code == NULL) {+ // Not using a filter, simply memcpy() as much as possible.+ lzma_bufcpy(in, in_pos, in_size, coder->mf.buffer,+ &write_pos, coder->mf.size);++ ret = action != LZMA_RUN && *in_pos == in_size+ ? LZMA_STREAM_END : LZMA_OK;++ } else {+ ret = coder->next.code(coder->next.coder, allocator,+ in, in_pos, in_size,+ coder->mf.buffer, &write_pos,+ coder->mf.size, action);+ }++ coder->mf.write_pos = write_pos;++ // Silence Valgrind. lzma_memcmplen() can read extra bytes+ // and Valgrind will give warnings if those bytes are uninitialized+ // because Valgrind cannot see that the values of the uninitialized+ // bytes are eventually ignored.+ memzero(coder->mf.buffer + write_pos, LZMA_MEMCMPLEN_EXTRA);++ // 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) {+ assert(*in_pos == in_size);+ ret = LZMA_OK;+ coder->mf.action = action;+ coder->mf.read_limit = coder->mf.write_pos;++ } else if (coder->mf.write_pos > coder->mf.keep_size_after) {+ // This needs to be done conditionally, because if we got+ // only little new input, there may be too little input+ // to do any encoding yet.+ coder->mf.read_limit = coder->mf.write_pos+ - coder->mf.keep_size_after;+ }++ // Restart the match finder after finished LZMA_SYNC_FLUSH.+ if (coder->mf.pending > 0+ && coder->mf.read_pos < coder->mf.read_limit) {+ // Match finder may update coder->pending and expects it to+ // start from zero, so use a temporary variable.+ const uint32_t pending = coder->mf.pending;+ coder->mf.pending = 0;++ // Rewind read_pos so that the match finder can hash+ // the pending bytes.+ assert(coder->mf.read_pos >= pending);+ coder->mf.read_pos -= pending;++ // Call the skip function directly instead of using+ // mf_skip(), since we don't want to touch mf->read_ahead.+ coder->mf.skip(&coder->mf, pending);+ }++ return ret;+}+++static lzma_ret+lz_encode(void *coder_ptr, const 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_coder *coder = coder_ptr;++ while (*out_pos < out_size+ && (*in_pos < in_size || action != LZMA_RUN)) {+ // Read more data to coder->mf.buffer if needed.+ if (coder->mf.action == LZMA_RUN && coder->mf.read_pos+ >= coder->mf.read_limit)+ return_if_error(fill_window(coder, allocator,+ in, in_pos, in_size, action));++ // Encode+ const lzma_ret ret = coder->lz.code(coder->lz.coder,+ &coder->mf, out, out_pos, out_size);+ if (ret != LZMA_OK) {+ // Setting this to LZMA_RUN for cases when we are+ // flushing. It doesn't matter when finishing or if+ // an error occurred.+ coder->mf.action = LZMA_RUN;+ return ret;+ }+ }++ return LZMA_OK;+}+++static bool+lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator,+ const lzma_lz_options *lz_options)+{+ // For now, the dictionary size is limited to 1.5 GiB. This may grow+ // in the future if needed, but it needs a little more work than just+ // changing this check.+ if (lz_options->dict_size < LZMA_DICT_SIZE_MIN+ || lz_options->dict_size+ > (UINT32_C(1) << 30) + (UINT32_C(1) << 29)+ || lz_options->nice_len > lz_options->match_len_max)+ return true;++ mf->keep_size_before = lz_options->before_size + lz_options->dict_size;++ mf->keep_size_after = lz_options->after_size+ + lz_options->match_len_max;++ // To avoid constant memmove()s, allocate some extra space. Since+ // memmove()s become more expensive when the size of the buffer+ // increases, we reserve more space when a large dictionary is+ // used to make the memmove() calls rarer.+ //+ // This works with dictionaries up to about 3 GiB. If bigger+ // dictionary is wanted, some extra work is needed:+ // - Several variables in lzma_mf have to be changed from uint32_t+ // to size_t.+ // - Memory usage calculation needs something too, e.g. use uint64_t+ // for mf->size.+ uint32_t reserve = lz_options->dict_size / 2;+ if (reserve > (UINT32_C(1) << 30))+ reserve /= 2;++ reserve += (lz_options->before_size + lz_options->match_len_max+ + lz_options->after_size) / 2 + (UINT32_C(1) << 19);++ const uint32_t old_size = mf->size;+ mf->size = mf->keep_size_before + reserve + mf->keep_size_after;++ // Deallocate the old history buffer if it exists but has different+ // size than what is needed now.+ if (mf->buffer != NULL && old_size != mf->size) {+ lzma_free(mf->buffer, allocator);+ mf->buffer = NULL;+ }++ // Match finder options+ mf->match_len_max = lz_options->match_len_max;+ mf->nice_len = lz_options->nice_len;++ // cyclic_size has to stay smaller than 2 Gi. Note that this doesn't+ // mean limiting dictionary size to less than 2 GiB. With a match+ // finder that uses multibyte resolution (hashes start at e.g. every+ // fourth byte), cyclic_size would stay below 2 Gi even when+ // dictionary size is greater than 2 GiB.+ //+ // It would be possible to allow cyclic_size >= 2 Gi, but then we+ // would need to be careful to use 64-bit types in various places+ // (size_t could do since we would need bigger than 32-bit address+ // space anyway). It would also require either zeroing a multigigabyte+ // buffer at initialization (waste of time and RAM) or allow+ // normalization in lz_encoder_mf.c to access uninitialized+ // memory to keep the code simpler. The current way is simple and+ // still allows pretty big dictionaries, so I don't expect these+ // limits to change.+ mf->cyclic_size = lz_options->dict_size + 1;++ // Validate the match finder ID and setup the function pointers.+ switch (lz_options->match_finder) {+#ifdef HAVE_MF_HC3+ case LZMA_MF_HC3:+ mf->find = &lzma_mf_hc3_find;+ mf->skip = &lzma_mf_hc3_skip;+ break;+#endif+#ifdef HAVE_MF_HC4+ case LZMA_MF_HC4:+ mf->find = &lzma_mf_hc4_find;+ mf->skip = &lzma_mf_hc4_skip;+ break;+#endif+#ifdef HAVE_MF_BT2+ case LZMA_MF_BT2:+ mf->find = &lzma_mf_bt2_find;+ mf->skip = &lzma_mf_bt2_skip;+ break;+#endif+#ifdef HAVE_MF_BT3+ case LZMA_MF_BT3:+ mf->find = &lzma_mf_bt3_find;+ mf->skip = &lzma_mf_bt3_skip;+ break;+#endif+#ifdef HAVE_MF_BT4+ case LZMA_MF_BT4:+ mf->find = &lzma_mf_bt4_find;+ mf->skip = &lzma_mf_bt4_skip;+ break;+#endif++ default:+ return true;+ }++ // Calculate the sizes of mf->hash and mf->son and check that+ // nice_len is big enough for the selected match finder.+ const uint32_t hash_bytes = lz_options->match_finder & 0x0F;+ if (hash_bytes > mf->nice_len)+ return true;++ const bool is_bt = (lz_options->match_finder & 0x10) != 0;+ uint32_t hs;++ if (hash_bytes == 2) {+ hs = 0xFFFF;+ } else {+ // Round dictionary size up to the next 2^n - 1 so it can+ // be used as a hash mask.+ hs = lz_options->dict_size - 1;+ hs |= hs >> 1;+ hs |= hs >> 2;+ hs |= hs >> 4;+ hs |= hs >> 8;+ hs >>= 1;+ hs |= 0xFFFF;++ if (hs > (UINT32_C(1) << 24)) {+ if (hash_bytes == 3)+ hs = (UINT32_C(1) << 24) - 1;+ else+ hs >>= 1;+ }+ }++ mf->hash_mask = hs;++ ++hs;+ if (hash_bytes > 2)+ hs += HASH_2_SIZE;+ if (hash_bytes > 3)+ hs += HASH_3_SIZE;+/*+ No match finder uses this at the moment.+ if (mf->hash_bytes > 4)+ hs += HASH_4_SIZE;+*/++ 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;++ // Deallocate the old hash array if it exists and has different size+ // than what is needed now.+ 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+ mf->depth = lz_options->depth;+ if (mf->depth == 0) {+ if (is_bt)+ mf->depth = 16 + mf->nice_len / 2;+ else+ mf->depth = 4 + mf->nice_len / 4;+ }++ return false;+}+++static bool+lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator,+ const lzma_lz_options *lz_options)+{+ // Allocate the history buffer.+ if (mf->buffer == NULL) {+ // 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+ // avoiding a few branches in the match finders. The downside is+ // that match finder needs to be normalized more often, which may+ // hurt performance with huge dictionaries.+ mf->offset = mf->cyclic_size;+ mf->read_pos = 0;+ mf->read_ahead = 0;+ mf->read_limit = 0;+ mf->write_pos = 0;+ mf->pending = 0;++#if UINT32_MAX >= SIZE_MAX / 4+ // Check for integer overflow. (Huge dictionaries are not+ // possible on 32-bit CPU.)+ 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_zero(mf->hash_count * sizeof(uint32_t),+ allocator);+ 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->cyclic_pos = 0;++ // Handle preset dictionary.+ if (lz_options->preset_dict != NULL+ && lz_options->preset_dict_size > 0) {+ // If the preset dictionary is bigger than the actual+ // dictionary, use only the tail.+ mf->write_pos = my_min(lz_options->preset_dict_size, mf->size);+ memcpy(mf->buffer, lz_options->preset_dict+ + lz_options->preset_dict_size - mf->write_pos,+ mf->write_pos);+ mf->action = LZMA_SYNC_FLUSH;+ mf->skip(mf, mf->write_pos);+ }++ mf->action = LZMA_RUN;++ return false;+}+++extern uint64_t+lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)+{+ // Old buffers must not exist when calling lz_encoder_prepare().+ lzma_mf mf = {+ .buffer = NULL,+ .hash = NULL,+ .son = NULL,+ .hash_count = 0,+ .sons_count = 0,+ };++ // Setup the size information into mf.+ if (lz_encoder_prepare(&mf, NULL, lz_options))+ return UINT64_MAX;++ // Calculate the memory usage.+ return ((uint64_t)(mf.hash_count) + mf.sons_count) * sizeof(uint32_t)+ + mf.size + sizeof(lzma_coder);+}+++static void+lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_coder *coder = coder_ptr;++ lzma_next_end(&coder->next, allocator);++ lzma_free(coder->mf.son, allocator);+ lzma_free(coder->mf.hash, allocator);+ lzma_free(coder->mf.buffer, allocator);++ if (coder->lz.end != NULL)+ coder->lz.end(coder->lz.coder, allocator);+ else+ lzma_free(coder->lz.coder, allocator);++ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+lz_encoder_update(void *coder_ptr, const lzma_allocator *allocator,+ const lzma_filter *filters_null lzma_attribute((__unused__)),+ const lzma_filter *reversed_filters)+{+ lzma_coder *coder = coder_ptr;++ if (coder->lz.options_update == NULL)+ return LZMA_PROG_ERROR;++ return_if_error(coder->lz.options_update(+ coder->lz.coder, reversed_filters));++ return lzma_next_filter_update(+ &coder->next, allocator, reversed_filters + 1);+}+++extern lzma_ret+lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters,+ lzma_ret (*lz_init)(lzma_lz_encoder *lz,+ const lzma_allocator *allocator, const void *options,+ lzma_lz_options *lz_options))+{+#ifdef HAVE_SMALL+ // We need that the CRC32 table has been initialized.+ lzma_crc32_init();+#endif++ // Allocate and initialize the base data structure.+ lzma_coder *coder = next->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &lz_encode;+ next->end = &lz_encoder_end;+ next->update = &lz_encoder_update;++ coder->lz.coder = NULL;+ coder->lz.code = NULL;+ coder->lz.end = NULL;++ // mf.size is initialized to silence Valgrind+ // when used on optimized binaries (GCC may reorder+ // code in a way that Valgrind gets unhappy).+ coder->mf.buffer = NULL;+ coder->mf.size = 0;+ coder->mf.hash = NULL;+ coder->mf.son = NULL;+ coder->mf.hash_count = 0;+ coder->mf.sons_count = 0;++ coder->next = LZMA_NEXT_CODER_INIT;+ }++ // Initialize the LZ-based encoder.+ lzma_lz_options lz_options;+ return_if_error(lz_init(&coder->lz, allocator,+ filters[0].options, &lz_options));++ // Setup the size information into coder->mf and deallocate+ // old buffers if they have wrong size.+ if (lz_encoder_prepare(&coder->mf, allocator, &lz_options))+ return LZMA_OPTIONS_ERROR;++ // Allocate new buffers if needed, and do the rest of+ // the initialization.+ if (lz_encoder_init(&coder->mf, allocator, &lz_options))+ return LZMA_MEM_ERROR;++ // Initialize the next filter in the chain, if any.+ return lzma_next_filter_init(&coder->next, allocator, filters + 1);+}+++extern LZMA_API(lzma_bool)+lzma_mf_is_supported(lzma_match_finder mf)+{+ bool ret = false;++#ifdef HAVE_MF_HC3+ if (mf == LZMA_MF_HC3)+ ret = true;+#endif++#ifdef HAVE_MF_HC4+ if (mf == LZMA_MF_HC4)+ ret = true;+#endif++#ifdef HAVE_MF_BT2+ if (mf == LZMA_MF_BT2)+ ret = true;+#endif++#ifdef HAVE_MF_BT3+ if (mf == LZMA_MF_BT3)+ ret = true;+#endif++#ifdef HAVE_MF_BT4+ if (mf == LZMA_MF_BT4)+ ret = true;+#endif++ return ret;+}
+ cbits/liblzma/lz/lz_encoder.h view
@@ -0,0 +1,327 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lz_encoder.h+/// \brief LZ in window and match finder API+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZ_ENCODER_H+#define LZMA_LZ_ENCODER_H++#include "common.h"+++/// A table of these is used by the LZ-based encoder to hold+/// the length-distance pairs found by the match finder.+typedef struct {+ uint32_t len;+ uint32_t dist;+} lzma_match;+++typedef struct lzma_mf_s lzma_mf;+struct lzma_mf_s {+ ///////////////+ // In Window //+ ///////////////++ /// Pointer to buffer with data to be compressed+ uint8_t *buffer;++ /// Total size of the allocated buffer (that is, including all+ /// the extra space)+ uint32_t size;++ /// Number of bytes that must be kept available in our input history.+ /// That is, once keep_size_before bytes have been processed,+ /// buffer[read_pos - keep_size_before] is the oldest byte that+ /// must be available for reading.+ uint32_t keep_size_before;++ /// Number of bytes that must be kept in buffer after read_pos.+ /// That is, read_pos <= write_pos - keep_size_after as long as+ /// action is LZMA_RUN; when action != LZMA_RUN, read_pos is allowed+ /// to reach write_pos so that the last bytes get encoded too.+ uint32_t keep_size_after;++ /// Match finders store locations of matches using 32-bit integers.+ /// To avoid adjusting several megabytes of integers every time the+ /// input window is moved with move_window, we only adjust the+ /// offset of the buffer. Thus, buffer[value_in_hash_table - offset]+ /// is the byte pointed by value_in_hash_table.+ uint32_t offset;++ /// buffer[read_pos] is the next byte to run through the match+ /// finder. This is incremented in the match finder once the byte+ /// has been processed.+ uint32_t read_pos;++ /// Number of bytes that have been ran through the match finder, but+ /// which haven't been encoded by the LZ-based encoder yet.+ uint32_t read_ahead;++ /// As long as read_pos is less than read_limit, there is enough+ /// input available in buffer for at least one encoding loop.+ ///+ /// Because of the stateful API, read_limit may and will get greater+ /// than read_pos quite often. This is taken into account when+ /// calculating the value for keep_size_after.+ uint32_t read_limit;++ /// buffer[write_pos] is the first byte that doesn't contain valid+ /// uncompressed data; that is, the next input byte will be copied+ /// to buffer[write_pos].+ uint32_t write_pos;++ /// Number of bytes not hashed before read_pos. This is needed to+ /// restart the match finder after LZMA_SYNC_FLUSH.+ uint32_t pending;++ //////////////////+ // Match Finder //+ //////////////////++ /// Find matches. Returns the number of distance-length pairs written+ /// to the matches array. This is called only via lzma_mf_find().+ uint32_t (*find)(lzma_mf *mf, lzma_match *matches);++ /// Skips num bytes. This is like find() but doesn't make the+ /// distance-length pairs available, thus being a little faster.+ /// This is called only via mf_skip().+ void (*skip)(lzma_mf *mf, uint32_t num);++ uint32_t *hash;+ uint32_t *son;+ uint32_t cyclic_pos;+ uint32_t cyclic_size; // Must be dictionary size + 1.+ uint32_t hash_mask;++ /// Maximum number of loops in the match finder+ uint32_t depth;++ /// Maximum length of a match that the match finder will try to find.+ uint32_t nice_len;++ /// Maximum length of a match supported by the LZ-based encoder.+ /// If the longest match found by the match finder is nice_len,+ /// mf_find() tries to expand it up to match_len_max bytes.+ uint32_t match_len_max;++ /// When running out of input, binary tree match finders need to know+ /// if it is due to flushing or finishing. The action is used also+ /// by the LZ-based encoders themselves.+ lzma_action action;++ /// Number of elements in hash[]+ uint32_t hash_count;++ /// Number of elements in son[]+ uint32_t sons_count;+};+++typedef struct {+ /// Extra amount of data to keep available before the "actual"+ /// dictionary.+ size_t before_size;++ /// Size of the history buffer+ size_t dict_size;++ /// Extra amount of data to keep available after the "actual"+ /// dictionary.+ size_t after_size;++ /// Maximum length of a match that the LZ-based encoder can accept.+ /// This is used to extend matches of length nice_len to the+ /// maximum possible length.+ size_t match_len_max;++ /// Match finder will search matches up to this length.+ /// This must be less than or equal to match_len_max.+ size_t nice_len;++ /// Type of the match finder to use+ lzma_match_finder match_finder;++ /// Maximum search depth+ uint32_t depth;++ /// TODO: Comment+ const uint8_t *preset_dict;++ uint32_t preset_dict_size;++} lzma_lz_options;+++// The total usable buffer space at any moment outside the match finder:+// before_size + dict_size + after_size + match_len_max+//+// In reality, there's some extra space allocated to prevent the number of+// memmove() calls reasonable. The bigger the dict_size is, the bigger+// this extra buffer will be since with bigger dictionaries memmove() would+// also take longer.+//+// A single encoder loop in the LZ-based encoder may call the match finder+// (mf_find() or mf_skip()) at most after_size times. In other words,+// a single encoder loop may increment lzma_mf.read_pos at most after_size+// times. Since matches are looked up to+// lzma_mf.buffer[lzma_mf.read_pos + match_len_max - 1], the total+// amount of extra buffer needed after dict_size becomes+// after_size + match_len_max.+//+// before_size has two uses. The first one is to keep literals available+// in cases when the LZ-based encoder has made some read ahead.+// TODO: Maybe this could be changed by making the LZ-based encoders to+// store the actual literals as they do with length-distance pairs.+//+// Algorithms such as LZMA2 first try to compress a chunk, and then check+// if the encoded result is smaller than the uncompressed one. If the chunk+// was uncompressible, it is better to store it in uncompressed form in+// the output stream. To do this, the whole uncompressed chunk has to be+// still available in the history buffer. before_size achieves that.+++typedef struct {+ /// Data specific to the LZ-based encoder+ void *coder;++ /// Function to encode from *dict to out[]+ lzma_ret (*code)(void *coder,+ lzma_mf *restrict mf, uint8_t *restrict out,+ size_t *restrict out_pos, size_t out_size);++ /// Free allocated resources+ void (*end)(void *coder, const lzma_allocator *allocator);++ /// Update the options in the middle of the encoding.+ lzma_ret (*options_update)(void *coder, const lzma_filter *filter);++} lzma_lz_encoder;+++// Basic steps:+// 1. Input gets copied into the dictionary.+// 2. Data in dictionary gets run through the match finder byte by byte.+// 3. The literals and matches are encoded using e.g. LZMA.+//+// The bytes that have been ran through the match finder, but not encoded yet,+// are called `read ahead'.+++/// Get pointer to the first byte not ran through the match finder+static inline const uint8_t *+mf_ptr(const lzma_mf *mf)+{+ return mf->buffer + mf->read_pos;+}+++/// Get the number of bytes that haven't been ran through the match finder yet.+static inline uint32_t+mf_avail(const lzma_mf *mf)+{+ return mf->write_pos - mf->read_pos;+}+++/// Get the number of bytes that haven't been encoded yet (some of these+/// bytes may have been ran through the match finder though).+static inline uint32_t+mf_unencoded(const lzma_mf *mf)+{+ return mf->write_pos - mf->read_pos + mf->read_ahead;+}+++/// Calculate the absolute offset from the beginning of the most recent+/// dictionary reset. Only the lowest four bits are important, so there's no+/// problem that we don't know the 64-bit size of the data encoded so far.+///+/// NOTE: When moving the input window, we need to do it so that the lowest+/// bits of dict->read_pos are not modified to keep this macro working+/// as intended.+static inline uint32_t+mf_position(const lzma_mf *mf)+{+ return mf->read_pos - mf->read_ahead;+}+++/// Since everything else begins with mf_, use it also for lzma_mf_find().+#define mf_find lzma_mf_find+++/// Skip the given number of bytes. This is used when a good match was found.+/// For example, if mf_find() finds a match of 200 bytes long, the first byte+/// of that match was already consumed by mf_find(), and the rest 199 bytes+/// have to be skipped with mf_skip(mf, 199).+static inline void+mf_skip(lzma_mf *mf, uint32_t amount)+{+ if (amount != 0) {+ mf->skip(mf, amount);+ mf->read_ahead += amount;+ }+}+++/// Copies at most *left number of bytes from the history buffer+/// to out[]. This is needed by LZMA2 to encode uncompressed chunks.+static inline void+mf_read(lzma_mf *mf, uint8_t *out, size_t *out_pos, size_t out_size,+ size_t *left)+{+ const size_t out_avail = out_size - *out_pos;+ const size_t copy_size = my_min(out_avail, *left);++ assert(mf->read_ahead == 0);+ assert(mf->read_pos >= *left);++ memcpy(out + *out_pos, mf->buffer + mf->read_pos - *left,+ copy_size);++ *out_pos += copy_size;+ *left -= copy_size;+ return;+}+++extern lzma_ret lzma_lz_encoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters,+ lzma_ret (*lz_init)(lzma_lz_encoder *lz,+ const lzma_allocator *allocator, const void *options,+ lzma_lz_options *lz_options));+++extern uint64_t lzma_lz_encoder_memusage(const lzma_lz_options *lz_options);+++// These are only for LZ encoder's internal use.+extern uint32_t lzma_mf_find(+ lzma_mf *mf, uint32_t *count, lzma_match *matches);++extern uint32_t lzma_mf_hc3_find(lzma_mf *dict, lzma_match *matches);+extern void lzma_mf_hc3_skip(lzma_mf *dict, uint32_t amount);++extern uint32_t lzma_mf_hc4_find(lzma_mf *dict, lzma_match *matches);+extern void lzma_mf_hc4_skip(lzma_mf *dict, uint32_t amount);++extern uint32_t lzma_mf_bt2_find(lzma_mf *dict, lzma_match *matches);+extern void lzma_mf_bt2_skip(lzma_mf *dict, uint32_t amount);++extern uint32_t lzma_mf_bt3_find(lzma_mf *dict, lzma_match *matches);+extern void lzma_mf_bt3_skip(lzma_mf *dict, uint32_t amount);++extern uint32_t lzma_mf_bt4_find(lzma_mf *dict, lzma_match *matches);+extern void lzma_mf_bt4_skip(lzma_mf *dict, uint32_t amount);++#endif
+ cbits/liblzma/lz/lz_encoder_hash.h view
@@ -0,0 +1,108 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lz_encoder_hash.h+/// \brief Hash macros for match finders+//+// Author: Igor Pavlov+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZ_ENCODER_HASH_H+#define LZMA_LZ_ENCODER_HASH_H++#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)+ // This is to make liblzma produce the same output on big endian+ // systems that it does on little endian systems. lz_encoder.c+ // takes care of including the actual table.+ extern const uint32_t lzma_lz_hash_table[256];+# define hash_table lzma_lz_hash_table+#else+# include "check.h"+# define hash_table lzma_crc32_table[0]+#endif++#define HASH_2_SIZE (UINT32_C(1) << 10)+#define HASH_3_SIZE (UINT32_C(1) << 16)+#define HASH_4_SIZE (UINT32_C(1) << 20)++#define HASH_2_MASK (HASH_2_SIZE - 1)+#define HASH_3_MASK (HASH_3_SIZE - 1)+#define HASH_4_MASK (HASH_4_SIZE - 1)++#define FIX_3_HASH_SIZE (HASH_2_SIZE)+#define FIX_4_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE)+#define FIX_5_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE + HASH_4_SIZE)++// Endianness doesn't matter in hash_2_calc() (no effect on the output).+#ifdef TUKLIB_FAST_UNALIGNED_ACCESS+# define hash_2_calc() \+ const uint32_t hash_value = read16ne(cur)+#else+# define hash_2_calc() \+ const uint32_t hash_value \+ = (uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)+#endif++#define hash_3_calc() \+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \+ const uint32_t hash_2_value = temp & HASH_2_MASK; \+ const uint32_t hash_value \+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask++#define hash_4_calc() \+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \+ const uint32_t hash_2_value = temp & HASH_2_MASK; \+ const uint32_t hash_3_value \+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \+ const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) \+ ^ (hash_table[cur[3]] << 5)) & mf->hash_mask+++// The following are not currently used.++#define hash_5_calc() \+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \+ const uint32_t hash_2_value = temp & HASH_2_MASK; \+ const uint32_t hash_3_value \+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \+ uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \+ ^ hash_table[cur[3]] << 5); \+ const uint32_t hash_value \+ = (hash_4_value ^ (hash_table[cur[4]] << 3)) \+ & mf->hash_mask; \+ hash_4_value &= HASH_4_MASK++/*+#define hash_zip_calc() \+ const uint32_t hash_value \+ = (((uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)) \+ ^ hash_table[cur[2]]) & 0xFFFF+*/++#define hash_zip_calc() \+ const uint32_t hash_value \+ = (((uint32_t)(cur[2]) | ((uint32_t)(cur[0]) << 8)) \+ ^ hash_table[cur[1]]) & 0xFFFF++#define mt_hash_2_calc() \+ const uint32_t hash_2_value \+ = (hash_table[cur[0]] ^ cur[1]) & HASH_2_MASK++#define mt_hash_3_calc() \+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \+ const uint32_t hash_2_value = temp & HASH_2_MASK; \+ const uint32_t hash_3_value \+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK++#define mt_hash_4_calc() \+ const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \+ const uint32_t hash_2_value = temp & HASH_2_MASK; \+ const uint32_t hash_3_value \+ = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \+ const uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \+ (hash_table[cur[3]] << 5)) & HASH_4_MASK++#endif
+ cbits/liblzma/lz/lz_encoder_hash_table.h view
@@ -0,0 +1,68 @@+/* This file has been automatically generated by crc32_tablegen.c. */++const uint32_t lzma_lz_hash_table[256] = {+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D+};
+ cbits/liblzma/lz/lz_encoder_mf.c view
@@ -0,0 +1,744 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lz_encoder_mf.c+/// \brief Match finders+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lz_encoder.h"+#include "lz_encoder_hash.h"+#include "memcmplen.h"+++/// \brief Find matches starting from the current byte+///+/// \return The length of the longest match found+extern uint32_t+lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)+{+ // Call the match finder. It returns the number of length-distance+ // pairs found.+ // FIXME: Minimum count is zero, what _exactly_ is the maximum?+ const uint32_t count = mf->find(mf, matches);++ // Length of the longest match; assume that no matches were found+ // and thus the maximum length is zero.+ uint32_t len_best = 0;++ if (count > 0) {+#ifndef NDEBUG+ // Validate the matches.+ for (uint32_t i = 0; i < count; ++i) {+ assert(matches[i].len <= mf->nice_len);+ assert(matches[i].dist < mf->read_pos);+ assert(memcmp(mf_ptr(mf) - 1,+ mf_ptr(mf) - matches[i].dist - 2,+ matches[i].len) == 0);+ }+#endif++ // The last used element in the array contains+ // the longest match.+ len_best = matches[count - 1].len;++ // If a match of maximum search length was found, try to+ // extend the match to maximum possible length.+ if (len_best == mf->nice_len) {+ // The limit for the match length is either the+ // maximum match length supported by the LZ-based+ // encoder or the number of bytes left in the+ // dictionary, whichever is smaller.+ uint32_t limit = mf_avail(mf) + 1;+ if (limit > mf->match_len_max)+ limit = mf->match_len_max;++ // Pointer to the byte we just ran through+ // the match finder.+ const uint8_t *p1 = mf_ptr(mf) - 1;++ // Pointer to the beginning of the match. We need -1+ // here because the match distances are zero based.+ const uint8_t *p2 = p1 - matches[count - 1].dist - 1;++ len_best = lzma_memcmplen(p1, p2, len_best, limit);+ }+ }++ *count_ptr = count;++ // Finally update the read position to indicate that match finder was+ // run for this dictionary offset.+ ++mf->read_ahead;++ return len_best;+}+++/// Hash value to indicate unused element in the hash. Since we start the+/// positions from dict_size + 1, zero is always too far to qualify+/// as usable match position.+#define EMPTY_HASH_VALUE 0+++/// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos+/// reaches MUST_NORMALIZE_POS.+#define MUST_NORMALIZE_POS UINT32_MAX+++/// \brief Normalizes hash values+///+/// The hash arrays store positions of match candidates. The positions are+/// relative to an arbitrary offset that is not the same as the absolute+/// offset in the input stream. The relative position of the current byte+/// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are+/// the differences of the current read position and the position found from+/// the hash.+///+/// To prevent integer overflows of the offsets stored in the hash arrays,+/// we need to "normalize" the stored values now and then. During the+/// normalization, we drop values that indicate distance greater than the+/// dictionary size, thus making space for new values.+static void+normalize(lzma_mf *mf)+{+ assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS);++ // In future we may not want to touch the lowest bits, because there+ // may be match finders that use larger resolution than one byte.+ const uint32_t subvalue+ = (MUST_NORMALIZE_POS - mf->cyclic_size);+ // & ~((UINT32_C(1) << 10) - 1);++ 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.+ if (mf->hash[i] <= subvalue)+ mf->hash[i] = EMPTY_HASH_VALUE;+ else+ 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.+ mf->offset -= subvalue;++ return;+}+++/// Mark the current byte as processed from point of view of the match finder.+static void+move_pos(lzma_mf *mf)+{+ if (++mf->cyclic_pos == mf->cyclic_size)+ mf->cyclic_pos = 0;++ ++mf->read_pos;+ assert(mf->read_pos <= mf->write_pos);++ if (unlikely(mf->read_pos + mf->offset == UINT32_MAX))+ normalize(mf);+}+++/// When flushing, we cannot run the match finder unless there is nice_len+/// bytes available in the dictionary. Instead, we skip running the match+/// finder (indicating that no match was found), and count how many bytes we+/// have ignored this way.+///+/// When new data is given after the flushing was completed, the match finder+/// is restarted by rewinding mf->read_pos backwards by mf->pending. Then+/// the missed bytes are added to the hash using the match finder's skip+/// function (with small amount of input, it may start using mf->pending+/// again if flushing).+///+/// Due to this rewinding, we don't touch cyclic_pos or test for+/// normalization. It will be done when the match finder's skip function+/// catches up after a flush.+static void+move_pending(lzma_mf *mf)+{+ ++mf->read_pos;+ assert(mf->read_pos <= mf->write_pos);+ ++mf->pending;+}+++/// Calculate len_limit and determine if there is enough input to run+/// the actual match finder code. Sets up "cur" and "pos". This macro+/// is used by all find functions and binary tree skip functions. Hash+/// chain skip function doesn't need len_limit so a simpler code is used+/// in them.+#define header(is_bt, len_min, ret_op) \+ uint32_t len_limit = mf_avail(mf); \+ if (mf->nice_len <= len_limit) { \+ len_limit = mf->nice_len; \+ } else if (len_limit < (len_min) \+ || (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \+ assert(mf->action != LZMA_RUN); \+ move_pending(mf); \+ ret_op; \+ } \+ const uint8_t *cur = mf_ptr(mf); \+ const uint32_t pos = mf->read_pos + mf->offset+++/// Header for find functions. "return 0" indicates that zero matches+/// were found.+#define header_find(is_bt, len_min) \+ header(is_bt, len_min, return 0); \+ uint32_t matches_count = 0+++/// Header for a loop in a skip function. "continue" tells to skip the rest+/// of the code in the loop.+#define header_skip(is_bt, len_min) \+ header(is_bt, len_min, continue)+++/// Calls hc_find_func() or bt_find_func() and calculates the total number+/// of matches found. Updates the dictionary position and returns the number+/// of matches found.+#define call_find(func, len_best) \+do { \+ matches_count = func(len_limit, pos, cur, cur_match, mf->depth, \+ mf->son, mf->cyclic_pos, mf->cyclic_size, \+ matches + matches_count, len_best) \+ - matches; \+ move_pos(mf); \+ return matches_count; \+} while (0)+++////////////////+// Hash Chain //+////////////////++#if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4)+///+///+/// \param len_limit Don't look for matches longer than len_limit.+/// \param pos lzma_mf.read_pos + lzma_mf.offset+/// \param cur Pointer to current byte (mf_ptr(mf))+/// \param cur_match Start position of the current match candidate+/// \param depth Maximum length of the hash chain+/// \param son lzma_mf.son (contains the hash chain)+/// \param cyclic_pos+/// \param cyclic_size+/// \param matches Array to hold the matches.+/// \param len_best The length of the longest match found so far.+static lzma_match *+hc_find_func(+ const uint32_t len_limit,+ const uint32_t pos,+ const uint8_t *const cur,+ uint32_t cur_match,+ uint32_t depth,+ uint32_t *const son,+ const uint32_t cyclic_pos,+ const uint32_t cyclic_size,+ lzma_match *matches,+ uint32_t len_best)+{+ son[cyclic_pos] = cur_match;++ while (true) {+ const uint32_t delta = pos - cur_match;+ if (depth-- == 0 || delta >= cyclic_size)+ return matches;++ const uint8_t *const pb = cur - delta;+ cur_match = son[cyclic_pos - delta+ + (delta > cyclic_pos ? cyclic_size : 0)];++ if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {+ uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit);++ if (len_best < len) {+ len_best = len;+ matches->len = len;+ matches->dist = delta - 1;+ ++matches;++ if (len == len_limit)+ return matches;+ }+ }+ }+}+++#define hc_find(len_best) \+ call_find(hc_find_func, len_best)+++#define hc_skip() \+do { \+ mf->son[mf->cyclic_pos] = cur_match; \+ move_pos(mf); \+} while (0)++#endif+++#ifdef HAVE_MF_HC3+extern uint32_t+lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches)+{+ header_find(false, 3);++ hash_3_calc();++ const uint32_t delta2 = pos - mf->hash[hash_2_value];+ const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;++ uint32_t len_best = 2;++ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {+ len_best = lzma_memcmplen(cur - delta2, cur,+ len_best, len_limit);++ matches[0].len = len_best;+ matches[0].dist = delta2 - 1;+ matches_count = 1;++ if (len_best == len_limit) {+ hc_skip();+ return 1; // matches_count+ }+ }++ hc_find(len_best);+}+++extern void+lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount)+{+ do {+ if (mf_avail(mf) < 3) {+ move_pending(mf);+ continue;+ }++ const uint8_t *cur = mf_ptr(mf);+ const uint32_t pos = mf->read_pos + mf->offset;++ hash_3_calc();++ const uint32_t cur_match+ = mf->hash[FIX_3_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;++ hc_skip();++ } while (--amount != 0);+}+#endif+++#ifdef HAVE_MF_HC4+extern uint32_t+lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches)+{+ header_find(false, 4);++ hash_4_calc();++ uint32_t delta2 = pos - mf->hash[hash_2_value];+ const uint32_t delta3+ = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];+ const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];++ mf->hash[hash_2_value ] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;++ uint32_t len_best = 1;++ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {+ len_best = 2;+ matches[0].len = 2;+ matches[0].dist = delta2 - 1;+ matches_count = 1;+ }++ if (delta2 != delta3 && delta3 < mf->cyclic_size+ && *(cur - delta3) == *cur) {+ len_best = 3;+ matches[matches_count++].dist = delta3 - 1;+ delta2 = delta3;+ }++ if (matches_count != 0) {+ len_best = lzma_memcmplen(cur - delta2, cur,+ len_best, len_limit);++ matches[matches_count - 1].len = len_best;++ if (len_best == len_limit) {+ hc_skip();+ return matches_count;+ }+ }++ if (len_best < 3)+ len_best = 3;++ hc_find(len_best);+}+++extern void+lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount)+{+ do {+ if (mf_avail(mf) < 4) {+ move_pending(mf);+ continue;+ }++ const uint8_t *cur = mf_ptr(mf);+ const uint32_t pos = mf->read_pos + mf->offset;++ hash_4_calc();++ const uint32_t cur_match+ = mf->hash[FIX_4_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;++ hc_skip();++ } while (--amount != 0);+}+#endif+++/////////////////+// Binary Tree //+/////////////////++#if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4)+static lzma_match *+bt_find_func(+ const uint32_t len_limit,+ const uint32_t pos,+ const uint8_t *const cur,+ uint32_t cur_match,+ uint32_t depth,+ uint32_t *const son,+ const uint32_t cyclic_pos,+ const uint32_t cyclic_size,+ lzma_match *matches,+ uint32_t len_best)+{+ uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;+ uint32_t *ptr1 = son + (cyclic_pos << 1);++ uint32_t len0 = 0;+ uint32_t len1 = 0;++ while (true) {+ const uint32_t delta = pos - cur_match;+ if (depth-- == 0 || delta >= cyclic_size) {+ *ptr0 = EMPTY_HASH_VALUE;+ *ptr1 = EMPTY_HASH_VALUE;+ return matches;+ }++ uint32_t *const pair = son + ((cyclic_pos - delta+ + (delta > cyclic_pos ? cyclic_size : 0))+ << 1);++ const uint8_t *const pb = cur - delta;+ uint32_t len = my_min(len0, len1);++ if (pb[len] == cur[len]) {+ len = lzma_memcmplen(pb, cur, len + 1, len_limit);++ if (len_best < len) {+ len_best = len;+ matches->len = len;+ matches->dist = delta - 1;+ ++matches;++ if (len == len_limit) {+ *ptr1 = pair[0];+ *ptr0 = pair[1];+ return matches;+ }+ }+ }++ if (pb[len] < cur[len]) {+ *ptr1 = cur_match;+ ptr1 = pair + 1;+ cur_match = *ptr1;+ len1 = len;+ } else {+ *ptr0 = cur_match;+ ptr0 = pair;+ cur_match = *ptr0;+ len0 = len;+ }+ }+}+++static void+bt_skip_func(+ const uint32_t len_limit,+ const uint32_t pos,+ const uint8_t *const cur,+ uint32_t cur_match,+ uint32_t depth,+ uint32_t *const son,+ const uint32_t cyclic_pos,+ const uint32_t cyclic_size)+{+ uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;+ uint32_t *ptr1 = son + (cyclic_pos << 1);++ uint32_t len0 = 0;+ uint32_t len1 = 0;++ while (true) {+ const uint32_t delta = pos - cur_match;+ if (depth-- == 0 || delta >= cyclic_size) {+ *ptr0 = EMPTY_HASH_VALUE;+ *ptr1 = EMPTY_HASH_VALUE;+ return;+ }++ uint32_t *pair = son + ((cyclic_pos - delta+ + (delta > cyclic_pos ? cyclic_size : 0))+ << 1);+ const uint8_t *pb = cur - delta;+ uint32_t len = my_min(len0, len1);++ if (pb[len] == cur[len]) {+ len = lzma_memcmplen(pb, cur, len + 1, len_limit);++ if (len == len_limit) {+ *ptr1 = pair[0];+ *ptr0 = pair[1];+ return;+ }+ }++ if (pb[len] < cur[len]) {+ *ptr1 = cur_match;+ ptr1 = pair + 1;+ cur_match = *ptr1;+ len1 = len;+ } else {+ *ptr0 = cur_match;+ ptr0 = pair;+ cur_match = *ptr0;+ len0 = len;+ }+ }+}+++#define bt_find(len_best) \+ call_find(bt_find_func, len_best)++#define bt_skip() \+do { \+ bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \+ mf->son, mf->cyclic_pos, \+ mf->cyclic_size); \+ move_pos(mf); \+} while (0)++#endif+++#ifdef HAVE_MF_BT2+extern uint32_t+lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches)+{+ header_find(true, 2);++ hash_2_calc();++ const uint32_t cur_match = mf->hash[hash_value];+ mf->hash[hash_value] = pos;++ bt_find(1);+}+++extern void+lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount)+{+ do {+ header_skip(true, 2);++ hash_2_calc();++ const uint32_t cur_match = mf->hash[hash_value];+ mf->hash[hash_value] = pos;++ bt_skip();++ } while (--amount != 0);+}+#endif+++#ifdef HAVE_MF_BT3+extern uint32_t+lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches)+{+ header_find(true, 3);++ hash_3_calc();++ const uint32_t delta2 = pos - mf->hash[hash_2_value];+ const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;++ uint32_t len_best = 2;++ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {+ len_best = lzma_memcmplen(+ cur, cur - delta2, len_best, len_limit);++ matches[0].len = len_best;+ matches[0].dist = delta2 - 1;+ matches_count = 1;++ if (len_best == len_limit) {+ bt_skip();+ return 1; // matches_count+ }+ }++ bt_find(len_best);+}+++extern void+lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount)+{+ do {+ header_skip(true, 3);++ hash_3_calc();++ const uint32_t cur_match+ = mf->hash[FIX_3_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;++ bt_skip();++ } while (--amount != 0);+}+#endif+++#ifdef HAVE_MF_BT4+extern uint32_t+lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches)+{+ header_find(true, 4);++ hash_4_calc();++ uint32_t delta2 = pos - mf->hash[hash_2_value];+ const uint32_t delta3+ = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];+ const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;++ uint32_t len_best = 1;++ if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {+ len_best = 2;+ matches[0].len = 2;+ matches[0].dist = delta2 - 1;+ matches_count = 1;+ }++ if (delta2 != delta3 && delta3 < mf->cyclic_size+ && *(cur - delta3) == *cur) {+ len_best = 3;+ matches[matches_count++].dist = delta3 - 1;+ delta2 = delta3;+ }++ if (matches_count != 0) {+ len_best = lzma_memcmplen(+ cur, cur - delta2, len_best, len_limit);++ matches[matches_count - 1].len = len_best;++ if (len_best == len_limit) {+ bt_skip();+ return matches_count;+ }+ }++ if (len_best < 3)+ len_best = 3;++ bt_find(len_best);+}+++extern void+lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount)+{+ do {+ header_skip(true, 4);++ hash_4_calc();++ const uint32_t cur_match+ = mf->hash[FIX_4_HASH_SIZE + hash_value];++ mf->hash[hash_2_value] = pos;+ mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;+ mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;++ bt_skip();++ } while (--amount != 0);+}+#endif
+ cbits/liblzma/lzma/fastpos.h view
@@ -0,0 +1,141 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file fastpos.h+/// \brief Kind of two-bit version of bit scan reverse+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_FASTPOS_H+#define LZMA_FASTPOS_H++// LZMA encodes match distances 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 .xz+// 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:+//+// dist 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_dist_slot(dist) is the basic version. get_dist_slot_2(dist)+// assumes that dist >= FULL_DISTANCES, thus the result is at least+// FULL_DISTANCES_BITS * 2. Using get_dist_slot(dist) instead of+// get_dist_slot_2(dist) would give the same result, but get_dist_slot_2(dist)+// 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.++#ifdef HAVE_SMALL+# define get_dist_slot(dist) \+ ((dist) <= 4 ? (dist) : get_dist_slot_2(dist))++static inline uint32_t+get_dist_slot_2(uint32_t dist)+{+ const uint32_t i = bsr32(dist);+ return (i + i) + ((dist >> (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(dist, extra, n) \+ (uint32_t)(lzma_fastpos[(dist) >> fastpos_shift(extra, n)]) \+ + 2 * fastpos_shift(extra, n)+++static inline uint32_t+get_dist_slot(uint32_t dist)+{+ // If it is small enough, we can pick the result directly from+ // the precalculated table.+ if (dist < fastpos_limit(0, 0))+ return lzma_fastpos[dist];++ if (dist < fastpos_limit(0, 1))+ return fastpos_result(dist, 0, 1);++ return fastpos_result(dist, 0, 2);+}+++#ifdef FULL_DISTANCES_BITS+static inline uint32_t+get_dist_slot_2(uint32_t dist)+{+ assert(dist >= FULL_DISTANCES);++ if (dist < fastpos_limit(FULL_DISTANCES_BITS - 1, 0))+ return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 0);++ if (dist < fastpos_limit(FULL_DISTANCES_BITS - 1, 1))+ return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 1);++ return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 2);+}+#endif++#endif++#endif
+ cbits/liblzma/lzma/fastpos_table.c view
@@ -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+};
+ cbits/liblzma/lzma/fastpos_tablegen.c view
@@ -0,0 +1,55 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file fastpos_tablegen.c+/// \brief Generates the lzma_fastpos[] lookup table+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#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;+}
+ cbits/liblzma/lzma/lzma2_decoder.c view
@@ -0,0 +1,310 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma2_decoder.c+/// \brief LZMA2 decoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lzma2_decoder.h"+#include "lz_decoder.h"+#include "lzma_decoder.h"+++typedef struct {+ enum sequence {+ SEQ_CONTROL,+ SEQ_UNCOMPRESSED_1,+ SEQ_UNCOMPRESSED_2,+ SEQ_COMPRESSED_0,+ SEQ_COMPRESSED_1,+ SEQ_PROPERTIES,+ SEQ_LZMA,+ SEQ_COPY,+ } sequence;++ /// Sequence after the size fields have been decoded.+ enum sequence next_sequence;++ /// LZMA decoder+ lzma_lz_decoder lzma;++ /// Uncompressed size of LZMA chunk+ size_t uncompressed_size;++ /// Compressed size of the chunk (naturally equals to uncompressed+ /// size of uncompressed chunk)+ size_t compressed_size;++ /// True if properties are needed. This is false before the+ /// first LZMA chunk.+ bool need_properties;++ /// True if dictionary reset is needed. This is false before the+ /// first chunk (LZMA or uncompressed).+ bool need_dictionary_reset;++ lzma_options_lzma options;+} lzma_lzma2_coder;+++static lzma_ret+lzma2_decode(void *coder_ptr, lzma_dict *restrict dict,+ const uint8_t *restrict in, size_t *restrict in_pos,+ size_t in_size)+{+ lzma_lzma2_coder *restrict coder = coder_ptr;++ // With SEQ_LZMA it is possible that no new input is needed to do+ // some progress. The rest of the sequences assume that there is+ // at least one byte of input.+ while (*in_pos < in_size || coder->sequence == SEQ_LZMA)+ switch (coder->sequence) {+ case SEQ_CONTROL: {+ const uint32_t control = in[*in_pos];+ ++*in_pos;++ // End marker+ if (control == 0x00)+ return LZMA_STREAM_END;++ if (control >= 0xE0 || control == 1) {+ // Dictionary reset implies that next LZMA chunk has+ // to set new properties.+ coder->need_properties = true;+ coder->need_dictionary_reset = true;+ } else if (coder->need_dictionary_reset) {+ return LZMA_DATA_ERROR;+ }++ if (control >= 0x80) {+ // LZMA chunk. The highest five bits of the+ // uncompressed size are taken from the control byte.+ coder->uncompressed_size = (control & 0x1F) << 16;+ coder->sequence = SEQ_UNCOMPRESSED_1;++ // See if there are new properties or if we need to+ // reset the state.+ if (control >= 0xC0) {+ // When there are new properties, state reset+ // is done at SEQ_PROPERTIES.+ coder->need_properties = false;+ coder->next_sequence = SEQ_PROPERTIES;++ } else if (coder->need_properties) {+ return LZMA_DATA_ERROR;++ } else {+ coder->next_sequence = SEQ_LZMA;++ // If only state reset is wanted with old+ // properties, do the resetting here for+ // simplicity.+ if (control >= 0xA0)+ coder->lzma.reset(coder->lzma.coder,+ &coder->options);+ }+ } else {+ // Invalid control values+ if (control > 2)+ return LZMA_DATA_ERROR;++ // It's uncompressed chunk+ coder->sequence = SEQ_COMPRESSED_0;+ coder->next_sequence = SEQ_COPY;+ }++ if (coder->need_dictionary_reset) {+ // Finish the dictionary reset and let the caller+ // flush the dictionary to the actual output buffer.+ coder->need_dictionary_reset = false;+ dict_reset(dict);+ return LZMA_OK;+ }++ break;+ }++ case SEQ_UNCOMPRESSED_1:+ coder->uncompressed_size += (uint32_t)(in[(*in_pos)++]) << 8;+ coder->sequence = SEQ_UNCOMPRESSED_2;+ break;++ case SEQ_UNCOMPRESSED_2:+ coder->uncompressed_size += in[(*in_pos)++] + 1U;+ coder->sequence = SEQ_COMPRESSED_0;+ coder->lzma.set_uncompressed(coder->lzma.coder,+ coder->uncompressed_size);+ break;++ case SEQ_COMPRESSED_0:+ coder->compressed_size = (uint32_t)(in[(*in_pos)++]) << 8;+ coder->sequence = SEQ_COMPRESSED_1;+ break;++ case SEQ_COMPRESSED_1:+ coder->compressed_size += in[(*in_pos)++] + 1U;+ coder->sequence = coder->next_sequence;+ break;++ case SEQ_PROPERTIES:+ if (lzma_lzma_lclppb_decode(&coder->options, in[(*in_pos)++]))+ return LZMA_DATA_ERROR;++ coder->lzma.reset(coder->lzma.coder, &coder->options);++ coder->sequence = SEQ_LZMA;+ break;++ case SEQ_LZMA: {+ // Store the start offset so that we can update+ // coder->compressed_size later.+ const size_t in_start = *in_pos;++ // Decode from in[] to *dict.+ const lzma_ret ret = coder->lzma.code(coder->lzma.coder,+ dict, in, in_pos, in_size);++ // Validate and update coder->compressed_size.+ const size_t in_used = *in_pos - in_start;+ if (in_used > coder->compressed_size)+ return LZMA_DATA_ERROR;++ coder->compressed_size -= in_used;++ // Return if we didn't finish the chunk, or an error occurred.+ if (ret != LZMA_STREAM_END)+ return ret;++ // The LZMA decoder must have consumed the whole chunk now.+ // We don't need to worry about uncompressed size since it+ // is checked by the LZMA decoder.+ if (coder->compressed_size != 0)+ return LZMA_DATA_ERROR;++ coder->sequence = SEQ_CONTROL;+ break;+ }++ case SEQ_COPY: {+ // Copy from input to the dictionary as is.+ dict_write(dict, in, in_pos, in_size, &coder->compressed_size);+ if (coder->compressed_size != 0)+ return LZMA_OK;++ coder->sequence = SEQ_CONTROL;+ break;+ }++ default:+ assert(0);+ return LZMA_PROG_ERROR;+ }++ return LZMA_OK;+}+++static void+lzma2_decoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_lzma2_coder *coder = coder_ptr;++ assert(coder->lzma.end == NULL);+ lzma_free(coder->lzma.coder, allocator);++ lzma_free(coder, allocator);++ return;+}+++static lzma_ret+lzma2_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,+ const void *opt, lzma_lz_options *lz_options)+{+ lzma_lzma2_coder *coder = lz->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ lz->coder = coder;+ lz->code = &lzma2_decode;+ lz->end = &lzma2_decoder_end;++ coder->lzma = LZMA_LZ_DECODER_INIT;+ }++ const lzma_options_lzma *options = opt;++ coder->sequence = SEQ_CONTROL;+ coder->need_properties = true;+ coder->need_dictionary_reset = options->preset_dict == NULL+ || options->preset_dict_size == 0;++ return lzma_lzma_decoder_create(&coder->lzma,+ allocator, options, lz_options);+}+++extern lzma_ret+lzma_lzma2_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ // LZMA2 can only be the last filter in the chain. This is enforced+ // by the raw_decoder initialization.+ assert(filters[1].init == NULL);++ return lzma_lz_decoder_init(next, allocator, filters,+ &lzma2_decoder_init);+}+++extern uint64_t+lzma_lzma2_decoder_memusage(const void *options)+{+ return sizeof(lzma_lzma2_coder)+ + lzma_lzma_decoder_memusage_nocheck(options);+}+++extern lzma_ret+lzma_lzma2_props_decode(void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size)+{+ if (props_size != 1)+ return LZMA_OPTIONS_ERROR;++ // Check that reserved bits are unset.+ if (props[0] & 0xC0)+ return LZMA_OPTIONS_ERROR;++ // Decode the dictionary size.+ if (props[0] > 40)+ return LZMA_OPTIONS_ERROR;++ lzma_options_lzma *opt = lzma_alloc(+ sizeof(lzma_options_lzma), allocator);+ if (opt == NULL)+ return LZMA_MEM_ERROR;++ if (props[0] == 40) {+ opt->dict_size = UINT32_MAX;+ } else {+ opt->dict_size = 2 | (props[0] & 1U);+ opt->dict_size <<= props[0] / 2U + 11;+ }++ opt->preset_dict = NULL;+ opt->preset_dict_size = 0;++ *options = opt;++ return LZMA_OK;+}
+ cbits/liblzma/lzma/lzma2_decoder.h view
@@ -0,0 +1,29 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma2_decoder.h+/// \brief LZMA2 decoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZMA2_DECODER_H+#define LZMA_LZMA2_DECODER_H++#include "common.h"++extern lzma_ret lzma_lzma2_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern uint64_t lzma_lzma2_decoder_memusage(const void *options);++extern lzma_ret lzma_lzma2_props_decode(+ void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size);++#endif
+ cbits/liblzma/lzma/lzma2_encoder.c view
@@ -0,0 +1,410 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma2_encoder.c+/// \brief LZMA2 encoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lz_encoder.h"+#include "lzma_encoder.h"+#include "fastpos.h"+#include "lzma2_encoder.h"+++typedef struct {+ enum {+ SEQ_INIT,+ SEQ_LZMA_ENCODE,+ SEQ_LZMA_COPY,+ SEQ_UNCOMPRESSED_HEADER,+ SEQ_UNCOMPRESSED_COPY,+ } sequence;++ /// LZMA encoder+ void *lzma;++ /// LZMA options currently in use.+ lzma_options_lzma opt_cur;++ bool need_properties;+ bool need_state_reset;+ bool need_dictionary_reset;++ /// Uncompressed size of a chunk+ size_t uncompressed_size;++ /// Compressed size of a chunk (excluding headers); this is also used+ /// to indicate the end of buf[] in SEQ_LZMA_COPY.+ size_t compressed_size;++ /// Read position in buf[]+ size_t buf_pos;++ /// Buffer to hold the chunk header and LZMA compressed data+ uint8_t buf[LZMA2_HEADER_MAX + LZMA2_CHUNK_MAX];+} lzma_lzma2_coder;+++static void+lzma2_header_lzma(lzma_lzma2_coder *coder)+{+ assert(coder->uncompressed_size > 0);+ assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);+ assert(coder->compressed_size > 0);+ assert(coder->compressed_size <= LZMA2_CHUNK_MAX);++ size_t pos;++ if (coder->need_properties) {+ pos = 0;++ if (coder->need_dictionary_reset)+ coder->buf[pos] = 0x80 + (3 << 5);+ else+ coder->buf[pos] = 0x80 + (2 << 5);+ } else {+ pos = 1;++ if (coder->need_state_reset)+ coder->buf[pos] = 0x80 + (1 << 5);+ else+ coder->buf[pos] = 0x80;+ }++ // Set the start position for copying.+ coder->buf_pos = pos;++ // Uncompressed size+ size_t size = coder->uncompressed_size - 1;+ coder->buf[pos++] += size >> 16;+ coder->buf[pos++] = (size >> 8) & 0xFF;+ coder->buf[pos++] = size & 0xFF;++ // Compressed size+ size = coder->compressed_size - 1;+ coder->buf[pos++] = size >> 8;+ coder->buf[pos++] = size & 0xFF;++ // Properties, if needed+ if (coder->need_properties)+ lzma_lzma_lclppb_encode(&coder->opt_cur, coder->buf + pos);++ coder->need_properties = false;+ coder->need_state_reset = false;+ coder->need_dictionary_reset = false;++ // The copying code uses coder->compressed_size to indicate the end+ // of coder->buf[], so we need add the maximum size of the header here.+ coder->compressed_size += LZMA2_HEADER_MAX;++ return;+}+++static void+lzma2_header_uncompressed(lzma_lzma2_coder *coder)+{+ assert(coder->uncompressed_size > 0);+ assert(coder->uncompressed_size <= LZMA2_CHUNK_MAX);++ // If this is the first chunk, we need to include dictionary+ // reset indicator.+ if (coder->need_dictionary_reset)+ coder->buf[0] = 1;+ else+ coder->buf[0] = 2;++ coder->need_dictionary_reset = false;++ // "Compressed" size+ coder->buf[1] = (coder->uncompressed_size - 1) >> 8;+ coder->buf[2] = (coder->uncompressed_size - 1) & 0xFF;++ // Set the start position for copying.+ coder->buf_pos = 0;+ return;+}+++static lzma_ret+lzma2_encode(void *coder_ptr, lzma_mf *restrict mf,+ uint8_t *restrict out, size_t *restrict out_pos,+ size_t out_size)+{+ lzma_lzma2_coder *restrict coder = coder_ptr;++ while (*out_pos < out_size)+ switch (coder->sequence) {+ case SEQ_INIT:+ // If there's no input left and we are flushing or finishing,+ // don't start a new chunk.+ if (mf_unencoded(mf) == 0) {+ // Write end of payload marker if finishing.+ if (mf->action == LZMA_FINISH)+ out[(*out_pos)++] = 0;++ return mf->action == LZMA_RUN+ ? LZMA_OK : LZMA_STREAM_END;+ }++ if (coder->need_state_reset)+ return_if_error(lzma_lzma_encoder_reset(+ coder->lzma, &coder->opt_cur));++ coder->uncompressed_size = 0;+ coder->compressed_size = 0;+ coder->sequence = SEQ_LZMA_ENCODE;++ // Fall through++ case SEQ_LZMA_ENCODE: {+ // Calculate how much more uncompressed data this chunk+ // could accept.+ const uint32_t left = LZMA2_UNCOMPRESSED_MAX+ - coder->uncompressed_size;+ uint32_t limit;++ if (left < mf->match_len_max) {+ // Must flush immediately since the next LZMA symbol+ // could make the uncompressed size of the chunk too+ // big.+ limit = 0;+ } else {+ // Calculate maximum read_limit that is OK from point+ // of view of LZMA2 chunk size.+ limit = mf->read_pos - mf->read_ahead+ + left - mf->match_len_max;+ }++ // Save the start position so that we can update+ // coder->uncompressed_size.+ const uint32_t read_start = mf->read_pos - mf->read_ahead;++ // Call the LZMA encoder until the chunk is finished.+ const lzma_ret ret = lzma_lzma_encode(coder->lzma, mf,+ coder->buf + LZMA2_HEADER_MAX,+ &coder->compressed_size,+ LZMA2_CHUNK_MAX, limit);++ coder->uncompressed_size += mf->read_pos - mf->read_ahead+ - read_start;++ assert(coder->compressed_size <= LZMA2_CHUNK_MAX);+ assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);++ if (ret != LZMA_STREAM_END)+ return LZMA_OK;++ // See if the chunk compressed. If it didn't, we encode it+ // as uncompressed chunk. This saves a few bytes of space+ // and makes decoding faster.+ if (coder->compressed_size >= coder->uncompressed_size) {+ coder->uncompressed_size += mf->read_ahead;+ assert(coder->uncompressed_size+ <= LZMA2_UNCOMPRESSED_MAX);+ mf->read_ahead = 0;+ lzma2_header_uncompressed(coder);+ coder->need_state_reset = true;+ coder->sequence = SEQ_UNCOMPRESSED_HEADER;+ break;+ }++ // The chunk did compress at least by one byte, so we store+ // the chunk as LZMA.+ lzma2_header_lzma(coder);++ coder->sequence = SEQ_LZMA_COPY;+ }++ // Fall through++ case SEQ_LZMA_COPY:+ // Copy the compressed chunk along its headers to the+ // output buffer.+ lzma_bufcpy(coder->buf, &coder->buf_pos,+ coder->compressed_size,+ out, out_pos, out_size);+ if (coder->buf_pos != coder->compressed_size)+ return LZMA_OK;++ coder->sequence = SEQ_INIT;+ break;++ case SEQ_UNCOMPRESSED_HEADER:+ // Copy the three-byte header to indicate uncompressed chunk.+ lzma_bufcpy(coder->buf, &coder->buf_pos,+ LZMA2_HEADER_UNCOMPRESSED,+ out, out_pos, out_size);+ if (coder->buf_pos != LZMA2_HEADER_UNCOMPRESSED)+ return LZMA_OK;++ coder->sequence = SEQ_UNCOMPRESSED_COPY;++ // Fall through++ case SEQ_UNCOMPRESSED_COPY:+ // Copy the uncompressed data as is from the dictionary+ // to the output buffer.+ mf_read(mf, out, out_pos, out_size, &coder->uncompressed_size);+ if (coder->uncompressed_size != 0)+ return LZMA_OK;++ coder->sequence = SEQ_INIT;+ break;+ }++ return LZMA_OK;+}+++static void+lzma2_encoder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_lzma2_coder *coder = coder_ptr;+ lzma_free(coder->lzma, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+lzma2_encoder_options_update(void *coder_ptr, const lzma_filter *filter)+{+ lzma_lzma2_coder *coder = coder_ptr;++ // New options can be set only when there is no incomplete chunk.+ // This is the case at the beginning of the raw stream and right+ // after LZMA_SYNC_FLUSH.+ if (filter->options == NULL || coder->sequence != SEQ_INIT)+ return LZMA_PROG_ERROR;++ // Look if there are new options. At least for now,+ // only lc/lp/pb can be changed.+ const lzma_options_lzma *opt = filter->options;+ if (coder->opt_cur.lc != opt->lc || coder->opt_cur.lp != opt->lp+ || coder->opt_cur.pb != opt->pb) {+ // Validate the options.+ if (opt->lc > LZMA_LCLP_MAX || opt->lp > LZMA_LCLP_MAX+ || opt->lc + opt->lp > LZMA_LCLP_MAX+ || opt->pb > LZMA_PB_MAX)+ return LZMA_OPTIONS_ERROR;++ // The new options will be used when the encoder starts+ // a new LZMA2 chunk.+ coder->opt_cur.lc = opt->lc;+ coder->opt_cur.lp = opt->lp;+ coder->opt_cur.pb = opt->pb;+ coder->need_properties = true;+ coder->need_state_reset = true;+ }++ return LZMA_OK;+}+++static lzma_ret+lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,+ const void *options, lzma_lz_options *lz_options)+{+ if (options == NULL)+ return LZMA_PROG_ERROR;++ lzma_lzma2_coder *coder = lz->coder;+ if (coder == NULL) {+ coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ lz->coder = coder;+ lz->code = &lzma2_encode;+ lz->end = &lzma2_encoder_end;+ lz->options_update = &lzma2_encoder_options_update;++ coder->lzma = NULL;+ }++ coder->opt_cur = *(const lzma_options_lzma *)(options);++ coder->sequence = SEQ_INIT;+ coder->need_properties = true;+ coder->need_state_reset = false;+ coder->need_dictionary_reset+ = coder->opt_cur.preset_dict == NULL+ || coder->opt_cur.preset_dict_size == 0;++ // Initialize LZMA encoder+ return_if_error(lzma_lzma_encoder_create(&coder->lzma, allocator,+ &coder->opt_cur, lz_options));++ // Make sure that we will always have enough history available in+ // case we need to use uncompressed chunks. They are used when the+ // compressed size of a chunk is not smaller than the uncompressed+ // size, so we need to have at least LZMA2_COMPRESSED_MAX bytes+ // history available.+ if (lz_options->before_size + lz_options->dict_size < LZMA2_CHUNK_MAX)+ lz_options->before_size+ = LZMA2_CHUNK_MAX - lz_options->dict_size;++ return LZMA_OK;+}+++extern lzma_ret+lzma_lzma2_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return lzma_lz_encoder_init(+ next, allocator, filters, &lzma2_encoder_init);+}+++extern uint64_t+lzma_lzma2_encoder_memusage(const void *options)+{+ const uint64_t lzma_mem = lzma_lzma_encoder_memusage(options);+ if (lzma_mem == UINT64_MAX)+ return UINT64_MAX;++ return sizeof(lzma_lzma2_coder) + lzma_mem;+}+++extern lzma_ret+lzma_lzma2_props_encode(const void *options, uint8_t *out)+{+ const lzma_options_lzma *const opt = options;+ uint32_t d = my_max(opt->dict_size, LZMA_DICT_SIZE_MIN);++ // Round up to the next 2^n - 1 or 2^n + 2^(n - 1) - 1 depending+ // on which one is the next:+ --d;+ d |= d >> 2;+ d |= d >> 3;+ d |= d >> 4;+ d |= d >> 8;+ d |= d >> 16;++ // Get the highest two bits using the proper encoding:+ if (d == UINT32_MAX)+ out[0] = 40;+ else+ out[0] = get_dist_slot(d + 1) - 24;++ return LZMA_OK;+}+++extern uint64_t+lzma_lzma2_block_size(const void *options)+{+ const lzma_options_lzma *const opt = options;++ // Use at least 1 MiB to keep compression ratio better.+ return my_max((uint64_t)(opt->dict_size) * 3, UINT64_C(1) << 20);+}
+ cbits/liblzma/lzma/lzma2_encoder.h view
@@ -0,0 +1,43 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma2_encoder.h+/// \brief LZMA2 encoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZMA2_ENCODER_H+#define LZMA_LZMA2_ENCODER_H++#include "common.h"+++/// Maximum number of bytes of actual data per chunk (no headers)+#define LZMA2_CHUNK_MAX (UINT32_C(1) << 16)++/// Maximum uncompressed size of LZMA chunk (no headers)+#define LZMA2_UNCOMPRESSED_MAX (UINT32_C(1) << 21)++/// Maximum size of LZMA2 headers+#define LZMA2_HEADER_MAX 6++/// Size of a header for uncompressed chunk+#define LZMA2_HEADER_UNCOMPRESSED 3+++extern lzma_ret lzma_lzma2_encoder_init(+ lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern uint64_t lzma_lzma2_encoder_memusage(const void *options);++extern lzma_ret lzma_lzma2_props_encode(const void *options, uint8_t *out);++extern uint64_t lzma_lzma2_block_size(const void *options);++#endif
+ cbits/liblzma/lzma/lzma_common.h view
@@ -0,0 +1,225 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_common.h+/// \brief Private definitions common to LZMA encoder and decoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZMA_COMMON_H+#define LZMA_LZMA_COMMON_H++#include "common.h"+#include "range_common.h"+++///////////////////+// Miscellaneous //+///////////////////++/// Maximum number of position states. A position state is the lowest pos bits+/// number of bits of the current uncompressed offset. In some places there+/// are different sets of probabilities for different pos states.+#define POS_STATES_MAX (1 << LZMA_PB_MAX)+++/// Validates lc, lp, and pb.+static inline bool+is_lclppb_valid(const lzma_options_lzma *options)+{+ return options->lc <= LZMA_LCLP_MAX && options->lp <= LZMA_LCLP_MAX+ && options->lc + options->lp <= LZMA_LCLP_MAX+ && options->pb <= LZMA_PB_MAX;+}+++///////////+// State //+///////////++/// 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;+++/// Total number of states+#define STATES 12++/// The lowest 7 states indicate that the previous state was a literal.+#define LIT_STATES 7+++/// 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)+++/////////////+// Literal //+/////////////++/// Each literal coder is divided in three sections:+/// - 0x001-0x0FF: Without match byte+/// - 0x101-0x1FF: With match byte; match bit is 0+/// - 0x201-0x2FF: With match byte; match bit is 1+///+/// Match byte is used when the previous LZMA symbol was something else than+/// a literal (that is, it was some kind of match).+#define LITERAL_CODER_SIZE 0x300++/// Maximum number of literal coders+#define LITERAL_CODERS_MAX (1 << LZMA_LCLP_MAX)++/// Locate the literal coder for the next literal byte. The choice depends on+/// - the lowest literal_pos_bits bits of the position of the current+/// byte; and+/// - the highest literal_context_bits bits of the previous byte.+#define literal_subcoder(probs, lc, lp_mask, pos, prev_byte) \+ ((probs)[(((pos) & (lp_mask)) << (lc)) \+ + ((uint32_t)(prev_byte) >> (8U - (lc)))])+++static inline void+literal_init(probability (*probs)[LITERAL_CODER_SIZE],+ uint32_t lc, uint32_t lp)+{+ assert(lc + lp <= LZMA_LCLP_MAX);++ const uint32_t coders = 1U << (lc + lp);++ for (uint32_t i = 0; i < coders; ++i)+ for (uint32_t j = 0; j < LITERAL_CODER_SIZE; ++j)+ bit_reset(probs[i][j]);++ return;+}+++//////////////////+// Match length //+//////////////////++// Minimum length of a match is two bytes.+#define MATCH_LEN_MIN 2++// Match length is encoded with 4, 5, or 10 bits.+//+// Length Bits+// 2-9 4 = Choice=0 + 3 bits+// 10-17 5 = Choice=1 + Choice2=0 + 3 bits+// 18-273 10 = Choice=1 + Choice2=1 + 8 bits+#define LEN_LOW_BITS 3+#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)+#define LEN_MID_BITS 3+#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)+#define LEN_HIGH_BITS 8+#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)+#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)++// Maximum length of a match is 273 which is a result of the encoding+// described above.+#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)+++////////////////////+// Match distance //+////////////////////++// Different sets of probabilities are used for match distances that have very+// short match length: Lengths of 2, 3, and 4 bytes have a separate set of+// probabilities for each length. The matches with longer length use a shared+// set of probabilities.+#define DIST_STATES 4++// Macro to get the index of the appropriate probability array.+#define get_dist_state(len) \+ ((len) < DIST_STATES + MATCH_LEN_MIN \+ ? (len) - MATCH_LEN_MIN \+ : DIST_STATES - 1)++// The highest two bits of a match distance (distance slot) are encoded+// using six bits. See fastpos.h for more explanation.+#define DIST_SLOT_BITS 6+#define DIST_SLOTS (1 << DIST_SLOT_BITS)++// Match distances up to 127 are fully encoded using probabilities. Since+// the highest two bits (distance slot) are always encoded using six bits,+// the distances 0-3 don't need any additional bits to encode, since the+// distance slot itself is the same as the actual distance. DIST_MODEL_START+// indicates the first distance slot where at least one additional bit is+// needed.+#define DIST_MODEL_START 4++// Match distances greater than 127 are encoded in three pieces:+// - distance slot: the highest two bits+// - direct bits: 2-26 bits below the highest two bits+// - alignment bits: four lowest bits+//+// Direct bits don't use any probabilities.+//+// The distance slot value of 14 is for distances 128-191 (see the table in+// fastpos.h to understand why).+#define DIST_MODEL_END 14++// Distance slots that indicate a distance <= 127.+#define FULL_DISTANCES_BITS (DIST_MODEL_END / 2)+#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)++// For match distances greater than 127, only the highest two bits and the+// lowest four bits (alignment) is encoded using probabilities.+#define ALIGN_BITS 4+#define ALIGN_SIZE (1 << ALIGN_BITS)+#define ALIGN_MASK (ALIGN_SIZE - 1)++// LZMA remembers the four most recent match distances. Reusing these distances+// tends to take less space than re-encoding the actual distance value.+#define REPS 4++#endif
+ cbits/liblzma/lzma/lzma_decoder.c view
@@ -0,0 +1,1064 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_decoder.c+/// \brief LZMA decoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lz_decoder.h"+#include "lzma_common.h"+#include "lzma_decoder.h"+#include "range_decoder.h"++// The macros unroll loops with switch statements.+// Silence warnings about missing fall-through comments.+#if TUKLIB_GNUC_REQ(7, 0)+# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"+#endif+++#ifdef HAVE_SMALL++// Macros for (somewhat) size-optimized code.+#define seq_4(seq) seq++#define seq_6(seq) seq++#define seq_8(seq) seq++#define seq_len(seq) \+ seq ## _CHOICE, \+ seq ## _CHOICE2, \+ seq ## _BITTREE++#define len_decode(target, ld, pos_state, seq) \+do { \+case seq ## _CHOICE: \+ rc_if_0(ld.choice, seq ## _CHOICE) { \+ rc_update_0(ld.choice); \+ probs = ld.low[pos_state];\+ limit = LEN_LOW_SYMBOLS; \+ target = MATCH_LEN_MIN; \+ } else { \+ rc_update_1(ld.choice); \+case seq ## _CHOICE2: \+ rc_if_0(ld.choice2, seq ## _CHOICE2) { \+ rc_update_0(ld.choice2); \+ probs = ld.mid[pos_state]; \+ limit = LEN_MID_SYMBOLS; \+ target = MATCH_LEN_MIN + LEN_LOW_SYMBOLS; \+ } else { \+ rc_update_1(ld.choice2); \+ probs = ld.high; \+ limit = LEN_HIGH_SYMBOLS; \+ target = MATCH_LEN_MIN + LEN_LOW_SYMBOLS \+ + LEN_MID_SYMBOLS; \+ } \+ } \+ symbol = 1; \+case seq ## _BITTREE: \+ do { \+ rc_bit(probs[symbol], , , seq ## _BITTREE); \+ } while (symbol < limit); \+ target += symbol - limit; \+} while (0)++#else // HAVE_SMALL++// Unrolled versions+#define seq_4(seq) \+ seq ## 0, \+ seq ## 1, \+ seq ## 2, \+ seq ## 3++#define seq_6(seq) \+ seq ## 0, \+ seq ## 1, \+ seq ## 2, \+ seq ## 3, \+ seq ## 4, \+ seq ## 5++#define seq_8(seq) \+ seq ## 0, \+ seq ## 1, \+ seq ## 2, \+ seq ## 3, \+ seq ## 4, \+ seq ## 5, \+ seq ## 6, \+ seq ## 7++#define seq_len(seq) \+ seq ## _CHOICE, \+ seq ## _LOW0, \+ seq ## _LOW1, \+ seq ## _LOW2, \+ seq ## _CHOICE2, \+ seq ## _MID0, \+ seq ## _MID1, \+ seq ## _MID2, \+ seq ## _HIGH0, \+ seq ## _HIGH1, \+ seq ## _HIGH2, \+ seq ## _HIGH3, \+ seq ## _HIGH4, \+ seq ## _HIGH5, \+ seq ## _HIGH6, \+ seq ## _HIGH7++#define len_decode(target, ld, pos_state, seq) \+do { \+ symbol = 1; \+case seq ## _CHOICE: \+ rc_if_0(ld.choice, seq ## _CHOICE) { \+ rc_update_0(ld.choice); \+ rc_bit_case(ld.low[pos_state][symbol], , , seq ## _LOW0); \+ rc_bit_case(ld.low[pos_state][symbol], , , seq ## _LOW1); \+ rc_bit_case(ld.low[pos_state][symbol], , , seq ## _LOW2); \+ target = symbol - LEN_LOW_SYMBOLS + MATCH_LEN_MIN; \+ } else { \+ rc_update_1(ld.choice); \+case seq ## _CHOICE2: \+ rc_if_0(ld.choice2, seq ## _CHOICE2) { \+ rc_update_0(ld.choice2); \+ rc_bit_case(ld.mid[pos_state][symbol], , , \+ seq ## _MID0); \+ rc_bit_case(ld.mid[pos_state][symbol], , , \+ seq ## _MID1); \+ rc_bit_case(ld.mid[pos_state][symbol], , , \+ seq ## _MID2); \+ target = symbol - LEN_MID_SYMBOLS \+ + MATCH_LEN_MIN + LEN_LOW_SYMBOLS; \+ } else { \+ rc_update_1(ld.choice2); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH0); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH1); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH2); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH3); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH4); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH5); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH6); \+ rc_bit_case(ld.high[symbol], , , seq ## _HIGH7); \+ target = symbol - LEN_HIGH_SYMBOLS \+ + MATCH_LEN_MIN \+ + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; \+ } \+ } \+} while (0)++#endif // HAVE_SMALL+++/// Length decoder probabilities; see comments in lzma_common.h.+typedef struct {+ probability choice;+ probability choice2;+ probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS];+ probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS];+ probability high[LEN_HIGH_SYMBOLS];+} lzma_length_decoder;+++typedef struct {+ ///////////////////+ // Probabilities //+ ///////////////////++ /// Literals; see comments in lzma_common.h.+ probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];++ /// If 1, it's a match. Otherwise it's a single 8-bit literal.+ probability is_match[STATES][POS_STATES_MAX];++ /// If 1, it's a repeated match. The distance is one of rep0 .. rep3.+ probability is_rep[STATES];++ /// If 0, distance of a repeated match is rep0.+ /// Otherwise check is_rep1.+ probability is_rep0[STATES];++ /// If 0, distance of a repeated match is rep1.+ /// Otherwise check is_rep2.+ probability is_rep1[STATES];++ /// If 0, distance of a repeated match is rep2. Otherwise it is rep3.+ probability is_rep2[STATES];++ /// If 1, the repeated match has length of one byte. Otherwise+ /// the length is decoded from rep_len_decoder.+ probability is_rep0_long[STATES][POS_STATES_MAX];++ /// Probability tree for the highest two bits of the match distance.+ /// There is a separate probability tree for match lengths of+ /// 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].+ probability dist_slot[DIST_STATES][DIST_SLOTS];++ /// Probability trees for additional bits for match distance when the+ /// distance is in the range [4, 127].+ probability pos_special[FULL_DISTANCES - DIST_MODEL_END];++ /// Probability tree for the lowest four bits of a match distance+ /// that is equal to or greater than 128.+ probability pos_align[ALIGN_SIZE];++ /// Length of a normal match+ lzma_length_decoder match_len_decoder;++ /// Length of a repeated match+ lzma_length_decoder rep_len_decoder;++ ///////////////////+ // Decoder state //+ ///////////////////++ // Range coder+ lzma_range_decoder rc;++ // Types of the most recently seen LZMA symbols+ 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+ uint32_t rep3; ///< Distance of fourth latest match++ uint32_t pos_mask; // (1U << pb) - 1+ uint32_t literal_context_bits;+ uint32_t literal_pos_mask;++ /// Uncompressed size as bytes, or LZMA_VLI_UNKNOWN if end of+ /// payload marker is expected.+ lzma_vli uncompressed_size;++ ////////////////////////////////+ // State of incomplete symbol //+ ////////////////////////////////++ /// Position where to continue the decoder loop+ enum {+ SEQ_NORMALIZE,+ SEQ_IS_MATCH,+ seq_8(SEQ_LITERAL),+ seq_8(SEQ_LITERAL_MATCHED),+ SEQ_LITERAL_WRITE,+ SEQ_IS_REP,+ seq_len(SEQ_MATCH_LEN),+ seq_6(SEQ_DIST_SLOT),+ SEQ_DIST_MODEL,+ SEQ_DIRECT,+ seq_4(SEQ_ALIGN),+ SEQ_EOPM,+ SEQ_IS_REP0,+ SEQ_SHORTREP,+ SEQ_IS_REP0_LONG,+ SEQ_IS_REP1,+ SEQ_IS_REP2,+ seq_len(SEQ_REP_LEN),+ SEQ_COPY,+ } sequence;++ /// Base of the current probability tree+ probability *probs;++ /// Symbol being decoded. This is also used as an index variable in+ /// bittree decoders: probs[symbol]+ uint32_t symbol;++ /// Used as a loop termination condition on bittree decoders and+ /// direct bits decoder.+ uint32_t limit;++ /// Matched literal decoder: 0x100 or 0 to help avoiding branches.+ /// Bittree reverse decoders: Offset of the next bit: 1 << offset+ uint32_t offset;++ /// If decoding a literal: match byte.+ /// If decoding a match: length of the match.+ uint32_t len;+} lzma_lzma1_decoder;+++static lzma_ret+lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr,+ const uint8_t *restrict in,+ size_t *restrict in_pos, size_t in_size)+{+ lzma_lzma1_decoder *restrict coder = coder_ptr;++ ////////////////////+ // Initialization //+ ////////////////////++ {+ const lzma_ret ret = rc_read_init(+ &coder->rc, in, in_pos, in_size);+ if (ret != LZMA_STREAM_END)+ return ret;+ }++ ///////////////+ // Variables //+ ///////////////++ // Making local copies of often-used variables improves both+ // speed and readability.++ lzma_dict dict = *dictptr;++ const size_t dict_start = dict.pos;++ // Range decoder+ rc_to_local(coder->rc, *in_pos);++ // State+ uint32_t state = coder->state;+ uint32_t rep0 = coder->rep0;+ uint32_t rep1 = coder->rep1;+ uint32_t rep2 = coder->rep2;+ uint32_t rep3 = coder->rep3;++ const uint32_t pos_mask = coder->pos_mask;++ // These variables are actually needed only if we last time ran+ // out of input in the middle of the decoder loop.+ probability *probs = coder->probs;+ uint32_t symbol = coder->symbol;+ uint32_t limit = coder->limit;+ uint32_t offset = coder->offset;+ uint32_t len = coder->len;++ const uint32_t literal_pos_mask = coder->literal_pos_mask;+ const uint32_t literal_context_bits = coder->literal_context_bits;++ // Temporary variables+ uint32_t pos_state = dict.pos & pos_mask;++ lzma_ret ret = LZMA_OK;++ // If uncompressed size is known, there must be no end of payload+ // marker.+ const bool no_eopm = coder->uncompressed_size+ != LZMA_VLI_UNKNOWN;+ if (no_eopm && coder->uncompressed_size < dict.limit - dict.pos)+ dict.limit = dict.pos + (size_t)(coder->uncompressed_size);++ // The main decoder loop. The "switch" is used to restart the decoder at+ // correct location. Once restarted, the "switch" is no longer used.+ switch (coder->sequence)+ while (true) {+ // Calculate new pos_state. This is skipped on the first loop+ // since we already calculated it when setting up the local+ // variables.+ pos_state = dict.pos & pos_mask;++ case SEQ_NORMALIZE:+ case SEQ_IS_MATCH:+ if (unlikely(no_eopm && dict.pos == dict.limit))+ break;++ rc_if_0(coder->is_match[state][pos_state], SEQ_IS_MATCH) {+ rc_update_0(coder->is_match[state][pos_state]);++ // It's a literal i.e. a single 8-bit byte.++ probs = literal_subcoder(coder->literal,+ literal_context_bits, literal_pos_mask,+ dict.pos, dict_get(&dict, 0));+ symbol = 1;++ if (is_literal_state(state)) {+ // Decode literal without match byte.+#ifdef HAVE_SMALL+ case SEQ_LITERAL:+ do {+ rc_bit(probs[symbol], , , SEQ_LITERAL);+ } while (symbol < (1 << 8));+#else+ rc_bit_case(probs[symbol], , , SEQ_LITERAL0);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL1);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL2);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL3);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL4);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL5);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL6);+ rc_bit_case(probs[symbol], , , SEQ_LITERAL7);+#endif+ } else {+ // Decode literal with match byte.+ //+ // We store the byte we compare against+ // ("match byte") to "len" to minimize the+ // number of variables we need to store+ // between decoder calls.+ len = (uint32_t)(dict_get(&dict, rep0)) << 1;++ // The usage of "offset" allows omitting some+ // branches, which should give tiny speed+ // improvement on some CPUs. "offset" gets+ // set to zero if match_bit didn't match.+ offset = 0x100;++#ifdef HAVE_SMALL+ case SEQ_LITERAL_MATCHED:+ do {+ const uint32_t match_bit+ = len & offset;+ const uint32_t subcoder_index+ = offset + match_bit+ + symbol;++ rc_bit(probs[subcoder_index],+ offset &= ~match_bit,+ offset &= match_bit,+ SEQ_LITERAL_MATCHED);++ // It seems to be faster to do this+ // here instead of putting it to the+ // beginning of the loop and then+ // putting the "case" in the middle+ // of the loop.+ len <<= 1;++ } while (symbol < (1 << 8));+#else+ // Unroll the loop.+ uint32_t match_bit;+ uint32_t subcoder_index;++# define d(seq) \+ case seq: \+ match_bit = len & offset; \+ subcoder_index = offset + match_bit + symbol; \+ rc_bit(probs[subcoder_index], \+ offset &= ~match_bit, \+ offset &= match_bit, \+ seq)++ d(SEQ_LITERAL_MATCHED0);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED1);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED2);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED3);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED4);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED5);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED6);+ len <<= 1;+ d(SEQ_LITERAL_MATCHED7);+# undef d+#endif+ }++ //update_literal(state);+ // Use a lookup table to update to literal state,+ // since compared to other state updates, this would+ // need two branches.+ static const lzma_lzma_state next_state[] = {+ STATE_LIT_LIT,+ STATE_LIT_LIT,+ STATE_LIT_LIT,+ 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_MATCH_LIT,+ STATE_REP_LIT+ };+ state = next_state[state];++ case SEQ_LITERAL_WRITE:+ if (unlikely(dict_put(&dict, symbol))) {+ coder->sequence = SEQ_LITERAL_WRITE;+ goto out;+ }++ continue;+ }++ // Instead of a new byte we are going to get a byte range+ // (distance and length) which will be repeated from our+ // output history.++ rc_update_1(coder->is_match[state][pos_state]);++ case SEQ_IS_REP:+ rc_if_0(coder->is_rep[state], SEQ_IS_REP) {+ // Not a repeated match+ rc_update_0(coder->is_rep[state]);+ update_match(state);++ // The latest three match distances are kept in+ // memory in case there are repeated matches.+ rep3 = rep2;+ rep2 = rep1;+ rep1 = rep0;++ // Decode the length of the match.+ len_decode(len, coder->match_len_decoder,+ pos_state, SEQ_MATCH_LEN);++ // Prepare to decode the highest two bits of the+ // match distance.+ probs = coder->dist_slot[get_dist_state(len)];+ symbol = 1;++#ifdef HAVE_SMALL+ case SEQ_DIST_SLOT:+ do {+ rc_bit(probs[symbol], , , SEQ_DIST_SLOT);+ } while (symbol < DIST_SLOTS);+#else+ rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT0);+ rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT1);+ rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT2);+ rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT3);+ rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT4);+ rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT5);+#endif+ // Get rid of the highest bit that was needed for+ // indexing of the probability array.+ symbol -= DIST_SLOTS;+ assert(symbol <= 63);++ if (symbol < DIST_MODEL_START) {+ // Match distances [0, 3] have only two bits.+ rep0 = symbol;+ } else {+ // Decode the lowest [1, 29] bits of+ // the match distance.+ limit = (symbol >> 1) - 1;+ assert(limit >= 1 && limit <= 30);+ rep0 = 2 + (symbol & 1);++ if (symbol < DIST_MODEL_END) {+ // Prepare to decode the low bits for+ // a distance of [4, 127].+ assert(limit <= 5);+ rep0 <<= limit;+ assert(rep0 <= 96);+ // -1 is fine, because we start+ // decoding at probs[1], not probs[0].+ // NOTE: This violates the C standard,+ // since we are doing pointer+ // arithmetic past the beginning of+ // the array.+ assert((int32_t)(rep0 - symbol - 1)+ >= -1);+ assert((int32_t)(rep0 - symbol - 1)+ <= 82);+ probs = coder->pos_special + rep0+ - symbol - 1;+ symbol = 1;+ offset = 0;+ case SEQ_DIST_MODEL:+#ifdef HAVE_SMALL+ do {+ rc_bit(probs[symbol], ,+ rep0 += 1U << offset,+ SEQ_DIST_MODEL);+ } while (++offset < limit);+#else+ switch (limit) {+ case 5:+ assert(offset == 0);+ rc_bit(probs[symbol], ,+ rep0 += 1U,+ SEQ_DIST_MODEL);+ ++offset;+ --limit;+ case 4:+ rc_bit(probs[symbol], ,+ rep0 += 1U << offset,+ SEQ_DIST_MODEL);+ ++offset;+ --limit;+ case 3:+ rc_bit(probs[symbol], ,+ rep0 += 1U << offset,+ SEQ_DIST_MODEL);+ ++offset;+ --limit;+ case 2:+ rc_bit(probs[symbol], ,+ rep0 += 1U << offset,+ SEQ_DIST_MODEL);+ ++offset;+ --limit;+ case 1:+ // We need "symbol" only for+ // indexing the probability+ // array, thus we can use+ // rc_bit_last() here to omit+ // the unneeded updating of+ // "symbol".+ rc_bit_last(probs[symbol], ,+ rep0 += 1U << offset,+ SEQ_DIST_MODEL);+ }+#endif+ } else {+ // The distance is >= 128. Decode the+ // lower bits without probabilities+ // except the lowest four bits.+ assert(symbol >= 14);+ assert(limit >= 6);+ limit -= ALIGN_BITS;+ assert(limit >= 2);+ case SEQ_DIRECT:+ // Not worth manual unrolling+ do {+ rc_direct(rep0, SEQ_DIRECT);+ } while (--limit > 0);++ // Decode the lowest four bits using+ // probabilities.+ rep0 <<= ALIGN_BITS;+ symbol = 1;+#ifdef HAVE_SMALL+ offset = 0;+ case SEQ_ALIGN:+ do {+ rc_bit(coder->pos_align[+ symbol], ,+ rep0 += 1U << offset,+ SEQ_ALIGN);+ } while (++offset < ALIGN_BITS);+#else+ case SEQ_ALIGN0:+ rc_bit(coder->pos_align[symbol], ,+ rep0 += 1, SEQ_ALIGN0);+ case SEQ_ALIGN1:+ rc_bit(coder->pos_align[symbol], ,+ rep0 += 2, SEQ_ALIGN1);+ case SEQ_ALIGN2:+ rc_bit(coder->pos_align[symbol], ,+ rep0 += 4, SEQ_ALIGN2);+ case SEQ_ALIGN3:+ // Like in SEQ_DIST_MODEL, we don't+ // need "symbol" for anything else+ // than indexing the probability array.+ rc_bit_last(coder->pos_align[symbol], ,+ rep0 += 8, SEQ_ALIGN3);+#endif++ if (rep0 == UINT32_MAX) {+ // End of payload marker was+ // found. It must not be+ // present if uncompressed+ // size is known.+ if (coder->uncompressed_size+ != LZMA_VLI_UNKNOWN) {+ ret = LZMA_DATA_ERROR;+ goto out;+ }++ case SEQ_EOPM:+ // LZMA1 stream with+ // end-of-payload marker.+ rc_normalize(SEQ_EOPM);+ ret = LZMA_STREAM_END;+ goto out;+ }+ }+ }++ // Validate the distance we just decoded.+ if (unlikely(!dict_is_distance_valid(&dict, rep0))) {+ ret = LZMA_DATA_ERROR;+ goto out;+ }++ } else {+ rc_update_1(coder->is_rep[state]);++ // Repeated match+ //+ // The match distance is a value that we have had+ // earlier. The latest four match distances are+ // available as rep0, rep1, rep2 and rep3. We will+ // now decode which of them is the new distance.+ //+ // There cannot be a match if we haven't produced+ // any output, so check that first.+ if (unlikely(!dict_is_distance_valid(&dict, 0))) {+ ret = LZMA_DATA_ERROR;+ goto out;+ }++ case SEQ_IS_REP0:+ rc_if_0(coder->is_rep0[state], SEQ_IS_REP0) {+ rc_update_0(coder->is_rep0[state]);+ // The distance is rep0.++ case SEQ_IS_REP0_LONG:+ rc_if_0(coder->is_rep0_long[state][pos_state],+ SEQ_IS_REP0_LONG) {+ rc_update_0(coder->is_rep0_long[+ state][pos_state]);++ update_short_rep(state);++ case SEQ_SHORTREP:+ if (unlikely(dict_put(&dict, dict_get(+ &dict, rep0)))) {+ coder->sequence = SEQ_SHORTREP;+ goto out;+ }++ continue;+ }++ // Repeating more than one byte at+ // distance of rep0.+ rc_update_1(coder->is_rep0_long[+ state][pos_state]);++ } else {+ rc_update_1(coder->is_rep0[state]);++ case SEQ_IS_REP1:+ // The distance is rep1, rep2 or rep3. Once+ // we find out which one of these three, it+ // is stored to rep0 and rep1, rep2 and rep3+ // are updated accordingly.+ rc_if_0(coder->is_rep1[state], SEQ_IS_REP1) {+ rc_update_0(coder->is_rep1[state]);++ const uint32_t distance = rep1;+ rep1 = rep0;+ rep0 = distance;++ } else {+ rc_update_1(coder->is_rep1[state]);+ case SEQ_IS_REP2:+ rc_if_0(coder->is_rep2[state],+ SEQ_IS_REP2) {+ rc_update_0(coder->is_rep2[+ state]);++ const uint32_t distance = rep2;+ rep2 = rep1;+ rep1 = rep0;+ rep0 = distance;++ } else {+ rc_update_1(coder->is_rep2[+ state]);++ const uint32_t distance = rep3;+ rep3 = rep2;+ rep2 = rep1;+ rep1 = rep0;+ rep0 = distance;+ }+ }+ }++ update_long_rep(state);++ // Decode the length of the repeated match.+ len_decode(len, coder->rep_len_decoder,+ pos_state, SEQ_REP_LEN);+ }++ /////////////////////////////////+ // Repeat from history buffer. //+ /////////////////////////////////++ // The length is always between these limits. There is no way+ // to trigger the algorithm to set len outside this range.+ assert(len >= MATCH_LEN_MIN);+ assert(len <= MATCH_LEN_MAX);++ case SEQ_COPY:+ // Repeat len bytes from distance of rep0.+ if (unlikely(dict_repeat(&dict, rep0, &len))) {+ coder->sequence = SEQ_COPY;+ goto out;+ }+ }++ rc_normalize(SEQ_NORMALIZE);+ coder->sequence = SEQ_IS_MATCH;++out:+ // Save state++ // NOTE: Must not copy dict.limit.+ dictptr->pos = dict.pos;+ dictptr->full = dict.full;++ rc_from_local(coder->rc, *in_pos);++ coder->state = state;+ coder->rep0 = rep0;+ coder->rep1 = rep1;+ coder->rep2 = rep2;+ coder->rep3 = rep3;++ coder->probs = probs;+ coder->symbol = symbol;+ coder->limit = limit;+ coder->offset = offset;+ coder->len = len;++ // Update the remaining amount of uncompressed data if uncompressed+ // size was known.+ if (coder->uncompressed_size != LZMA_VLI_UNKNOWN) {+ coder->uncompressed_size -= dict.pos - dict_start;++ // Since there cannot be end of payload marker if the+ // uncompressed size was known, we check here if we+ // finished decoding.+ if (coder->uncompressed_size == 0 && ret == LZMA_OK+ && coder->sequence != SEQ_NORMALIZE)+ ret = coder->sequence == SEQ_IS_MATCH+ ? LZMA_STREAM_END : LZMA_DATA_ERROR;+ }++ // We can do an additional check in the range decoder to catch some+ // corrupted files.+ if (ret == LZMA_STREAM_END) {+ if (!rc_is_finished(coder->rc))+ ret = LZMA_DATA_ERROR;++ // Reset the range decoder so that it is ready to reinitialize+ // for a new LZMA2 chunk.+ rc_reset(coder->rc);+ }++ return ret;+}++++static void+lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)+{+ lzma_lzma1_decoder *coder = coder_ptr;+ coder->uncompressed_size = uncompressed_size;+}+++static void+lzma_decoder_reset(void *coder_ptr, const void *opt)+{+ lzma_lzma1_decoder *coder = coder_ptr;+ const lzma_options_lzma *options = opt;++ // NOTE: We assume that lc/lp/pb are valid since they were+ // successfully decoded with lzma_lzma_decode_properties().++ // Calculate pos_mask. We don't need pos_bits as is for anything.+ coder->pos_mask = (1U << options->pb) - 1;++ // Initialize the literal decoder.+ literal_init(coder->literal, options->lc, options->lp);++ coder->literal_context_bits = options->lc;+ coder->literal_pos_mask = (1U << options->lp) - 1;++ // State+ coder->state = STATE_LIT_LIT;+ coder->rep0 = 0;+ coder->rep1 = 0;+ coder->rep2 = 0;+ coder->rep3 = 0;+ coder->pos_mask = (1U << options->pb) - 1;++ // Range decoder+ rc_reset(coder->rc);++ // Bit and bittree decoders+ for (uint32_t i = 0; i < STATES; ++i) {+ for (uint32_t j = 0; j <= coder->pos_mask; ++j) {+ bit_reset(coder->is_match[i][j]);+ bit_reset(coder->is_rep0_long[i][j]);+ }++ bit_reset(coder->is_rep[i]);+ bit_reset(coder->is_rep0[i]);+ bit_reset(coder->is_rep1[i]);+ bit_reset(coder->is_rep2[i]);+ }++ for (uint32_t i = 0; i < DIST_STATES; ++i)+ bittree_reset(coder->dist_slot[i], DIST_SLOT_BITS);++ for (uint32_t i = 0; i < FULL_DISTANCES - DIST_MODEL_END; ++i)+ bit_reset(coder->pos_special[i]);++ bittree_reset(coder->pos_align, ALIGN_BITS);++ // Len decoders (also bit/bittree)+ const uint32_t num_pos_states = 1U << options->pb;+ bit_reset(coder->match_len_decoder.choice);+ bit_reset(coder->match_len_decoder.choice2);+ bit_reset(coder->rep_len_decoder.choice);+ bit_reset(coder->rep_len_decoder.choice2);++ for (uint32_t pos_state = 0; pos_state < num_pos_states; ++pos_state) {+ bittree_reset(coder->match_len_decoder.low[pos_state],+ LEN_LOW_BITS);+ bittree_reset(coder->match_len_decoder.mid[pos_state],+ LEN_MID_BITS);++ bittree_reset(coder->rep_len_decoder.low[pos_state],+ LEN_LOW_BITS);+ bittree_reset(coder->rep_len_decoder.mid[pos_state],+ LEN_MID_BITS);+ }++ bittree_reset(coder->match_len_decoder.high, LEN_HIGH_BITS);+ bittree_reset(coder->rep_len_decoder.high, LEN_HIGH_BITS);++ coder->sequence = SEQ_IS_MATCH;+ coder->probs = NULL;+ coder->symbol = 0;+ coder->limit = 0;+ coder->offset = 0;+ coder->len = 0;++ return;+}+++extern lzma_ret+lzma_lzma_decoder_create(lzma_lz_decoder *lz, const lzma_allocator *allocator,+ const void *opt, lzma_lz_options *lz_options)+{+ if (lz->coder == NULL) {+ lz->coder = lzma_alloc(sizeof(lzma_lzma1_decoder), allocator);+ if (lz->coder == NULL)+ return LZMA_MEM_ERROR;++ lz->code = &lzma_decode;+ lz->reset = &lzma_decoder_reset;+ lz->set_uncompressed = &lzma_decoder_uncompressed;+ }++ // All dictionary sizes are OK here. LZ decoder will take care of+ // the special cases.+ const lzma_options_lzma *options = opt;+ lz_options->dict_size = options->dict_size;+ lz_options->preset_dict = options->preset_dict;+ lz_options->preset_dict_size = options->preset_dict_size;++ return LZMA_OK;+}+++/// Allocate and initialize LZMA decoder. This is used only via LZ+/// initialization (lzma_lzma_decoder_init() passes function pointer to+/// the LZ initialization).+static lzma_ret+lzma_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,+ const void *options, lzma_lz_options *lz_options)+{+ if (!is_lclppb_valid(options))+ return LZMA_PROG_ERROR;++ return_if_error(lzma_lzma_decoder_create(+ lz, allocator, options, lz_options));++ lzma_decoder_reset(lz->coder, options);+ lzma_decoder_uncompressed(lz->coder, LZMA_VLI_UNKNOWN);++ return LZMA_OK;+}+++extern lzma_ret+lzma_lzma_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ // LZMA can only be the last filter in the chain. This is enforced+ // by the raw_decoder initialization.+ assert(filters[1].init == NULL);++ return lzma_lz_decoder_init(next, allocator, filters,+ &lzma_decoder_init);+}+++extern bool+lzma_lzma_lclppb_decode(lzma_options_lzma *options, uint8_t byte)+{+ if (byte > (4 * 5 + 4) * 9 + 8)+ return true;++ // See the file format specification to understand this.+ options->pb = byte / (9 * 5);+ byte -= options->pb * 9 * 5;+ options->lp = byte / 9;+ options->lc = byte - options->lp * 9;++ return options->lc + options->lp > LZMA_LCLP_MAX;+}+++extern uint64_t+lzma_lzma_decoder_memusage_nocheck(const void *options)+{+ const lzma_options_lzma *const opt = options;+ return sizeof(lzma_lzma1_decoder)+ + lzma_lz_decoder_memusage(opt->dict_size);+}+++extern uint64_t+lzma_lzma_decoder_memusage(const void *options)+{+ if (!is_lclppb_valid(options))+ return UINT64_MAX;++ return lzma_lzma_decoder_memusage_nocheck(options);+}+++extern lzma_ret+lzma_lzma_props_decode(void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size)+{+ if (props_size != 5)+ return LZMA_OPTIONS_ERROR;++ lzma_options_lzma *opt+ = lzma_alloc(sizeof(lzma_options_lzma), allocator);+ if (opt == NULL)+ return LZMA_MEM_ERROR;++ if (lzma_lzma_lclppb_decode(opt, props[0]))+ goto error;++ // All dictionary sizes are accepted, including zero. LZ decoder+ // will automatically use a dictionary at least a few KiB even if+ // a smaller dictionary is requested.+ opt->dict_size = read32le(props + 1);++ opt->preset_dict = NULL;+ opt->preset_dict_size = 0;++ *options = opt;++ return LZMA_OK;++error:+ lzma_free(opt, allocator);+ return LZMA_OPTIONS_ERROR;+}
+ cbits/liblzma/lzma/lzma_decoder.h view
@@ -0,0 +1,53 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_decoder.h+/// \brief LZMA decoder API+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZMA_DECODER_H+#define LZMA_LZMA_DECODER_H++#include "common.h"+++/// Allocates and initializes LZMA decoder+extern lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern uint64_t lzma_lzma_decoder_memusage(const void *options);++extern lzma_ret lzma_lzma_props_decode(+ void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size);+++/// \brief Decodes the LZMA Properties byte (lc/lp/pb)+///+/// \return true if error occurred, false on success+///+extern bool lzma_lzma_lclppb_decode(+ lzma_options_lzma *options, uint8_t byte);+++#ifdef LZMA_LZ_DECODER_H+/// Allocate and setup function pointers only. This is used by LZMA1 and+/// LZMA2 decoders.+extern lzma_ret lzma_lzma_decoder_create(+ lzma_lz_decoder *lz, const lzma_allocator *allocator,+ const void *opt, lzma_lz_options *lz_options);++/// Gets memory usage without validating lc/lp/pb. This is used by LZMA2+/// decoder, because raw LZMA2 decoding doesn't need lc/lp/pb.+extern uint64_t lzma_lzma_decoder_memusage_nocheck(const void *options);++#endif++#endif
+ cbits/liblzma/lzma/lzma_encoder.c view
@@ -0,0 +1,677 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_encoder.c+/// \brief LZMA encoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lzma2_encoder.h"+#include "lzma_encoder_private.h"+#include "fastpos.h"+++/////////////+// Literal //+/////////////++static inline void+literal_matched(lzma_range_encoder *rc, probability *subcoder,+ uint32_t match_byte, uint32_t symbol)+{+ uint32_t offset = 0x100;+ symbol += UINT32_C(1) << 8;++ do {+ match_byte <<= 1;+ const uint32_t match_bit = match_byte & offset;+ const uint32_t subcoder_index+ = offset + match_bit + (symbol >> 8);+ const uint32_t bit = (symbol >> 7) & 1;+ rc_bit(rc, &subcoder[subcoder_index], bit);++ symbol <<= 1;+ offset &= ~(match_byte ^ symbol);++ } while (symbol < (UINT32_C(1) << 16));+}+++static inline void+literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position)+{+ // Locate the literal byte to be encoded and the subcoder.+ const uint8_t cur_byte = mf->buffer[+ mf->read_pos - mf->read_ahead];+ probability *subcoder = literal_subcoder(coder->literal,+ coder->literal_context_bits, coder->literal_pos_mask,+ position, mf->buffer[mf->read_pos - mf->read_ahead - 1]);++ if (is_literal_state(coder->state)) {+ // Previous LZMA-symbol was a literal. Encode a normal+ // literal without a match byte.+ rc_bittree(&coder->rc, subcoder, 8, cur_byte);+ } else {+ // Previous LZMA-symbol was a match. Use the last byte of+ // the match as a "match byte". That is, compare the bits+ // of the current literal and the match byte.+ const uint8_t match_byte = mf->buffer[+ mf->read_pos - coder->reps[0] - 1+ - mf->read_ahead];+ literal_matched(&coder->rc, subcoder, match_byte, cur_byte);+ }++ update_literal(coder->state);+}+++//////////////////+// Match length //+//////////////////++static void+length_update_prices(lzma_length_encoder *lc, const uint32_t pos_state)+{+ const uint32_t table_size = lc->table_size;+ lc->counters[pos_state] = table_size;++ const uint32_t a0 = rc_bit_0_price(lc->choice);+ const uint32_t a1 = rc_bit_1_price(lc->choice);+ const uint32_t b0 = a1 + rc_bit_0_price(lc->choice2);+ const uint32_t b1 = a1 + rc_bit_1_price(lc->choice2);+ uint32_t *const prices = lc->prices[pos_state];++ uint32_t i;+ for (i = 0; i < table_size && i < LEN_LOW_SYMBOLS; ++i)+ prices[i] = a0 + rc_bittree_price(lc->low[pos_state],+ LEN_LOW_BITS, i);++ for (; i < table_size && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i)+ prices[i] = b0 + rc_bittree_price(lc->mid[pos_state],+ LEN_MID_BITS, i - LEN_LOW_SYMBOLS);++ for (; i < table_size; ++i)+ prices[i] = b1 + rc_bittree_price(lc->high, LEN_HIGH_BITS,+ i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS);++ return;+}+++static inline void+length(lzma_range_encoder *rc, lzma_length_encoder *lc,+ const uint32_t pos_state, uint32_t len, const bool fast_mode)+{+ assert(len <= MATCH_LEN_MAX);+ len -= MATCH_LEN_MIN;++ if (len < LEN_LOW_SYMBOLS) {+ rc_bit(rc, &lc->choice, 0);+ rc_bittree(rc, lc->low[pos_state], LEN_LOW_BITS, len);+ } else {+ rc_bit(rc, &lc->choice, 1);+ len -= LEN_LOW_SYMBOLS;++ if (len < LEN_MID_SYMBOLS) {+ rc_bit(rc, &lc->choice2, 0);+ rc_bittree(rc, lc->mid[pos_state], LEN_MID_BITS, len);+ } else {+ rc_bit(rc, &lc->choice2, 1);+ len -= LEN_MID_SYMBOLS;+ rc_bittree(rc, lc->high, LEN_HIGH_BITS, len);+ }+ }++ // Only getoptimum uses the prices so don't update the table when+ // in fast mode.+ if (!fast_mode)+ if (--lc->counters[pos_state] == 0)+ length_update_prices(lc, pos_state);+}+++///////////+// Match //+///////////++static inline void+match(lzma_lzma1_encoder *coder, const uint32_t pos_state,+ const uint32_t distance, const uint32_t len)+{+ update_match(coder->state);++ length(&coder->rc, &coder->match_len_encoder, pos_state, len,+ coder->fast_mode);++ const uint32_t dist_slot = get_dist_slot(distance);+ const uint32_t dist_state = get_dist_state(len);+ rc_bittree(&coder->rc, coder->dist_slot[dist_state],+ DIST_SLOT_BITS, dist_slot);++ if (dist_slot >= DIST_MODEL_START) {+ const uint32_t footer_bits = (dist_slot >> 1) - 1;+ const uint32_t base = (2 | (dist_slot & 1)) << footer_bits;+ const uint32_t dist_reduced = distance - base;++ if (dist_slot < DIST_MODEL_END) {+ // Careful here: base - dist_slot - 1 can be -1, but+ // rc_bittree_reverse starts at probs[1], not probs[0].+ rc_bittree_reverse(&coder->rc,+ coder->dist_special + base - dist_slot - 1,+ footer_bits, dist_reduced);+ } else {+ rc_direct(&coder->rc, dist_reduced >> ALIGN_BITS,+ footer_bits - ALIGN_BITS);+ rc_bittree_reverse(+ &coder->rc, coder->dist_align,+ ALIGN_BITS, dist_reduced & ALIGN_MASK);+ ++coder->align_price_count;+ }+ }++ coder->reps[3] = coder->reps[2];+ coder->reps[2] = coder->reps[1];+ coder->reps[1] = coder->reps[0];+ coder->reps[0] = distance;+ ++coder->match_price_count;+}+++////////////////////+// Repeated match //+////////////////////++static inline void+rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state,+ const uint32_t rep, const uint32_t len)+{+ if (rep == 0) {+ rc_bit(&coder->rc, &coder->is_rep0[coder->state], 0);+ rc_bit(&coder->rc,+ &coder->is_rep0_long[coder->state][pos_state],+ len != 1);+ } else {+ const uint32_t distance = coder->reps[rep];+ rc_bit(&coder->rc, &coder->is_rep0[coder->state], 1);++ if (rep == 1) {+ rc_bit(&coder->rc, &coder->is_rep1[coder->state], 0);+ } else {+ rc_bit(&coder->rc, &coder->is_rep1[coder->state], 1);+ rc_bit(&coder->rc, &coder->is_rep2[coder->state],+ rep - 2);++ if (rep == 3)+ coder->reps[3] = coder->reps[2];++ coder->reps[2] = coder->reps[1];+ }++ coder->reps[1] = coder->reps[0];+ coder->reps[0] = distance;+ }++ if (len == 1) {+ update_short_rep(coder->state);+ } else {+ length(&coder->rc, &coder->rep_len_encoder, pos_state, len,+ coder->fast_mode);+ update_long_rep(coder->state);+ }+}+++//////////+// Main //+//////////++static void+encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf,+ uint32_t back, uint32_t len, uint32_t position)+{+ const uint32_t pos_state = position & coder->pos_mask;++ if (back == UINT32_MAX) {+ // Literal i.e. eight-bit byte+ assert(len == 1);+ rc_bit(&coder->rc,+ &coder->is_match[coder->state][pos_state], 0);+ literal(coder, mf, position);+ } else {+ // Some type of match+ rc_bit(&coder->rc,+ &coder->is_match[coder->state][pos_state], 1);++ if (back < REPS) {+ // It's a repeated match i.e. the same distance+ // has been used earlier.+ rc_bit(&coder->rc, &coder->is_rep[coder->state], 1);+ rep_match(coder, pos_state, back, len);+ } else {+ // Normal match+ rc_bit(&coder->rc, &coder->is_rep[coder->state], 0);+ match(coder, pos_state, back - REPS, len);+ }+ }++ assert(mf->read_ahead >= len);+ mf->read_ahead -= len;+}+++static bool+encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf)+{+ assert(mf_position(mf) == 0);++ if (mf->read_pos == mf->read_limit) {+ if (mf->action == LZMA_RUN)+ return false; // We cannot do anything.++ // We are finishing (we cannot get here when flushing).+ assert(mf->write_pos == mf->read_pos);+ assert(mf->action == LZMA_FINISH);+ } else {+ // Do the actual initialization. The first LZMA symbol must+ // always be a literal.+ mf_skip(mf, 1);+ mf->read_ahead = 0;+ rc_bit(&coder->rc, &coder->is_match[0][0], 0);+ rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]);+ }++ // Initialization is done (except if empty file).+ coder->is_initialized = true;++ return true;+}+++static void+encode_eopm(lzma_lzma1_encoder *coder, uint32_t position)+{+ const uint32_t pos_state = position & coder->pos_mask;+ rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1);+ rc_bit(&coder->rc, &coder->is_rep[coder->state], 0);+ match(coder, pos_state, UINT32_MAX, MATCH_LEN_MIN);+}+++/// Number of bytes that a single encoding loop in lzma_lzma_encode() can+/// consume from the dictionary. This limit comes from lzma_lzma_optimum()+/// and may need to be updated if that function is significantly modified.+#define LOOP_INPUT_MAX (OPTS + 1)+++extern lzma_ret+lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,+ uint8_t *restrict out, size_t *restrict out_pos,+ size_t out_size, uint32_t limit)+{+ // Initialize the stream if no data has been encoded yet.+ if (!coder->is_initialized && !encode_init(coder, mf))+ return LZMA_OK;++ // Get the lowest bits of the uncompressed offset from the LZ layer.+ uint32_t position = mf_position(mf);++ while (true) {+ // Encode pending bits, if any. Calling this before encoding+ // the next symbol is needed only with plain LZMA, since+ // LZMA2 always provides big enough buffer to flush+ // everything out from the range encoder. For the same reason,+ // rc_encode() never returns true when this function is used+ // as part of LZMA2 encoder.+ if (rc_encode(&coder->rc, out, out_pos, out_size)) {+ assert(limit == UINT32_MAX);+ return LZMA_OK;+ }++ // With LZMA2 we need to take care that compressed size of+ // a chunk doesn't get too big.+ // FIXME? Check if this could be improved.+ if (limit != UINT32_MAX+ && (mf->read_pos - mf->read_ahead >= limit+ || *out_pos + rc_pending(&coder->rc)+ >= LZMA2_CHUNK_MAX+ - LOOP_INPUT_MAX))+ break;++ // Check that there is some input to process.+ if (mf->read_pos >= mf->read_limit) {+ if (mf->action == LZMA_RUN)+ return LZMA_OK;++ if (mf->read_ahead == 0)+ break;+ }++ // Get optimal match (repeat position and length).+ // Value ranges for pos:+ // - [0, REPS): repeated match+ // - [REPS, UINT32_MAX):+ // match at (pos - REPS)+ // - UINT32_MAX: not a match but a literal+ // Value ranges for len:+ // - [MATCH_LEN_MIN, MATCH_LEN_MAX]+ uint32_t len;+ uint32_t back;++ if (coder->fast_mode)+ lzma_lzma_optimum_fast(coder, mf, &back, &len);+ else+ lzma_lzma_optimum_normal(+ coder, mf, &back, &len, position);++ encode_symbol(coder, mf, back, len, position);++ position += len;+ }++ if (!coder->is_flushed) {+ coder->is_flushed = true;++ // We don't support encoding plain LZMA streams without EOPM,+ // and LZMA2 doesn't use EOPM at LZMA level.+ if (limit == UINT32_MAX)+ encode_eopm(coder, position);++ // Flush the remaining bytes from the range encoder.+ rc_flush(&coder->rc);++ // Copy the remaining bytes to the output buffer. If there+ // isn't enough output space, we will copy out the remaining+ // bytes on the next call to this function by using+ // the rc_encode() call in the encoding loop above.+ if (rc_encode(&coder->rc, out, out_pos, out_size)) {+ assert(limit == UINT32_MAX);+ return LZMA_OK;+ }+ }++ // Make it ready for the next LZMA2 chunk.+ coder->is_flushed = false;++ return LZMA_STREAM_END;+}+++static lzma_ret+lzma_encode(void *coder, lzma_mf *restrict mf,+ uint8_t *restrict out, size_t *restrict out_pos,+ size_t out_size)+{+ // Plain LZMA has no support for sync-flushing.+ if (unlikely(mf->action == LZMA_SYNC_FLUSH))+ return LZMA_OPTIONS_ERROR;++ return lzma_lzma_encode(coder, mf, out, out_pos, out_size, UINT32_MAX);+}+++////////////////////+// Initialization //+////////////////////++static bool+is_options_valid(const lzma_options_lzma *options)+{+ // Validate some of the options. LZ encoder validates nice_len too+ // but we need a valid value here earlier.+ return is_lclppb_valid(options)+ && options->nice_len >= MATCH_LEN_MIN+ && options->nice_len <= MATCH_LEN_MAX+ && (options->mode == LZMA_MODE_FAST+ || options->mode == LZMA_MODE_NORMAL);+}+++static void+set_lz_options(lzma_lz_options *lz_options, const lzma_options_lzma *options)+{+ // LZ encoder initialization does the validation for these so we+ // don't need to validate here.+ lz_options->before_size = OPTS;+ lz_options->dict_size = options->dict_size;+ lz_options->after_size = LOOP_INPUT_MAX;+ lz_options->match_len_max = MATCH_LEN_MAX;+ lz_options->nice_len = options->nice_len;+ lz_options->match_finder = options->mf;+ lz_options->depth = options->depth;+ lz_options->preset_dict = options->preset_dict;+ lz_options->preset_dict_size = options->preset_dict_size;+ return;+}+++static void+length_encoder_reset(lzma_length_encoder *lencoder,+ const uint32_t num_pos_states, const bool fast_mode)+{+ bit_reset(lencoder->choice);+ bit_reset(lencoder->choice2);++ for (size_t pos_state = 0; pos_state < num_pos_states; ++pos_state) {+ bittree_reset(lencoder->low[pos_state], LEN_LOW_BITS);+ bittree_reset(lencoder->mid[pos_state], LEN_MID_BITS);+ }++ bittree_reset(lencoder->high, LEN_HIGH_BITS);++ if (!fast_mode)+ for (uint32_t pos_state = 0; pos_state < num_pos_states;+ ++pos_state)+ length_update_prices(lencoder, pos_state);++ return;+}+++extern lzma_ret+lzma_lzma_encoder_reset(lzma_lzma1_encoder *coder,+ const lzma_options_lzma *options)+{+ if (!is_options_valid(options))+ return LZMA_OPTIONS_ERROR;++ coder->pos_mask = (1U << options->pb) - 1;+ coder->literal_context_bits = options->lc;+ coder->literal_pos_mask = (1U << options->lp) - 1;++ // Range coder+ rc_reset(&coder->rc);++ // State+ coder->state = STATE_LIT_LIT;+ for (size_t i = 0; i < REPS; ++i)+ coder->reps[i] = 0;++ literal_init(coder->literal, options->lc, options->lp);++ // Bit encoders+ for (size_t i = 0; i < STATES; ++i) {+ for (size_t j = 0; j <= coder->pos_mask; ++j) {+ bit_reset(coder->is_match[i][j]);+ bit_reset(coder->is_rep0_long[i][j]);+ }++ bit_reset(coder->is_rep[i]);+ bit_reset(coder->is_rep0[i]);+ bit_reset(coder->is_rep1[i]);+ bit_reset(coder->is_rep2[i]);+ }++ for (size_t i = 0; i < FULL_DISTANCES - DIST_MODEL_END; ++i)+ bit_reset(coder->dist_special[i]);++ // Bit tree encoders+ for (size_t i = 0; i < DIST_STATES; ++i)+ bittree_reset(coder->dist_slot[i], DIST_SLOT_BITS);++ bittree_reset(coder->dist_align, ALIGN_BITS);++ // Length encoders+ length_encoder_reset(&coder->match_len_encoder,+ 1U << options->pb, coder->fast_mode);++ length_encoder_reset(&coder->rep_len_encoder,+ 1U << options->pb, coder->fast_mode);++ // Price counts are incremented every time appropriate probabilities+ // are changed. price counts are set to zero when the price tables+ // are updated, which is done when the appropriate price counts have+ // big enough value, and lzma_mf.read_ahead == 0 which happens at+ // least every OPTS (a few thousand) possible price count increments.+ //+ // By resetting price counts to UINT32_MAX / 2, we make sure that the+ // price tables will be initialized before they will be used (since+ // the value is definitely big enough), and that it is OK to increment+ // price counts without risk of integer overflow (since UINT32_MAX / 2+ // is small enough). The current code doesn't increment price counts+ // before initializing price tables, but it maybe done in future if+ // we add support for saving the state between LZMA2 chunks.+ coder->match_price_count = UINT32_MAX / 2;+ coder->align_price_count = UINT32_MAX / 2;++ coder->opts_end_index = 0;+ coder->opts_current_index = 0;++ return LZMA_OK;+}+++extern lzma_ret+lzma_lzma_encoder_create(void **coder_ptr,+ const lzma_allocator *allocator,+ const lzma_options_lzma *options, lzma_lz_options *lz_options)+{+ // Allocate lzma_lzma1_encoder if it wasn't already allocated.+ if (*coder_ptr == NULL) {+ *coder_ptr = lzma_alloc(sizeof(lzma_lzma1_encoder), allocator);+ if (*coder_ptr == NULL)+ return LZMA_MEM_ERROR;+ }++ lzma_lzma1_encoder *coder = *coder_ptr;++ // Set compression mode. We haven't validates the options yet,+ // but it's OK here, since nothing bad happens with invalid+ // options in the code below, and they will get rejected by+ // lzma_lzma_encoder_reset() call at the end of this function.+ switch (options->mode) {+ case LZMA_MODE_FAST:+ coder->fast_mode = true;+ break;++ case LZMA_MODE_NORMAL: {+ coder->fast_mode = false;++ // Set dist_table_size.+ // Round the dictionary size up to next 2^n.+ uint32_t log_size = 0;+ while ((UINT32_C(1) << log_size) < options->dict_size)+ ++log_size;++ coder->dist_table_size = log_size * 2;++ // Length encoders' price table size+ coder->match_len_encoder.table_size+ = options->nice_len + 1 - MATCH_LEN_MIN;+ coder->rep_len_encoder.table_size+ = options->nice_len + 1 - MATCH_LEN_MIN;+ break;+ }++ default:+ return LZMA_OPTIONS_ERROR;+ }++ // We don't need to write the first byte as literal if there is+ // a non-empty preset dictionary. encode_init() wouldn't even work+ // if there is a non-empty preset dictionary, because encode_init()+ // assumes that position is zero and previous byte is also zero.+ coder->is_initialized = options->preset_dict != NULL+ && options->preset_dict_size > 0;+ coder->is_flushed = false;++ set_lz_options(lz_options, options);++ return lzma_lzma_encoder_reset(coder, options);+}+++static lzma_ret+lzma_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,+ const void *options, lzma_lz_options *lz_options)+{+ lz->code = &lzma_encode;+ return lzma_lzma_encoder_create(+ &lz->coder, allocator, options, lz_options);+}+++extern lzma_ret+lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return lzma_lz_encoder_init(+ next, allocator, filters, &lzma_encoder_init);+}+++extern uint64_t+lzma_lzma_encoder_memusage(const void *options)+{+ if (!is_options_valid(options))+ return UINT64_MAX;++ lzma_lz_options lz_options;+ set_lz_options(&lz_options, options);++ const uint64_t lz_memusage = lzma_lz_encoder_memusage(&lz_options);+ if (lz_memusage == UINT64_MAX)+ return UINT64_MAX;++ return (uint64_t)(sizeof(lzma_lzma1_encoder)) + lz_memusage;+}+++extern bool+lzma_lzma_lclppb_encode(const lzma_options_lzma *options, uint8_t *byte)+{+ if (!is_lclppb_valid(options))+ return true;++ *byte = (options->pb * 5 + options->lp) * 9 + options->lc;+ assert(*byte <= (4 * 5 + 4) * 9 + 8);++ return false;+}+++#ifdef HAVE_ENCODER_LZMA1+extern lzma_ret+lzma_lzma_props_encode(const void *options, uint8_t *out)+{+ const lzma_options_lzma *const opt = options;++ if (lzma_lzma_lclppb_encode(opt, out))+ return LZMA_PROG_ERROR;++ write32le(out + 1, opt->dict_size);++ return LZMA_OK;+}+#endif+++extern LZMA_API(lzma_bool)+lzma_mode_is_supported(lzma_mode mode)+{+ return mode == LZMA_MODE_FAST || mode == LZMA_MODE_NORMAL;+}
+ cbits/liblzma/lzma/lzma_encoder.h view
@@ -0,0 +1,58 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_encoder.h+/// \brief LZMA encoder API+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZMA_ENCODER_H+#define LZMA_LZMA_ENCODER_H++#include "common.h"+++typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder;+++extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);+++extern uint64_t lzma_lzma_encoder_memusage(const void *options);++extern lzma_ret lzma_lzma_props_encode(const void *options, uint8_t *out);+++/// Encodes lc/lp/pb into one byte. Returns false on success and true on error.+extern bool lzma_lzma_lclppb_encode(+ const lzma_options_lzma *options, uint8_t *byte);+++#ifdef LZMA_LZ_ENCODER_H++/// Initializes raw LZMA encoder; this is used by LZMA2.+extern lzma_ret lzma_lzma_encoder_create(+ void **coder_ptr, const lzma_allocator *allocator,+ const lzma_options_lzma *options, lzma_lz_options *lz_options);+++/// Resets an already initialized LZMA encoder; this is used by LZMA2.+extern lzma_ret lzma_lzma_encoder_reset(+ lzma_lzma1_encoder *coder, const lzma_options_lzma *options);+++extern lzma_ret lzma_lzma_encode(lzma_lzma1_encoder *restrict coder,+ lzma_mf *restrict mf, uint8_t *restrict out,+ size_t *restrict out_pos, size_t out_size,+ uint32_t read_limit);++#endif++#endif
+ cbits/liblzma/lzma/lzma_encoder_optimum_fast.c view
@@ -0,0 +1,170 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_encoder_optimum_fast.c+//+// Author: Igor Pavlov+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lzma_encoder_private.h"+#include "memcmplen.h"+++#define change_pair(small_dist, big_dist) \+ (((big_dist) >> 7) > (small_dist))+++extern void+lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder,+ lzma_mf *restrict mf,+ uint32_t *restrict back_res, uint32_t *restrict len_res)+{+ const uint32_t nice_len = mf->nice_len;++ uint32_t len_main;+ uint32_t matches_count;+ if (mf->read_ahead == 0) {+ len_main = mf_find(mf, &matches_count, coder->matches);+ } else {+ assert(mf->read_ahead == 1);+ len_main = coder->longest_match_length;+ matches_count = coder->matches_count;+ }++ const uint8_t *buf = mf_ptr(mf) - 1;+ const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);++ if (buf_avail < 2) {+ // There's not enough input left to encode a match.+ *back_res = UINT32_MAX;+ *len_res = 1;+ return;+ }++ // Look for repeated matches; scan the previous four match distances+ uint32_t rep_len = 0;+ uint32_t rep_index = 0;++ for (uint32_t i = 0; i < REPS; ++i) {+ // Pointer to the beginning of the match candidate+ const uint8_t *const buf_back = buf - coder->reps[i] - 1;++ // If the first two bytes (2 == MATCH_LEN_MIN) do not match,+ // this rep is not useful.+ if (not_equal_16(buf, buf_back))+ continue;++ // The first two bytes matched.+ // Calculate the length of the match.+ 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.+ if (len >= nice_len) {+ *back_res = i;+ *len_res = len;+ mf_skip(mf, len - 1);+ return;+ }++ if (len > rep_len) {+ rep_index = i;+ rep_len = len;+ }+ }++ // We didn't find a long enough repeated match. Encode it as a normal+ // match if the match length is at least nice_len.+ if (len_main >= nice_len) {+ *back_res = coder->matches[matches_count - 1].dist + REPS;+ *len_res = len_main;+ mf_skip(mf, len_main - 1);+ return;+ }++ uint32_t back_main = 0;+ if (len_main >= 2) {+ back_main = coder->matches[matches_count - 1].dist;++ while (matches_count > 1 && len_main ==+ coder->matches[matches_count - 2].len + 1) {+ if (!change_pair(coder->matches[+ matches_count - 2].dist,+ back_main))+ break;++ --matches_count;+ len_main = coder->matches[matches_count - 1].len;+ back_main = coder->matches[matches_count - 1].dist;+ }++ if (len_main == 2 && back_main >= 0x80)+ len_main = 1;+ }++ if (rep_len >= 2) {+ if (rep_len + 1 >= len_main+ || (rep_len + 2 >= len_main+ && back_main > (UINT32_C(1) << 9))+ || (rep_len + 3 >= len_main+ && back_main > (UINT32_C(1) << 15))) {+ *back_res = rep_index;+ *len_res = rep_len;+ mf_skip(mf, rep_len - 1);+ return;+ }+ }++ if (len_main < 2 || buf_avail <= 2) {+ *back_res = UINT32_MAX;+ *len_res = 1;+ return;+ }++ // Get the matches for the next byte. If we find a better match,+ // the current byte is encoded as a literal.+ coder->longest_match_length = mf_find(mf,+ &coder->matches_count, coder->matches);++ if (coder->longest_match_length >= 2) {+ const uint32_t new_dist = coder->matches[+ coder->matches_count - 1].dist;++ if ((coder->longest_match_length >= len_main+ && new_dist < back_main)+ || (coder->longest_match_length == len_main + 1+ && !change_pair(back_main, new_dist))+ || (coder->longest_match_length > len_main + 1)+ || (coder->longest_match_length + 1 >= len_main+ && len_main >= 3+ && change_pair(new_dist, back_main))) {+ *back_res = UINT32_MAX;+ *len_res = 1;+ return;+ }+ }++ // In contrast to LZMA SDK, dictionary could not have been moved+ // between mf_find() calls, thus it is safe to just increment+ // the old buf pointer instead of recalculating it with mf_ptr().+ ++buf;++ const uint32_t limit = my_max(2, len_main - 1);++ for (uint32_t i = 0; i < REPS; ++i) {+ if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) {+ *back_res = UINT32_MAX;+ *len_res = 1;+ return;+ }+ }++ *back_res = back_main + REPS;+ *len_res = len_main;+ mf_skip(mf, len_main - 2);+ return;+}
+ cbits/liblzma/lzma/lzma_encoder_optimum_normal.c view
@@ -0,0 +1,859 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_encoder_optimum_normal.c+//+// Author: Igor Pavlov+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "lzma_encoder_private.h"+#include "fastpos.h"+#include "memcmplen.h"+++////////////+// Prices //+////////////++static uint32_t+get_literal_price(const lzma_lzma1_encoder *const coder, const uint32_t pos,+ const uint32_t prev_byte, const bool match_mode,+ uint32_t match_byte, uint32_t symbol)+{+ const probability *const subcoder = literal_subcoder(coder->literal,+ coder->literal_context_bits, coder->literal_pos_mask,+ pos, prev_byte);++ uint32_t price = 0;++ if (!match_mode) {+ price = rc_bittree_price(subcoder, 8, symbol);+ } else {+ uint32_t offset = 0x100;+ symbol += UINT32_C(1) << 8;++ do {+ match_byte <<= 1;++ const uint32_t match_bit = match_byte & offset;+ const uint32_t subcoder_index+ = offset + match_bit + (symbol >> 8);+ const uint32_t bit = (symbol >> 7) & 1;+ price += rc_bit_price(subcoder[subcoder_index], bit);++ symbol <<= 1;+ offset &= ~(match_byte ^ symbol);++ } while (symbol < (UINT32_C(1) << 16));+ }++ return price;+}+++static inline uint32_t+get_len_price(const lzma_length_encoder *const lencoder,+ const uint32_t len, const uint32_t pos_state)+{+ // NOTE: Unlike the other price tables, length prices are updated+ // in lzma_encoder.c+ return lencoder->prices[pos_state][len - MATCH_LEN_MIN];+}+++static inline uint32_t+get_short_rep_price(const lzma_lzma1_encoder *const coder,+ const lzma_lzma_state state, const uint32_t pos_state)+{+ return rc_bit_0_price(coder->is_rep0[state])+ + rc_bit_0_price(coder->is_rep0_long[state][pos_state]);+}+++static inline uint32_t+get_pure_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index,+ const lzma_lzma_state state, uint32_t pos_state)+{+ uint32_t price;++ if (rep_index == 0) {+ price = rc_bit_0_price(coder->is_rep0[state]);+ price += rc_bit_1_price(coder->is_rep0_long[state][pos_state]);+ } else {+ price = rc_bit_1_price(coder->is_rep0[state]);++ if (rep_index == 1) {+ price += rc_bit_0_price(coder->is_rep1[state]);+ } else {+ price += rc_bit_1_price(coder->is_rep1[state]);+ price += rc_bit_price(coder->is_rep2[state],+ rep_index - 2);+ }+ }++ return price;+}+++static inline uint32_t+get_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index,+ const uint32_t len, const lzma_lzma_state state,+ const uint32_t pos_state)+{+ return get_len_price(&coder->rep_len_encoder, len, pos_state)+ + get_pure_rep_price(coder, rep_index, state, pos_state);+}+++static inline uint32_t+get_dist_len_price(const lzma_lzma1_encoder *const coder, const uint32_t dist,+ const uint32_t len, const uint32_t pos_state)+{+ const uint32_t dist_state = get_dist_state(len);+ uint32_t price;++ if (dist < FULL_DISTANCES) {+ price = coder->dist_prices[dist_state][dist];+ } else {+ const uint32_t dist_slot = get_dist_slot_2(dist);+ price = coder->dist_slot_prices[dist_state][dist_slot]+ + coder->align_prices[dist & ALIGN_MASK];+ }++ price += get_len_price(&coder->match_len_encoder, len, pos_state);++ return price;+}+++static void+fill_dist_prices(lzma_lzma1_encoder *coder)+{+ for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) {++ uint32_t *const dist_slot_prices+ = coder->dist_slot_prices[dist_state];++ // Price to encode the dist_slot.+ for (uint32_t dist_slot = 0;+ dist_slot < coder->dist_table_size; ++dist_slot)+ dist_slot_prices[dist_slot] = rc_bittree_price(+ coder->dist_slot[dist_state],+ DIST_SLOT_BITS, dist_slot);++ // For matches with distance >= FULL_DISTANCES, add the price+ // of the direct bits part of the match distance. (Align bits+ // are handled by fill_align_prices()).+ for (uint32_t dist_slot = DIST_MODEL_END;+ dist_slot < coder->dist_table_size;+ ++dist_slot)+ dist_slot_prices[dist_slot] += rc_direct_price(+ ((dist_slot >> 1) - 1) - ALIGN_BITS);++ // Distances in the range [0, 3] are fully encoded with+ // dist_slot, so they are used for coder->dist_prices+ // as is.+ for (uint32_t i = 0; i < DIST_MODEL_START; ++i)+ coder->dist_prices[dist_state][i]+ = dist_slot_prices[i];+ }++ // Distances in the range [4, 127] depend on dist_slot and+ // dist_special. We do this in a loop separate from the above+ // loop to avoid redundant calls to get_dist_slot().+ for (uint32_t i = DIST_MODEL_START; i < FULL_DISTANCES; ++i) {+ const uint32_t dist_slot = get_dist_slot(i);+ const uint32_t footer_bits = ((dist_slot >> 1) - 1);+ const uint32_t base = (2 | (dist_slot & 1)) << footer_bits;+ const uint32_t price = rc_bittree_reverse_price(+ coder->dist_special + base - dist_slot - 1,+ footer_bits, i - base);++ for (uint32_t dist_state = 0; dist_state < DIST_STATES;+ ++dist_state)+ coder->dist_prices[dist_state][i]+ = price + coder->dist_slot_prices[+ dist_state][dist_slot];+ }++ coder->match_price_count = 0;+ return;+}+++static void+fill_align_prices(lzma_lzma1_encoder *coder)+{+ for (uint32_t i = 0; i < ALIGN_SIZE; ++i)+ coder->align_prices[i] = rc_bittree_reverse_price(+ coder->dist_align, ALIGN_BITS, i);++ coder->align_price_count = 0;+ return;+}+++/////////////+// Optimal //+/////////////++static inline void+make_literal(lzma_optimal *optimal)+{+ optimal->back_prev = UINT32_MAX;+ optimal->prev_1_is_literal = false;+}+++static inline void+make_short_rep(lzma_optimal *optimal)+{+ optimal->back_prev = 0;+ optimal->prev_1_is_literal = false;+}+++#define is_short_rep(optimal) \+ ((optimal).back_prev == 0)+++static void+backward(lzma_lzma1_encoder *restrict coder, uint32_t *restrict len_res,+ uint32_t *restrict back_res, uint32_t cur)+{+ coder->opts_end_index = cur;++ uint32_t pos_mem = coder->opts[cur].pos_prev;+ uint32_t back_mem = coder->opts[cur].back_prev;++ do {+ if (coder->opts[cur].prev_1_is_literal) {+ make_literal(&coder->opts[pos_mem]);+ coder->opts[pos_mem].pos_prev = pos_mem - 1;++ if (coder->opts[cur].prev_2) {+ coder->opts[pos_mem - 1].prev_1_is_literal+ = false;+ coder->opts[pos_mem - 1].pos_prev+ = coder->opts[cur].pos_prev_2;+ coder->opts[pos_mem - 1].back_prev+ = coder->opts[cur].back_prev_2;+ }+ }++ const uint32_t pos_prev = pos_mem;+ const uint32_t back_cur = back_mem;++ back_mem = coder->opts[pos_prev].back_prev;+ pos_mem = coder->opts[pos_prev].pos_prev;++ coder->opts[pos_prev].back_prev = back_cur;+ coder->opts[pos_prev].pos_prev = cur;+ cur = pos_prev;++ } while (cur != 0);++ coder->opts_current_index = coder->opts[0].pos_prev;+ *len_res = coder->opts[0].pos_prev;+ *back_res = coder->opts[0].back_prev;++ return;+}+++//////////+// Main //+//////////++static inline uint32_t+helper1(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,+ uint32_t *restrict back_res, uint32_t *restrict len_res,+ uint32_t position)+{+ const uint32_t nice_len = mf->nice_len;++ uint32_t len_main;+ uint32_t matches_count;++ if (mf->read_ahead == 0) {+ len_main = mf_find(mf, &matches_count, coder->matches);+ } else {+ assert(mf->read_ahead == 1);+ len_main = coder->longest_match_length;+ matches_count = coder->matches_count;+ }++ const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);+ if (buf_avail < 2) {+ *back_res = UINT32_MAX;+ *len_res = 1;+ return UINT32_MAX;+ }++ const uint8_t *const buf = mf_ptr(mf) - 1;++ uint32_t rep_lens[REPS];+ uint32_t rep_max_index = 0;++ 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)) {+ rep_lens[i] = 0;+ continue;+ }++ rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail);++ if (rep_lens[i] > rep_lens[rep_max_index])+ rep_max_index = i;+ }++ if (rep_lens[rep_max_index] >= nice_len) {+ *back_res = rep_max_index;+ *len_res = rep_lens[rep_max_index];+ mf_skip(mf, *len_res - 1);+ return UINT32_MAX;+ }+++ if (len_main >= nice_len) {+ *back_res = coder->matches[matches_count - 1].dist + REPS;+ *len_res = len_main;+ mf_skip(mf, len_main - 1);+ return UINT32_MAX;+ }++ const uint8_t current_byte = *buf;+ const uint8_t match_byte = *(buf - coder->reps[0] - 1);++ if (len_main < 2 && current_byte != match_byte+ && rep_lens[rep_max_index] < 2) {+ *back_res = UINT32_MAX;+ *len_res = 1;+ return UINT32_MAX;+ }++ coder->opts[0].state = coder->state;++ const uint32_t pos_state = position & coder->pos_mask;++ coder->opts[1].price = rc_bit_0_price(+ coder->is_match[coder->state][pos_state])+ + get_literal_price(coder, position, buf[-1],+ !is_literal_state(coder->state),+ match_byte, current_byte);++ make_literal(&coder->opts[1]);++ const uint32_t match_price = rc_bit_1_price(+ coder->is_match[coder->state][pos_state]);+ const uint32_t rep_match_price = match_price+ + rc_bit_1_price(coder->is_rep[coder->state]);++ if (match_byte == current_byte) {+ const uint32_t short_rep_price = rep_match_price+ + get_short_rep_price(+ coder, coder->state, pos_state);++ if (short_rep_price < coder->opts[1].price) {+ coder->opts[1].price = short_rep_price;+ make_short_rep(&coder->opts[1]);+ }+ }++ const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]);++ if (len_end < 2) {+ *back_res = coder->opts[1].back_prev;+ *len_res = 1;+ return UINT32_MAX;+ }++ coder->opts[1].pos_prev = 0;++ for (uint32_t i = 0; i < REPS; ++i)+ coder->opts[0].backs[i] = coder->reps[i];++ uint32_t len = len_end;+ do {+ coder->opts[len].price = RC_INFINITY_PRICE;+ } while (--len >= 2);+++ for (uint32_t i = 0; i < REPS; ++i) {+ uint32_t rep_len = rep_lens[i];+ if (rep_len < 2)+ continue;++ const uint32_t price = rep_match_price + get_pure_rep_price(+ coder, i, coder->state, pos_state);++ do {+ const uint32_t cur_and_len_price = price+ + get_len_price(+ &coder->rep_len_encoder,+ rep_len, pos_state);++ if (cur_and_len_price < coder->opts[rep_len].price) {+ coder->opts[rep_len].price = cur_and_len_price;+ coder->opts[rep_len].pos_prev = 0;+ coder->opts[rep_len].back_prev = i;+ coder->opts[rep_len].prev_1_is_literal = false;+ }+ } while (--rep_len >= 2);+ }+++ const uint32_t normal_match_price = match_price+ + rc_bit_0_price(coder->is_rep[coder->state]);++ len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2;+ if (len <= len_main) {+ uint32_t i = 0;+ while (len > coder->matches[i].len)+ ++i;++ for(; ; ++len) {+ const uint32_t dist = coder->matches[i].dist;+ const uint32_t cur_and_len_price = normal_match_price+ + get_dist_len_price(coder,+ dist, len, pos_state);++ if (cur_and_len_price < coder->opts[len].price) {+ coder->opts[len].price = cur_and_len_price;+ coder->opts[len].pos_prev = 0;+ coder->opts[len].back_prev = dist + REPS;+ coder->opts[len].prev_1_is_literal = false;+ }++ if (len == coder->matches[i].len)+ if (++i == matches_count)+ break;+ }+ }++ return len_end;+}+++static inline uint32_t+helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf,+ uint32_t len_end, uint32_t position, const uint32_t cur,+ const uint32_t nice_len, const uint32_t buf_avail_full)+{+ uint32_t matches_count = coder->matches_count;+ uint32_t new_len = coder->longest_match_length;+ uint32_t pos_prev = coder->opts[cur].pos_prev;+ lzma_lzma_state state;++ if (coder->opts[cur].prev_1_is_literal) {+ --pos_prev;++ if (coder->opts[cur].prev_2) {+ state = coder->opts[coder->opts[cur].pos_prev_2].state;++ if (coder->opts[cur].back_prev_2 < REPS)+ update_long_rep(state);+ else+ update_match(state);++ } else {+ state = coder->opts[pos_prev].state;+ }++ update_literal(state);++ } else {+ state = coder->opts[pos_prev].state;+ }++ if (pos_prev == cur - 1) {+ if (is_short_rep(coder->opts[cur]))+ update_short_rep(state);+ else+ update_literal(state);+ } else {+ uint32_t pos;+ if (coder->opts[cur].prev_1_is_literal+ && coder->opts[cur].prev_2) {+ pos_prev = coder->opts[cur].pos_prev_2;+ pos = coder->opts[cur].back_prev_2;+ update_long_rep(state);+ } else {+ pos = coder->opts[cur].back_prev;+ if (pos < REPS)+ update_long_rep(state);+ else+ update_match(state);+ }++ if (pos < REPS) {+ reps[0] = coder->opts[pos_prev].backs[pos];++ uint32_t i;+ for (i = 1; i <= pos; ++i)+ reps[i] = coder->opts[pos_prev].backs[i - 1];++ for (; i < REPS; ++i)+ reps[i] = coder->opts[pos_prev].backs[i];++ } else {+ reps[0] = pos - REPS;++ for (uint32_t i = 1; i < REPS; ++i)+ reps[i] = coder->opts[pos_prev].backs[i - 1];+ }+ }++ coder->opts[cur].state = state;++ for (uint32_t i = 0; i < REPS; ++i)+ coder->opts[cur].backs[i] = reps[i];++ const uint32_t cur_price = coder->opts[cur].price;++ const uint8_t current_byte = *buf;+ const uint8_t match_byte = *(buf - reps[0] - 1);++ const uint32_t pos_state = position & coder->pos_mask;++ const uint32_t cur_and_1_price = cur_price+ + rc_bit_0_price(coder->is_match[state][pos_state])+ + get_literal_price(coder, position, buf[-1],+ !is_literal_state(state), match_byte, current_byte);++ bool next_is_literal = false;++ if (cur_and_1_price < coder->opts[cur + 1].price) {+ coder->opts[cur + 1].price = cur_and_1_price;+ coder->opts[cur + 1].pos_prev = cur;+ make_literal(&coder->opts[cur + 1]);+ next_is_literal = true;+ }++ const uint32_t match_price = cur_price+ + rc_bit_1_price(coder->is_match[state][pos_state]);+ const uint32_t rep_match_price = match_price+ + rc_bit_1_price(coder->is_rep[state]);++ if (match_byte == current_byte+ && !(coder->opts[cur + 1].pos_prev < cur+ && coder->opts[cur + 1].back_prev == 0)) {++ const uint32_t short_rep_price = rep_match_price+ + get_short_rep_price(coder, state, pos_state);++ if (short_rep_price <= coder->opts[cur + 1].price) {+ coder->opts[cur + 1].price = short_rep_price;+ coder->opts[cur + 1].pos_prev = cur;+ make_short_rep(&coder->opts[cur + 1]);+ next_is_literal = true;+ }+ }++ if (buf_avail_full < 2)+ return len_end;++ const uint32_t buf_avail = my_min(buf_avail_full, nice_len);++ if (!next_is_literal && match_byte != current_byte) { // speed optimization+ // try literal + rep0+ const uint8_t *const buf_back = buf - reps[0] - 1;+ const uint32_t limit = my_min(buf_avail_full, nice_len + 1);++ const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1;++ if (len_test >= 2) {+ lzma_lzma_state state_2 = state;+ update_literal(state_2);++ const uint32_t pos_state_next = (position + 1) & coder->pos_mask;+ const uint32_t next_rep_match_price = cur_and_1_price+ + rc_bit_1_price(coder->is_match[state_2][pos_state_next])+ + rc_bit_1_price(coder->is_rep[state_2]);++ //for (; len_test >= 2; --len_test) {+ const uint32_t offset = cur + 1 + len_test;++ while (len_end < offset)+ coder->opts[++len_end].price = RC_INFINITY_PRICE;++ const uint32_t cur_and_len_price = next_rep_match_price+ + get_rep_price(coder, 0, len_test,+ state_2, pos_state_next);++ if (cur_and_len_price < coder->opts[offset].price) {+ coder->opts[offset].price = cur_and_len_price;+ coder->opts[offset].pos_prev = cur + 1;+ coder->opts[offset].back_prev = 0;+ coder->opts[offset].prev_1_is_literal = true;+ coder->opts[offset].prev_2 = false;+ }+ //}+ }+ }+++ uint32_t start_len = 2; // speed optimization++ for (uint32_t rep_index = 0; rep_index < REPS; ++rep_index) {+ const uint8_t *const buf_back = buf - reps[rep_index] - 1;+ if (not_equal_16(buf, buf_back))+ continue;++ 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;++ const uint32_t len_test_temp = len_test;+ const uint32_t price = rep_match_price + get_pure_rep_price(+ coder, rep_index, state, pos_state);++ do {+ const uint32_t cur_and_len_price = price+ + get_len_price(&coder->rep_len_encoder,+ len_test, pos_state);++ if (cur_and_len_price < coder->opts[cur + len_test].price) {+ coder->opts[cur + len_test].price = cur_and_len_price;+ coder->opts[cur + len_test].pos_prev = cur;+ coder->opts[cur + len_test].back_prev = rep_index;+ coder->opts[cur + len_test].prev_1_is_literal = false;+ }+ } while (--len_test >= 2);++ len_test = len_test_temp;++ if (rep_index == 0)+ start_len = len_test + 1;+++ uint32_t len_test_2 = len_test + 1;+ const uint32_t limit = my_min(buf_avail_full,+ len_test_2 + nice_len);+ // NOTE: len_test_2 may be greater than limit so the call to+ // lzma_memcmplen() must be done conditionally.+ if (len_test_2 < limit)+ len_test_2 = lzma_memcmplen(buf, buf_back, len_test_2, limit);++ len_test_2 -= len_test + 1;++ if (len_test_2 >= 2) {+ lzma_lzma_state state_2 = state;+ update_long_rep(state_2);++ uint32_t pos_state_next = (position + len_test) & coder->pos_mask;++ const uint32_t cur_and_len_literal_price = price+ + get_len_price(&coder->rep_len_encoder,+ len_test, pos_state)+ + rc_bit_0_price(coder->is_match[state_2][pos_state_next])+ + get_literal_price(coder, position + len_test,+ buf[len_test - 1], true,+ buf_back[len_test], buf[len_test]);++ update_literal(state_2);++ pos_state_next = (position + len_test + 1) & coder->pos_mask;++ const uint32_t next_rep_match_price = cur_and_len_literal_price+ + rc_bit_1_price(coder->is_match[state_2][pos_state_next])+ + rc_bit_1_price(coder->is_rep[state_2]);++ //for(; len_test_2 >= 2; len_test_2--) {+ const uint32_t offset = cur + len_test + 1 + len_test_2;++ while (len_end < offset)+ coder->opts[++len_end].price = RC_INFINITY_PRICE;++ const uint32_t cur_and_len_price = next_rep_match_price+ + get_rep_price(coder, 0, len_test_2,+ state_2, pos_state_next);++ if (cur_and_len_price < coder->opts[offset].price) {+ coder->opts[offset].price = cur_and_len_price;+ coder->opts[offset].pos_prev = cur + len_test + 1;+ coder->opts[offset].back_prev = 0;+ coder->opts[offset].prev_1_is_literal = true;+ coder->opts[offset].prev_2 = true;+ coder->opts[offset].pos_prev_2 = cur;+ coder->opts[offset].back_prev_2 = rep_index;+ }+ //}+ }+ }+++ //for (uint32_t len_test = 2; len_test <= new_len; ++len_test)+ if (new_len > buf_avail) {+ new_len = buf_avail;++ matches_count = 0;+ while (new_len > coder->matches[matches_count].len)+ ++matches_count;++ coder->matches[matches_count++].len = new_len;+ }+++ if (new_len >= start_len) {+ const uint32_t normal_match_price = match_price+ + rc_bit_0_price(coder->is_rep[state]);++ while (len_end < cur + new_len)+ coder->opts[++len_end].price = RC_INFINITY_PRICE;++ uint32_t i = 0;+ while (start_len > coder->matches[i].len)+ ++i;++ for (uint32_t len_test = start_len; ; ++len_test) {+ const uint32_t cur_back = coder->matches[i].dist;+ uint32_t cur_and_len_price = normal_match_price+ + get_dist_len_price(coder,+ cur_back, len_test, pos_state);++ if (cur_and_len_price < coder->opts[cur + len_test].price) {+ coder->opts[cur + len_test].price = cur_and_len_price;+ coder->opts[cur + len_test].pos_prev = cur;+ coder->opts[cur + len_test].back_prev+ = cur_back + REPS;+ coder->opts[cur + len_test].prev_1_is_literal = false;+ }++ if (len_test == coder->matches[i].len) {+ // Try Match + Literal + Rep0+ const uint8_t *const buf_back = buf - cur_back - 1;+ uint32_t len_test_2 = len_test + 1;+ const uint32_t limit = my_min(buf_avail_full,+ len_test_2 + nice_len);++ // NOTE: len_test_2 may be greater than limit+ // so the call to lzma_memcmplen() must be+ // done conditionally.+ if (len_test_2 < limit)+ len_test_2 = lzma_memcmplen(buf, buf_back,+ len_test_2, limit);++ len_test_2 -= len_test + 1;++ if (len_test_2 >= 2) {+ lzma_lzma_state state_2 = state;+ update_match(state_2);+ uint32_t pos_state_next+ = (position + len_test) & coder->pos_mask;++ const uint32_t cur_and_len_literal_price = cur_and_len_price+ + rc_bit_0_price(+ coder->is_match[state_2][pos_state_next])+ + get_literal_price(coder,+ position + len_test,+ buf[len_test - 1],+ true,+ buf_back[len_test],+ buf[len_test]);++ update_literal(state_2);+ pos_state_next = (pos_state_next + 1) & coder->pos_mask;++ const uint32_t next_rep_match_price+ = cur_and_len_literal_price+ + rc_bit_1_price(+ coder->is_match[state_2][pos_state_next])+ + rc_bit_1_price(coder->is_rep[state_2]);++ // for(; len_test_2 >= 2; --len_test_2) {+ const uint32_t offset = cur + len_test + 1 + len_test_2;++ while (len_end < offset)+ coder->opts[++len_end].price = RC_INFINITY_PRICE;++ cur_and_len_price = next_rep_match_price+ + get_rep_price(coder, 0, len_test_2,+ state_2, pos_state_next);++ if (cur_and_len_price < coder->opts[offset].price) {+ coder->opts[offset].price = cur_and_len_price;+ coder->opts[offset].pos_prev = cur + len_test + 1;+ coder->opts[offset].back_prev = 0;+ coder->opts[offset].prev_1_is_literal = true;+ coder->opts[offset].prev_2 = true;+ coder->opts[offset].pos_prev_2 = cur;+ coder->opts[offset].back_prev_2+ = cur_back + REPS;+ }+ //}+ }++ if (++i == matches_count)+ break;+ }+ }+ }++ return len_end;+}+++extern void+lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder,+ lzma_mf *restrict mf,+ uint32_t *restrict back_res, uint32_t *restrict len_res,+ uint32_t position)+{+ // If we have symbols pending, return the next pending symbol.+ if (coder->opts_end_index != coder->opts_current_index) {+ assert(mf->read_ahead > 0);+ *len_res = coder->opts[coder->opts_current_index].pos_prev+ - coder->opts_current_index;+ *back_res = coder->opts[coder->opts_current_index].back_prev;+ coder->opts_current_index = coder->opts[+ coder->opts_current_index].pos_prev;+ return;+ }++ // Update the price tables. In LZMA SDK <= 4.60 (and possibly later)+ // this was done in both initialization function and in the main loop.+ // In liblzma they were moved into this single place.+ if (mf->read_ahead == 0) {+ if (coder->match_price_count >= (1 << 7))+ fill_dist_prices(coder);++ if (coder->align_price_count >= ALIGN_SIZE)+ fill_align_prices(coder);+ }++ // TODO: This needs quite a bit of cleaning still. But splitting+ // the original function into two pieces makes it at least a little+ // more readable, since those two parts don't share many variables.++ uint32_t len_end = helper1(coder, mf, back_res, len_res, position);+ if (len_end == UINT32_MAX)+ return;++ uint32_t reps[REPS];+ memcpy(reps, coder->reps, sizeof(reps));++ uint32_t cur;+ for (cur = 1; cur < len_end; ++cur) {+ assert(cur < OPTS);++ coder->longest_match_length = mf_find(+ mf, &coder->matches_count, coder->matches);++ if (coder->longest_match_length >= mf->nice_len)+ break;++ len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end,+ position + cur, cur, mf->nice_len,+ my_min(mf_avail(mf) + 1, OPTS - 1 - cur));+ }++ backward(coder, len_res, back_res, cur);+ return;+}
+ cbits/liblzma/lzma/lzma_encoder_presets.c view
@@ -0,0 +1,64 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_encoder_presets.c+/// \brief Encoder presets+/// \note xz needs this even when only decoding is enabled.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "common.h"+++extern LZMA_API(lzma_bool)+lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)+{+ const uint32_t level = preset & LZMA_PRESET_LEVEL_MASK;+ const uint32_t flags = preset & ~LZMA_PRESET_LEVEL_MASK;+ const uint32_t supported_flags = LZMA_PRESET_EXTREME;++ if (level > 9 || (flags & ~supported_flags))+ return true;++ options->preset_dict = NULL;+ options->preset_dict_size = 0;++ options->lc = LZMA_LC_DEFAULT;+ options->lp = LZMA_LP_DEFAULT;+ options->pb = LZMA_PB_DEFAULT;++ 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;+ static const uint8_t depths[] = { 4, 8, 24, 48 };+ options->depth = depths[level];+ } else {+ options->mode = LZMA_MODE_NORMAL;+ options->mf = LZMA_MF_BT4;+ options->nice_len = level == 4 ? 16 : level == 5 ? 32 : 64;+ options->depth = 0;+ }++ if (flags & LZMA_PRESET_EXTREME) {+ options->mode = LZMA_MODE_NORMAL;+ options->mf = LZMA_MF_BT4;+ if (level == 3 || level == 5) {+ options->nice_len = 192;+ options->depth = 0;+ } else {+ options->nice_len = 273;+ options->depth = 512;+ }+ }++ return false;+}
+ cbits/liblzma/lzma/lzma_encoder_private.h view
@@ -0,0 +1,147 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file lzma_encoder_private.h+/// \brief Private definitions for LZMA encoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_LZMA_ENCODER_PRIVATE_H+#define LZMA_LZMA_ENCODER_PRIVATE_H++#include "lz_encoder.h"+#include "range_encoder.h"+#include "lzma_common.h"+#include "lzma_encoder.h"+++// Macro to compare if the first two bytes in two buffers differ. This is+// needed in lzma_lzma_optimum_*() to test if the match is at least+// MATCH_LEN_MIN bytes. Unaligned access gives tiny gain so there's no+// reason to not use it when it is supported.+#ifdef TUKLIB_FAST_UNALIGNED_ACCESS+# define not_equal_16(a, b) (read16ne(a) != read16ne(b))+#else+# define not_equal_16(a, b) \+ ((a)[0] != (b)[0] || (a)[1] != (b)[1])+#endif+++// Optimal - Number of entries in the optimum array.+#define OPTS (1 << 12)+++typedef struct {+ probability choice;+ probability choice2;+ probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS];+ probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS];+ probability high[LEN_HIGH_SYMBOLS];++ uint32_t prices[POS_STATES_MAX][LEN_SYMBOLS];+ uint32_t table_size;+ uint32_t counters[POS_STATES_MAX];++} lzma_length_encoder;+++typedef struct {+ lzma_lzma_state state;++ bool prev_1_is_literal;+ bool prev_2;++ uint32_t pos_prev_2;+ uint32_t back_prev_2;++ uint32_t price;+ uint32_t pos_prev; // pos_next;+ uint32_t back_prev;++ uint32_t backs[REPS];++} lzma_optimal;+++struct lzma_lzma1_encoder_s {+ /// Range encoder+ lzma_range_encoder rc;++ /// State+ lzma_lzma_state state;++ /// The four most recent match distances+ uint32_t reps[REPS];++ /// Array of match candidates+ lzma_match matches[MATCH_LEN_MAX + 1];++ /// Number of match candidates in matches[]+ uint32_t matches_count;++ /// Variable to hold the length of the longest match between calls+ /// to lzma_lzma_optimum_*().+ uint32_t longest_match_length;++ /// True if using getoptimumfast+ bool fast_mode;++ /// True if the encoder has been initialized by encoding the first+ /// byte as a literal.+ bool is_initialized;++ /// True if the range encoder has been flushed, but not all bytes+ /// have been written to the output buffer yet.+ bool is_flushed;++ uint32_t pos_mask; ///< (1 << pos_bits) - 1+ uint32_t literal_context_bits;+ uint32_t literal_pos_mask;++ // These are the same as in lzma_decoder.c. See comments there.+ probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];+ probability is_match[STATES][POS_STATES_MAX];+ probability is_rep[STATES];+ probability is_rep0[STATES];+ probability is_rep1[STATES];+ probability is_rep2[STATES];+ probability is_rep0_long[STATES][POS_STATES_MAX];+ probability dist_slot[DIST_STATES][DIST_SLOTS];+ probability dist_special[FULL_DISTANCES - DIST_MODEL_END];+ probability dist_align[ALIGN_SIZE];++ // These are the same as in lzma_decoder.c except that the encoders+ // include also price tables.+ lzma_length_encoder match_len_encoder;+ lzma_length_encoder rep_len_encoder;++ // Price tables+ uint32_t dist_slot_prices[DIST_STATES][DIST_SLOTS];+ uint32_t dist_prices[DIST_STATES][FULL_DISTANCES];+ uint32_t dist_table_size;+ uint32_t match_price_count;++ uint32_t align_prices[ALIGN_SIZE];+ uint32_t align_price_count;++ // Optimal+ uint32_t opts_end_index;+ uint32_t opts_current_index;+ lzma_optimal opts[OPTS];+};+++extern void lzma_lzma_optimum_fast(+ lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,+ uint32_t *restrict back_res, uint32_t *restrict len_res);++extern void lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder,+ lzma_mf *restrict mf, uint32_t *restrict back_res,+ uint32_t *restrict len_res, uint32_t position);++#endif
+ cbits/liblzma/rangecoder/price.h view
@@ -0,0 +1,92 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file price.h+/// \brief Probability price calculation+//+// Author: Igor Pavlov+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_PRICE_H+#define LZMA_PRICE_H+++#define RC_MOVE_REDUCING_BITS 4+#define RC_BIT_PRICE_SHIFT_BITS 4+#define RC_PRICE_TABLE_SIZE (RC_BIT_MODEL_TOTAL >> RC_MOVE_REDUCING_BITS)++#define RC_INFINITY_PRICE (UINT32_C(1) << 30)+++/// Lookup table for the inline functions defined in this file.+extern const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE];+++static inline uint32_t+rc_bit_price(const probability prob, const uint32_t bit)+{+ return lzma_rc_prices[(prob ^ ((UINT32_C(0) - bit)+ & (RC_BIT_MODEL_TOTAL - 1))) >> RC_MOVE_REDUCING_BITS];+}+++static inline uint32_t+rc_bit_0_price(const probability prob)+{+ return lzma_rc_prices[prob >> RC_MOVE_REDUCING_BITS];+}+++static inline uint32_t+rc_bit_1_price(const probability prob)+{+ return lzma_rc_prices[(prob ^ (RC_BIT_MODEL_TOTAL - 1))+ >> RC_MOVE_REDUCING_BITS];+}+++static inline uint32_t+rc_bittree_price(const probability *const probs,+ const uint32_t bit_levels, uint32_t symbol)+{+ uint32_t price = 0;+ symbol += UINT32_C(1) << bit_levels;++ do {+ const uint32_t bit = symbol & 1;+ symbol >>= 1;+ price += rc_bit_price(probs[symbol], bit);+ } while (symbol != 1);++ return price;+}+++static inline uint32_t+rc_bittree_reverse_price(const probability *const 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 += rc_bit_price(probs[model_index], bit);+ model_index = (model_index << 1) + bit;+ } while (--bit_levels != 0);++ return price;+}+++static inline uint32_t+rc_direct_price(const uint32_t bits)+{+ return bits << RC_BIT_PRICE_SHIFT_BITS;+}++#endif
+ cbits/liblzma/rangecoder/price_table.c view
@@ -0,0 +1,22 @@+/* This file has been automatically generated by price_tablegen.c. */++#include "range_encoder.h"++const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE] = {+ 128, 103, 91, 84, 78, 73, 69, 66,+ 63, 61, 58, 56, 54, 52, 51, 49,+ 48, 46, 45, 44, 43, 42, 41, 40,+ 39, 38, 37, 36, 35, 34, 34, 33,+ 32, 31, 31, 30, 29, 29, 28, 28,+ 27, 26, 26, 25, 25, 24, 24, 23,+ 23, 22, 22, 22, 21, 21, 20, 20,+ 19, 19, 19, 18, 18, 17, 17, 17,+ 16, 16, 16, 15, 15, 15, 14, 14,+ 14, 13, 13, 13, 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, 5, 4, 4, 4, 4,+ 3, 3, 3, 3, 3, 2, 2, 2,+ 2, 2, 2, 1, 1, 1, 1, 1+};
+ cbits/liblzma/rangecoder/price_tablegen.c view
@@ -0,0 +1,87 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file price_tablegen.c+/// \brief Probability price table generator+///+/// Compiling: gcc -std=c99 -o price_tablegen price_tablegen.c+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include <inttypes.h>+#include <stdio.h>+#include "range_common.h"+#include "price.h"+++static uint32_t rc_prices[RC_PRICE_TABLE_SIZE];+++static void+init_price_table(void)+{+ for (uint32_t i = (UINT32_C(1) << RC_MOVE_REDUCING_BITS) / 2;+ i < RC_BIT_MODEL_TOTAL;+ i += (UINT32_C(1) << RC_MOVE_REDUCING_BITS)) {+ const uint32_t cycles_bits = RC_BIT_PRICE_SHIFT_BITS;+ uint32_t w = i;+ uint32_t bit_count = 0;++ for (uint32_t j = 0; j < cycles_bits; ++j) {+ w *= w;+ bit_count <<= 1;++ while (w >= (UINT32_C(1) << 16)) {+ w >>= 1;+ ++bit_count;+ }+ }++ rc_prices[i >> RC_MOVE_REDUCING_BITS]+ = (RC_BIT_MODEL_TOTAL_BITS << cycles_bits)+ - 15 - bit_count;+ }++ return;+}+++static void+print_price_table(void)+{+ printf("/* This file has been automatically generated by "+ "price_tablegen.c. */\n\n"+ "#include \"range_encoder.h\"\n\n"+ "const uint8_t lzma_rc_prices["+ "RC_PRICE_TABLE_SIZE] = {");++ const size_t array_size = sizeof(lzma_rc_prices)+ / sizeof(lzma_rc_prices[0]);+ for (size_t i = 0; i < array_size; ++i) {+ if (i % 8 == 0)+ printf("\n\t");++ printf("%4" PRIu32, rc_prices[i]);++ if (i != array_size - 1)+ printf(",");+ }++ printf("\n};\n");++ return;+}+++int+main(void)+{+ init_price_table();+ print_price_table();+ return 0;+}
+ cbits/liblzma/rangecoder/range_common.h view
@@ -0,0 +1,71 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file range_common.h+/// \brief Common things for range encoder and decoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_RANGE_COMMON_H+#define LZMA_RANGE_COMMON_H++#include "common.h"+++///////////////+// Constants //+///////////////++#define RC_SHIFT_BITS 8+#define RC_TOP_BITS 24+#define RC_TOP_VALUE (UINT32_C(1) << RC_TOP_BITS)+#define RC_BIT_MODEL_TOTAL_BITS 11+#define RC_BIT_MODEL_TOTAL (UINT32_C(1) << RC_BIT_MODEL_TOTAL_BITS)+#define RC_MOVE_BITS 5+++////////////+// Macros //+////////////++// Resets the probability so that both 0 and 1 have probability of 50 %+#define bit_reset(prob) \+ prob = RC_BIT_MODEL_TOTAL >> 1++// This does the same for a complete bit tree.+// (A tree represented as an array.)+#define bittree_reset(probs, bit_levels) \+ for (uint32_t bt_i = 0; bt_i < (1 << (bit_levels)); ++bt_i) \+ bit_reset((probs)[bt_i])+++//////////////////////+// Type definitions //+//////////////////////++/// \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
+ cbits/liblzma/rangecoder/range_decoder.h view
@@ -0,0 +1,185 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file range_decoder.h+/// \brief Range Decoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_RANGE_DECODER_H+#define LZMA_RANGE_DECODER_H++#include "range_common.h"+++typedef struct {+ uint32_t range;+ uint32_t code;+ uint32_t init_bytes_left;+} lzma_range_decoder;+++/// Reads the first five bytes to initialize the range decoder.+static inline lzma_ret+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 LZMA_OK;++ // The first byte is always 0x00. It could have been omitted+ // in LZMA2 but it wasn't, so one byte is wasted in every+ // LZMA2 chunk.+ if (rc->init_bytes_left == 5 && in[*in_pos] != 0x00)+ return LZMA_DATA_ERROR;++ rc->code = (rc->code << 8) | in[*in_pos];+ ++*in_pos;+ --rc->init_bytes_left;+ }++ return LZMA_STREAM_END;+}+++/// Makes local copies of range decoder and *in_pos variables. Doing this+/// improves speed significantly. The range decoder macros expect also+/// variables `in' and `in_size' to be defined.+#define rc_to_local(range_decoder, in_pos) \+ lzma_range_decoder rc = range_decoder; \+ size_t rc_in_pos = (in_pos); \+ uint32_t rc_bound+++/// Stores the local copes back to the range decoder structure.+#define rc_from_local(range_decoder, in_pos) \+do { \+ range_decoder = rc; \+ in_pos = rc_in_pos; \+} while (0)+++/// Resets the range decoder structure.+#define rc_reset(range_decoder) \+do { \+ (range_decoder).range = UINT32_MAX; \+ (range_decoder).code = 0; \+ (range_decoder).init_bytes_left = 5; \+} while (0)+++/// When decoding has been properly finished, rc.code is always zero unless+/// the input stream is corrupt. So checking this can catch some corrupt+/// files especially if they don't have any other integrity check.+#define rc_is_finished(range_decoder) \+ ((range_decoder).code == 0)+++/// Read the next input byte if needed. If more input is needed but there is+/// no more input available, "goto out" is used to jump out of the main+/// decoder loop.+#define rc_normalize(seq) \+do { \+ if (rc.range < RC_TOP_VALUE) { \+ if (unlikely(rc_in_pos == in_size)) { \+ coder->sequence = seq; \+ goto out; \+ } \+ rc.range <<= RC_SHIFT_BITS; \+ rc.code = (rc.code << RC_SHIFT_BITS) | in[rc_in_pos++]; \+ } \+} while (0)+++/// Start decoding a bit. This must be used together with rc_update_0()+/// and rc_update_1():+///+/// rc_if_0(prob, seq) {+/// rc_update_0(prob);+/// // Do something+/// } else {+/// rc_update_1(prob);+/// // Do something else+/// }+///+#define rc_if_0(prob, seq) \+ rc_normalize(seq); \+ rc_bound = (rc.range >> RC_BIT_MODEL_TOTAL_BITS) * (prob); \+ if (rc.code < rc_bound)+++/// Update the range decoder state and the used probability variable to+/// match a decoded bit of 0.+#define rc_update_0(prob) \+do { \+ rc.range = rc_bound; \+ prob += (RC_BIT_MODEL_TOTAL - (prob)) >> RC_MOVE_BITS; \+} while (0)+++/// Update the range decoder state and the used probability variable to+/// match a decoded bit of 1.+#define rc_update_1(prob) \+do { \+ rc.range -= rc_bound; \+ rc.code -= rc_bound; \+ prob -= (prob) >> RC_MOVE_BITS; \+} while (0)+++/// Decodes one bit and runs action0 or action1 depending on the decoded bit.+/// This macro is used as the last step in bittree reverse decoders since+/// those don't use "symbol" for anything else than indexing the probability+/// arrays.+#define rc_bit_last(prob, action0, action1, seq) \+do { \+ rc_if_0(prob, seq) { \+ rc_update_0(prob); \+ action0; \+ } else { \+ rc_update_1(prob); \+ action1; \+ } \+} while (0)+++/// Decodes one bit, updates "symbol", and runs action0 or action1 depending+/// on the decoded bit.+#define rc_bit(prob, action0, action1, seq) \+ rc_bit_last(prob, \+ symbol <<= 1; action0, \+ symbol = (symbol << 1) + 1; action1, \+ seq);+++/// Like rc_bit() but add "case seq:" as a prefix. This makes the unrolled+/// loops more readable because the code isn't littered with "case"+/// statements. On the other hand this also makes it less readable, since+/// spotting the places where the decoder loop may be restarted is less+/// obvious.+#define rc_bit_case(prob, action0, action1, seq) \+ case seq: rc_bit(prob, action0, action1, seq)+++/// Decode a bit without using a probability.+#define rc_direct(dest, seq) \+do { \+ rc_normalize(seq); \+ 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 (0)+++// NOTE: No macros are provided for bittree decoding. It seems to be simpler+// to just write them open in the code.++#endif
+ cbits/liblzma/rangecoder/range_encoder.h view
@@ -0,0 +1,231 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file range_encoder.h+/// \brief Range Encoder+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_RANGE_ENCODER_H+#define LZMA_RANGE_ENCODER_H++#include "range_common.h"+#include "price.h"+++/// Maximum number of symbols that can be put pending into lzma_range_encoder+/// structure between calls to lzma_rc_encode(). For LZMA, 52+5 is enough+/// (match with big distance and length followed by range encoder flush).+#define RC_SYMBOLS_MAX 58+++typedef struct {+ uint64_t low;+ uint64_t cache_size;+ uint32_t range;+ uint8_t cache;++ /// Number of symbols in the tables+ size_t count;++ /// rc_encode()'s position in the tables+ size_t pos;++ /// Symbols to encode+ enum {+ RC_BIT_0,+ RC_BIT_1,+ RC_DIRECT_0,+ RC_DIRECT_1,+ RC_FLUSH,+ } symbols[RC_SYMBOLS_MAX];++ /// Probabilities associated with RC_BIT_0 or RC_BIT_1+ probability *probs[RC_SYMBOLS_MAX];++} lzma_range_encoder;+++static inline void+rc_reset(lzma_range_encoder *rc)+{+ rc->low = 0;+ rc->cache_size = 1;+ rc->range = UINT32_MAX;+ rc->cache = 0;+ rc->count = 0;+ rc->pos = 0;+}+++static inline void+rc_bit(lzma_range_encoder *rc, probability *prob, uint32_t bit)+{+ rc->symbols[rc->count] = bit;+ rc->probs[rc->count] = prob;+ ++rc->count;+}+++static inline void+rc_bittree(lzma_range_encoder *rc, probability *probs,+ uint32_t bit_count, uint32_t symbol)+{+ uint32_t model_index = 1;++ do {+ const uint32_t bit = (symbol >> --bit_count) & 1;+ rc_bit(rc, &probs[model_index], bit);+ model_index = (model_index << 1) + bit;+ } while (bit_count != 0);+}+++static inline void+rc_bittree_reverse(lzma_range_encoder *rc, probability *probs,+ uint32_t bit_count, uint32_t symbol)+{+ uint32_t model_index = 1;++ do {+ const uint32_t bit = symbol & 1;+ symbol >>= 1;+ rc_bit(rc, &probs[model_index], bit);+ model_index = (model_index << 1) + bit;+ } while (--bit_count != 0);+}+++static inline void+rc_direct(lzma_range_encoder *rc,+ uint32_t value, uint32_t bit_count)+{+ do {+ rc->symbols[rc->count++]+ = RC_DIRECT_0 + ((value >> --bit_count) & 1);+ } while (bit_count != 0);+}+++static inline void+rc_flush(lzma_range_encoder *rc)+{+ for (size_t i = 0; i < 5; ++i)+ rc->symbols[rc->count++] = RC_FLUSH;+}+++static inline bool+rc_shift_low(lzma_range_encoder *rc,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000)+ || (uint32_t)(rc->low >> 32) != 0) {+ do {+ if (*out_pos == out_size)+ return true;++ out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32);+ ++*out_pos;+ rc->cache = 0xFF;++ } while (--rc->cache_size != 0);++ rc->cache = (rc->low >> 24) & 0xFF;+ }++ ++rc->cache_size;+ rc->low = (rc->low & 0x00FFFFFF) << RC_SHIFT_BITS;++ return false;+}+++static inline bool+rc_encode(lzma_range_encoder *rc,+ uint8_t *out, size_t *out_pos, size_t out_size)+{+ assert(rc->count <= RC_SYMBOLS_MAX);++ while (rc->pos < rc->count) {+ // Normalize+ if (rc->range < RC_TOP_VALUE) {+ if (rc_shift_low(rc, out, out_pos, out_size))+ return true;++ rc->range <<= RC_SHIFT_BITS;+ }++ // Encode a bit+ switch (rc->symbols[rc->pos]) {+ case RC_BIT_0: {+ probability prob = *rc->probs[rc->pos];+ rc->range = (rc->range >> RC_BIT_MODEL_TOTAL_BITS)+ * prob;+ prob += (RC_BIT_MODEL_TOTAL - prob) >> RC_MOVE_BITS;+ *rc->probs[rc->pos] = prob;+ break;+ }++ case RC_BIT_1: {+ probability prob = *rc->probs[rc->pos];+ const uint32_t bound = prob * (rc->range+ >> RC_BIT_MODEL_TOTAL_BITS);+ rc->low += bound;+ rc->range -= bound;+ prob -= prob >> RC_MOVE_BITS;+ *rc->probs[rc->pos] = prob;+ break;+ }++ case RC_DIRECT_0:+ rc->range >>= 1;+ break;++ case RC_DIRECT_1:+ rc->range >>= 1;+ rc->low += rc->range;+ break;++ case RC_FLUSH:+ // Prevent further normalizations.+ rc->range = UINT32_MAX;++ // Flush the last five bytes (see rc_flush()).+ do {+ if (rc_shift_low(rc, out, out_pos, out_size))+ return true;+ } while (++rc->pos < rc->count);++ // Reset the range encoder so we are ready to continue+ // encoding if we weren't finishing the stream.+ rc_reset(rc);+ return false;++ default:+ assert(0);+ break;+ }++ ++rc->pos;+ }++ rc->count = 0;+ rc->pos = 0;++ return false;+}+++static inline uint64_t+rc_pending(const lzma_range_encoder *rc)+{+ return rc->cache_size + 5 - 1;+}++#endif
+ cbits/liblzma/simple/arm.c view
@@ -0,0 +1,71 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file arm.c+/// \brief Filter for ARM binaries+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++static size_t+arm_code(void *simple lzma_attribute((__unused__)),+ uint32_t now_pos, bool is_encoder,+ uint8_t *buffer, size_t size)+{+ size_t i;+ for (i = 0; i + 4 <= size; i += 4) {+ if (buffer[i + 3] == 0xEB) {+ uint32_t src = ((uint32_t)(buffer[i + 2]) << 16)+ | ((uint32_t)(buffer[i + 1]) << 8)+ | (uint32_t)(buffer[i + 0]);+ src <<= 2;++ uint32_t dest;+ if (is_encoder)+ dest = now_pos + (uint32_t)(i) + 8 + src;+ else+ dest = src - (now_pos + (uint32_t)(i) + 8);++ dest >>= 2;+ buffer[i + 2] = (dest >> 16);+ buffer[i + 1] = (dest >> 8);+ buffer[i + 0] = dest;+ }+ }++ return i;+}+++static lzma_ret+arm_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters, bool is_encoder)+{+ return lzma_simple_coder_init(next, allocator, filters,+ &arm_code, 0, 4, 4, is_encoder);+}+++extern lzma_ret+lzma_simple_arm_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return arm_coder_init(next, allocator, filters, true);+}+++extern lzma_ret+lzma_simple_arm_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return arm_coder_init(next, allocator, filters, false);+}
+ cbits/liblzma/simple/armthumb.c view
@@ -0,0 +1,76 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file armthumb.c+/// \brief Filter for ARM-Thumb binaries+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++static size_t+armthumb_code(void *simple lzma_attribute((__unused__)),+ uint32_t now_pos, bool is_encoder,+ uint8_t *buffer, size_t size)+{+ size_t i;+ for (i = 0; i + 4 <= size; i += 2) {+ if ((buffer[i + 1] & 0xF8) == 0xF0+ && (buffer[i + 3] & 0xF8) == 0xF8) {+ uint32_t src = (((uint32_t)(buffer[i + 1]) & 7) << 19)+ | ((uint32_t)(buffer[i + 0]) << 11)+ | (((uint32_t)(buffer[i + 3]) & 7) << 8)+ | (uint32_t)(buffer[i + 2]);++ src <<= 1;++ uint32_t dest;+ if (is_encoder)+ dest = now_pos + (uint32_t)(i) + 4 + src;+ else+ dest = src - (now_pos + (uint32_t)(i) + 4);++ dest >>= 1;+ buffer[i + 1] = 0xF0 | ((dest >> 19) & 0x7);+ buffer[i + 0] = (dest >> 11);+ buffer[i + 3] = 0xF8 | ((dest >> 8) & 0x7);+ buffer[i + 2] = (dest);+ i += 2;+ }+ }++ return i;+}+++static lzma_ret+armthumb_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters, bool is_encoder)+{+ return lzma_simple_coder_init(next, allocator, filters,+ &armthumb_code, 0, 4, 2, is_encoder);+}+++extern lzma_ret+lzma_simple_armthumb_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return armthumb_coder_init(next, allocator, filters, true);+}+++extern lzma_ret+lzma_simple_armthumb_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return armthumb_coder_init(next, allocator, filters, false);+}
+ cbits/liblzma/simple/ia64.c view
@@ -0,0 +1,112 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file ia64.c+/// \brief Filter for IA64 (Itanium) binaries+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++static size_t+ia64_code(void *simple lzma_attribute((__unused__)),+ uint32_t now_pos, bool is_encoder,+ uint8_t *buffer, size_t size)+{+ static const uint32_t BRANCH_TABLE[32] = {+ 0, 0, 0, 0, 0, 0, 0, 0,+ 0, 0, 0, 0, 0, 0, 0, 0,+ 4, 4, 6, 6, 0, 0, 7, 7,+ 4, 4, 0, 0, 4, 4, 0, 0+ };++ size_t i;+ for (i = 0; i + 16 <= size; i += 16) {+ const uint32_t instr_template = buffer[i] & 0x1F;+ const uint32_t mask = BRANCH_TABLE[instr_template];+ uint32_t bit_pos = 5;++ for (size_t slot = 0; slot < 3; ++slot, bit_pos += 41) {+ if (((mask >> slot) & 1) == 0)+ continue;++ const size_t byte_pos = (bit_pos >> 3);+ const uint32_t bit_res = bit_pos & 0x7;+ uint64_t instruction = 0;++ for (size_t j = 0; j < 6; ++j)+ instruction += (uint64_t)(+ buffer[i + j + byte_pos])+ << (8 * j);++ uint64_t inst_norm = instruction >> bit_res;++ if (((inst_norm >> 37) & 0xF) == 0x5+ && ((inst_norm >> 9) & 0x7) == 0+ /* && (inst_norm & 0x3F)== 0 */+ ) {+ uint32_t src = (uint32_t)(+ (inst_norm >> 13) & 0xFFFFF);+ src |= ((inst_norm >> 36) & 1) << 20;++ src <<= 4;++ uint32_t dest;+ if (is_encoder)+ dest = now_pos + (uint32_t)(i) + src;+ else+ dest = src - (now_pos + (uint32_t)(i));++ dest >>= 4;++ inst_norm &= ~((uint64_t)(0x8FFFFF) << 13);+ inst_norm |= (uint64_t)(dest & 0xFFFFF) << 13;+ inst_norm |= (uint64_t)(dest & 0x100000)+ << (36 - 20);++ instruction &= (1U << bit_res) - 1;+ instruction |= (inst_norm << bit_res);++ for (size_t j = 0; j < 6; j++)+ buffer[i + j + byte_pos] = (uint8_t)(+ instruction+ >> (8 * j));+ }+ }+ }++ return i;+}+++static lzma_ret+ia64_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters, bool is_encoder)+{+ return lzma_simple_coder_init(next, allocator, filters,+ &ia64_code, 0, 16, 16, is_encoder);+}+++extern lzma_ret+lzma_simple_ia64_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return ia64_coder_init(next, allocator, filters, true);+}+++extern lzma_ret+lzma_simple_ia64_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return ia64_coder_init(next, allocator, filters, false);+}
+ cbits/liblzma/simple/powerpc.c view
@@ -0,0 +1,76 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file powerpc.c+/// \brief Filter for PowerPC (big endian) binaries+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++static size_t+powerpc_code(void *simple lzma_attribute((__unused__)),+ uint32_t now_pos, bool is_encoder,+ uint8_t *buffer, size_t size)+{+ size_t i;+ for (i = 0; i + 4 <= size; i += 4) {+ // PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)+ if ((buffer[i] >> 2) == 0x12+ && ((buffer[i + 3] & 3) == 1)) {++ const uint32_t src+ = (((uint32_t)(buffer[i + 0]) & 3) << 24)+ | ((uint32_t)(buffer[i + 1]) << 16)+ | ((uint32_t)(buffer[i + 2]) << 8)+ | ((uint32_t)(buffer[i + 3]) & ~UINT32_C(3));++ uint32_t dest;+ if (is_encoder)+ dest = now_pos + (uint32_t)(i) + src;+ else+ dest = src - (now_pos + (uint32_t)(i));++ buffer[i + 0] = 0x48 | ((dest >> 24) & 0x03);+ buffer[i + 1] = (dest >> 16);+ buffer[i + 2] = (dest >> 8);+ buffer[i + 3] &= 0x03;+ buffer[i + 3] |= dest;+ }+ }++ return i;+}+++static lzma_ret+powerpc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters, bool is_encoder)+{+ return lzma_simple_coder_init(next, allocator, filters,+ &powerpc_code, 0, 4, 4, is_encoder);+}+++extern lzma_ret+lzma_simple_powerpc_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return powerpc_coder_init(next, allocator, filters, true);+}+++extern lzma_ret+lzma_simple_powerpc_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return powerpc_coder_init(next, allocator, filters, false);+}
+ cbits/liblzma/simple/simple_coder.c view
@@ -0,0 +1,290 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_coder.c+/// \brief Wrapper for simple filters+///+/// Simple filters don't change the size of the data i.e. number of bytes+/// in equals the number of bytes out.+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++/// Copied or encodes/decodes more data to out[].+static lzma_ret+copy_or_code(lzma_simple_coder *coder, const 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)+{+ assert(!coder->end_was_reached);++ if (coder->next.code == NULL) {+ lzma_bufcpy(in, in_pos, in_size, out, out_pos, out_size);++ // Check if end of stream was reached.+ if (coder->is_encoder && action == LZMA_FINISH+ && *in_pos == in_size)+ coder->end_was_reached = true;++ } else {+ // Call the next coder in the chain to provide us some data.+ const lzma_ret ret = coder->next.code(+ coder->next.coder, allocator,+ in, in_pos, in_size,+ out, out_pos, out_size, action);++ if (ret == LZMA_STREAM_END) {+ assert(!coder->is_encoder+ || action == LZMA_FINISH);+ coder->end_was_reached = true;++ } else if (ret != LZMA_OK) {+ return ret;+ }+ }++ return LZMA_OK;+}+++static size_t+call_filter(lzma_simple_coder *coder, uint8_t *buffer, size_t size)+{+ const size_t filtered = coder->filter(coder->simple,+ coder->now_pos, coder->is_encoder,+ buffer, size);+ coder->now_pos += filtered;+ return filtered;+}+++static lzma_ret+simple_code(void *coder_ptr, const 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_simple_coder *coder = coder_ptr;++ // 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_OPTIONS_ERROR;++ // Flush already filtered data from coder->buffer[] to out[].+ if (coder->pos < coder->filtered) {+ lzma_bufcpy(coder->buffer, &coder->pos, coder->filtered,+ out, out_pos, out_size);++ // If we couldn't flush all the filtered data, return to+ // application immediately.+ if (coder->pos < coder->filtered)+ return LZMA_OK;++ if (coder->end_was_reached) {+ assert(coder->filtered == coder->size);+ return LZMA_STREAM_END;+ }+ }++ // If we get here, there is no filtered data left in the buffer.+ coder->filtered = 0;++ assert(!coder->end_was_reached);++ // If there is more output space left than there is unfiltered data+ // in coder->buffer[], flush coder->buffer[] to out[], and copy/code+ // more data to out[] hopefully filling it completely. Then filter+ // the data in out[]. This step is where most of the data gets+ // filtered if the buffer sizes used by the application are reasonable.+ const size_t out_avail = out_size - *out_pos;+ const size_t buf_avail = coder->size - coder->pos;+ if (out_avail > buf_avail || buf_avail == 0) {+ // Store the old position so that we know from which byte+ // to start filtering.+ const size_t out_start = *out_pos;++ // Flush data from coder->buffer[] to out[], but don't reset+ // coder->pos and coder->size yet. This way the coder can be+ // restarted if the next filter in the chain returns e.g.+ // LZMA_MEM_ERROR.+ //+ // Do the memcpy() conditionally because out can be NULL+ // (in which case buf_avail is always 0). Calling memcpy()+ // with a null-pointer is undefined even if the third+ // argument is 0.+ if (buf_avail > 0)+ memcpy(out + *out_pos, coder->buffer + coder->pos,+ buf_avail);++ *out_pos += buf_avail;++ // Copy/Encode/Decode more data to out[].+ {+ const lzma_ret ret = copy_or_code(coder, allocator,+ in, in_pos, in_size,+ out, out_pos, out_size, action);+ assert(ret != LZMA_STREAM_END);+ if (ret != LZMA_OK)+ return ret;+ }++ // Filter out[].+ const size_t size = *out_pos - out_start;+ const size_t filtered = call_filter(+ coder, out + out_start, size);++ const size_t unfiltered = size - filtered;+ assert(unfiltered <= coder->allocated / 2);++ // Now we can update coder->pos and coder->size, because+ // the next coder in the chain (if any) was successful.+ coder->pos = 0;+ coder->size = unfiltered;++ if (coder->end_was_reached) {+ // The last byte has been copied to out[] already.+ // They are left as is.+ coder->size = 0;++ } else if (unfiltered > 0) {+ // There is unfiltered data left in out[]. Copy it to+ // coder->buffer[] and rewind *out_pos appropriately.+ *out_pos -= unfiltered;+ memcpy(coder->buffer, out + *out_pos, unfiltered);+ }+ } else if (coder->pos > 0) {+ memmove(coder->buffer, coder->buffer + coder->pos, buf_avail);+ coder->size -= coder->pos;+ coder->pos = 0;+ }++ assert(coder->pos == 0);++ // If coder->buffer[] isn't empty, try to fill it by copying/decoding+ // more data. Then filter coder->buffer[] and copy the successfully+ // filtered data to out[]. It is probable, that some filtered and+ // unfiltered data will be left to coder->buffer[].+ if (coder->size > 0) {+ {+ const lzma_ret ret = copy_or_code(coder, allocator,+ in, in_pos, in_size,+ coder->buffer, &coder->size,+ coder->allocated, action);+ assert(ret != LZMA_STREAM_END);+ if (ret != LZMA_OK)+ return ret;+ }++ coder->filtered = call_filter(+ coder, coder->buffer, coder->size);++ // Everything is considered to be filtered if coder->buffer[]+ // contains the last bytes of the data.+ if (coder->end_was_reached)+ coder->filtered = coder->size;++ // Flush as much as possible.+ lzma_bufcpy(coder->buffer, &coder->pos, coder->filtered,+ out, out_pos, out_size);+ }++ // Check if we got everything done.+ if (coder->end_was_reached && coder->pos == coder->size)+ return LZMA_STREAM_END;++ return LZMA_OK;+}+++static void+simple_coder_end(void *coder_ptr, const lzma_allocator *allocator)+{+ lzma_simple_coder *coder = coder_ptr;+ lzma_next_end(&coder->next, allocator);+ lzma_free(coder->simple, allocator);+ lzma_free(coder, allocator);+ return;+}+++static lzma_ret+simple_coder_update(void *coder_ptr, const lzma_allocator *allocator,+ const lzma_filter *filters_null lzma_attribute((__unused__)),+ const lzma_filter *reversed_filters)+{+ lzma_simple_coder *coder = coder_ptr;++ // No update support, just call the next filter in the chain.+ return lzma_next_filter_update(+ &coder->next, allocator, reversed_filters + 1);+}+++extern lzma_ret+lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters,+ size_t (*filter)(void *simple, uint32_t now_pos,+ bool is_encoder, uint8_t *buffer, size_t size),+ size_t simple_size, size_t unfiltered_max,+ uint32_t alignment, bool is_encoder)+{+ // Allocate memory for the lzma_simple_coder structure if needed.+ lzma_simple_coder *coder = next->coder;+ if (coder == NULL) {+ // Here we allocate space also for the temporary buffer. We+ // need twice the size of unfiltered_max, because then it+ // is always possible to filter at least unfiltered_max bytes+ // more data in coder->buffer[] if it can be filled completely.+ coder = lzma_alloc(sizeof(lzma_simple_coder)+ + 2 * unfiltered_max, allocator);+ if (coder == NULL)+ return LZMA_MEM_ERROR;++ next->coder = coder;+ next->code = &simple_code;+ next->end = &simple_coder_end;+ next->update = &simple_coder_update;++ coder->next = LZMA_NEXT_CODER_INIT;+ coder->filter = filter;+ coder->allocated = 2 * unfiltered_max;++ // Allocate memory for filter-specific data structure.+ if (simple_size > 0) {+ coder->simple = lzma_alloc(simple_size, allocator);+ if (coder->simple == NULL)+ return LZMA_MEM_ERROR;+ } else {+ coder->simple = NULL;+ }+ }++ if (filters[0].options != NULL) {+ const lzma_options_bcj *simple = filters[0].options;+ coder->now_pos = simple->start_offset;+ if (coder->now_pos & (alignment - 1))+ return LZMA_OPTIONS_ERROR;+ } else {+ coder->now_pos = 0;+ }++ // Reset variables.+ coder->is_encoder = is_encoder;+ coder->end_was_reached = false;+ coder->pos = 0;+ coder->filtered = 0;+ coder->size = 0;++ return lzma_next_filter_init(&coder->next, allocator, filters + 1);+}
+ cbits/liblzma/simple/simple_coder.h view
@@ -0,0 +1,72 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_coder.h+/// \brief Wrapper for simple filters+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_SIMPLE_CODER_H+#define LZMA_SIMPLE_CODER_H++#include "common.h"+++extern lzma_ret lzma_simple_x86_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_simple_x86_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);+++extern lzma_ret lzma_simple_powerpc_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_simple_powerpc_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);+++extern lzma_ret lzma_simple_ia64_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_simple_ia64_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);+++extern lzma_ret lzma_simple_arm_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_simple_arm_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);+++extern lzma_ret lzma_simple_armthumb_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_simple_armthumb_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);+++extern lzma_ret lzma_simple_sparc_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++extern lzma_ret lzma_simple_sparc_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters);++#endif
+ cbits/liblzma/simple/simple_decoder.c view
@@ -0,0 +1,40 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_decoder.c+/// \brief Properties decoder for simple filters+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_decoder.h"+++extern lzma_ret+lzma_simple_props_decode(void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size)+{+ if (props_size == 0)+ return LZMA_OK;++ if (props_size != 4)+ return LZMA_OPTIONS_ERROR;++ lzma_options_bcj *opt = lzma_alloc(+ sizeof(lzma_options_bcj), allocator);+ if (opt == NULL)+ return LZMA_MEM_ERROR;++ opt->start_offset = read32le(props);++ // Don't leave an options structure allocated if start_offset is zero.+ if (opt->start_offset == 0)+ lzma_free(opt, allocator);+ else+ *options = opt;++ return LZMA_OK;+}
+ cbits/liblzma/simple/simple_decoder.h view
@@ -0,0 +1,22 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_decoder.h+/// \brief Properties decoder for simple filters+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_SIMPLE_DECODER_H+#define LZMA_SIMPLE_DECODER_H++#include "simple_coder.h"++extern lzma_ret lzma_simple_props_decode(+ void **options, const lzma_allocator *allocator,+ const uint8_t *props, size_t props_size);++#endif
+ cbits/liblzma/simple/simple_encoder.c view
@@ -0,0 +1,38 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_encoder.c+/// \brief Properties encoder for simple filters+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_encoder.h"+++extern lzma_ret+lzma_simple_props_size(uint32_t *size, const void *options)+{+ const lzma_options_bcj *const opt = options;+ *size = (opt == NULL || opt->start_offset == 0) ? 0 : 4;+ return LZMA_OK;+}+++extern lzma_ret+lzma_simple_props_encode(const void *options, uint8_t *out)+{+ const lzma_options_bcj *const opt = options;++ // The default start offset is zero, so we don't need to store any+ // options unless the start offset is non-zero.+ if (opt == NULL || opt->start_offset == 0)+ return LZMA_OK;++ write32le(out, opt->start_offset);++ return LZMA_OK;+}
+ cbits/liblzma/simple/simple_encoder.h view
@@ -0,0 +1,23 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_encoder.c+/// \brief Properties encoder for simple filters+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_SIMPLE_ENCODER_H+#define LZMA_SIMPLE_ENCODER_H++#include "simple_coder.h"+++extern lzma_ret lzma_simple_props_size(uint32_t *size, const void *options);++extern lzma_ret lzma_simple_props_encode(const void *options, uint8_t *out);++#endif
+ cbits/liblzma/simple/simple_private.h view
@@ -0,0 +1,74 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file simple_private.h+/// \brief Private definitions for so called simple filters+//+// Author: Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#ifndef LZMA_SIMPLE_PRIVATE_H+#define LZMA_SIMPLE_PRIVATE_H++#include "simple_coder.h"+++typedef struct {+ /// Next filter in the chain+ lzma_next_coder next;++ /// True if the next coder in the chain has returned LZMA_STREAM_END.+ bool end_was_reached;++ /// True if filter() should encode the data; false to decode.+ /// Currently all simple filters use the same function for encoding+ /// and decoding, because the difference between encoders and decoders+ /// is very small.+ bool is_encoder;++ /// Pointer to filter-specific function, which does+ /// the actual filtering.+ size_t (*filter)(void *simple, uint32_t now_pos,+ bool is_encoder, uint8_t *buffer, size_t size);++ /// Pointer to filter-specific data, or NULL if filter doesn't need+ /// any extra data.+ void *simple;++ /// The lowest 32 bits of the current position in the data. Most+ /// filters need this to do conversions between absolute and relative+ /// addresses.+ uint32_t now_pos;++ /// Size of the memory allocated for the buffer.+ size_t allocated;++ /// Flushing position in the temporary buffer. buffer[pos] is the+ /// next byte to be copied to out[].+ size_t pos;++ /// buffer[filtered] is the first unfiltered byte. When pos is smaller+ /// than filtered, there is unflushed filtered data in the buffer.+ size_t filtered;++ /// Total number of bytes (both filtered and unfiltered) currently+ /// in the temporary buffer.+ size_t size;++ /// Temporary buffer+ uint8_t buffer[];+} lzma_simple_coder;+++extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters,+ size_t (*filter)(void *simple, uint32_t now_pos,+ bool is_encoder, uint8_t *buffer, size_t size),+ size_t simple_size, size_t unfiltered_max,+ uint32_t alignment, bool is_encoder);++#endif
+ cbits/liblzma/simple/sparc.c view
@@ -0,0 +1,83 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file sparc.c+/// \brief Filter for SPARC binaries+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++static size_t+sparc_code(void *simple lzma_attribute((__unused__)),+ uint32_t now_pos, bool is_encoder,+ uint8_t *buffer, size_t size)+{+ size_t i;+ for (i = 0; i + 4 <= size; i += 4) {++ if ((buffer[i] == 0x40 && (buffer[i + 1] & 0xC0) == 0x00)+ || (buffer[i] == 0x7F+ && (buffer[i + 1] & 0xC0) == 0xC0)) {++ uint32_t src = ((uint32_t)buffer[i + 0] << 24)+ | ((uint32_t)buffer[i + 1] << 16)+ | ((uint32_t)buffer[i + 2] << 8)+ | ((uint32_t)buffer[i + 3]);++ src <<= 2;++ uint32_t dest;+ if (is_encoder)+ dest = now_pos + (uint32_t)(i) + src;+ else+ dest = src - (now_pos + (uint32_t)(i));++ dest >>= 2;++ dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF)+ | (dest & 0x3FFFFF)+ | 0x40000000;++ buffer[i + 0] = (uint8_t)(dest >> 24);+ buffer[i + 1] = (uint8_t)(dest >> 16);+ buffer[i + 2] = (uint8_t)(dest >> 8);+ buffer[i + 3] = (uint8_t)(dest);+ }+ }++ return i;+}+++static lzma_ret+sparc_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters, bool is_encoder)+{+ return lzma_simple_coder_init(next, allocator, filters,+ &sparc_code, 0, 4, 4, is_encoder);+}+++extern lzma_ret+lzma_simple_sparc_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return sparc_coder_init(next, allocator, filters, true);+}+++extern lzma_ret+lzma_simple_sparc_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return sparc_coder_init(next, allocator, filters, false);+}
+ cbits/liblzma/simple/x86.c view
@@ -0,0 +1,159 @@+///////////////////////////////////////////////////////////////////////////////+//+/// \file x86.c+/// \brief Filter for x86 binaries (BCJ filter)+///+// Authors: Igor Pavlov+// Lasse Collin+//+// This file has been put into the public domain.+// You can do whatever you want with this file.+//+///////////////////////////////////////////////////////////////////////////////++#include "simple_private.h"+++#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)+++typedef struct {+ uint32_t prev_mask;+ uint32_t prev_pos;+} lzma_simple_x86;+++static size_t+x86_code(void *simple_ptr, uint32_t now_pos, bool is_encoder,+ uint8_t *buffer, size_t size)+{+ static const bool MASK_TO_ALLOWED_STATUS[8]+ = { true, true, true, false, true, false, false, false };++ static const uint32_t MASK_TO_BIT_NUMBER[8]+ = { 0, 1, 2, 2, 3, 3, 3, 3 };++ lzma_simple_x86 *simple = simple_ptr;+ uint32_t prev_mask = simple->prev_mask;+ uint32_t prev_pos = simple->prev_pos;++ if (size < 5)+ return 0;++ if (now_pos - prev_pos > 5)+ prev_pos = now_pos - 5;++ const size_t limit = size - 5;+ size_t buffer_pos = 0;++ while (buffer_pos <= limit) {+ uint8_t b = buffer[buffer_pos];+ if (b != 0xE8 && b != 0xE9) {+ ++buffer_pos;+ continue;+ }++ const uint32_t offset = now_pos + (uint32_t)(buffer_pos)+ - prev_pos;+ prev_pos = now_pos + (uint32_t)(buffer_pos);++ if (offset > 5) {+ prev_mask = 0;+ } else {+ for (uint32_t i = 0; i < offset; ++i) {+ prev_mask &= 0x77;+ prev_mask <<= 1;+ }+ }++ b = buffer[buffer_pos + 4];++ if (Test86MSByte(b)+ && MASK_TO_ALLOWED_STATUS[(prev_mask >> 1) & 0x7]+ && (prev_mask >> 1) < 0x10) {++ uint32_t src = ((uint32_t)(b) << 24)+ | ((uint32_t)(buffer[buffer_pos + 3]) << 16)+ | ((uint32_t)(buffer[buffer_pos + 2]) << 8)+ | (buffer[buffer_pos + 1]);++ uint32_t dest;+ while (true) {+ if (is_encoder)+ dest = src + (now_pos + (uint32_t)(+ buffer_pos) + 5);+ else+ dest = src - (now_pos + (uint32_t)(+ buffer_pos) + 5);++ if (prev_mask == 0)+ break;++ const uint32_t i = MASK_TO_BIT_NUMBER[+ prev_mask >> 1];++ b = (uint8_t)(dest >> (24 - i * 8));++ if (!Test86MSByte(b))+ break;++ src = dest ^ ((1U << (32 - i * 8)) - 1);+ }++ buffer[buffer_pos + 4]+ = (uint8_t)(~(((dest >> 24) & 1) - 1));+ buffer[buffer_pos + 3] = (uint8_t)(dest >> 16);+ buffer[buffer_pos + 2] = (uint8_t)(dest >> 8);+ buffer[buffer_pos + 1] = (uint8_t)(dest);+ buffer_pos += 5;+ prev_mask = 0;++ } else {+ ++buffer_pos;+ prev_mask |= 1;+ if (Test86MSByte(b))+ prev_mask |= 0x10;+ }+ }++ simple->prev_mask = prev_mask;+ simple->prev_pos = prev_pos;++ return buffer_pos;+}+++static lzma_ret+x86_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,+ const lzma_filter_info *filters, bool is_encoder)+{+ const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters,+ &x86_code, sizeof(lzma_simple_x86), 5, 1, is_encoder);++ if (ret == LZMA_OK) {+ lzma_simple_coder *coder = next->coder;+ lzma_simple_x86 *simple = coder->simple;+ simple->prev_mask = 0;+ simple->prev_pos = (uint32_t)(-5);+ }++ return ret;+}+++extern lzma_ret+lzma_simple_x86_encoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return x86_coder_init(next, allocator, filters, true);+}+++extern lzma_ret+lzma_simple_x86_decoder_init(lzma_next_coder *next,+ const lzma_allocator *allocator,+ const lzma_filter_info *filters)+{+ return x86_coder_init(next, allocator, filters, false);+}
+ cbits/lzma_wrapper.c view
@@ -0,0 +1,65 @@+/*+ * FFI wrappers for `lzma-streams`+ *+ * Copyright (c) 2014, Herbert Valerio Riedel <hvr@gnu.org>+ *+ * This code is BSD3 licensed, see ../LICENSE file for details+ *+ */++#include <stdio.h>+#include <string.h>+#include <lzma.h>+#include <HsFFI.h>++HsInt+hs_lzma_init_decoder(lzma_stream *ls, HsBool autolzma, uint64_t memlimit, uint32_t flags)+{+ /* recommended super-portable initialization */+ const lzma_stream ls_init = LZMA_STREAM_INIT;+ *ls = ls_init;++ const lzma_ret ret = (autolzma ? lzma_auto_decoder : lzma_stream_decoder)(ls, memlimit, flags);++ return ret;+}++HsInt+hs_lzma_init_encoder(lzma_stream *ls, uint32_t preset, HsInt check)+{+ /* recommended super-portable initialization */+ const lzma_stream ls_init = LZMA_STREAM_INIT;+ *ls = ls_init;++ const lzma_ret ret = lzma_easy_encoder(ls, preset, check);++ return ret;+}++void+hs_lzma_done(lzma_stream *ls)+{+ lzma_end(ls);+}++HsInt+hs_lzma_run(lzma_stream *const ls, const HsInt action,+ const uint8_t ibuf[], const HsInt ibuf_len,+ uint8_t obuf[], const HsInt obuf_len)+{+ ls->next_in = ibuf;+ ls->avail_in = ibuf_len;+ ls->next_out = obuf;+ ls->avail_out = obuf_len;++ // paranoia+ memset(obuf, 0, obuf_len);+ + const lzma_ret ret = lzma_code(ls, action);++ // paranoia+ ls->next_in = NULL;+ ls->next_out = NULL;++ return ret;+}
+ lzma-static.cabal view
@@ -0,0 +1,200 @@+cabal-version: 2.2+name: lzma-static+version: 5.2.5++synopsis: LZMA/XZ compression and decompression (static)+homepage: https://github.com/hasufell/lzma-static+bug-reports: https://github.com/hasufell/lzma-static/issues+license: BSD-3-Clause+license-file: LICENSE+author: Julian Ospald+maintainer: hasufell@posteo.de+copyright: (c) 2015, Herbert Valerio Riedel, (c) 2021 Julian Ospald+stability: experimental+category: Codec, Compression+build-type: Simple+tested-with: GHC==8.6.5, GHC==8.8.4, GHC==8.10.4+description:+ This package provides a pure interface for compressing and+ decompressing+ <https://en.wikipedia.org/wiki/LZMA LZMA (Lempel–Ziv–Markov chain algorithm)>+ streams of data represented as lazy @ByteString@s. A+ monadic incremental interface is provided as well. This package+ relies on the <http://tukaani.org/xz/ liblzma C library>.++extra-source-files:+ Changelog.md+ autoconf-darwin/config.h+ autoconf-linux/config.h+ autoconf-win32/config.h+ cbits/common/*.c+ cbits/common/*.h+ cbits/liblzma/api/lzma.h+ cbits/liblzma/api/lzma/*.h+ cbits/liblzma/check/*.c+ cbits/liblzma/check/*.h+ cbits/liblzma/common/*.c+ cbits/liblzma/common/*.h+ cbits/liblzma/delta/*.c+ cbits/liblzma/delta/*.h+ cbits/liblzma/lz/*.c+ cbits/liblzma/lz/*.h+ cbits/liblzma/lzma/*.c+ cbits/liblzma/lzma/*.h+ cbits/liblzma/rangecoder/*.c+ cbits/liblzma/rangecoder/*.h+ cbits/liblzma/simple/*.c+ cbits/liblzma/simple/*.h++source-repository head+ type: git+ location: https://github.com/hasufell/lzma-static.git++library+ default-language: Haskell2010+ other-extensions: BangPatterns, RecordWildCards, DeriveDataTypeable+ hs-source-dirs: src++ exposed-modules: Codec.Compression.Lzma+ other-modules: LibLzma++ build-depends: base >=4.5 && <4.15+ , bytestring >=0.9.2 && <0.11++ if os(windows)+ include-dirs: autoconf-win32+ elif os(darwin)+ include-dirs: autoconf-darwin+ elif os(linux)+ include-dirs: autoconf-linux+ else+ build-depends: unbuildable<0+ buildable: False++ c-sources:+ cbits/lzma_wrapper.c+ cbits/common/tuklib_cpucores.c+ cbits/common/tuklib_physmem.c+ cbits/liblzma/check/check.c+ cbits/liblzma/check/crc32_fast.c+ cbits/liblzma/check/crc32_table.c+ cbits/liblzma/check/crc64_fast.c+ cbits/liblzma/check/crc64_table.c+ cbits/liblzma/check/sha256.c+ cbits/liblzma/common/alone_decoder.c+ cbits/liblzma/common/alone_encoder.c+ cbits/liblzma/common/auto_decoder.c+ cbits/liblzma/common/block_buffer_decoder.c+ cbits/liblzma/common/block_buffer_encoder.c+ cbits/liblzma/common/block_decoder.c+ cbits/liblzma/common/block_encoder.c+ cbits/liblzma/common/block_header_decoder.c+ cbits/liblzma/common/block_header_encoder.c+ cbits/liblzma/common/block_util.c+ cbits/liblzma/common/common.c+ cbits/liblzma/common/easy_buffer_encoder.c+ cbits/liblzma/common/easy_decoder_memusage.c+ cbits/liblzma/common/easy_encoder.c+ cbits/liblzma/common/easy_encoder_memusage.c+ cbits/liblzma/common/easy_preset.c+ cbits/liblzma/common/filter_buffer_decoder.c+ cbits/liblzma/common/filter_buffer_encoder.c+ cbits/liblzma/common/filter_common.c+ cbits/liblzma/common/filter_decoder.c+ cbits/liblzma/common/filter_encoder.c+ cbits/liblzma/common/filter_flags_decoder.c+ cbits/liblzma/common/filter_flags_encoder.c+ cbits/liblzma/common/hardware_cputhreads.c+ cbits/liblzma/common/hardware_physmem.c+ cbits/liblzma/common/index.c+ cbits/liblzma/common/index_decoder.c+ cbits/liblzma/common/index_encoder.c+ cbits/liblzma/common/index_hash.c+ cbits/liblzma/common/outqueue.c+ cbits/liblzma/common/stream_buffer_decoder.c+ cbits/liblzma/common/stream_buffer_encoder.c+ cbits/liblzma/common/stream_decoder.c+ cbits/liblzma/common/stream_encoder.c+ cbits/liblzma/common/stream_encoder_mt.c+ cbits/liblzma/common/stream_flags_common.c+ cbits/liblzma/common/stream_flags_decoder.c+ cbits/liblzma/common/stream_flags_encoder.c+ cbits/liblzma/common/vli_decoder.c+ cbits/liblzma/common/vli_encoder.c+ cbits/liblzma/common/vli_size.c+ cbits/liblzma/delta/delta_common.c+ cbits/liblzma/delta/delta_decoder.c+ cbits/liblzma/delta/delta_encoder.c+ cbits/liblzma/lz/lz_decoder.c+ cbits/liblzma/lz/lz_encoder.c+ cbits/liblzma/lz/lz_encoder_mf.c+ cbits/liblzma/lzma/fastpos_table.c+ cbits/liblzma/lzma/lzma2_decoder.c+ cbits/liblzma/lzma/lzma2_encoder.c+ cbits/liblzma/lzma/lzma_decoder.c+ cbits/liblzma/lzma/lzma_encoder.c+ cbits/liblzma/lzma/lzma_encoder_optimum_fast.c+ cbits/liblzma/lzma/lzma_encoder_optimum_normal.c+ cbits/liblzma/lzma/lzma_encoder_presets.c+ cbits/liblzma/rangecoder/price_table.c+ cbits/liblzma/simple/arm.c+ cbits/liblzma/simple/armthumb.c+ cbits/liblzma/simple/ia64.c+ cbits/liblzma/simple/powerpc.c+ cbits/liblzma/simple/simple_coder.c+ cbits/liblzma/simple/simple_decoder.c+ cbits/liblzma/simple/simple_encoder.c+ cbits/liblzma/simple/sparc.c+ cbits/liblzma/simple/x86.c++ include-dirs:+ cbits/liblzma/api+ cbits/liblzma/common+ cbits/liblzma/check+ cbits/liblzma/delta+ cbits/liblzma/lz+ cbits/liblzma/lzma+ cbits/liblzma/rangecoder+ cbits/liblzma/simple+ cbits/common++ install-includes:+ lzma.h+ lzma/base.h+ lzma/bcj.h+ lzma/block.h+ lzma/check.h+ lzma/container.h+ lzma/delta.h+ lzma/filter.h+ lzma/hardware.h+ lzma/index.h+ lzma/index_hash.h+ lzma/lzma12.h+ lzma/stream_flags.h+ lzma/version.h+ lzma/vli.h++ cc-options: -std=gnu99 -DHAVE_CONFIG_H -DTUKLIB_SYMBOL_PREFIX=lzma_+ ghc-options: -Wall+++test-suite lzma-tests+ default-language: Haskell2010+ other-extensions: OverloadedStrings+ hs-source-dirs: src-tests+ type: exitcode-stdio-1.0+ main-is: lzma-tests.hs++ -- dependencies with version bounds inherited from the library stanza+ build-depends: lzma-static+ , base+ , bytestring+ -- additional dependencies that require version bounds+ build-depends: HUnit >= 1.2 && <1.7+ , QuickCheck >= 2.8 && <2.14+ , tasty >= 0.10 && <1.4+ , tasty-hunit >= 0.9 && <0.11+ , tasty-quickcheck >= 0.8.3.2 && <0.11++ ghc-options: -Wall -threaded
+ src-tests/lzma-tests.hs view
@@ -0,0 +1,98 @@+module Main (main) where++import Control.Applicative+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Lazy.Char8 as BL8+import Data.List+import Data.Monoid+import Prelude++import Test.Tasty+import Test.Tasty.QuickCheck as QC+import Test.Tasty.HUnit++import Codec.Compression.Lzma as Lzma++main :: IO ()+main = defaultMain tests++-- this is supposed to be equivalent to 'id'+codecompress :: BL.ByteString -> BL.ByteString+codecompress = decompress . compress++newtype ZeroBS = ZeroBS BL.ByteString++instance Show ZeroBS where+ show (ZeroBS s) | BL.length s > 0 = "ZeroBS (replicate " ++ show (BL.length s) ++ " " ++ show (BL.head s) ++ ")"+ | otherwise = "ZeroBS (empty)"++instance Arbitrary ZeroBS where+ arbitrary = do+ len <- choose (0, 1*1024*1024) -- up to 1MiB+ return $ (ZeroBS $ BL.replicate len 0)++-- shrink (ABS bs) = map ABS $ shrinks bs++randBS :: Int -> Gen BS.ByteString+randBS n = BS.pack `fmap` vectorOf n (choose (0, 255))++randBL :: Gen BL.ByteString+randBL = do+ ns <- arbitrary+ chunks <- mapM (randBS . (`mod` 10240)) ns+ return $ BL.fromChunks chunks++newtype RandBLSm = RandBLSm BL.ByteString+ deriving Show++newtype RandBL = RandBL BL.ByteString+ deriving Show++instance Arbitrary RandBL where+ arbitrary = RandBL <$> randBL++instance Arbitrary RandBLSm where+ arbitrary = do+ n <- choose (0,1024)+ RandBLSm . BL.fromChunks . (:[]) <$> randBS n++tests :: TestTree+tests = testGroup "ByteString API" [unitTests, properties]+ where+ unitTests = testGroup "testcases"+ [ testCase "decode-empty" $ decompress nullxz @?= BL.empty+ , testCase "encode-empty" $ codecompress BL.empty @?= BL.empty+ , testCase "encode-hello" $ codecompress (BL8.pack "hello") @?= BL8.pack "hello"+ , testCase "encode-hello2" $ codecompress (singletonChunked $ BL8.pack "hello") @?= BL8.pack "hello"+ , testCase "decode-sample" $ decompress samplexz @?= sampleref+ , testCase "decode-sample2" $ decompress (singletonChunked samplexz) @?= sampleref+ , testCase "encode-sample" $ codecompress sampleref @?= sampleref+ , testCase "encode-empty^50" $ (iterate decompress (iterate (compressWith lowProf) (BL8.pack "") !! 50) !! 50) @?= BL8.pack ""+ , testCase "encode-10MiB-zeros" $ let z = BL.replicate (10*1024*1024) 0 in codecompress z @?= z+ ]++ properties = testGroup "properties"+ [ QC.testProperty "decompress . compress === id (zeros)" $+ \(ZeroBS bs) -> codecompress bs == bs++ , QC.testProperty "decompress . compress === id (chunked)" $+ \(RandBL bs) -> codecompress bs == bs++ , QC.testProperty "decompress . (compress a <> compress b) === a <> b" $+ \(RandBLSm a) (RandBLSm b) -> decompress (compress a `mappend` compress b) == a `mappend` b+ ]++ lowProf = defaultCompressParams { compressLevel = CompressionLevel0 }++nullxz :: BL.ByteString+nullxz = BL.pack [253,55,122,88,90,0,0,4,230,214,180,70,0,0,0,0,28,223,68,33,31,182,243,125,1,0,0,0,0,4,89,90]++samplexz :: BL.ByteString+samplexz = BL.pack [253,55,122,88,90,0,0,4,230,214,180,70,2,0,33,1,16,0,0,0,168,112,142,134,224,1,149,0,44,93,0,42,26,9,39,100,25,234,181,131,189,58,102,36,15,228,64,252,88,41,53,203,78,255,4,93,168,153,174,39,186,76,120,56,49,148,191,144,96,136,20,247,240,0,0,0,157,204,158,16,53,174,37,20,0,1,72,150,3,0,0,0,130,33,173,108,177,196,103,251,2,0,0,0,0,4,89,90]++singletonChunked :: BL.ByteString -> BL.ByteString+singletonChunked = BL.fromChunks . map BS.singleton . BL.unpack++sampleref :: BL.ByteString+sampleref = BL.concat (intersperse (BL8.pack " ") $ replicate 11 $ BL8.pack "This sentence occurs multiple times.")
+ src/Codec/Compression/Lzma.hs view
@@ -0,0 +1,400 @@+{-# LANGUAGE BangPatterns #-}++-- |+-- Module : Codec.Compression.Lzma+-- Copyright : © 2015 Herbert Valerio Riedel+-- License : BSD3+--+-- Maintainer : hvr@gnu.org+-- Stability : experimental+--+-- Compression and decompression of data streams in the lzma/xz format+--+-- See also the XZ Utils home page: <http://tukaani.org/xz/>+module Codec.Compression.Lzma+ ( -- * Simple (de)compression+ compress+ , decompress++ -- * Extended API with control over parameters+ , compressWith+ , decompressWith++ -- * Monadic incremental (de)compression API+ --+ -- | See <http://hackage.haskell.org/package/zlib-0.6.1.1/docs/Codec-Compression-Zlib-Internal.html#g:2 zlib's incremental API documentation> for more information.++ -- ** Compression+ , CompressStream(..)+ , compressIO+ , compressST++ -- ** Decompression+ , DecompressStream(..)+ , decompressIO+ , decompressST+ , LzmaRet(..)++ -- * Parameters+ -- ** Compression parameters+ , defaultCompressParams++ , CompressParams+ , compressIntegrityCheck+ , compressLevel+ , compressLevelExtreme++ , IntegrityCheck(..)+ , CompressionLevel(..)++ -- ** Decompression parameters+ , defaultDecompressParams++ , DecompressParams+ , decompressTellNoCheck+ , decompressTellUnsupportedCheck+ , decompressTellAnyCheck+ , decompressConcatenated+ , decompressAutoDecoder+ , decompressMemLimit+ ) where++import Control.Exception+import Control.Monad+import Control.Monad.ST (stToIO)+import Control.Monad.ST.Lazy (ST, runST, strictToLazyST)+import qualified Control.Monad.ST.Strict as ST.Strict (ST)+import Control.Monad.ST.Unsafe (unsafeIOToST)+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL+import qualified Data.ByteString.Lazy.Internal as BSL+import GHC.IO (noDuplicate)+import LibLzma++-- | Decompress lazy 'ByteString' from the @.xz@ format+decompress :: BSL.ByteString -> BSL.ByteString+decompress = decompressWith defaultDecompressParams++-- | Like 'decompress' but with the ability to specify various decompression+-- parameters. Typical usage:+--+-- > decompressWith defaultDecompressParams { decompress... = ... }+decompressWith :: DecompressParams -> BSL.ByteString -> BSL.ByteString+decompressWith parms input = runST (decompress' input)+ where+ decompress' :: BSL.ByteString -> ST s BSL.ByteString+ decompress' ibs0 = loop ibs0 =<< decompressST parms+ where+ loop BSL.Empty (DecompressStreamEnd rest)+ | BS.null rest = return BSL.Empty+ | otherwise = fail "Codec.Compression.Lzma.decompressWith: trailing data"+ loop (BSL.Chunk _ _) (DecompressStreamEnd _) =+ fail "Codec.Compression.Lzma.decompressWith: trailing data"+ loop _ (DecompressStreamError e) =+ fail ("Codec.Compression.Lzma.decompressWith: decoding error " ++ show e)+ loop BSL.Empty (DecompressInputRequired supply) =+ loop BSL.Empty =<< supply BS.empty+ loop (BSL.Chunk c bs') (DecompressInputRequired supply) =+ loop bs' =<< supply c+ loop ibs (DecompressOutputAvailable oc next) = do+ obs <- loop ibs =<< next+ return (BSL.chunk oc obs)++{-# NOINLINE decompressWith #-}++----------------------------------------------------------------------------+----------------------------------------------------------------------------++-- | Compress lazy 'ByteString' into @.xz@ format using 'defaultCompressParams'.+compress :: BSL.ByteString -> BSL.ByteString+compress = compressWith defaultCompressParams++-- | Like 'compress' but with the ability to specify various compression+-- parameters. Typical usage:+--+-- > compressWith defaultCompressParams { compress... = ... }+compressWith :: CompressParams -> BSL.ByteString -> BSL.ByteString+compressWith parms input = runST (compress' input)+ where+ compress' :: BSL.ByteString -> ST s BSL.ByteString+ compress' ibs0 = loop ibs0 =<< compressST parms+ where+ loop BSL.Empty CompressStreamEnd =+ return BSL.Empty+ loop (BSL.Chunk _ _) CompressStreamEnd =+ fail "Codec.Compression.Lzma.compressWith: the impossible happened"+ loop BSL.Empty (CompressInputRequired _ supply) =+ loop BSL.Empty =<< supply BS.empty+ loop (BSL.Chunk c bs') (CompressInputRequired _ supply) =+ loop bs' =<< supply c+ loop ibs (CompressOutputAvailable oc next) = do+ obs <- loop ibs =<< next+ return (BSL.chunk oc obs)+{-# NOINLINE compressWith #-}++--------------------------------------------------------------------------------+--------------------------------------------------------------------------------++-- Type derived from 'zlib' and augmented with flushing support++data CompressStream m =+ CompressInputRequired {- flush -} (m (CompressStream m))+ {- supply -} (ByteString -> m (CompressStream m))+ -- ^ Compression process requires input to proceed. You can+ -- either flush the stream (first field), supply an input chunk+ -- (second field), or signal the end of input (via empty+ -- chunk).+ | CompressOutputAvailable !ByteString (m (CompressStream m)) -- ^ Output chunk available.+ | CompressStreamEnd++-- | Incremental compression in the 'IO' monad.+compressIO :: CompressParams -> IO (CompressStream IO)+compressIO parms = (stToIO $ newEncodeLzmaStream parms) >>= either throwIO go+ where+ bUFSIZ = 32752++ go :: LzmaStream -> IO (CompressStream IO)+ go ls = return inputRequired+ where+ inputRequired = CompressInputRequired goFlush (withChunk goFinish goInput)++ goInput :: ByteString -> IO (CompressStream IO)+ goInput chunk = do+ (rc, used, obuf) <- stToIO $ runLzmaStream ls chunk LzmaRun bUFSIZ++ let chunk' = BS.drop used chunk++ case rc of+ LzmaRetOK+ | BS.null obuf -> do+ unless (used > 0) $+ fail "compressIO: input chunk not consumed"+ withChunk (return inputRequired) goInput chunk'+ | otherwise -> return (CompressOutputAvailable obuf+ (withChunk (return inputRequired) goInput chunk'))++ _ -> throwIO rc++ goFlush, goFinish :: IO (CompressStream IO)+ goFlush = goSync LzmaSyncFlush (return inputRequired)+ goFinish = goSync LzmaFinish retStreamEnd++ -- drain encoder till LzmaRetStreamEnd is reported+ goSync :: LzmaAction -> IO (CompressStream IO) -> IO (CompressStream IO)+ goSync LzmaRun _ = fail "goSync called with invalid argument"+ goSync action next = goSync'+ where+ goSync' = do+ (rc, 0, obuf) <- stToIO $ runLzmaStream ls BS.empty action bUFSIZ+ case rc of+ LzmaRetOK+ | BS.null obuf -> fail ("compressIO: empty output chunk during " ++ show action)+ | otherwise -> return (CompressOutputAvailable obuf goSync')+ LzmaRetStreamEnd+ | BS.null obuf -> next+ | otherwise -> return (CompressOutputAvailable obuf next)+ _ -> throwIO rc++ retStreamEnd = do+ !() <- stToIO (endLzmaStream ls)+ return CompressStreamEnd++-- | Incremental compression in the lazy 'ST' monad.+compressST :: CompressParams -> ST s (CompressStream (ST s))+compressST parms = strictToLazyST (newEncodeLzmaStream parms) >>=+ either throw go+ where+ bUFSIZ = 32752++ go ls = return inputRequired+ where+ inputRequired = CompressInputRequired goFlush (withChunk goFinish goInput)++ goInput :: ByteString -> ST s (CompressStream (ST s))+ goInput chunk = do+ (rc, used, obuf) <- strictToLazyST (noDuplicateST >>+ runLzmaStream ls chunk LzmaRun bUFSIZ)++ let chunk' = BS.drop used chunk++ case rc of+ LzmaRetOK+ | BS.null obuf -> do+ unless (used > 0) $+ fail "compressST: input chunk not consumed"+ withChunk (return inputRequired) goInput chunk'+ | otherwise -> return (CompressOutputAvailable obuf+ (withChunk (return inputRequired) goInput chunk'))++ _ -> throw rc++ goFlush, goFinish :: ST s (CompressStream (ST s))+ goFlush = goSync LzmaSyncFlush (return inputRequired)+ goFinish = goSync LzmaFinish retStreamEnd++ -- drain encoder till LzmaRetStreamEnd is reported+ goSync :: LzmaAction -> ST s (CompressStream (ST s)) -> ST s (CompressStream (ST s))+ goSync LzmaRun _ = fail "compressST: goSync called with invalid argument"+ goSync action next = goSync'+ where+ goSync' = do+ (rc, 0, obuf) <- strictToLazyST (noDuplicateST >>+ runLzmaStream ls BS.empty action bUFSIZ)+ case rc of+ LzmaRetOK+ | BS.null obuf -> fail ("compressIO: empty output chunk during " ++ show action)+ | otherwise -> return (CompressOutputAvailable obuf goSync')+ LzmaRetStreamEnd+ | BS.null obuf -> next+ | otherwise -> return (CompressOutputAvailable obuf next)+ _ -> throw rc++ retStreamEnd = do+ !() <- strictToLazyST (noDuplicateST >> endLzmaStream ls)+ return CompressStreamEnd++--------------------------------------------------------------------------------++data DecompressStream m =+ DecompressInputRequired (ByteString -> m (DecompressStream m)) -- ^ Decoding process requires input to proceed. An empty 'ByteString' chunk signals end of input.+ | DecompressOutputAvailable !ByteString (m (DecompressStream m)) -- ^ Decompressed output chunk available.+ | DecompressStreamEnd ByteString -- ^ Decoded stream is finished. Any unconsumed leftovers from the input stream are returned via the 'ByteString' field+ | DecompressStreamError !LzmaRet -- TODO define subset-enum of LzmaRet++-- | Incremental decompression in the 'IO' monad.+decompressIO :: DecompressParams -> IO (DecompressStream IO)+decompressIO parms = stToIO (newDecodeLzmaStream parms) >>= either (return . DecompressStreamError) go+ where+ bUFSIZ = 32752++ go :: LzmaStream -> IO (DecompressStream IO)+ go ls = return inputRequired+ where+ inputRequired = DecompressInputRequired goInput++ goInput :: ByteString -> IO (DecompressStream IO)+ goInput chunk+ | BS.null chunk = goFinish+ | otherwise = do+ (rc, used, obuf) <- stToIO $ runLzmaStream ls chunk LzmaRun bUFSIZ++ let chunk' = BS.drop used chunk++ case rc of+ LzmaRetOK+ | BS.null obuf -> do+ unless (used > 0) $+ fail "decompressIO: input chunk not consumed"+ withChunk (return inputRequired) goInput chunk'+ | otherwise -> return (DecompressOutputAvailable obuf+ (withChunk goDrain goInput chunk'))++ LzmaRetStreamEnd+ | BS.null obuf -> retStreamEnd chunk'+ | otherwise -> return (DecompressOutputAvailable obuf+ (retStreamEnd chunk'))++ _ -> return (DecompressStreamError rc)++ goDrain, goFinish :: IO (DecompressStream IO)+ goDrain = goSync LzmaRun (return inputRequired)+ goFinish = goSync LzmaFinish (return $ DecompressStreamError LzmaRetOK)++ goSync :: LzmaAction -> IO (DecompressStream IO) -> IO (DecompressStream IO)+ goSync action next = goSync'+ where+ goSync' = do+ (rc, 0, obuf) <- stToIO $ runLzmaStream ls BS.empty action bUFSIZ+ case rc of+ LzmaRetOK+ | BS.null obuf -> next+ | otherwise -> return (DecompressOutputAvailable obuf goSync')++ LzmaRetStreamEnd+ | BS.null obuf -> eof0+ | otherwise -> return (DecompressOutputAvailable obuf eof0)++ _ -> return (DecompressStreamError rc)++ eof0 = retStreamEnd BS.empty++ retStreamEnd chunk' = do+ !() <- stToIO (endLzmaStream ls)+ return (DecompressStreamEnd chunk')++-- | Incremental decompression in the lazy 'ST' monad.+decompressST :: DecompressParams -> ST s (DecompressStream (ST s))+decompressST parms = strictToLazyST (newDecodeLzmaStream parms) >>=+ either (return . DecompressStreamError) go+ where+ bUFSIZ = 32752++ go :: LzmaStream -> ST s (DecompressStream (ST s))+ go ls = return inputRequired+ where+ inputRequired = DecompressInputRequired goInput++ goInput :: ByteString -> ST s (DecompressStream (ST s))+ goInput chunk+ | BS.null chunk = goFinish+ | otherwise = do+ (rc, used, obuf) <- strictToLazyST (noDuplicateST >>+ runLzmaStream ls chunk LzmaRun bUFSIZ)++ let chunk' = BS.drop used chunk++ case rc of+ LzmaRetOK+ | BS.null obuf -> do+ unless (used > 0) $+ fail "decompressST: input chunk not consumed"+ withChunk (return inputRequired) goInput chunk'+ | otherwise -> return (DecompressOutputAvailable obuf+ (withChunk goDrain goInput chunk'))++ LzmaRetStreamEnd+ | BS.null obuf -> retStreamEnd chunk'+ | otherwise -> return (DecompressOutputAvailable obuf+ (retStreamEnd chunk'))++ _ -> return (DecompressStreamError rc)+++ goDrain, goFinish :: ST s (DecompressStream (ST s))+ goDrain = goSync LzmaRun (return inputRequired)+ goFinish = goSync LzmaFinish (return $ DecompressStreamError LzmaRetOK)++ goSync :: LzmaAction -> ST s (DecompressStream (ST s)) -> ST s (DecompressStream (ST s))+ goSync action next = goSync'+ where+ goSync' = do+ (rc, 0, obuf) <- strictToLazyST (noDuplicateST >>+ runLzmaStream ls BS.empty action bUFSIZ)+ case rc of+ LzmaRetOK+ | BS.null obuf -> next+ | otherwise -> return (DecompressOutputAvailable obuf goSync')++ LzmaRetStreamEnd+ | BS.null obuf -> eof0+ | otherwise -> return (DecompressOutputAvailable obuf eof0)++ _ -> return (DecompressStreamError rc)++ eof0 = retStreamEnd BS.empty++ retStreamEnd chunk' = do+ !() <- strictToLazyST (noDuplicateST >> endLzmaStream ls)+ return (DecompressStreamEnd chunk')++-- | Small 'maybe'-ish helper distinguishing between empty and+-- non-empty 'ByteString's+withChunk :: t -> (ByteString -> t) -> ByteString -> t+withChunk emptyChunk nemptyChunk chunk+ | BS.null chunk = emptyChunk+ | otherwise = nemptyChunk chunk++-- | See <https://github.com/haskell/zlib/issues/7>+noDuplicateST :: ST.Strict.ST s ()+noDuplicateST = unsafeIOToST noDuplicate
+ src/LibLzma.hsc view
@@ -0,0 +1,251 @@+{-# LANGUAGE RecordWildCards, DeriveDataTypeable #-}++-- Copyright (c) 2014, Herbert Valerio Riedel <hvr@gnu.org>+--+-- This code is BSD3 licensed, see ../LICENSE file for details+--++-- | Internal low-level bindings to liblzma+--+-- See @<lzma.h>@ header file for documentation about primitives not+-- documented here+module LibLzma+ ( LzmaStream+ , LzmaRet(..)+ , IntegrityCheck(..)+ , CompressionLevel(..)++ , newDecodeLzmaStream+ , DecompressParams(..)+ , defaultDecompressParams++ , newEncodeLzmaStream+ , CompressParams(..)+ , defaultCompressParams++ , runLzmaStream+ , endLzmaStream+ , LzmaAction(..)+ ) where++import Control.Applicative+import Control.Exception+import Control.Monad+import Control.Monad.ST.Strict (ST)+import Control.Monad.ST.Unsafe (unsafeIOToST)+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BS+import qualified Data.ByteString.Unsafe as BS+import Data.Typeable+import Foreign+import Prelude++#include <lzma.h>++newtype LzmaStream = LS (ForeignPtr LzmaStream)++data LzmaRet = LzmaRetOK+ | LzmaRetStreamEnd+ | LzmaRetUnsupportedCheck+ | LzmaRetGetCheck+ | LzmaRetMemError+ | LzmaRetMemlimitError+ | LzmaRetFormatError+ | LzmaRetOptionsError+ | LzmaRetDataError+ | LzmaRetBufError+ | LzmaRetProgError+ deriving (Eq,Ord,Read,Show,Typeable)++instance Exception LzmaRet++toLzmaRet :: Int -> Maybe LzmaRet+toLzmaRet i = case i of+ (#const LZMA_OK ) -> Just LzmaRetOK+ (#const LZMA_STREAM_END ) -> Just LzmaRetStreamEnd+ (#const LZMA_UNSUPPORTED_CHECK) -> Just LzmaRetUnsupportedCheck+ (#const LZMA_GET_CHECK ) -> Just LzmaRetGetCheck+ (#const LZMA_MEM_ERROR ) -> Just LzmaRetMemError+ (#const LZMA_MEMLIMIT_ERROR ) -> Just LzmaRetMemlimitError+ (#const LZMA_FORMAT_ERROR ) -> Just LzmaRetFormatError+ (#const LZMA_OPTIONS_ERROR ) -> Just LzmaRetOptionsError+ (#const LZMA_DATA_ERROR ) -> Just LzmaRetDataError+ (#const LZMA_BUF_ERROR ) -> Just LzmaRetBufError+ (#const LZMA_PROG_ERROR ) -> Just LzmaRetProgError+ _ -> Nothing++-- | Integrity check type (only supported when compressing @.xz@ files)+data IntegrityCheck = IntegrityCheckNone -- ^ disable integrity check (not recommended)+ | IntegrityCheckCrc32 -- ^ CRC32 using the polynomial from IEEE-802.3+ | IntegrityCheckCrc64 -- ^ CRC64 using the polynomial from ECMA-182+ | IntegrityCheckSha256 -- ^ SHA-256+ deriving (Eq,Ord,Read,Show,Typeable)++fromIntegrityCheck :: IntegrityCheck -> Int+fromIntegrityCheck lc = case lc of+ IntegrityCheckNone -> #const LZMA_CHECK_NONE+ IntegrityCheckCrc32 -> #const LZMA_CHECK_CRC32+ IntegrityCheckCrc64 -> #const LZMA_CHECK_CRC64+ IntegrityCheckSha256 -> #const LZMA_CHECK_SHA256++-- | Compression level presets that define the tradeoff between+-- computational complexity and compression ratio+--+-- 'CompressionLevel0' has the lowest compression ratio as well as the+-- lowest memory requirements, whereas 'CompressionLevel9' has the+-- highest compression ratio and can require over 600MiB during+-- compression (and over 60MiB during decompression). The+-- <https://www.freebsd.org/cgi/man.cgi?query=xz&sektion=1&manpath=FreeBSD+10.2-stable&arch=default&format=html man-page for xz(1)>+-- contains more detailed information with tables describing the+-- properties of all compression level presets.+--+-- 'CompressionLevel6' is the default setting in+-- 'defaultCompressParams' as it provides a good trade-off and+-- matches the default of the @xz(1)@ tool.++data CompressionLevel = CompressionLevel0+ | CompressionLevel1+ | CompressionLevel2+ | CompressionLevel3+ | CompressionLevel4+ | CompressionLevel5+ | CompressionLevel6+ | CompressionLevel7+ | CompressionLevel8+ | CompressionLevel9+ deriving (Eq,Ord,Read,Show,Enum,Typeable)++-- | Set of parameters for decompression. The defaults are+-- 'defaultDecompressParams'.+data DecompressParams = DecompressParams+ { decompressTellNoCheck :: !Bool -- ^ 'DecompressParams' field: If set, abort if decoded stream has no integrity check.+ , decompressTellUnsupportedCheck :: !Bool -- ^ 'DecompressParams' field: If set, abort (via 'LzmaRetGetCheck') if decoded stream integrity check is unsupported.+ , decompressTellAnyCheck :: !Bool -- ^ 'DecompressParams' field: If set, abort (via 'LzmaRetGetCheck') as soon as the type of the integrity check has been detected.+ , decompressConcatenated :: !Bool -- ^ 'DecompressParams' field: If set, concatenated files as decoded seamless.+ , decompressAutoDecoder :: !Bool -- ^ 'DecompressParams' field: If set, legacy @.lzma@-encoded streams are allowed too.+ , decompressMemLimit :: !Word64 -- ^ 'DecompressParams' field: decompressor memory limit. Set to 'maxBound' to disable memory limit.+ } deriving (Eq,Show)++-- | The default set of parameters for decompression. This is+-- typically used with the 'decompressWith' function with specific+-- parameters overridden.+defaultDecompressParams :: DecompressParams+defaultDecompressParams = DecompressParams {..}+ where+ decompressTellNoCheck = False+ decompressTellUnsupportedCheck = False+ decompressTellAnyCheck = False+ decompressConcatenated = True+ decompressAutoDecoder = False+ decompressMemLimit = maxBound -- disables limit-check++-- | Set of parameters for compression. The defaults are 'defaultCompressParams'.+data CompressParams = CompressParams+ { compressIntegrityCheck :: !IntegrityCheck -- ^ 'CompressParams' field: Specify type of integrity check+ , compressLevel :: !CompressionLevel -- ^ 'CompressParams' field: See documentation of 'CompressionLevel'+ , compressLevelExtreme :: !Bool -- ^ 'CompressParams' field: Enable slower variant of the+ -- 'lzmaCompLevel' preset, see @xz(1)@+ -- man-page for details.+ } deriving (Eq,Show)++-- | The default set of parameters for compression. This is typically+-- used with the 'compressWith' function with specific parameters+-- overridden.+defaultCompressParams :: CompressParams+defaultCompressParams = CompressParams {..}+ where+ compressIntegrityCheck = IntegrityCheckCrc64+ compressLevel = CompressionLevel6+ compressLevelExtreme = False++newDecodeLzmaStream :: DecompressParams -> ST s (Either LzmaRet LzmaStream)+newDecodeLzmaStream (DecompressParams {..}) = unsafeIOToST $ do+ fp <- mallocForeignPtrBytes (#size lzma_stream)+ addForeignPtrFinalizer c_hs_lzma_done_funptr fp+ rc <- withForeignPtr fp (\ptr -> c_hs_lzma_init_decoder ptr decompressAutoDecoder decompressMemLimit flags')+ rc' <- maybe (fail "newDecodeLzmaStream: invalid return code") pure $ toLzmaRet rc++ return $ case rc' of+ LzmaRetOK -> Right (LS fp)+ _ -> Left rc'+ where+ flags' =+ (if decompressTellNoCheck then (#const LZMA_TELL_NO_CHECK) else 0) .|.+ (if decompressTellUnsupportedCheck then (#const LZMA_TELL_UNSUPPORTED_CHECK) else 0) .|.+ (if decompressTellAnyCheck then (#const LZMA_TELL_ANY_CHECK) else 0) .|.+ (if decompressConcatenated then (#const LZMA_CONCATENATED) else 0)++newEncodeLzmaStream :: CompressParams -> ST s (Either LzmaRet LzmaStream)+newEncodeLzmaStream (CompressParams {..}) = unsafeIOToST $ do+ fp <- mallocForeignPtrBytes (#size lzma_stream)+ addForeignPtrFinalizer c_hs_lzma_done_funptr fp+ rc <- withForeignPtr fp (\ptr -> c_hs_lzma_init_encoder ptr preset check)+ rc' <- maybe (fail "newDecodeLzmaStream: invalid return code") pure $ toLzmaRet rc++ return $ case rc' of+ LzmaRetOK -> Right (LS fp)+ _ -> Left rc'++ where+ preset = fromIntegral (fromEnum compressLevel) .|.+ (if compressLevelExtreme then (#const LZMA_PRESET_EXTREME) else 0)+ check = fromIntegrityCheck compressIntegrityCheck++data LzmaAction = LzmaRun+ | LzmaSyncFlush+ | LzmaFullFlush+ | LzmaFinish+ deriving (Eq,Show)++runLzmaStream :: LzmaStream -> ByteString -> LzmaAction -> Int -> ST s (LzmaRet,Int,ByteString)+runLzmaStream (LS ls) ibs action0 buflen+ | buflen <= 0 = return (LzmaRetOptionsError,0,BS.empty)+ | otherwise = unsafeIOToST $ withForeignPtr ls $ \lsptr ->+ BS.unsafeUseAsCStringLen ibs $ \(ibsptr, ibslen) -> do+ (obuf,rc) <- BS.createAndTrim' buflen $ \bufptr -> do+ rc' <- c_hs_lzma_run lsptr action (castPtr ibsptr) ibslen bufptr buflen+ rc'' <- maybe (fail "runLzmaStream: invalid return code") pure $ toLzmaRet rc'++ availOut <- (#peek lzma_stream, avail_out) lsptr+ unless (buflen >= availOut && availOut >= 0) $+ fail "runLzmaStream: invalid avail_out"+ let produced = buflen - availOut++ return (0, produced, rc'')++ availIn <- (#peek lzma_stream, avail_in) lsptr+ unless (ibslen >= availIn && availIn >= 0) $+ fail "runLzmaStream: invalid avail_in"+ let consumed = ibslen - availIn+ -- print ("run", action0, BS.length ibs, buflen, rc, consumed, BS.length obuf)++ return (rc, fromIntegral consumed, obuf)+ where+ action = case action0 of+ LzmaRun -> #const LZMA_RUN+ LzmaSyncFlush -> #const LZMA_SYNC_FLUSH+ LzmaFullFlush -> #const LZMA_FULL_FLUSH+ LzmaFinish -> #const LZMA_FINISH+++-- | Force immediate finalization of 'ForeignPtr' associated with+-- 'LzmaStream'. This triggers a call to @lzma_end()@, therefore it's+-- a programming error to call 'runLzmaStream' afterwards.+endLzmaStream :: LzmaStream -> ST s ()+endLzmaStream (LS ls) = unsafeIOToST $ finalizeForeignPtr ls++----------------------------------------------------------------------------+-- trivial helper wrappers defined in ../cbits/lzma_wrapper.c++foreign import ccall "hs_lzma_init_decoder"+ c_hs_lzma_init_decoder :: Ptr LzmaStream -> Bool -> Word64 -> Word32 -> IO Int++foreign import ccall "hs_lzma_init_encoder"+ c_hs_lzma_init_encoder :: Ptr LzmaStream -> Word32 -> Int -> IO Int++foreign import ccall "hs_lzma_run"+ c_hs_lzma_run :: Ptr LzmaStream -> Int -> Ptr Word8 -> Int -> Ptr Word8 -> Int -> IO Int++foreign import ccall "&hs_lzma_done"+ c_hs_lzma_done_funptr :: FunPtr (Ptr LzmaStream -> IO ())