IntelFrameworkModulePkg Lzma: Update LZMA SDK version to 18.05

https://bugzilla.tianocore.org/show_bug.cgi?id=1006
New formal release in https://www.7-zip.org/sdk.html is 18.05.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Liming Gao
2018-08-29 08:51:26 +08:00
parent f0737de8d9
commit 39bbbc8759
15 changed files with 779 additions and 358 deletions

View File

@ -1,4 +1,4 @@
LzmaCustomDecompressLib is based on the LZMA SDK 16.04. LzmaCustomDecompressLib is based on the LZMA SDK 18.05.
LZMA SDK 16.04 was placed in the public domain on LZMA SDK 18.05 was placed in the public domain on
2016-10-04. It was released on the 2018-04-30. It was released on the
http://www.7-zip.org/sdk.html website. http://www.7-zip.org/sdk.html website.

View File

@ -1,11 +1,11 @@
## @file ## @file
# LzmaArchCustomDecompressLib produces LZMA custom decompression algorithm with the converter for the different arch code. # LzmaArchCustomDecompressLib produces LZMA custom decompression algorithm with the converter for the different arch code.
# #
# It is based on the LZMA SDK 16.04 # It is based on the LZMA SDK 18.05
# LZMA SDK 16.04 was placed in the public domain on 2016-10-04. # LZMA SDK 18.05 was placed in the public domain on 2018-04-30.
# It was released on the http://www.7-zip.org/sdk.html website. # It was released on the http://www.7-zip.org/sdk.html website.
# #
# Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2012 - 2018, Intel Corporation. All rights reserved.<BR>
# #
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # are licensed and made available under the terms and conditions of the BSD License

View File

@ -1,8 +1,8 @@
## @file ## @file
# LzmaCustomDecompressLib produces LZMA custom decompression algorithm. # LzmaCustomDecompressLib produces LZMA custom decompression algorithm.
# #
# It is based on the LZMA SDK 16.04. # It is based on the LZMA SDK 18.05.
# LZMA SDK 16.04 was placed in the public domain on 2016-10-04. # LZMA SDK 18.05 was placed in the public domain on 2018-04-30.
# It was released on the http://www.7-zip.org/sdk.html website. # It was released on the http://www.7-zip.org/sdk.html website.
# #
# Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
@ -30,7 +30,7 @@
# #
# The following information is for reference only and not required by the build tools. # The following information is for reference only and not required by the build tools.
# #
# VALID_ARCHITECTURES = IA32 X64 EBC # VALID_ARCHITECTURES = IA32 X64 IPF EBC
# #
[Sources] [Sources]

View File

