From 68665167d5a9a155016d8a5cab61131bae11c2f5 Mon Sep 17 00:00:00 2001 From: Abs62 Date: Sat, 14 Sep 2013 20:17:32 +0400 Subject: [PATCH] Add ZIM format support (issue #267). Now turned on by default for Windows only. Under Linux/MacOS use "qmake "CONFIG+=zim_support"" (liblzma-dev package required. Or take xz 5.0.5 sources from http://tukaani.org/xz/ and compile it). --- article-style.css | 8 + btreeidx.hh | 4 +- decompress.cc | 43 ++ decompress.hh | 6 + goldendict.pro | 13 +- icons/icon32_zim.png | Bin 0 -> 1096 bytes loaddictionaries.cc | 16 +- resources.qrc | 1 + winlibs/include/lzma.h | 313 +++++++++ winlibs/include/lzma/base.h | 601 ++++++++++++++++ winlibs/include/lzma/bcj.h | 90 +++ winlibs/include/lzma/block.h | 530 ++++++++++++++ winlibs/include/lzma/check.h | 150 ++++ winlibs/include/lzma/container.h | 424 +++++++++++ winlibs/include/lzma/delta.h | 77 ++ winlibs/include/lzma/filter.h | 424 +++++++++++ winlibs/include/lzma/hardware.h | 50 ++ winlibs/include/lzma/index.h | 682 ++++++++++++++++++ winlibs/include/lzma/index_hash.h | 107 +++ winlibs/include/lzma/lzma.h | 420 +++++++++++ winlibs/include/lzma/stream_flags.h | 223 ++++++ winlibs/include/lzma/version.h | 121 ++++ winlibs/include/lzma/vli.h | 166 +++++ winlibs/lib/liblzma.a | Bin 0 -> 210466 bytes zim.cc | 1012 +++++++++++++++++++++++++++ zim.hh | 24 + 26 files changed, 5500 insertions(+), 5 deletions(-) create mode 100644 icons/icon32_zim.png create mode 100644 winlibs/include/lzma.h create mode 100644 winlibs/include/lzma/base.h create mode 100644 winlibs/include/lzma/bcj.h create mode 100644 winlibs/include/lzma/block.h create mode 100644 winlibs/include/lzma/check.h create mode 100644 winlibs/include/lzma/container.h create mode 100644 winlibs/include/lzma/delta.h create mode 100644 winlibs/include/lzma/filter.h create mode 100644 winlibs/include/lzma/hardware.h create mode 100644 winlibs/include/lzma/index.h create mode 100644 winlibs/include/lzma/index_hash.h create mode 100644 winlibs/include/lzma/lzma.h create mode 100644 winlibs/include/lzma/stream_flags.h create mode 100644 winlibs/include/lzma/version.h create mode 100644 winlibs/include/lzma/vli.h create mode 100644 winlibs/lib/liblzma.a create mode 100644 zim.cc create mode 100644 zim.hh diff --git a/article-style.css b/article-style.css index b97f6aea..382bd07a 100644 --- a/article-style.css +++ b/article-style.css @@ -491,6 +491,14 @@ div.xdxf color: inherit; } +/************* Zim dictionaries **************/ + +.zimdict_headword +{ + font-weight: bold!important; +/* font-size: 150%; */ +} + /************* Spelling suggestions *****************/ .gdspellsuggestion diff --git a/btreeidx.hh b/btreeidx.hh index 25a53c9b..a0d89482 100644 --- a/btreeidx.hh +++ b/btreeidx.hh @@ -74,8 +74,6 @@ public: BtreeIndex(); -protected: - /// Opens the index. The file reference is saved to be used for /// subsequent lookups. /// The mutex is the one to be locked when working with the file. @@ -85,6 +83,8 @@ protected: /// is performed. vector< WordArticleLink > findArticles( wstring const & ); +protected: + /// Finds the offset in the btree leaf for the given word, either matching /// by an exact match, or by finding the smallest entry that might match /// by prefix. It can return zero if there isn't even a possible prefx diff --git a/decompress.cc b/decompress.cc index 4842b970..9ca0fff2 100644 --- a/decompress.cc +++ b/decompress.cc @@ -2,6 +2,10 @@ #include "zlib.h" #include "bzlib.h" +#ifdef MAKE_ZIM_SUPPORT +#include "lzma.h" +#endif + #define CHUNK_SIZE 2048 QByteArray zlibDecompress( const char * bufptr, unsigned length ) @@ -74,3 +78,42 @@ int res; return str; } +#ifdef MAKE_ZIM_SUPPORT + +#define BUFSIZE 0xFFFF + +string decompressLzma2( const char * bufptr, unsigned length ) +{ +string str; +lzma_ret res; +char buf[BUFSIZE]; + + lzma_stream strm = LZMA_STREAM_INIT; + strm.next_in = reinterpret_cast< const uint8_t * >( bufptr ); + strm.avail_in = length; + + while( 1 ) + { + res = lzma_stream_decoder( &strm, UINT64_MAX, 0 ); + if( res != LZMA_OK ) + break; + + while ( res != LZMA_STREAM_END ) + { + strm.next_out = reinterpret_cast< uint8_t * >( buf ); + strm.avail_out = BUFSIZE; + res = lzma_code( &strm, LZMA_RUN ); + str.append( buf, BUFSIZE - strm.avail_out ); + if( res != LZMA_OK && res != LZMA_STREAM_END ) + break; + } + lzma_end( &strm ); + if( res != LZMA_STREAM_END ) + str.clear(); + + break; + } + return str; +} + +#endif diff --git a/decompress.hh b/decompress.hh index 3d93d7b0..f0d00c79 100644 --- a/decompress.hh +++ b/decompress.hh @@ -12,4 +12,10 @@ string decompressZlib( const char * bufptr, unsigned length ); string decompressBzip2( const char * bufptr, unsigned length ); +#ifdef MAKE_ZIM_SUPPORT + +string decompressLzma2( const char * bufptr, unsigned length ); + +#endif + #endif // DECOMPRESS_HH diff --git a/goldendict.pro b/goldendict.pro index 24a8921f..c03dbce2 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -83,6 +83,8 @@ win32 { Release:DEFINES += NO_CONSOLE gcc48:QMAKE_CXXFLAGS += -Wno-unused-local-typedefs + + CONFIG += zim_support } unix:!mac { @@ -264,7 +266,8 @@ HEADERS += folding.hh \ voiceengines.hh \ ffmpegaudio.hh \ articleinspector.hh \ - delegate.hh + delegate.hh \ + zim.hh FORMS += groups.ui \ dictgroupwidget.ui \ @@ -373,7 +376,8 @@ SOURCES += folding.cc \ voiceengines.cc \ ffmpegaudio.cc \ articleinspector.cc \ - delegate.cc + delegate.cc \ + zim.cc win32 { FORMS += texttospeechsource.ui @@ -403,6 +407,11 @@ mac { SOURCES += texttospeechsource.cc } +CONFIG( zim_support ) { + DEFINES += MAKE_ZIM_SUPPORT + LIBS += -llzma +} + RESOURCES += resources.qrc \ flags.qrc TRANSLATIONS += locale/ru_RU.ts \ diff --git a/icons/icon32_zim.png b/icons/icon32_zim.png new file mode 100644 index 0000000000000000000000000000000000000000..7277646d47c0925508db215fbdc6ab67769c5021 GIT binary patch literal 1096 zcmbu7+iP4^6vn@p64QYx6Kh3`mn15-OF-#L|5lb4>#s_Z^+o3kr&_az5)=Mkwt%x9KX(|=8J`EMTK;g`Co%t6$aL$Ik_xjfN z{nj}!JhZV`xUK-8ICy`#YHLsacDCEMJp1x#pdG`TM=EWA+S3f$WNlKGL1R;6)EG3f zCdwi-G&MvGL4{Q)6DT*8qp~QoGGz>@B|qj_Ok~C7--m^kz%chm;Eod(*OFR__zDc<-5=XD}(d$Q0PwhVu># zLu-k}gFT!FNR@0VHU{;iWLPO_4#Qv>o#-fmf*KnN!IUVFStPH9ihRh0*^vj4Iv0t8 zb4)~T05&lPV`&ks^MJD-#Rh2Ox47n_HPL*YDZ!>DfjUqFo(4wjF9rI5lHL6u$Bjl~adB~BVWD2H*J`!# z@$u2o(Q>)m*Vot8)n(f0wU5r&(zd%gv;}wn{*$@IKZE6aMxHtQ+v~@QU#u=wbZKYj zfyxg(y^||TcddAM_!#!iK6+zeN%5*}FZPy}PRRTX7oVTqfupq}dvE{c;J(S5Dlhb3 z`{V4|^JB}8AD()0>#g%0!`*X#rV~>ep4j=o)t3twM}J+hee3=;-<>E`)>dWx=ABpE zH#XCA;n4EWj^BHBe&XcE*beaq0gZ%Dsse literal 0 HcmV?d00001 diff --git a/loaddictionaries.cc b/loaddictionaries.cc index fdfbe54f..e696372d 100644 --- a/loaddictionaries.cc +++ b/loaddictionaries.cc @@ -27,6 +27,7 @@ #include "aard.hh" #include "zipsounds.hh" #include "mdx.hh" +#include "zim.hh" #include #include @@ -50,7 +51,11 @@ LoadDictionaries::LoadDictionaries( Config::Class const & cfg ): nameFilters << "*.bgl" << "*.ifo" << "*.lsa" << "*.dat" << "*.dsl" << "*.dsl.dz" << "*.index" << "*.xdxf" << "*.xdxf.dz" << "*.dct" << "*.aar" << "*.zips" - << "*.mdx"; + << "*.mdx" +#ifdef MAKE_ZIM_SUPPORT + << "*.zim" +#endif +; } void LoadDictionaries::run() @@ -185,6 +190,15 @@ void LoadDictionaries::handlePath( Config::Path const & path ) dictionaries.insert( dictionaries.end(), mdxDictionaries.begin(), mdxDictionaries.end() ); } +#ifdef MAKE_ZIM_SUPPORT + { + vector< sptr< Dictionary::Class > > zimDictionaries = + Zim::makeDictionaries( allFiles, FsEncoding::encode( Config::getIndexDir() ), *this ); + + dictionaries.insert( dictionaries.end(), zimDictionaries.begin(), + zimDictionaries.end() ); + } +#endif } void LoadDictionaries::indexingDictionary( string const & dictionaryName ) throw() diff --git a/resources.qrc b/resources.qrc index 49687f04..2f64a522 100644 --- a/resources.qrc +++ b/resources.qrc @@ -75,5 +75,6 @@ icons/programicon_old.png icons/playsound_color.png icons/playsound_full.png + icons/icon32_zim.png diff --git a/winlibs/include/lzma.h b/winlibs/include/lzma.h new file mode 100644 index 00000000..fb874c3e --- /dev/null +++ b/winlibs/include/lzma.h @@ -0,0 +1,313 @@ +/** + * \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 . 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 + * . + * + * The SHA-256 implementation is based on the public domain code found from + * 7-Zip , which has a modified version of the public + * domain SHA-256 code found from Crypto++ . + * 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 + + /* + * 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 has no C99 support, and thus it cannot be used to + * compile liblzma. The liblzma API has to still be usable + * from MSVC, so we need to define the required standard + * integer types here. + */ +# if defined(_WIN32) && defined(_MSC_VER) + 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 +# 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 +# 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) +# define lzma_nothrow throw() +# elif __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 __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/lzma.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 */ diff --git a/winlibs/include/lzma/base.h b/winlibs/include/lzma/base.h new file mode 100644 index 00000000..43dde8d6 --- /dev/null +++ b/winlibs/include/lzma/base.h @@ -0,0 +1,601 @@ +/** + * \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 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, 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_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. + * + * 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). + */ +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. + */ +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(). + */ + 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 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. + * + * \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 or memlimit was zero. + */ +extern LZMA_API(lzma_ret) lzma_memlimit_set( + lzma_stream *strm, uint64_t memlimit) lzma_nothrow; diff --git a/winlibs/include/lzma/bcj.h b/winlibs/include/lzma/bcj.h new file mode 100644 index 00000000..8e37538a --- /dev/null +++ b/winlibs/include/lzma/bcj.h @@ -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 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; diff --git a/winlibs/include/lzma/block.h b/winlibs/include/lzma/block.h new file mode 100644 index 00000000..8a4bf232 --- /dev/null +++ b/winlibs/include/lzma/block.h @@ -0,0 +1,530 @@ +/** + * \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 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 if new features are needed in + * the Block field, a version number is used to indicate which + * fields in this structure are in use. For now, version must always + * be zero. With non-zero version, most Block related functions will + * return LZMA_OPTIONS_ERROR. + * + * 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; + 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; + +} 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 be set to the highest value supported by the + * application; currently the only possible version is zero. This function + * will set version to the lowest value that still supports all the features + * required by the Block Header. + * + * The size of the Block Header must have already been decoded with + * lzma_block_header_size_decode() macro and stored to block->header_size. + * + * 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, + 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 buid 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, 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 .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, 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; diff --git a/winlibs/include/lzma/check.h b/winlibs/include/lzma/check.h new file mode 100644 index 00000000..6a243db0 --- /dev/null +++ b/winlibs/include/lzma/check.h @@ -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 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; diff --git a/winlibs/include/lzma/container.h b/winlibs/include/lzma/container.h new file mode 100644 index 00000000..7a9ffc64 --- /dev/null +++ b/winlibs/include/lzma/container.h @@ -0,0 +1,424 @@ +/** + * \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 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 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, + 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 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, + 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 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. + * \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. + * \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) + * + * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH. + * There is no need to use LZMA_FINISH, but allowing 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, 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; diff --git a/winlibs/include/lzma/delta.h b/winlibs/include/lzma/delta.h new file mode 100644 index 00000000..592fc4f8 --- /dev/null +++ b/winlibs/include/lzma/delta.h @@ -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 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; diff --git a/winlibs/include/lzma/filter.h b/winlibs/include/lzma/filter.h new file mode 100644 index 00000000..e0bc163a --- /dev/null +++ b/winlibs/include/lzma/filter.h @@ -0,0 +1,424 @@ +/** + * \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 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, 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, 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, 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 to filter->options. + * 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, 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, lzma_allocator *allocator, + const uint8_t *in, size_t *in_pos, size_t in_size) + lzma_nothrow lzma_attr_warn_unused_result; diff --git a/winlibs/include/lzma/hardware.h b/winlibs/include/lzma/hardware.h new file mode 100644 index 00000000..e7dd03c3 --- /dev/null +++ b/winlibs/include/lzma/hardware.h @@ -0,0 +1,50 @@ +/** + * \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 underlaying 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 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; diff --git a/winlibs/include/lzma/index.h b/winlibs/include/lzma/index.h new file mode 100644 index 00000000..16bacc28 --- /dev/null +++ b/winlibs/include/lzma/index.h @@ -0,0 +1,682 @@ +/** + * \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 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(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, 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, 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, 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, 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; use LZMA_RUN + * to support liblzma versions older than 5.0.0). + * + * \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. + * + * 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; use LZMA_RUN + * to support liblzma versions older than 5.0.0). + * + * \return - LZMA_OK: Initialization succeeded, continue with lzma_code(). + * - LZMA_MEM_ERROR + * - LZMA_MEMLIMIT_ERROR + * - LZMA_PROG_ERROR + */ +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, lzma_allocator *allocator, + const uint8_t *in, size_t *in_pos, size_t in_size) + lzma_nothrow; diff --git a/winlibs/include/lzma/index_hash.h b/winlibs/include/lzma/index_hash.h new file mode 100644 index 00000000..fa2e048d --- /dev/null +++ b/winlibs/include/lzma/index_hash.h @@ -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 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, 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, 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; diff --git a/winlibs/include/lzma/lzma.h b/winlibs/include/lzma/lzma.h new file mode 100644 index 00000000..3f8e095f --- /dev/null +++ b/winlibs/include/lzma/lzma.h @@ -0,0 +1,420 @@ +/** + * \file lzma/lzma.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 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 aligment 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; diff --git a/winlibs/include/lzma/stream_flags.h b/winlibs/include/lzma/stream_flags.h new file mode 100644 index 00000000..bbdd4082 --- /dev/null +++ b/winlibs/include/lzma/stream_flags.h @@ -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 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; diff --git a/winlibs/include/lzma/version.h b/winlibs/include/lzma/version.h new file mode 100644 index 00000000..629e8e1a --- /dev/null +++ b/winlibs/include/lzma/version.h @@ -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 instead. +#endif + + +/* + * Version number split into components + */ +#define LZMA_VERSION_MAJOR 5 +#define LZMA_VERSION_MINOR 0 +#define LZMA_VERSION_PATCH 4 +#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 diff --git a/winlibs/include/lzma/vli.h b/winlibs/include/lzma/vli.h new file mode 100644 index 00000000..9ad13f2e --- /dev/null +++ b/winlibs/include/lzma/vli.h @@ -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 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 + * underlaying 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; diff --git a/winlibs/lib/liblzma.a b/winlibs/lib/liblzma.a new file mode 100644 index 0000000000000000000000000000000000000000..e8548fc015f0b3e31a69afde3985797748263986 GIT binary patch literal 210466 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 z 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

1Ogf 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

"; + result += "

"; + result += i->second.first; + result += "

"; + result += i->second.second; + result += cleaner + "
"; + } + + for( i = alternateArticles.begin(); i != alternateArticles.end(); ++i ) + { + result += "
"; + result += "

"; + result += i->second.first; + result += "

"; + result += i->second.second; + result += cleaner + "
"; + } + + Mutex::Lock _( dataMutex ); + + data.resize( result.size() ); + + memcpy( &data.front(), result.data(), result.size() ); + + hasAnyData = true; + + finish(); +} + +sptr< Dictionary::DataRequest > ZimDictionary::getArticle( wstring const & word, + vector< wstring > const & alts, + wstring const & ) + throw( std::exception ) +{ + return new ZimArticleRequest( word, alts, *this ); +} + +//// ZimDictionary::getResource() + +class ZimResourceRequest; + +class ZimResourceRequestRunnable: public QRunnable +{ + ZimResourceRequest & r; + QSemaphore & hasExited; + +public: + + ZimResourceRequestRunnable( ZimResourceRequest & r_, + QSemaphore & hasExited_ ): r( r_ ), + hasExited( hasExited_ ) + {} + + ~ZimResourceRequestRunnable() + { + hasExited.release(); + } + + virtual void run(); +}; + +class ZimResourceRequest: public Dictionary::DataRequest +{ + friend class ZimResourceRequestRunnable; + + ZimDictionary & dict; + + string resourceName; + + QAtomicInt isCancelled; + QSemaphore hasExited; + +public: + + ZimResourceRequest( ZimDictionary & dict_, + string const & resourceName_ ): + dict( dict_ ), + resourceName( resourceName_ ) + { + QThreadPool::globalInstance()->start( + new ZimResourceRequestRunnable( *this, hasExited ) ); + } + + void run(); // Run from another thread by ZimResourceRequestRunnable + + virtual void cancel() + { + isCancelled.ref(); + } + + ~ZimResourceRequest() + { + isCancelled.ref(); + hasExited.acquire(); + } +}; + +void ZimResourceRequestRunnable::run() +{ + r.run(); +} + +void ZimResourceRequest::run() +{ + // Some runnables linger enough that they are cancelled before they start + if ( isCancelled ) + { + finish(); + return; + } + + try + { + string resource; + dict.loadResource( resourceName, resource ); + if( resource.empty() ) + throw File::Ex(); + + if( Filetype::isNameOfCSS( resourceName ) ) + { + QString css = QString::fromUtf8( resource.data(), resource.size() ); + dict.isolateCSS( css, ".zimdict" ); + QByteArray bytes = css.toUtf8(); + data.resize( bytes.size() ); + memcpy( &data.front(), bytes.constData(), bytes.size() ); + } + else + if ( Filetype::isNameOfTiff( resourceName ) ) + { + // Convert it + + dataMutex.lock(); + + QImage img = QImage::fromData( reinterpret_cast< const uchar * >( resource.data() ), resource.size() ); + + dataMutex.unlock(); + + if ( !img.isNull() ) + { + // Managed to load -- now store it back as BMP + + QByteArray ba; + QBuffer buffer( &ba ); + buffer.open( QIODevice::WriteOnly ); + img.save( &buffer, "BMP" ); + + Mutex::Lock _( dataMutex ); + + data.resize( buffer.size() ); + + memcpy( &data.front(), buffer.data(), data.size() ); + } + } + else + { + Mutex::Lock _( dataMutex ); + data.resize( resource.size() ); + memcpy( &data.front(), resource.data(), data.size() ); + } + + hasAnyData = true; + } + catch( File::Ex & ) + { + // No such resource -- we don't set the hasAnyData flag then + } + catch( Utf8::exCantDecode ) + { + // Failed to decode some utf8 -- probably the resource name is no good + } + + finish(); +} + +sptr< Dictionary::DataRequest > ZimDictionary::getResource( string const & name ) + throw( std::exception ) +{ + return new ZimResourceRequest( *this, name ); +} + +} // anonymous namespace + +vector< sptr< Dictionary::Class > > makeDictionaries( + vector< string > const & fileNames, + string const & indicesDir, + Dictionary::Initializing & initializing ) + throw( std::exception ) +{ + vector< sptr< Dictionary::Class > > dictionaries; + + for( vector< string >::const_iterator i = fileNames.begin(); i != fileNames.end(); + ++i ) + { + // Skip files with the extensions different to .zim to speed up the + // scanning + if ( i->size() < 4 || + strcasecmp( i->c_str() + ( i->size() - 4 ), ".zim" ) != 0 ) + continue; + + // Got the file -- check if we need to rebuid the index + + vector< string > dictFiles( 1, *i ); + + string dictId = Dictionary::makeDictionaryId( dictFiles ); + + string indexFile = indicesDir + dictId; + + if ( Dictionary::needToRebuildIndex( dictFiles, indexFile ) || + indexIsOldOrBad( indexFile ) ) + { + try + { + ZIM_header zh; + + unsigned articleCount = 0; + unsigned wordCount = 0; + + QFile df( FsEncoding::decode( i->c_str() ) ); + df.open( QFile::ReadOnly ); + + qint64 ret = df.read( reinterpret_cast< char * >( &zh ), sizeof( zh ) ); + if( ret != sizeof( zh ) ) + throw exCantReadFile( i->c_str() ); + + if( zh.magicNumber != 0x44D495A ) + throw exNotZimFile( i->c_str() ); + + { + int n = df.fileName().lastIndexOf( '/' ); + initializing.indexingDictionary( df.fileName().mid( n + 1 ).toUtf8().constData() ); + } + + File::Class idx( indexFile, "wb" ); + IdxHeader idxHeader; + memset( &idxHeader, 0, sizeof( idxHeader ) ); + idxHeader.namePtr = 0xFFFFFFFF; + idxHeader.descriptionPtr = 0xFFFFFFFF; + + // We write a dummy header first. At the end of the process the header + // will be rewritten with the right values. + + idx.write( idxHeader ); + + IndexedWords indexedWords, indexedResources; + + QByteArray artEntries; + df.seek( zh.urlPtrPos ); + artEntries = df.read( (quint64)zh.articleCount * 8 ); + + QVector< quint64 > clusters; + clusters.reserve( zh.clusterCount ); + df.seek( zh.clusterPtrPos ); + { + QByteArray data = df.read( (quint64)zh.clusterCount * 8 ); + for( unsigned n = 0; n < zh.clusterCount; n++ ) + clusters.append( *( reinterpret_cast< const quint64 * >( data.constData() ) + n ) ); + } + + const quint64 * ptr; + quint16 mimetype; + ArticleEntry artEntry; + RedirectEntry redEntry; + string url, title; + char nameSpace; + for( unsigned n = 0; n < zh.articleCount; n++ ) + { + ptr = reinterpret_cast< const quint64 * >( artEntries.constData() ) + n; + df.seek( *ptr ); + df.read( reinterpret_cast< char * >( &mimetype ), sizeof(mimetype) ); + if( mimetype == 0xFFFF ) + { + redEntry.mimetype = mimetype; + ret = df.read( reinterpret_cast< char * >( &redEntry ) + 2, sizeof(RedirectEntry) - 2 ); + if( ret != sizeof(RedirectEntry) - 2 ) + throw exCantReadFile( i->c_str() ); + + nameSpace = redEntry.nameSpace; + } + else + { + artEntry.mimetype = mimetype; + ret = df.read( reinterpret_cast< char * >( &artEntry ) + 2, sizeof(ArticleEntry) - 2 ); + if( ret != sizeof(ArticleEntry) - 2 ) + throw exCantReadFile( i->c_str() ); + + nameSpace = artEntry.nameSpace; + + if( nameSpace == 'A' ) + articleCount++; + } + + // Read article url and title + char ch; + + url.clear(); + while( df.getChar( &ch ) ) + { + if( ch == 0 ) + break; + url.push_back( ch ); + } + + title.clear(); + while( df.getChar( &ch ) ) + { + if( ch == 0 ) + break; + title.push_back( ch ); + } + + if( nameSpace == 'A' ) + { + if( !title.empty() ) + indexedWords.addWord( Utf8::decode( title ), n ); + else + indexedWords.addWord( Utf8::decode( url ), n ); + wordCount++; + } + else + if( nameSpace == 'M' ) + { + if( url.compare( "Title") == 0 ) + { + idxHeader.namePtr = n; + string name; + readArticle( df, zh, n, name ); + initializing.indexingDictionary( name ); + } + else + if( url.compare( "Description") == 0 ) + idxHeader.descriptionPtr = n; + else + if( url.compare( "Language") == 0 ) + { + string lang; + readArticle( df, zh, n, lang ); + if( lang.size() == 2 ) + idxHeader.langFrom = LangCoder::code2toInt( lang.c_str() ); + else + if( lang.size() == 3 ) + idxHeader.langFrom = LangCoder::code3toInt( lang.c_str() ); + idxHeader.langTo = idxHeader.langFrom; + } + } + else + { + url.insert( url.begin(), '/' ); + url.insert( url.begin(), nameSpace ); + indexedResources.addSingleWord( Utf8::decode( url ), n ); + } + } + + // Build index + + { + IndexInfo idxInfo = BtreeIndexing::buildIndex( indexedWords, idx ); + + idxHeader.indexBtreeMaxElements = idxInfo.btreeMaxElements; + idxHeader.indexRootOffset = idxInfo.rootOffset; + + indexedWords.clear(); // Release memory -- no need for this data + } + + { + IndexInfo idxInfo = BtreeIndexing::buildIndex( indexedResources, idx ); + + idxHeader.resourceIndexBtreeMaxElements = idxInfo.btreeMaxElements; + idxHeader.resourceIndexRootOffset = idxInfo.rootOffset; + + indexedResources.clear(); // Release memory -- no need for this data + } + + idxHeader.signature = Signature; + idxHeader.formatVersion = CurrentFormatVersion; + + idxHeader.articleCount = articleCount; + idxHeader.wordCount = wordCount; + + idx.rewind(); + + idx.write( &idxHeader, sizeof( idxHeader ) ); + } + catch( std::exception & e ) + { + FDPRINTF( stderr, "Zim dictionary indexing failed: %s, error: %s\n", + i->c_str(), e.what() ); + continue; + } + catch( ... ) + { + FDPRINTF( stderr, "Zim dictionary indexing failed\n" ); + continue; + } + } + dictionaries.push_back( new ZimDictionary( dictId, + indexFile, + dictFiles ) ); + } + return dictionaries; +} + +} // namespace Zim + +#endif diff --git a/zim.hh b/zim.hh new file mode 100644 index 00000000..2717cd06 --- /dev/null +++ b/zim.hh @@ -0,0 +1,24 @@ +#ifndef __ZIM_HH_INCLUDED__ +#define __ZIM_HH_INCLUDED__ + +#ifdef MAKE_ZIM_SUPPORT + +#include "dictionary.hh" + +/// Support for the Zim dictionaries. +namespace Zim { + +using std::vector; +using std::string; + +vector< sptr< Dictionary::Class > > makeDictionaries( + vector< string > const & fileNames, + string const & indicesDir, + Dictionary::Initializing & ) + throw( std::exception ); + +} + +#endif + +#endif

wNnPWuRKk@hE7ga5{DsZo)1Jl6-uLSSH z#o#cEJeqh@(&$c2N*s>&1ru+@-vO@}e-}=kI}h&q3MPUZJox=Lr*x;MFzjRrs{-*Z zC>1F9{od)_znVU4bTo*DdP&Drd3O&KqE$$9!@KR5rr_xKOWl#ej`sJ(L=ja6DSatn zA0R1(HIR_fmq0JXvp<>M{Webd zbxk>p@KfH(3Qj$vuC4?Rb-#^##|A&{@WN=USGzxeZDsGJNbuODNU%3ieN0-KjT!vT zD@XfOOTQul0b3WLnf)nygr{_9xB7Yw` z7gu)T(p+3x8@Fc5p)y*RddQ2bz(_o|JtJaGsaa1qdNzD~^(dpTJ2G)kC* zc|OfWU=MTtZ5~c*{-7|HpOY3>7XBQ62S3(L?L9f0BI`VmBgzIv)*L`=l3d!2O|?rF zjaiHklBx3Hn^a9{_4yueg`&RW9S{b0g}Mfq`AEQBp>6@@E`!Nlq2lmUIU=AuXKID= zQcW&mRdItEAk>$lG;ANp_@bI$n0U|+Wy2}g$tN2w91FJY% z#lXTGRM=k1`@)-6WQffFk$Ka}=wHQ~MgZmGO=}xBXOjX$3&xxI99Nn9Xru*~BQJO6 zQ&x6v*~ldaa}4U?hmd^E)XZmEckxdi&gw=$HK?wh#SWBf64NjL9H#GtrZ8sk0?k}T z_!zxDMA_U@>wL|+x-xS?b-1T$(o4IZL7$CT-$M`W8c`!_KPF6Lq zyZfe5kw}*#_fFQzMTH|}a3=rjk*v87{cQH!ClYi2bfP&mrf20iB#&$_U?gc zMoJao6!I(rjkrh>4NVgiWhgkc)XIVWdnC1Dm^W{1*?fN{d2qM{&hdQbTxboDDYcdX zlPR^{49vfu)Vc+^tA~`~F@U5DQeBrkxXwH@LIoI?P^cgir53sOR`ODdg;_R_PhpJZ zTknTKYq{QcXoAbv?|!|%5~WbnucJKLq9;6N;`3dX72t0Cg7lS+@1wz8|AHbar;wH| zIIrU$gi)?M$_s?xw3S~D<#5=BQ|P}Oh5>r53n2Hsf4sZzg2XG^-vKXhJqQ8hwd+BQ zxWq<5Vo)rXkd(MIV?vrThpH5&dVX)TV0-p#N3SYgd| z=F>=7!T?tH)IOszYCy+;{jtGhOBw$HKRxs%g)_@*+^^H*oGP#$fvZNUtI3HA=b|Ob zH$Nd!{u8AlOLOYKmgVL-7L+@Bb(iNLm7o;)?|OP0#zS>d2HagfYFQ8X>NYntKb)}` RW%sd;;CY=Xev<3n{{t~<77zdc literal 0 HcmV?d00001 diff --git a/zim.cc b/zim.cc new file mode 100644 index 00000000..d7ddd14a --- /dev/null +++ b/zim.cc @@ -0,0 +1,1012 @@ +/* This file is (c) 2012 Abs62 + * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ + +#ifdef MAKE_ZIM_SUPPORT + +#include "zim.hh" +#include "btreeidx.hh" +#include "fsencoding.hh" +#include "folding.hh" +#include "dprintf.hh" +#include "utf8.hh" +#include "decompress.hh" +#include "langcoder.hh" +#include "wstring_qt.hh" +#include "filetype.hh" +#include "file.hh" + +#ifdef _MSC_VER +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Zim { + +using std::string; +using std::map; +using std::vector; +using std::multimap; +using std::pair; +using std::set; +using gd::wstring; + +using BtreeIndexing::WordArticleLink; +using BtreeIndexing::IndexedWords; +using BtreeIndexing::IndexInfo; + +DEF_EX_STR( exNotZimFile, "Not an Zim file", Dictionary::Ex ) +DEF_EX_STR( exCantReadFile, "Can't read file", Dictionary::Ex ) + +namespace { + +#ifdef _MSC_VER +#pragma pack( push, 1 ) +#endif + +enum CompressionType +{ + Default = 0, None, Zlib, Bzip2, Lzma2 +}; + +/// Zim file header +struct ZIM_header +{ + quint32 magicNumber; + quint32 version; + quint8 uuid[ 16 ]; + quint32 articleCount; + quint32 clusterCount; + quint64 urlPtrPos; + quint64 titlePtrPos; + quint64 clusterPtrPos; + quint64 mimeListPos; + quint32 mainPage; + quint32 layoutPage; + quint64 checksumPos; +} +#ifndef _MSC_VER +__attribute__((packed)) +#endif +; + +struct ArticleEntry +{ + quint16 mimetype; + quint8 parameterLen; + char nameSpace; + quint32 revision; + quint32 clusterNumber; + quint32 blobNumber; +} +#ifndef _MSC_VER +__attribute__((packed)) +#endif +; + +struct RedirectEntry +{ + quint16 mimetype; + quint8 parameterLen; + char nameSpace; + quint32 revision; + quint32 redirectIndex; +} +#ifndef _MSC_VER +__attribute__((packed)) +#endif +; + +enum +{ + Signature = 0x584D495A, // ZIMX on little-endian, XMIZ on big-endian + CurrentFormatVersion = 1 + BtreeIndexing::FormatVersion + Folding::Version +}; + +struct IdxHeader +{ + quint32 signature; // First comes the signature, ZIMX + quint32 formatVersion; // File format version (CurrentFormatVersion) + quint32 indexBtreeMaxElements; // Two fields from IndexInfo + quint32 indexRootOffset; + quint32 resourceIndexBtreeMaxElements; // Two fields from IndexInfo + quint32 resourceIndexRootOffset; + quint32 wordCount; + quint32 articleCount; + quint32 namePtr; + quint32 descriptionPtr; + quint32 langFrom; // Source language + quint32 langTo; // Target language +} +#ifndef _MSC_VER +__attribute__((packed)) +#endif +; + +#ifdef _MSC_VER +#pragma pack( pop, 1 ) +#endif + +bool indexIsOldOrBad( string const & indexFile ) +{ + File::Class idx( indexFile, "rb" ); + + IdxHeader header; + + return idx.readRecords( &header, sizeof( header ), 1 ) != 1 || + header.signature != Signature || + header.formatVersion != CurrentFormatVersion; +} + +quint32 readArticle( QFile & file, ZIM_header & header, uint32_t articleNumber, string & result, + set< quint32 > * loadedArticles = NULL ) +{ + while( 1 ) + { + if( articleNumber >= header.articleCount ) + break; + + file.seek( header.urlPtrPos + (quint64)articleNumber * 8 ); + quint64 pos; + if( file.read( reinterpret_cast< char * >( &pos ), sizeof(pos) ) != sizeof(pos) ) + break; + + // Read article info + + quint16 mimetype; + + file.seek( pos ); + if( file.read( reinterpret_cast< char * >( &mimetype ), sizeof(mimetype) ) != sizeof(mimetype) ) + break; + + if( mimetype == 0xFFFF ) // Redirect to other article + { + RedirectEntry redEntry; + if( file.read( reinterpret_cast< char * >( &redEntry ) + 2, sizeof(redEntry) - 2 ) != sizeof(redEntry) - 2 ) + break; + if( articleNumber == redEntry.redirectIndex ) + break; + articleNumber = redEntry.redirectIndex; + continue; + } + + if( loadedArticles && loadedArticles->find( articleNumber ) != loadedArticles->end() ) + break; + + ArticleEntry artEntry; + artEntry.mimetype = mimetype; + if( file.read( reinterpret_cast< char * >( &artEntry ) + 2, sizeof(artEntry) - 2 ) != sizeof(artEntry) - 2 ) + break; + + // Read cluster pointers + + quint64 clusters[ 2 ]; + file.seek( header.clusterPtrPos + (quint64)artEntry.clusterNumber * 8 ); + if( file.read( reinterpret_cast< char * >( clusters ), sizeof(clusters) ) != sizeof(clusters) ) + break; + + // Calculate cluster size + + quint64 clusterSize; + if( artEntry.clusterNumber < header.clusterCount - 1 ) + clusterSize = clusters[ 1 ] - clusters[ 0 ]; + else + clusterSize = file.size() - clusters[ 0 ]; + + // Read cluster data + + file.seek( clusters[ 0 ] ); + + char compressionType; + if( !file.getChar( &compressionType ) ) + break; + + string decompressedData; + + QByteArray data = file.read( clusterSize ); + if( compressionType == Default || compressionType == None ) + decompressedData = string( data.data(), data.size() ); + else + if( compressionType == Zlib ) + decompressedData = decompressZlib( data.constData(), data.size() ); + else + if( compressionType == Bzip2 ) + decompressedData = decompressBzip2( data.constData(), data.size() ); + else + if( compressionType == Lzma2 ) + decompressedData = decompressLzma2( data.constData(), data.size() ); + else + break; + + // Take article data from cluster + + quint32 blobCount; + memcpy( &blobCount, decompressedData.data(), sizeof(blobCount) ); + if( artEntry.blobNumber > blobCount ) + break; + + quint32 offsets[ 2 ]; + memcpy( offsets, decompressedData.data() + artEntry.blobNumber * 4, sizeof(offsets) ); + quint32 size = offsets[ 1 ] - offsets[ 0 ]; + + result.clear(); + result.append( decompressedData, offsets[ 0 ], size ); + + return articleNumber; + } + return 0xFFFFFFFF; +} + +class ZimDictionary: public BtreeIndexing::BtreeDictionary +{ + Mutex idxMutex; + Mutex zimMutex, idxResourceMutex; + File::Class idx; + BtreeIndex resourceIndex; + IdxHeader idxHeader; + string dictionaryName; + QFile df; + ZIM_header zimHeader; + + public: + + ZimDictionary( string const & id, string const & indexFile, + vector< string > const & dictionaryFiles ); + + ~ZimDictionary(); + + virtual string getName() throw() + { return dictionaryName; } + + virtual map< Dictionary::Property, string > getProperties() throw() + { return map< Dictionary::Property, string >(); } + + virtual unsigned long getArticleCount() throw() + { return idxHeader.articleCount; } + + virtual unsigned long getWordCount() throw() + { return idxHeader.wordCount; } + + inline virtual quint32 getLangFrom() const + { return idxHeader.langFrom; } + + inline virtual quint32 getLangTo() const + { return idxHeader.langTo; } + + virtual sptr< Dictionary::DataRequest > getArticle( wstring const &, + vector< wstring > const & alts, + wstring const & ) + throw( std::exception ); + + virtual sptr< Dictionary::DataRequest > getResource( string const & name ) + throw( std::exception ); + + virtual QString const& getDescription(); + + /// Loads the resource. + void loadResource( std::string &resourceName, string & data ); + +protected: + + virtual void loadIcon() throw(); + +private: + + /// Loads the article. + quint32 loadArticle( quint32 address, + string & articleText, + set< quint32 > * loadedArticles ); + + string convert( string const & in_data ); + friend class ZimArticleRequest; + friend class ZimResourceRequest; +}; + +ZimDictionary::ZimDictionary( string const & id, + string const & indexFile, + vector< string > const & dictionaryFiles ): + BtreeDictionary( id, dictionaryFiles ), + idx( indexFile, "rb" ), + idxHeader( idx.read< IdxHeader >() ), + df( FsEncoding::decode( dictionaryFiles[ 0 ].c_str() ) ) +{ + // Open data file + + df.open( QFile::ReadOnly ); + memset( &zimHeader, 0, sizeof(zimHeader) ); + df.read( reinterpret_cast< char * >( &zimHeader ), sizeof( zimHeader ) ); + + // Initialize the indexes + + openIndex( IndexInfo( idxHeader.indexBtreeMaxElements, + idxHeader.indexRootOffset ), + idx, idxMutex ); + + resourceIndex.openIndex( IndexInfo( idxHeader.resourceIndexBtreeMaxElements, + idxHeader.resourceIndexRootOffset ), + idx, idxResourceMutex ); + + // Read dictionary name + + if( idxHeader.namePtr == 0xFFFFFFFF ) + { + int n = df.fileName().lastIndexOf( '/' ); + dictionaryName = string( df.fileName().mid( n + 1 ).toUtf8().constData() ); + } + else + { + readArticle( df, zimHeader, idxHeader.namePtr, dictionaryName ); + } +} + +ZimDictionary::~ZimDictionary() +{ + df.close(); +} + +void ZimDictionary::loadIcon() throw() +{ + if ( dictionaryIconLoaded ) + return; + + QString fileName = + QDir::fromNativeSeparators( FsEncoding::decode( getDictionaryFilenames()[ 0 ].c_str() ) ); + + // Remove the extension + fileName.chop( 3 ); + + if( !loadIconFromFile( fileName ) ) + { + // Load failed -- use default icons + dictionaryNativeIcon = dictionaryIcon = QIcon(":/icons/icon32_zim.png"); + } + + dictionaryIconLoaded = true; +} + +quint32 ZimDictionary::loadArticle( quint32 address, + string & articleText, + set< quint32 > * loadedArticles ) +{ +quint32 ret; + { + Mutex::Lock _( zimMutex ); + ret = readArticle( df, zimHeader, address, articleText, loadedArticles ); + } + articleText = convert( articleText ); + return ret; +} + +string ZimDictionary::convert( const string & in ) +{ + QString text = QString::fromUtf8( in.c_str() ); + + text.replace( QRegExp( "<\\s*body\\s*([^>]*)background:([^;\"]*)" ), + QString( "]*)src=\"/" ), + QString( "<\\1 \\2src=\"bres://%1/").arg( getId().c_str() ) ); + + text.replace( QRegExp( "<\\s*link\\s*([^>]*)href=\"/" ), + QString( "]*)href=\"/[^\"]*\"\\s*title=\"([^\"]*)\"" ), + QString( "]*)href=\"/A/([^\"]*)\"" ), + QString( ""; + + return text.toUtf8().data(); +} + +void ZimDictionary::loadResource( std::string & resourceName, string & data ) +{ + vector< WordArticleLink > link; + string resData; + + link = resourceIndex.findArticles( Utf8::decode( resourceName ) ); + + if( link.empty() ) + return; + + { + Mutex::Lock _( zimMutex ); + readArticle( df, zimHeader, link[ 0 ].articleOffset, data ); + } +} + +QString const& ZimDictionary::getDescription() +{ + if( !dictionaryDescription.isEmpty() || idxHeader.descriptionPtr == 0xFFFFFFFF ) + return dictionaryDescription; + + string str; + { + Mutex::Lock _( zimMutex ); + readArticle( df, zimHeader, idxHeader.descriptionPtr, str ); + } + + if( !str.empty() ) + dictionaryDescription = QString::fromUtf8( str.c_str(), str.size() ); + + return dictionaryDescription; +} + +/// ZimDictionary::getArticle() + +class ZimArticleRequest; + +class ZimArticleRequestRunnable: public QRunnable +{ + ZimArticleRequest & r; + QSemaphore & hasExited; + +public: + + ZimArticleRequestRunnable( ZimArticleRequest & r_, + QSemaphore & hasExited_ ): r( r_ ), + hasExited( hasExited_ ) + {} + + ~ZimArticleRequestRunnable() + { + hasExited.release(); + } + + virtual void run(); +}; + +class ZimArticleRequest: public Dictionary::DataRequest +{ + friend class ZimArticleRequestRunnable; + + wstring word; + vector< wstring > alts; + ZimDictionary & dict; + + QAtomicInt isCancelled; + QSemaphore hasExited; + +public: + + ZimArticleRequest( wstring const & word_, + vector< wstring > const & alts_, + ZimDictionary & dict_ ): + word( word_ ), alts( alts_ ), dict( dict_ ) + { + QThreadPool::globalInstance()->start( + new ZimArticleRequestRunnable( *this, hasExited ) ); + } + + void run(); // Run from another thread by ZimArticleRequestRunnable + + virtual void cancel() + { + isCancelled.ref(); + } + + ~ZimArticleRequest() + { + isCancelled.ref(); + hasExited.acquire(); + } +}; + +void ZimArticleRequestRunnable::run() +{ + r.run(); +} + +void ZimArticleRequest::run() +{ + if ( isCancelled ) + { + finish(); + return; + } + + vector< WordArticleLink > chain = dict.findArticles( word ); + + for( unsigned x = 0; x < alts.size(); ++x ) + { + /// Make an additional query for each alt + + vector< WordArticleLink > altChain = dict.findArticles( alts[ x ] ); + + chain.insert( chain.end(), altChain.begin(), altChain.end() ); + } + + multimap< wstring, pair< string, string > > mainArticles, alternateArticles; + + set< quint32 > articlesIncluded; // Some synonims make it that the articles + // appear several times. We combat this + // by only allowing them to appear once. + + wstring wordCaseFolded = Folding::applySimpleCaseOnly( word ); + + for( unsigned x = 0; x < chain.size(); ++x ) + { + if ( isCancelled ) + { + finish(); + return; + } + + // Now grab that article + + string headword, articleText; + + headword = chain[ x ].word; + + quint32 articleNumber; + try + { + articleNumber = dict.loadArticle( chain[ x ].articleOffset, articleText, &articlesIncluded ); + } + catch(...) + { + } + + if( articleNumber == 0xFFFFFFFF ) + continue; // No article loaded + + if ( articlesIncluded.find( articleNumber ) != articlesIncluded.end() ) + continue; // We already have this article in the body. + + // Ok. Now, does it go to main articles, or to alternate ones? We list + // main ones first, and alternates after. + + // We do the case-folded comparison here. + + wstring headwordStripped = + Folding::applySimpleCaseOnly( Utf8::decode( headword ) ); + + multimap< wstring, pair< string, string > > & mapToUse = + ( wordCaseFolded == headwordStripped ) ? + mainArticles : alternateArticles; + + mapToUse.insert( pair< wstring, pair< string, string > >( + Folding::applySimpleCaseOnly( Utf8::decode( headword ) ), + pair< string, string >( headword, articleText ) ) ); + + articlesIncluded.insert( articleNumber ); + } + + if ( mainArticles.empty() && alternateArticles.empty() ) + { + // No such word + finish(); + return; + } + + string result; + + // See Issue #271: A mechanism to clean-up invalid HTML cards. + string cleaner = """""""""""" + """""""""""" + "" + "" + ""; + + multimap< wstring, pair< string, string > >::const_iterator i; + + + for( i = mainArticles.begin(); i != mainArticles.end(); ++i ) + { + result += "