@ -36,7 +36,7 @@ typedef struct
**/ **/
VOID * VOID *
SzAlloc ( SzAlloc (
VOID *P, CONST ISzAlloc *P,
size_t Size size_t Size
) )
{ {
@ -64,7 +64,7 @@ SzAlloc (
**/ **/
VOID VOID
SzFree ( SzFree (
VOID *P, CONST ISzAlloc *P,
VOID *Address VOID *Address
) )
{ {

View File

@ -1,5 +1,5 @@
/* 7zTypes.h -- Basic types /* 7zTypes.h -- Basic types
2013-11-12 : Igor Pavlov : Public domain */ 2017-07-17 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
@ -46,13 +46,23 @@ EXTERN_C_BEGIN
typedef int SRes; typedef int SRes;
#ifdef _WIN32 #ifdef _WIN32
/* typedef DWORD WRes; */ /* typedef DWORD WRes; */
typedef unsigned WRes; typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
#else #else
typedef int WRes; typedef int WRes;
#define MY__FACILITY_WIN32 7
#define MY__FACILITY__WRes MY__FACILITY_WIN32
#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
#endif #endif
#ifndef RINOK #ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif #endif
@ -116,48 +126,72 @@ typedef int Bool;
#define MY_NO_INLINE #define MY_NO_INLINE
#endif #endif
#define MY_FORCE_INLINE __forceinline
#define MY_CDECL __cdecl #define MY_CDECL __cdecl
#define MY_FAST_CALL __fastcall #define MY_FAST_CALL __fastcall
#else #else
#define MY_NO_INLINE #define MY_NO_INLINE
#define MY_FORCE_INLINE
#define MY_CDECL #define MY_CDECL
#define MY_FAST_CALL #define MY_FAST_CALL
/* inline keyword : for C++ / C99 */
/* GCC, clang: */
/*
#if defined (__GNUC__) && (__GNUC__ >= 4)
#define MY_FORCE_INLINE __attribute__((always_inline))
#define MY_NO_INLINE __attribute__((noinline))
#endif
*/
#endif #endif
/* The following interfaces use first parameter as pointer to structure */ /* The following interfaces use first parameter as pointer to structure */
typedef struct typedef struct IByteIn IByteIn;
struct IByteIn
{ {
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
} IByteIn; };
#define IByteIn_Read(p) (p)->Read(p)
typedef struct
{
void (*Write)(void *p, Byte b);
} IByteOut;
typedef struct typedef struct IByteOut IByteOut;
struct IByteOut
{ {
SRes (*Read)(void *p, void *buf, size_t *size); void (*Write)(const IByteOut *p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
typedef struct ISeqInStream ISeqInStream;
struct ISeqInStream
{
SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
} ISeqInStream; };
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* it can return SZ_ERROR_INPUT_EOF */ /* it can return SZ_ERROR_INPUT_EOF */
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
typedef struct
typedef struct ISeqOutStream ISeqOutStream;
struct ISeqOutStream
{ {
size_t (*Write)(void *p, const void *buf, size_t size); size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes. /* Returns: result - the number of actually written bytes.
(result < size) means error */ (result < size) means error */
} ISeqOutStream; };
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum typedef enum
{ {
@ -166,78 +200,162 @@ typedef enum
SZ_SEEK_END = 2 SZ_SEEK_END = 2
} ESzSeek; } ESzSeek;
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
} ISeekInStream;
typedef struct typedef struct ISeekInStream ISeekInStream;
struct ISeekInStream
{ {
SRes (*Look)(void *p, const void **buf, size_t *size); SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
typedef struct ILookInStream ILookInStream;
struct ILookInStream
{
SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed (output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */ (output(*size) < input(*size)) is allowed */
SRes (*Skip)(void *p, size_t offset); SRes (*Skip)(const ILookInStream *p, size_t offset);
/* offset must be <= output(*size) of Look */ /* offset must be <= output(*size) of Look */
SRes (*Read)(void *p, void *buf, size_t *size); SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */ /* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
} ILookInStream; };
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); #define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); #define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
/* reads via ILookInStream::Read */ /* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
#define LookToRead_BUF_SIZE (1 << 14)
typedef struct typedef struct
{ {
ILookInStream s; ILookInStream vt;
ISeekInStream *realStream; const ISeekInStream *realStream;
size_t pos; size_t pos;
size_t size; size_t size; /* it's data size */
Byte buf[LookToRead_BUF_SIZE];
} CLookToRead; /* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
void LookToRead_Init(CLookToRead *p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
ILookInStream *realStream; const ILookInStream *realStream;
} CSecToLook; } CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p); void SecToLook_CreateVTable(CSecToLook *p);
typedef struct typedef struct
{ {
ISeqInStream s; ISeqInStream vt;
ILookInStream *realStream; const ILookInStream *realStream;
} CSecToRead; } CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p); void SecToRead_CreateVTable(CSecToRead *p);
typedef struct
typedef struct ICompressProgress ICompressProgress;
struct ICompressProgress
{ {
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break. /* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */ Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress; };
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{ {
void *(*Alloc)(void *p, size_t size); void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */ void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
} ISzAlloc; };
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef MY_container_of
/*
#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
#endif
#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
/*
#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
*/
#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
*/
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#ifdef _WIN32 #ifdef _WIN32

View File

@ -1,14 +1,21 @@
#define MY_VER_MAJOR 16 #define MY_VER_MAJOR 18
#define MY_VER_MINOR 04 #define MY_VER_MINOR 05
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "16.04" #define MY_VERSION_NUMBERS "18.05"
#define MY_VERSION "16.04" #define MY_VERSION MY_VERSION_NUMBERS
#define MY_DATE "2016-10-04"
#ifdef MY_CPU_NAME
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
#else
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2018-04-30"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov" #define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR #ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR
@ -16,4 +23,5 @@
#define MY_COPYRIGHT MY_COPYRIGHT_PD #define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif #endif
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE #define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE

View File

@ -1,5 +1,5 @@
/* Bra86.c -- Converter for x86 code (BCJ) /* Bra86.c -- Converter for x86 code (BCJ)
2013-11-12 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
else else
{ {
mask >>= (unsigned)d; mask >>= (unsigned)d;
if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
{ {
mask = (mask >> 1) | 4; mask = (mask >> 1) | 4;
pos++; pos++;

View File

@ -1,5 +1,5 @@
/* Compiler.h /* Compiler.h
2015-08-02 : Igor Pavlov : Public domain */ 2017-04-03 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H #ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H #define __7Z_COMPILER_H
@ -21,6 +21,7 @@
#pragma warning(disable : 4514) // unreferenced inline function has been removed #pragma warning(disable : 4514) // unreferenced inline function has been removed
#pragma warning(disable : 4702) // unreachable code #pragma warning(disable : 4702) // unreachable code
#pragma warning(disable : 4710) // not inlined #pragma warning(disable : 4710) // not inlined
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
#endif #endif

View File

@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2016-06-09: Igor Pavlov : Public domain */ 2017-09-04 : Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
*/ */
#if defined(_M_X64) \ #if defined(_M_X64) \
|| defined(_M_AMD64) \ || defined(_M_AMD64) \
|| defined(__x86_64__) \ || defined(__x86_64__) \
|| defined(__AMD64__) \ || defined(__AMD64__) \
|| defined(__amd64__) || defined(__amd64__)
#define MY_CPU_AMD64 #define MY_CPU_AMD64
#endif #ifdef __ILP32__
#define MY_CPU_NAME "x32"
#if defined(MY_CPU_AMD64) \ #else
|| defined(_M_IA64) \ #define MY_CPU_NAME "x64"
|| defined(__AARCH64EL__) \ #endif
|| defined(__AARCH64EB__)
#define MY_CPU_64BIT #define MY_CPU_64BIT
#endif #endif
#if defined(_M_IX86) || defined(__i386__)
#define MY_CPU_X86 #if defined(_M_IX86) \
|| defined(__i386__)
#define MY_CPU_X86
#define MY_CPU_NAME "x86"
#define MY_CPU_32BIT
#endif #endif
#if defined(_M_ARM64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
#define MY_CPU_NAME "arm64"
#define MY_CPU_64BIT
#endif
#if defined(_M_ARM) \
|| defined(_M_ARM_NT) \
|| defined(_M_ARMT) \
|| defined(__arm__) \
|| defined(__thumb__) \
|| defined(__ARMEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEL__) \
|| defined(__THUMBEB__)
#define MY_CPU_ARM
#define MY_CPU_NAME "arm"
#define MY_CPU_32BIT
#endif
#if defined(_M_IA64) \
|| defined(__ia64__)
#define MY_CPU_IA64
#define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT
#endif
#if defined(__mips64) \
|| defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT
#elif defined(__mips__)
#define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */
#endif
#if defined(__ppc64__) \
|| defined(__powerpc64__)
#ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32"
#else
#define MY_CPU_NAME "ppc64"
#endif
#define MY_CPU_64BIT
#elif defined(__ppc__) \
|| defined(__powerpc__)
#define MY_CPU_NAME "ppc"
#define MY_CPU_32BIT
#endif
#if defined(__sparc64__)
#define MY_CPU_NAME "sparc64"
#define MY_CPU_64BIT
#elif defined(__sparc__)
#define MY_CPU_NAME "sparc"
/* #define MY_CPU_32BIT */
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64 #define MY_CPU_X86_OR_AMD64
#endif #endif
#if defined(MY_CPU_X86) \
|| defined(_M_ARM) \ #ifdef _WIN32
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \ #ifdef MY_CPU_ARM
|| defined(__ARMEB__) \ #define MY_CPU_ARM_LE
|| defined(__THUMBEB__) #endif
#define MY_CPU_32BIT
#ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE
#endif
#ifdef _M_IA64
#define MY_CPU_IA64_LE
#endif
#endif #endif
#if defined(_WIN32) && defined(_M_ARM)
#define MY_CPU_ARM_LE
#endif
#if defined(_WIN32) && defined(_M_IA64)
#define MY_CPU_IA64_LE
#endif
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \ || defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \ || defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \ || defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \ || defined(__ARMEL__) \
@ -86,14 +160,37 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE) #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian #error Stop_Compiling_Bad_Endian
#endif #endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT
#endif
#ifndef MY_CPU_NAME
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE"
#else
/*
#define MY_CPU_NAME ""
*/
#endif
#endif
#ifdef MY_CPU_LE #ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \ #if defined(MY_CPU_X86_OR_AMD64) \
/* || defined(__AARCH64EL__) */ || defined(MY_CPU_ARM64) \
|| defined(__ARM_FEATURE_UNALIGNED)
#define MY_CPU_LE_UNALIGN #define MY_CPU_LE_UNALIGN
#endif #endif
#endif #endif
@ -139,6 +236,11 @@ Stop_Compiling_Bad_Endian
#endif #endif
#ifdef __has_builtin
#define MY__has_builtin(x) __has_builtin(x)
#else
#define MY__has_builtin(x) 0
#endif
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
@ -146,15 +248,21 @@ Stop_Compiling_Bad_Endian
#include <stdlib.h> #include <stdlib.h>
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong) #pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64) #pragma intrinsic(_byteswap_uint64)
/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) #elif defined(MY_CPU_LE_UNALIGN) && ( \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|| (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
@ -179,10 +287,14 @@ Stop_Compiling_Bad_Endian
#endif #endif
#ifndef GetBe16
#define GetBe16(p) ( (UInt16) ( \ #define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \ ((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] )) ((const Byte *)(p))[1] ))
#endif
#ifdef MY_CPU_X86_OR_AMD64 #ifdef MY_CPU_X86_OR_AMD64

View File

@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms /* LzFind.c -- Match finder for LZ algorithms
2015-10-15 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@ -18,18 +18,18 @@
#define kStartMaxLen 3 #define kStartMaxLen 3
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
{ {
if (!p->directInput) if (!p->directInput)
{ {
alloc->Free(alloc, p->bufferBase); ISzAlloc_Free(alloc, p->bufferBase);
p->bufferBase = NULL; p->bufferBase = NULL;
} }
} }
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
{ {
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
if (p->directInput) if (p->directInput)
@ -41,7 +41,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
{ {
LzInWindow_Free(p, alloc); LzInWindow_Free(p, alloc);
p->blockSize = blockSize; p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
} }
return (p->bufferBase != NULL); return (p->bufferBase != NULL);
} }
@ -83,7 +83,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
if (size == 0) if (size == 0)
return; return;
p->result = p->stream->Read(p->stream, dest, &size); p->result = ISeqInStream_Read(p->stream, dest, &size);
if (p->result != SZ_OK) if (p->result != SZ_OK)
return; return;
if (size == 0) if (size == 0)
@ -144,6 +144,7 @@ void MatchFinder_Construct(CMatchFinder *p)
p->bufferBase = NULL; p->bufferBase = NULL;
p->directInput = 0; p->directInput = 0;
p->hash = NULL; p->hash = NULL;
p->expectedDataSize = (UInt64)(Int64)-1;
MatchFinder_SetDefaultSettings(p); MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -151,34 +152,34 @@ void MatchFinder_Construct(CMatchFinder *p)
UInt32 r = i; UInt32 r = i;
unsigned j; unsigned j;
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
p->crc[i] = r; p->crc[i] = r;
} }
} }
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->hash); ISzAlloc_Free(alloc, p->hash);
p->hash = NULL; p->hash = NULL;
} }
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
{ {
MatchFinder_FreeThisClassMemory(p, alloc); MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc); LzInWindow_Free(p, alloc);
} }
static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
{ {
size_t sizeInBytes = (size_t)num * sizeof(CLzRef); size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num) if (sizeInBytes / sizeof(CLzRef) != num)
return NULL; return NULL;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
} }
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc) ISzAllocPtr alloc)
{ {
UInt32 sizeReserv; UInt32 sizeReserv;
@ -210,7 +211,11 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
hs = (1 << 16) - 1; hs = (1 << 16) - 1;
else else
{ {
hs = historySize - 1; hs = historySize;
if (hs > p->expectedDataSize)
hs = (UInt32)p->expectedDataSize;
if (hs != 0)
hs--;
hs |= (hs >> 1); hs |= (hs >> 1);
hs |= (hs >> 2); hs |= (hs >> 2);
hs |= (hs >> 4); hs |= (hs >> 4);
@ -294,17 +299,33 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
p->posLimit = p->pos + limit; p->posLimit = p->pos + limit;
} }
void MatchFinder_Init_2(CMatchFinder *p, int readData)
void MatchFinder_Init_LowHash(CMatchFinder *p)
{
size_t i;
CLzRef *items = p->hash;
size_t numItems = p->fixedHashSize;
for (i = 0; i < numItems; i++)
items[i] = kEmptyHashValue;
}
void MatchFinder_Init_HighHash(CMatchFinder *p)
{
size_t i;
CLzRef *items = p->hash + p->fixedHashSize;
size_t numItems = (size_t)p->hashMask + 1;
for (i = 0; i < numItems; i++)
items[i] = kEmptyHashValue;
}
void MatchFinder_Init_3(CMatchFinder *p, int readData)
{ {
UInt32 i;
UInt32 *hash = p->hash;
UInt32 num = p->hashSizeSum;
for (i = 0; i < num; i++)
hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0; p->cyclicBufferPos = 0;
p->buffer = p->bufferBase; p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize; p->pos =
p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK; p->result = SZ_OK;
p->streamEndWasReached = 0; p->streamEndWasReached = 0;
@ -314,10 +335,14 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData)
MatchFinder_SetLimits(p); MatchFinder_SetLimits(p);
} }
void MatchFinder_Init(CMatchFinder *p) void MatchFinder_Init(CMatchFinder *p)
{ {
MatchFinder_Init_2(p, True); MatchFinder_Init_HighHash(p);
MatchFinder_Init_LowHash(p);
MatchFinder_Init_3(p, True);
} }
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{ {
@ -560,10 +585,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
d2 = pos - hash[h2]; d2 = pos - hash[h2];
curMatch = hash[kFix3HashSize + hv]; curMatch = (hash + kFix3HashSize)[hv];
hash[h2] = pos; hash[h2] = pos;
hash[kFix3HashSize + hv] = pos; (hash + kFix3HashSize)[hv] = pos;
maxLen = 2; maxLen = 2;
offset = 0; offset = 0;
@ -596,13 +621,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + hv] = pos; (hash + kFix4HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -617,7 +642,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{ {
maxLen = 3; maxLen = 3;
distances[offset + 1] = d3 - 1; distances[(size_t)offset + 1] = d3 - 1;
offset += 2; offset += 2;
d2 = d3; d2 = d3;
} }
@ -625,7 +650,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@ -652,15 +677,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
d4 = pos - hash[kFix4HashSize + h4]; d4 = pos - (hash + kFix4HashSize)[h4];
curMatch = hash[kFix5HashSize + hv]; curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + h4] = pos; (hash + kFix4HashSize)[h4] = pos;
hash[kFix5HashSize + hv] = pos; (hash + kFix5HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -693,7 +718,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
&& *(cur - d4 + 3) == *(cur + 3)) && *(cur - d4 + 3) == *(cur + 3))
{ {
maxLen = 4; maxLen = 4;
distances[offset + 1] = d4 - 1; distances[(size_t)offset + 1] = d4 - 1;
offset += 2; offset += 2;
d2 = d4; d2 = d4;
} }
@ -701,7 +726,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@ -728,13 +753,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + hv] = pos; (hash + kFix4HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -749,7 +774,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{ {
maxLen = 3; maxLen = 3;
distances[offset + 1] = d3 - 1; distances[(size_t)offset + 1] = d3 - 1;
offset += 2; offset += 2;
d2 = d3; d2 = d3;
} }
@ -757,7 +782,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
@ -786,15 +811,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
pos = p->pos; pos = p->pos;
d2 = pos - hash[ h2]; d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3]; d3 = pos - (hash + kFix3HashSize)[h3];
d4 = pos - hash[kFix4HashSize + h4]; d4 = pos - (hash + kFix4HashSize)[h4];
curMatch = hash[kFix5HashSize + hv]; curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = pos; hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos; (hash + kFix3HashSize)[h3] = pos;
hash[kFix4HashSize + h4] = pos; (hash + kFix4HashSize)[h4] = pos;
hash[kFix5HashSize + hv] = pos; (hash + kFix5HashSize)[hv] = pos;
maxLen = 0; maxLen = 0;
offset = 0; offset = 0;
@ -827,7 +852,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
&& *(cur - d4 + 3) == *(cur + 3)) && *(cur - d4 + 3) == *(cur + 3))
{ {
maxLen = 4; maxLen = 4;
distances[offset + 1] = d4 - 1; distances[(size_t)offset + 1] = d4 - 1;
offset += 2; offset += 2;
d2 = d4; d2 = d4;
} }
@ -835,7 +860,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
if (offset != 0) if (offset != 0)
{ {
UPDATE_maxLen UPDATE_maxLen
distances[offset - 2] = maxLen; distances[(size_t)offset - 2] = maxLen;
if (maxLen == lenLimit) if (maxLen == lenLimit)
{ {
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
@ -899,9 +924,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(3) SKIP_HEADER(3)
HASH3_CALC; HASH3_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix3HashSize + hv]; curMatch = (hash + kFix3HashSize)[hv];
hash[h2] = hash[h2] =
hash[kFix3HashSize + hv] = p->pos; (hash + kFix3HashSize)[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@ -916,10 +941,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + hv] = p->pos; (hash + kFix4HashSize)[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@ -935,11 +960,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(5) SKIP_HEADER(5)
HASH5_CALC; HASH5_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix5HashSize + hv]; curMatch = (hash + kFix5HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + h4] = (hash + kFix4HashSize)[h4] =
hash[kFix5HashSize + hv] = p->pos; (hash + kFix5HashSize)[hv] = p->pos;
SKIP_FOOTER SKIP_FOOTER
} }
while (--num != 0); while (--num != 0);
@ -955,10 +980,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
hash = p->hash; hash = p->hash;
curMatch = hash[kFix4HashSize + hv]; curMatch = (hash + kFix4HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + hv] = p->pos; (hash + kFix4HashSize)[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS MOVE_POS
} }
@ -975,11 +1000,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
SKIP_HEADER(5) SKIP_HEADER(5)
HASH5_CALC; HASH5_CALC;
hash = p->hash; hash = p->hash;
curMatch = p->hash[kFix5HashSize + hv]; curMatch = hash + kFix5HashSize)[hv];
hash[ h2] = hash[ h2] =
hash[kFix3HashSize + h3] = (hash + kFix3HashSize)[h3] =
hash[kFix4HashSize + h4] = (hash + kFix4HashSize)[h4] =
hash[kFix5HashSize + hv] = p->pos; (hash + kFix5HashSize)[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch; p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS MOVE_POS
} }

View File

@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2015-10-15 : Igor Pavlov : Public domain */ 2017-06-10 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H #ifndef __LZ_FIND_H
#define __LZ_FIND_H #define __LZ_FIND_H
@ -47,6 +47,8 @@ typedef struct _CMatchFinder
SRes result; SRes result;
UInt32 crc[256]; UInt32 crc[256];
size_t numRefs; size_t numRefs;
UInt64 expectedDataSize;
} CMatchFinder; } CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
@ -71,8 +73,8 @@ void MatchFinder_Construct(CMatchFinder *p);
*/ */
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc); ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
@ -103,7 +105,9 @@ typedef struct _IMatchFinder
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init_2(CMatchFinder *p, int readData); void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_3(CMatchFinder *p, int readData);
void MatchFinder_Init(CMatchFinder *p); void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);

View File

@ -1,8 +1,9 @@
/* LzmaDec.c -- LZMA Decoder /* LzmaDec.c -- LZMA Decoder
2016-05-16 : Igor Pavlov : Public domain */ 2018-02-28 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
/* #include "CpuArch.h" */
#include "LzmaDec.h" #include "LzmaDec.h"
#ifndef EFIAPI #ifndef EFIAPI
@ -26,9 +27,16 @@
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
{ UPDATE_0(p); i = (i + i); A0; } else \ { UPDATE_0(p); i = (i + i); A0; } else \
{ UPDATE_1(p); i = (i + i) + 1; A1; } { UPDATE_1(p); i = (i + i) + 1; A1; }
#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
{ UPDATE_0(p + i); A0; } else \
{ UPDATE_1(p + i); A1; }
#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
#define TREE_DECODE(probs, limit, i) \ #define TREE_DECODE(probs, limit, i) \
{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
@ -48,12 +56,15 @@
i -= 0x40; } i -= 0x40; }
#endif #endif
#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol) #define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
#define MATCHED_LITER_DEC \ #define MATCHED_LITER_DEC \
matchByte <<= 1; \ matchByte += matchByte; \
bit = (matchByte & offs); \ bit = offs; \
probLit = prob + offs + bit + symbol; \ offs &= matchByte; \
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) probLit = prob + (offs + bit + symbol); \
GET_BIT2(probLit, symbol, offs ^= bit; , ;)
#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
@ -68,25 +79,28 @@
{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
{ UPDATE_0_CHECK; i += m; m += m; } else \
{ UPDATE_1_CHECK; m += m; i += m; }
#define kNumPosBitsMax 4 #define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax) #define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3 #define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits) #define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8 #define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits) #define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0 #define LenLow 0
#define LenChoice2 (LenChoice + 1) #define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols) #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define LenChoice LenLow
#define LenChoice2 (LenLow + (1 << kLenNumLowBits))
#define kNumStates 12 #define kNumStates 12
#define kNumStates2 16
#define kNumLitStates 7 #define kNumLitStates 7
#define kStartPosModelIndex 4 #define kStartPosModelIndex 4
@ -100,54 +114,117 @@
#define kAlignTableSize (1 << kNumAlignBits) #define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2 #define kMatchMinLen 2
#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) #define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
#define IsMatch 0 /* External ASM code needs same CLzmaProb array layout. So don't change it. */
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
/* (probs_1664) is faster and better for code size at some platforms */
/*
#ifdef MY_CPU_X86_OR_AMD64
*/
#define kStartOffset 1664
#define GET_PROBS p->probs_1664
/*
#define GET_PROBS p->probs + kStartOffset
#else
#define kStartOffset 0
#define GET_PROBS p->probs
#endif
*/
#define SpecPos (-kStartOffset)
#define IsRep0Long (SpecPos + kNumFullDistances)
#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))
#define LenCoder (RepLenCoder + kNumLenProbs)
#define IsMatch (LenCoder + kNumLenProbs)
#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))
#define IsRep (Align + kAlignTableSize)
#define IsRepG0 (IsRep + kNumStates) #define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates) #define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates) #define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates) #define PosSlot (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) #define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) #define NUM_BASE_PROBS (Literal + kStartOffset)
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846 #if Align != 0 && kStartOffset != 0
#define LZMA_LIT_SIZE 0x300 #error Stop_Compiling_Bad_LZMA_kAlign
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif #endif
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) #if NUM_BASE_PROBS != 1984
#error Stop_Compiling_Bad_LZMA_PROBS
#endif
#define LZMA_LIT_SIZE 0x300
#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
#define COMBINED_PS_STATE (posState + state)
#define GET_LEN_STATE (posState)
#define LZMA_DIC_MIN (1 << 12) #define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded. /*
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization p->remainLen : shows status of LZMA decoder:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : need init range coder
= kMatchSpecLenStart + 2 : need init range coder and state
*/
/* ---------- LZMA_DECODE_REAL ---------- */
/*
LzmaDec_DecodeReal_3() can be implemented in external ASM file.
3 - is the code compatibility version of that function for check at link time.
*/
#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
/*
LZMA_DECODE_REAL()
In:
RangeCoder is normalized
if (p->dicPos == limit)
{
LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
is not END_OF_PAYALOAD_MARKER, then function returns error code.
}
Processing:
first LZMA symbol will be decoded in any case
All checks for limits are at the end of main loop,
It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
Out: Out:
RangeCoder is normalized
Result: Result:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_DATA - Error SZ_ERROR_DATA - Error
p->remainLen: p->remainLen:
< kMatchSpecLenStart : normal remain < kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished = kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker (unused now)
= kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/ */
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
CLzmaProb *probs = p->probs;
unsigned state = p->state; #ifdef _LZMA_DEC_OPT
int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);
#else
static
int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{
CLzmaProb *probs = GET_PROBS;
unsigned state = (unsigned)p->state;
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
unsigned lc = p->prop.lc; unsigned lc = p->prop.lc;
unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);
Byte *dic = p->dic; Byte *dic = p->dic;
SizeT dicBufSize = p->dicBufSize; SizeT dicBufSize = p->dicBufSize;
@ -166,17 +243,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
CLzmaProb *prob; CLzmaProb *prob;
UInt32 bound; UInt32 bound;
unsigned ttt; unsigned ttt;
unsigned posState = processedPos & pbMask; unsigned posState = CALC_POS_STATE(processedPos, pbMask);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; prob = probs + IsMatch + COMBINED_PS_STATE;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
unsigned symbol; unsigned symbol;
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + Literal; prob = probs + Literal;
if (processedPos != 0 || checkDicSize != 0) if (processedPos != 0 || checkDicSize != 0)
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
processedPos++; processedPos++;
if (state < kNumLitStates) if (state < kNumLitStates)
@ -242,13 +318,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
else else
{ {
UPDATE_1(prob); UPDATE_1(prob);
/*
// that case was checked before with kBadRepCode
if (checkDicSize == 0 && processedPos == 0) if (checkDicSize == 0 && processedPos == 0)
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
*/
prob = probs + IsRepG0 + state; prob = probs + IsRepG0 + state;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob); UPDATE_0(prob);
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; prob = probs + IsRep0Long + COMBINED_PS_STATE;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
UPDATE_0(prob); UPDATE_0(prob);
@ -301,7 +380,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + GET_LEN_STATE;
offset = 0; offset = 0;
lim = (1 << kLenNumLowBits); lim = (1 << kLenNumLowBits);
} }
@ -312,15 +391,15 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
lim = (1 << kLenNumMidBits); lim = (1 << kLenNumLowBits);
} }
else else
{ {
UPDATE_1(probLen); UPDATE_1(probLen);
probLen = prob + LenHigh; probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols; offset = kLenNumLowSymbols * 2;
lim = (1 << kLenNumHighBits); lim = (1 << kLenNumHighBits);
} }
} }
@ -333,7 +412,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + GET_LEN_STATE;
len = 1; len = 1;
TREE_GET_BIT(probLen, len); TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len); TREE_GET_BIT(probLen, len);
@ -347,7 +426,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
len = 1; len = 1;
TREE_GET_BIT(probLen, len); TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len); TREE_GET_BIT(probLen, len);
@ -358,7 +437,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
UPDATE_1(probLen); UPDATE_1(probLen);
probLen = prob + LenHigh; probLen = prob + LenHigh;
TREE_DECODE(probLen, (1 << kLenNumHighBits), len); TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
len += kLenNumLowSymbols + kLenNumMidSymbols; len += kLenNumLowSymbols * 2;
} }
} }
} }
@ -378,16 +457,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (posSlot < kEndPosModelIndex) if (posSlot < kEndPosModelIndex)
{ {
distance <<= numDirectBits; distance <<= numDirectBits;
prob = probs + SpecPos + distance - posSlot - 1; prob = probs + SpecPos;
{ {
UInt32 mask = 1; UInt32 m = 1;
unsigned i = 1; distance++;
do do
{ {
GET_BIT2(prob + i, i, ; , distance |= mask); REV_BIT_VAR(prob, distance, m);
mask <<= 1;
} }
while (--numDirectBits != 0); while (--numDirectBits);
distance -= m;
} }
} }
else else
@ -414,19 +493,20 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
} }
*/ */
} }
while (--numDirectBits != 0); while (--numDirectBits);
prob = probs + Align; prob = probs + Align;
distance <<= kNumAlignBits; distance <<= kNumAlignBits;
{ {
unsigned i = 1; unsigned i = 1;
GET_BIT2(prob + i, i, ; , distance |= 1); REV_BIT_CONST(prob, i, 1);
GET_BIT2(prob + i, i, ; , distance |= 2); REV_BIT_CONST(prob, i, 2);
GET_BIT2(prob + i, i, ; , distance |= 4); REV_BIT_CONST(prob, i, 4);
GET_BIT2(prob + i, i, ; , distance |= 8); REV_BIT_LAST (prob, i, 8);
distance |= i;
} }
if (distance == (UInt32)0xFFFFFFFF) if (distance == (UInt32)0xFFFFFFFF)
{ {
len += kMatchSpecLenStart; len = kMatchSpecLenStart;
state -= kNumStates; state -= kNumStates;
break; break;
} }
@ -437,20 +517,12 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
rep2 = rep1; rep2 = rep1;
rep1 = rep0; rep1 = rep0;
rep0 = distance + 1; rep0 = distance + 1;
if (checkDicSize == 0) state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
{ if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
if (distance >= processedPos)
{
p->dicPos = dicPos;
return SZ_ERROR_DATA;
}
}
else if (distance >= checkDicSize)
{ {
p->dicPos = dicPos; p->dicPos = dicPos;
return SZ_ERROR_DATA; return SZ_ERROR_DATA;
} }
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
} }
len += kMatchMinLen; len += kMatchMinLen;
@ -513,6 +585,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
return SZ_OK; return SZ_OK;
} }
#endif
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
{ {
@ -521,7 +594,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
Byte *dic = p->dic; Byte *dic = p->dic;
SizeT dicPos = p->dicPos; SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize; SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen; unsigned len = (unsigned)p->remainLen;
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
SizeT rem = limit - dicPos; SizeT rem = limit - dicPos;
if (rem < len) if (rem < len)
@ -542,6 +615,14 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
} }
} }
#define kRange0 0xFFFFFFFF
#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
#if kBadRepCode != (0xC0000000 - 0x400)
#error Stop_Compiling_Bad_LZMA_Check
#endif
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
{ {
do do
@ -552,9 +633,13 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
UInt32 rem = p->prop.dicSize - p->processedPos; UInt32 rem = p->prop.dicSize - p->processedPos;
if (limit - p->dicPos > rem) if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem; limit2 = p->dicPos + rem;
if (p->processedPos == 0)
if (p->code >= kBadRepCode)
return SZ_ERROR_DATA;
} }
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit));
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = p->prop.dicSize;
@ -563,9 +648,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
} }
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
p->remainLen = kMatchSpecLenStart;
return 0; return 0;
} }
@ -582,17 +664,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range; UInt32 range = p->range;
UInt32 code = p->code; UInt32 code = p->code;
const Byte *bufLimit = buf + inSize; const Byte *bufLimit = buf + inSize;
const CLzmaProb *probs = p->probs; const CLzmaProb *probs = GET_PROBS;
unsigned state = p->state; unsigned state = (unsigned)p->state;
ELzmaDummy res; ELzmaDummy res;
{ {
const CLzmaProb *prob; const CLzmaProb *prob;
UInt32 bound; UInt32 bound;
unsigned ttt; unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; prob = probs + IsMatch + COMBINED_PS_STATE;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK UPDATE_0_CHECK
@ -620,10 +702,11 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
{ {
unsigned bit; unsigned bit;
const CLzmaProb *probLit; const CLzmaProb *probLit;
matchByte <<= 1; matchByte += matchByte;
bit = (matchByte & offs); bit = offs;
probLit = prob + offs + bit + symbol; offs &= matchByte;
GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) probLit = prob + (offs + bit + symbol);
GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )
} }
while (symbol < 0x100); while (symbol < 0x100);
} }
@ -650,7 +733,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; prob = probs + IsRep0Long + COMBINED_PS_STATE;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
@ -693,7 +776,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
probLen = prob + LenLow + (posState << kLenNumLowBits); probLen = prob + LenLow + GET_LEN_STATE;
offset = 0; offset = 0;
limit = 1 << kLenNumLowBits; limit = 1 << kLenNumLowBits;
} }
@ -704,15 +787,15 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
probLen = prob + LenMid + (posState << kLenNumMidBits); probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
offset = kLenNumLowSymbols; offset = kLenNumLowSymbols;
limit = 1 << kLenNumMidBits; limit = 1 << kLenNumLowBits;
} }
else else
{ {
UPDATE_1_CHECK; UPDATE_1_CHECK;
probLen = prob + LenHigh; probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols; offset = kLenNumLowSymbols * 2;
limit = 1 << kLenNumHighBits; limit = 1 << kLenNumHighBits;
} }
} }
@ -724,7 +807,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
{ {
unsigned posSlot; unsigned posSlot;
prob = probs + PosSlot + prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits); kNumPosSlotBits);
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex) if (posSlot >= kStartPosModelIndex)
@ -735,7 +818,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
if (posSlot < kEndPosModelIndex) if (posSlot < kEndPosModelIndex)
{ {
prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);
} }
else else
{ {
@ -747,17 +830,18 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
code -= range & (((code - range) >> 31) - 1); code -= range & (((code - range) >> 31) - 1);
/* if (code >= range) code -= range; */ /* if (code >= range) code -= range; */
} }
while (--numDirectBits != 0); while (--numDirectBits);
prob = probs + Align; prob = probs + Align;
numDirectBits = kNumAlignBits; numDirectBits = kNumAlignBits;
} }
{ {
unsigned i = 1; unsigned i = 1;
unsigned m = 1;
do do
{ {
GET_BIT_CHECK(prob + i, i); REV_BIT_CHECK(prob, i, m);
} }
while (--numDirectBits != 0); while (--numDirectBits);
} }
} }
} }
@ -770,18 +854,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{ {
p->needFlush = 1; p->remainLen = kMatchSpecLenStart + 1;
p->remainLen = 0;
p->tempBufSize = 0; p->tempBufSize = 0;
if (initDic) if (initDic)
{ {
p->processedPos = 0; p->processedPos = 0;
p->checkDicSize = 0; p->checkDicSize = 0;
p->needInitState = 1; p->remainLen = kMatchSpecLenStart + 2;
} }
if (initState) if (initState)
p->needInitState = 1; p->remainLen = kMatchSpecLenStart + 2;
} }
void LzmaDec_Init(CLzmaDec *p) void LzmaDec_Init(CLzmaDec *p)
@ -790,53 +873,54 @@ void LzmaDec_Init(CLzmaDec *p)
LzmaDec_InitDicAndState(p, True, True); LzmaDec_InitDicAndState(p, True, True);
} }
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
p->needInitState = 0;
}
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status) ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT inSize = *srcLen; SizeT inSize = *srcLen;
(*srcLen) = 0; (*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit);
*status = LZMA_STATUS_NOT_SPECIFIED; *status = LZMA_STATUS_NOT_SPECIFIED;
if (p->remainLen > kMatchSpecLenStart)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize != 0 && p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
p->code =
((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->tempBufSize = 0;
if (p->remainLen > kMatchSpecLenStart + 1)
{
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
}
p->remainLen = 0;
}
LzmaDec_WriteRem(p, dicLimit);
while (p->remainLen != kMatchSpecLenStart) while (p->remainLen != kMatchSpecLenStart)
{ {
int checkEndMarkNow; int checkEndMarkNow = 0;
if (p->needFlush)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE)
{
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK;
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
p->code =
((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
p->tempBufSize = 0;
}
checkEndMarkNow = 0;
if (p->dicPos >= dicLimit) if (p->dicPos >= dicLimit)
{ {
if (p->remainLen == 0 && p->code == 0) if (p->remainLen == 0 && p->code == 0)
@ -857,9 +941,6 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
checkEndMarkNow = 1; checkEndMarkNow = 1;
} }
if (p->needInitState)
LzmaDec_InitStateReal(p);
if (p->tempBufSize == 0) if (p->tempBufSize == 0)
{ {
SizeT processed; SizeT processed;
@ -932,11 +1013,14 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->tempBufSize = 0; p->tempBufSize = 0;
} }
} }
if (p->code == 0)
*status = LZMA_STATUS_FINISHED_WITH_MARK; if (p->code != 0)
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; return SZ_ERROR_DATA;
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
} }
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT outSize = *destLen; SizeT outSize = *destLen;
@ -977,19 +1061,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
} }
} }
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->probs); ISzAlloc_Free(alloc, p->probs);
p->probs = NULL; p->probs = NULL;
} }
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
{ {
alloc->Free(alloc, p->dic); ISzAlloc_Free(alloc, p->dic);
p->dic = NULL; p->dic = NULL;
} }
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
@ -1013,29 +1097,30 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
if (d >= (9 * 5 * 5)) if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED; return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9; p->lc = (Byte)(d % 9);
d /= 9; d /= 9;
p->pb = d / 5; p->pb = (Byte)(d / 5);
p->lp = d % 5; p->lp = (Byte)(d % 5);
return SZ_OK; return SZ_OK;
} }
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
{ {
UInt32 numProbs = LzmaProps_GetNumProbs(propNew); UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (!p->probs || numProbs != p->numProbs) if (!p->probs || numProbs != p->numProbs)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (!p->probs) if (!p->probs)
return SZ_ERROR_MEM; return SZ_ERROR_MEM;
p->probs_1664 = p->probs + 1664;
p->numProbs = numProbs;
} }
return SZ_OK; return SZ_OK;
} }
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{ {
CLzmaProps propNew; CLzmaProps propNew;
RINOK(LzmaProps_Decode(&propNew, props, propsSize)); RINOK(LzmaProps_Decode(&propNew, props, propsSize));
@ -1044,7 +1129,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
return SZ_OK; return SZ_OK;
} }
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
{ {
CLzmaProps propNew; CLzmaProps propNew;
SizeT dicBufSize; SizeT dicBufSize;
@ -1064,7 +1149,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
if (!p->dic || dicBufSize != p->dicBufSize) if (!p->dic || dicBufSize != p->dicBufSize)
{ {
LzmaDec_FreeDict(p, alloc); LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
if (!p->dic) if (!p->dic)
{ {
LzmaDec_FreeProbs(p, alloc); LzmaDec_FreeProbs(p, alloc);
@ -1078,7 +1163,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc) ELzmaStatus *status, ISzAllocPtr alloc)
{ {
CLzmaDec p; CLzmaDec p;
SRes res; SRes res;

View File

@ -1,5 +1,5 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2013-01-18 : Igor Pavlov : Public domain */ 2018-04-21 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H #ifndef __LZMA_DEC_H
#define __LZMA_DEC_H #define __LZMA_DEC_H
@ -12,11 +12,13 @@ EXTERN_C_BEGIN
/* _LZMA_PROB32 can increase the speed on some CPUs, /* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */ but memory usage for CLzmaDec::probs will be doubled in that case */
typedef
#ifdef _LZMA_PROB32 #ifdef _LZMA_PROB32
#define CLzmaProb UInt32 UInt32
#else #else
#define CLzmaProb UInt16 UInt16
#endif #endif
CLzmaProb;
/* ---------- LZMA Properties ---------- */ /* ---------- LZMA Properties ---------- */
@ -25,7 +27,10 @@ EXTERN_C_BEGIN
typedef struct _CLzmaProps typedef struct _CLzmaProps
{ {
unsigned lc, lp, pb; Byte lc;
Byte lp;
Byte pb;
Byte _pad_;
UInt32 dicSize; UInt32 dicSize;
} CLzmaProps; } CLzmaProps;
@ -47,32 +52,34 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
typedef struct typedef struct
{ {
/* Don't change this structure. ASM code can use it. */
CLzmaProps prop; CLzmaProps prop;
CLzmaProb *probs; CLzmaProb *probs;
CLzmaProb *probs_1664;
Byte *dic; Byte *dic;
const Byte *buf;
UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize; SizeT dicBufSize;
SizeT dicPos;
const Byte *buf;
UInt32 range;
UInt32 code;
UInt32 processedPos; UInt32 processedPos;
UInt32 checkDicSize; UInt32 checkDicSize;
unsigned state;
UInt32 reps[4]; UInt32 reps[4];
unsigned remainLen; UInt32 state;
int needFlush; UInt32 remainLen;
int needInitState;
UInt32 numProbs; UInt32 numProbs;
unsigned tempBufSize; unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } #define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
void LzmaDec_Init(CLzmaDec *p); void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams: /* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum typedef enum
{ {
@ -129,11 +136,11 @@ LzmaDec_Allocate* can return:
SZ_ERROR_UNSUPPORTED - Unsupported properties SZ_ERROR_UNSUPPORTED - Unsupported properties
*/ */
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */ /* ---------- Dictionary Interface ---------- */
@ -142,7 +149,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
You must work with CLzmaDec variables directly in this interface. You must work with CLzmaDec variables directly in this interface.
STEPS: STEPS:
LzmaDec_Constr() LzmaDec_Construct()
LzmaDec_Allocate() LzmaDec_Allocate()
for (each new stream) for (each new stream)
{ {
@ -220,7 +227,7 @@ Returns:
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc); ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END EXTERN_C_END

View File

@ -1,6 +1,67 @@
HISTORY of the LZMA SDK HISTORY of the LZMA SDK
----------------------- -----------------------
18.05 2018-04-30
-------------------------
- The speed for LZMA/LZMA2 compressing was increased
by 8% for fastest/fast compression levels and
by 3% for normal/maximum compression levels.
- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in
Windows 10 because of some BUG with "Large Pages" in Windows 10.
Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299).
- The BUG was fixed in Lzma2Enc.c
Lzma2Enc_Encode2() function worked incorretly,
if (inStream == NULL) and the number of block threads is more than 1.
18.03 beta 2018-03-04
-------------------------
- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm
for x64 with about 30% higher speed than main version of LZMA decoder written in C.
- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%.
- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
if there are multiple independent data chunks in LZMA2 stream.
- 7-Zip now can use multi-threading for xz decoding,
if there are multiple blocks in xz stream.
18.01 2019-01-28
-------------------------
- The BUG in 17.01 - 18.00 beta was fixed:
XzDec.c : random block unpacking and XzUnpacker_IsBlockFinished()
didn't work correctly for xz archives without checksum (CRC).
18.00 beta 2019-01-10
-------------------------
- The BUG in xz encoder was fixed:
There was memory leak of 16 KB for each file compressed with
xz compression method, if additional filter was used.
17.01 beta 2017-08-28
-------------------------
- Minor speed optimization for LZMA2 (xz and 7z) multi-threading compression.
7-Zip now uses additional memory buffers for multi-block LZMA2 compression.
CPU utilization was slightly improved.
- 7-zip now creates multi-block xz archives by default. Block size can be
specified with -ms[Size]{m|g} switch.
- xz decoder now can unpack random block from multi-block xz archives.
- 7-Zip command line: @listfile now doesn't work after -- switch.
Use -i@listfile before -- switch instead.
- The BUGs were fixed:
7-Zip 17.00 beta crashed for commands that write anti-item to 7z archive.
17.00 beta 2017-04-29
-------------------------
- NewHandler.h / NewHandler.cpp:
now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900).
- C/7zTypes.h : the names of variables in interface structures were changed (vt).
- Some bugs were fixed. 7-Zip could crash in some cases.
- Some internal changes in code.
16.04 2016-10-04 16.04 2016-10-04
------------------------- -------------------------
- The bug was fixed in DllSecur.c. - The bug was fixed in DllSecur.c.
@ -168,7 +229,7 @@ HISTORY of the LZMA SDK
4.57 2007-12-12 4.57 2007-12-12
------------------------- -------------------------
- Speed optimizations in C++ LZMA Decoder. - Speed optimizations in ?++ LZMA Decoder.
- Small changes for more compatibility with some C/C++ compilers. - Small changes for more compatibility with some C/C++ compilers.

View File

@ -1,4 +1,4 @@
LZMA SDK 16.04 LZMA SDK 18.05
-------------- --------------
LZMA SDK provides the documentation, samples, header files, LZMA SDK provides the documentation, samples, header files,