BaseTools LzmaCompress: Update LZMA to new 16.04 version
New version LZMA SDK improves the compression performance on windows OS, and has no change on the compression ratio. I compress 8M FVMAIN image, the compression time is reduced from 2.590s to 1.419s. Cc: Yonghong Zhu <yonghong.zhu@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| ## @file | ||||
| # GNU/Linux makefile for 'LzmaCompress' module build. | ||||
| # | ||||
| # Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> | ||||
| # Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> | ||||
| # This program and the accompanying materials | ||||
| # are licensed and made available under the terms and conditions of the BSD License | ||||
| # which accompanies this distribution.  The full text of the license may be found at | ||||
| @@ -29,3 +29,4 @@ OBJECTS = \ | ||||
|  | ||||
| include $(MAKEROOT)/Makefiles/app.makefile | ||||
|  | ||||
| BUILD_CFLAGS += -D_7ZIP_ST | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| LzmaCompress is based on the LZMA SDK 4.65.  LZMA SDK 4.65 | ||||
| was placed in the public domain on 2009-02-03.  It was | ||||
| LzmaCompress is based on the LZMA SDK 16.04.  LZMA SDK 16.04 | ||||
| was placed in the public domain on 2016-10-04.  It was | ||||
| released on the http://www.7-zip.org/sdk.html website. | ||||
| @@ -1,11 +1,11 @@ | ||||
| /** @file | ||||
|   LZMA Compress/Decompress tool (LzmaCompress) | ||||
|  | ||||
|   Based on LZMA SDK 4.65: | ||||
|   Based on LZMA SDK 16.04: | ||||
|     LzmaUtil.c -- Test application for LZMA compression | ||||
|     2008-11-23 : Igor Pavlov : Public domain | ||||
|     2016-10-04 : Igor Pavlov : Public domain | ||||
|  | ||||
|   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> | ||||
|   Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> | ||||
|   This program and the accompanying materials | ||||
|   are licensed and made available under the terms and conditions of the BSD License | ||||
|   which accompanies this distribution.  The full text of the license may be found at | ||||
| @@ -43,10 +43,6 @@ const char *kCantWriteMessage = "Can not write output file"; | ||||
| const char *kCantAllocateMessage = "Can not allocate memory"; | ||||
| const char *kDataErrorMessage = "Data error"; | ||||
|  | ||||
| static void *SzAlloc(void *p, size_t size) { (void)p; return MyAlloc(size); } | ||||
| static void SzFree(void *p, void *address) { (void)p; MyFree(address); } | ||||
| static ISzAlloc g_Alloc = { SzAlloc, SzFree }; | ||||
|  | ||||
| static Bool mQuietMode = False; | ||||
| static CONVERTER_TYPE mConType = NoConverter; | ||||
|  | ||||
| @@ -54,7 +50,7 @@ static CONVERTER_TYPE mConType = NoConverter; | ||||
| #define UTILITY_MAJOR_VERSION 0 | ||||
| #define UTILITY_MINOR_VERSION 2 | ||||
| #define INTEL_COPYRIGHT \ | ||||
|   "Copyright (c) 2009-2012, Intel Corporation. All rights reserved." | ||||
|   "Copyright (c) 2009-2016, Intel Corporation. All rights reserved." | ||||
| void PrintHelp(char *buffer) | ||||
| { | ||||
|   strcat(buffer, | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| ## @file | ||||
| # Windows makefile for 'LzmaCompress' module build. | ||||
| # | ||||
| # Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> | ||||
| # Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> | ||||
| # This program and the accompanying materials | ||||
| # are licensed and made available under the terms and conditions of the BSD License | ||||
| # which accompanies this distribution.  The full text of the license may be found at | ||||
| @@ -26,7 +26,9 @@ OBJECTS = \ | ||||
|   $(SDK_C)\LzmaEnc.obj \ | ||||
|   $(SDK_C)\7zFile.obj \ | ||||
|   $(SDK_C)\7zStream.obj \ | ||||
|   $(SDK_C)\Bra86.obj | ||||
|   $(SDK_C)\Bra86.obj \ | ||||
|   $(SDK_C)\LzFindMt.obj \ | ||||
|   $(SDK_C)\Threads.obj | ||||
|  | ||||
| !INCLUDE ..\Makefiles\ms.app | ||||
|  | ||||
|   | ||||
| @@ -1,15 +1,17 @@ | ||||
| /* 7zFile.c -- File IO | ||||
| 2008-11-22 : Igor Pavlov : Public domain */ | ||||
| 2009-11-24 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #include "7zFile.h" | ||||
|  | ||||
| #ifndef USE_WINDOWS_FILE | ||||
|  | ||||
| #ifndef UNDER_CE | ||||
| #include <errno.h> | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_WINDOWS_FILE | ||||
| #else | ||||
|  | ||||
| /* | ||||
|    ReadFile and WriteFile functions in Windows have BUG: | ||||
| @@ -34,6 +36,7 @@ void File_Construct(CSzFile *p) | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) | ||||
| static WRes File_Open(CSzFile *p, const char *name, int writeMode) | ||||
| { | ||||
|   #ifdef USE_WINDOWS_FILE | ||||
| @@ -45,12 +48,32 @@ static WRes File_Open(CSzFile *p, const char *name, int writeMode) | ||||
|   return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); | ||||
|   #else | ||||
|   p->file = fopen(name, writeMode ? "wb+" : "rb"); | ||||
|   return (p->file != 0) ? 0 : errno; | ||||
|   return (p->file != 0) ? 0 : | ||||
|     #ifdef UNDER_CE | ||||
|     2; /* ENOENT */ | ||||
|     #else | ||||
|     errno; | ||||
|     #endif | ||||
|   #endif | ||||
| } | ||||
|  | ||||
| WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } | ||||
| WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_WINDOWS_FILE | ||||
| static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) | ||||
| { | ||||
|   p->handle = CreateFileW(name, | ||||
|       writeMode ? GENERIC_WRITE : GENERIC_READ, | ||||
|       FILE_SHARE_READ, NULL, | ||||
|       writeMode ? CREATE_ALWAYS : OPEN_EXISTING, | ||||
|       FILE_ATTRIBUTE_NORMAL, NULL); | ||||
|   return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); | ||||
| } | ||||
| WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } | ||||
| WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } | ||||
| #endif | ||||
|  | ||||
| WRes File_Close(CSzFile *p) | ||||
| { | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* 7zFile.h -- File IO | ||||
| 2008-11-22 : Igor Pavlov : Public domain */ | ||||
| 2013-01-18 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __7Z_FILE_H | ||||
| #define __7Z_FILE_H | ||||
| @@ -14,8 +14,9 @@ | ||||
| #include <stdio.h> | ||||
| #endif | ||||
|  | ||||
| #include "Types.h" | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| /* ---------- File ---------- */ | ||||
|  | ||||
| @@ -29,8 +30,14 @@ typedef struct | ||||
| } CSzFile; | ||||
|  | ||||
| void File_Construct(CSzFile *p); | ||||
| #if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) | ||||
| WRes InFile_Open(CSzFile *p, const char *name); | ||||
| WRes OutFile_Open(CSzFile *p, const char *name); | ||||
| #endif | ||||
| #ifdef USE_WINDOWS_FILE | ||||
| WRes InFile_OpenW(CSzFile *p, const WCHAR *name); | ||||
| WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); | ||||
| #endif | ||||
| WRes File_Close(CSzFile *p); | ||||
|  | ||||
| /* reads max(*size, remain file's size) bytes */ | ||||
| @@ -71,4 +78,6 @@ typedef struct | ||||
|  | ||||
| void FileOutStream_CreateVTable(CFileOutStream *p); | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| /* 7zStream.c -- 7z Stream functions | ||||
| 2008-11-23 : Igor Pavlov : Public domain */ | ||||
| 2013-11-12 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| #include "Types.h" | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) | ||||
| { | ||||
| @@ -39,7 +41,7 @@ SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset) | ||||
|  | ||||
| SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) | ||||
| { | ||||
|   void *lookBuf; | ||||
|   const void *lookBuf; | ||||
|   if (*size == 0) | ||||
|     return SZ_OK; | ||||
|   RINOK(stream->Look(stream, &lookBuf, size)); | ||||
| @@ -66,7 +68,7 @@ SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) | ||||
|   return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); | ||||
| } | ||||
|  | ||||
| static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) | ||||
| static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) | ||||
| { | ||||
|   SRes res = SZ_OK; | ||||
|   CLookToRead *p = (CLookToRead *)pp; | ||||
| @@ -84,7 +86,7 @@ static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size) | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size) | ||||
| static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) | ||||
| { | ||||
|   SRes res = SZ_OK; | ||||
|   CLookToRead *p = (CLookToRead *)pp; | ||||
|   | ||||
| @@ -1,14 +1,26 @@ | ||||
| /* Types.h -- Basic types
 | ||||
| 2008-11-23 : Igor Pavlov : Public domain */ | ||||
| /* 7zTypes.h -- Basic types
 | ||||
| 2013-11-12 : Igor Pavlov : Public domain */ | ||||
| 
 | ||||
| #ifndef __7Z_TYPES_H | ||||
| #define __7Z_TYPES_H | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| /* #include <windows.h> */ | ||||
| #endif | ||||
| 
 | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| #include <windows.h> | ||||
| #ifndef EXTERN_C_BEGIN | ||||
| #ifdef __cplusplus | ||||
| #define EXTERN_C_BEGIN extern "C" { | ||||
| #define EXTERN_C_END } | ||||
| #else | ||||
| #define EXTERN_C_BEGIN | ||||
| #define EXTERN_C_END | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| EXTERN_C_BEGIN | ||||
| 
 | ||||
| #define SZ_OK 0 | ||||
| 
 | ||||
| @@ -31,7 +43,8 @@ | ||||
| typedef int SRes; | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| typedef DWORD WRes; | ||||
| /* typedef DWORD WRes; */ | ||||
| typedef unsigned WRes; | ||||
| #else | ||||
| typedef int WRes; | ||||
| #endif | ||||
| @@ -65,9 +78,11 @@ typedef unsigned long UInt64; | ||||
| #if defined(_MSC_VER) || defined(__BORLANDC__) | ||||
| typedef __int64 Int64; | ||||
| typedef unsigned __int64 UInt64; | ||||
| #define UINT64_CONST(n) n | ||||
| #else | ||||
| typedef long long int Int64; | ||||
| typedef unsigned long long int UInt64; | ||||
| #define UINT64_CONST(n) n ## ULL | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
| @@ -83,6 +98,12 @@ typedef int Bool; | ||||
| #define False 0 | ||||
| 
 | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| #define MY_STD_CALL __stdcall | ||||
| #else | ||||
| #define MY_STD_CALL | ||||
| #endif | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
| 
 | ||||
| #if _MSC_VER >= 1300 | ||||
| @@ -92,13 +113,12 @@ typedef int Bool; | ||||
| #endif | ||||
| 
 | ||||
| #define MY_CDECL __cdecl | ||||
| #define MY_STD_CALL __stdcall | ||||
| #define MY_FAST_CALL MY_NO_INLINE __fastcall | ||||
| #define MY_FAST_CALL __fastcall | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #define MY_NO_INLINE | ||||
| #define MY_CDECL | ||||
| #define MY_STD_CALL | ||||
| #define MY_FAST_CALL | ||||
| 
 | ||||
| #endif | ||||
| @@ -106,6 +126,16 @@ typedef int Bool; | ||||
| 
 | ||||
| /* The following interfaces use first parameter as pointer to structure */ | ||||
| 
 | ||||
| typedef struct | ||||
| { | ||||
|   Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ | ||||
| } IByteIn; | ||||
| 
 | ||||
| typedef struct | ||||
| { | ||||
|   void (*Write)(void *p, Byte b); | ||||
| } IByteOut; | ||||
| 
 | ||||
| typedef struct | ||||
| { | ||||
|   SRes (*Read)(void *p, void *buf, size_t *size); | ||||
| @@ -140,7 +170,7 @@ typedef struct | ||||
| 
 | ||||
| typedef struct | ||||
| { | ||||
|   SRes (*Look)(void *p, void **buf, size_t *size); | ||||
|   SRes (*Look)(void *p, const void **buf, size_t *size); | ||||
|     /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
 | ||||
|        (output(*size) > input(*size)) is not allowed | ||||
|        (output(*size) < input(*size)) is allowed */ | ||||
| @@ -205,4 +235,22 @@ typedef struct | ||||
| #define IAlloc_Alloc(p, size) (p)->Alloc((p), size) | ||||
| #define IAlloc_Free(p, a) (p)->Free((p), a) | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| 
 | ||||
| #define CHAR_PATH_SEPARATOR '\\' | ||||
| #define WCHAR_PATH_SEPARATOR L'\\' | ||||
| #define STRING_PATH_SEPARATOR "\\" | ||||
| #define WSTRING_PATH_SEPARATOR L"\\" | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
| #define CHAR_PATH_SEPARATOR '/' | ||||
| #define WCHAR_PATH_SEPARATOR L'/' | ||||
| #define STRING_PATH_SEPARATOR "/" | ||||
| #define WSTRING_PATH_SEPARATOR L"/" | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| EXTERN_C_END | ||||
| 
 | ||||
| #endif | ||||
| @@ -1,7 +1,19 @@ | ||||
| #define MY_VER_MAJOR 4 | ||||
| #define MY_VER_MINOR 65 | ||||
| #define MY_VER_MAJOR 16 | ||||
| #define MY_VER_MINOR 04 | ||||
| #define MY_VER_BUILD 0 | ||||
| #define MY_VERSION "4.65" | ||||
| #define MY_DATE "2009-02-03" | ||||
| #define MY_COPYRIGHT ": Igor Pavlov : Public domain" | ||||
| #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE | ||||
| #define MY_VERSION_NUMBERS "16.04" | ||||
| #define MY_VERSION "16.04" | ||||
| #define MY_DATE "2016-10-04" | ||||
| #undef MY_COPYRIGHT | ||||
| #undef MY_VERSION_COPYRIGHT_DATE | ||||
| #define MY_AUTHOR_NAME "Igor Pavlov" | ||||
| #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" | ||||
| #define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov" | ||||
|  | ||||
| #ifdef USE_COPYRIGHT_CR | ||||
|   #define MY_COPYRIGHT MY_COPYRIGHT_CR | ||||
| #else | ||||
|   #define MY_COPYRIGHT MY_COPYRIGHT_PD | ||||
| #endif | ||||
|  | ||||
| #define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* Alloc.c -- Memory allocation functions | ||||
| 2008-09-24 | ||||
| Igor Pavlov | ||||
| Public domain */ | ||||
| 2015-02-21 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #include <windows.h> | ||||
| @@ -125,3 +125,12 @@ void BigFree(void *address) | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
| static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); } | ||||
| static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); } | ||||
| ISzAlloc g_Alloc = { SzAlloc, SzFree }; | ||||
|  | ||||
| static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); } | ||||
| static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); } | ||||
| ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; | ||||
|   | ||||
| @@ -1,12 +1,12 @@ | ||||
| /* Alloc.h -- Memory allocation functions | ||||
| 2008-03-13 | ||||
| Igor Pavlov | ||||
| Public domain */ | ||||
| 2015-02-21 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __COMMON_ALLOC_H | ||||
| #define __COMMON_ALLOC_H | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| void *MyAlloc(size_t size); | ||||
| void MyFree(void *address); | ||||
| @@ -29,4 +29,9 @@ void BigFree(void *address); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| extern ISzAlloc g_Alloc; | ||||
| extern ISzAlloc g_BigAlloc; | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| /* Bra.h -- Branch converters for executables | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2013-01-18 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __BRA_H | ||||
| #define __BRA_H | ||||
|  | ||||
| #include "Types.h" | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| /* | ||||
| These functions convert relative addresses to absolute addresses | ||||
| @@ -57,4 +59,6 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); | ||||
| SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); | ||||
| SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,85 +1,82 @@ | ||||
| /* Bra86.c -- Converter for x86 code (BCJ) | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2013-11-12 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #include "Bra.h" | ||||
|  | ||||
| #define Test86MSByte(b) ((b) == 0 || (b) == 0xFF) | ||||
|  | ||||
| const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; | ||||
| const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; | ||||
| #define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) | ||||
|  | ||||
| SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) | ||||
| { | ||||
|   SizeT bufferPos = 0, prevPosT; | ||||
|   UInt32 prevMask = *state & 0x7; | ||||
|   SizeT pos = 0; | ||||
|   UInt32 mask = *state & 7; | ||||
|   if (size < 5) | ||||
|     return 0; | ||||
|   size -= 4; | ||||
|   ip += 5; | ||||
|   prevPosT = (SizeT)0 - 1; | ||||
|  | ||||
|   for (;;) | ||||
|   { | ||||
|     Byte *p = data + bufferPos; | ||||
|     Byte *limit = data + size - 4; | ||||
|     Byte *p = data + pos; | ||||
|     const Byte *limit = data + size; | ||||
|     for (; p < limit; p++) | ||||
|       if ((*p & 0xFE) == 0xE8) | ||||
|         break; | ||||
|     bufferPos = (SizeT)(p - data); | ||||
|     if (p >= limit) | ||||
|       break; | ||||
|     prevPosT = bufferPos - prevPosT; | ||||
|     if (prevPosT > 3) | ||||
|       prevMask = 0; | ||||
|     else | ||||
|  | ||||
|     { | ||||
|       prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; | ||||
|       if (prevMask != 0) | ||||
|       SizeT d = (SizeT)(p - data - pos); | ||||
|       pos = (SizeT)(p - data); | ||||
|       if (p >= limit) | ||||
|       { | ||||
|         Byte b = p[4 - kMaskToBitNumber[prevMask]]; | ||||
|         if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b)) | ||||
|         *state = (d > 2 ? 0 : mask >> (unsigned)d); | ||||
|         return pos; | ||||
|       } | ||||
|       if (d > 2) | ||||
|         mask = 0; | ||||
|       else | ||||
|       { | ||||
|         mask >>= (unsigned)d; | ||||
|         if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1]))) | ||||
|         { | ||||
|           prevPosT = bufferPos; | ||||
|           prevMask = ((prevMask << 1) & 0x7) | 1; | ||||
|           bufferPos++; | ||||
|           mask = (mask >> 1) | 4; | ||||
|           pos++; | ||||
|           continue; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     prevPosT = bufferPos; | ||||
|  | ||||
|     if (Test86MSByte(p[4])) | ||||
|     { | ||||
|       UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); | ||||
|       UInt32 dest; | ||||
|       for (;;) | ||||
|       UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); | ||||
|       UInt32 cur = ip + (UInt32)pos; | ||||
|       pos += 5; | ||||
|       if (encoding) | ||||
|         v += cur; | ||||
|       else | ||||
|         v -= cur; | ||||
|       if (mask != 0) | ||||
|       { | ||||
|         Byte b; | ||||
|         int index; | ||||
|         if (encoding) | ||||
|           dest = (ip + (UInt32)bufferPos) + src; | ||||
|         else | ||||
|           dest = src - (ip + (UInt32)bufferPos); | ||||
|         if (prevMask == 0) | ||||
|           break; | ||||
|         index = kMaskToBitNumber[prevMask] * 8; | ||||
|         b = (Byte)(dest >> (24 - index)); | ||||
|         if (!Test86MSByte(b)) | ||||
|           break; | ||||
|         src = dest ^ ((1 << (32 - index)) - 1); | ||||
|         unsigned sh = (mask & 6) << 2; | ||||
|         if (Test86MSByte((Byte)(v >> sh))) | ||||
|         { | ||||
|           v ^= (((UInt32)0x100 << sh) - 1); | ||||
|           if (encoding) | ||||
|             v += cur; | ||||
|           else | ||||
|             v -= cur; | ||||
|         } | ||||
|         mask = 0; | ||||
|       } | ||||
|       p[4] = (Byte)(~(((dest >> 24) & 1) - 1)); | ||||
|       p[3] = (Byte)(dest >> 16); | ||||
|       p[2] = (Byte)(dest >> 8); | ||||
|       p[1] = (Byte)dest; | ||||
|       bufferPos += 5; | ||||
|       p[1] = (Byte)v; | ||||
|       p[2] = (Byte)(v >> 8); | ||||
|       p[3] = (Byte)(v >> 16); | ||||
|       p[4] = (Byte)(0 - ((v >> 24) & 1)); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       prevMask = ((prevMask << 1) & 0x7) | 1; | ||||
|       bufferPos++; | ||||
|       mask = (mask >> 1) | 4; | ||||
|       pos++; | ||||
|     } | ||||
|   } | ||||
|   prevPosT = bufferPos - prevPosT; | ||||
|   *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); | ||||
|   return bufferPos; | ||||
| } | ||||
|   | ||||
							
								
								
									
										32
									
								
								BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /* Compiler.h | ||||
| 2015-08-02 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __7Z_COMPILER_H | ||||
| #define __7Z_COMPILER_H | ||||
|  | ||||
| #ifdef _MSC_VER | ||||
|  | ||||
|   #ifdef UNDER_CE | ||||
|     #define RPC_NO_WINDOWS_H | ||||
|     /* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */ | ||||
|     #pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union | ||||
|     #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int | ||||
|   #endif | ||||
|  | ||||
|   #if _MSC_VER >= 1300 | ||||
|     #pragma warning(disable : 4996) // This function or variable may be unsafe | ||||
|   #else | ||||
|     #pragma warning(disable : 4511) // copy constructor could not be generated | ||||
|     #pragma warning(disable : 4512) // assignment operator could not be generated | ||||
|     #pragma warning(disable : 4514) // unreferenced inline function has been removed | ||||
|     #pragma warning(disable : 4702) // unreachable code | ||||
|     #pragma warning(disable : 4710) // not inlined | ||||
|     #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information | ||||
|   #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #define UNUSED_VAR(x) (void)x; | ||||
| /* #define UNUSED_VAR(x) x=x; */ | ||||
|  | ||||
| #endif | ||||
| @@ -1,33 +1,119 @@ | ||||
| /* CpuArch.h | ||||
| 2008-08-05 | ||||
| Igor Pavlov | ||||
| Public domain */ | ||||
| /* CpuArch.h -- CPU specific code | ||||
| 2016-06-09: Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __CPUARCH_H | ||||
| #define __CPUARCH_H | ||||
| #ifndef __CPU_ARCH_H | ||||
| #define __CPU_ARCH_H | ||||
|  | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| /* | ||||
| LITTLE_ENDIAN_UNALIGN means: | ||||
|   1) CPU is LITTLE_ENDIAN | ||||
|   2) it's allowed to make unaligned memory accesses | ||||
| if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know | ||||
| about these properties of platform. | ||||
| MY_CPU_LE means that CPU is LITTLE ENDIAN. | ||||
| MY_CPU_BE means that CPU is BIG ENDIAN. | ||||
| If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform. | ||||
|  | ||||
| MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. | ||||
| */ | ||||
|  | ||||
| #if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__) | ||||
| #define LITTLE_ENDIAN_UNALIGN | ||||
| #if defined(_M_X64) \ | ||||
|    || defined(_M_AMD64) \ | ||||
|    || defined(__x86_64__) \ | ||||
|    || defined(__AMD64__) \ | ||||
|    || defined(__amd64__) | ||||
|   #define MY_CPU_AMD64 | ||||
| #endif | ||||
|  | ||||
| #ifdef LITTLE_ENDIAN_UNALIGN | ||||
| #if defined(MY_CPU_AMD64) \ | ||||
|     || defined(_M_IA64) \ | ||||
|     || defined(__AARCH64EL__) \ | ||||
|     || defined(__AARCH64EB__) | ||||
|   #define MY_CPU_64BIT | ||||
| #endif | ||||
|  | ||||
| #define GetUi16(p) (*(const UInt16 *)(p)) | ||||
| #define GetUi32(p) (*(const UInt32 *)(p)) | ||||
| #define GetUi64(p) (*(const UInt64 *)(p)) | ||||
| #define SetUi32(p, d) *(UInt32 *)(p) = (d); | ||||
| #if defined(_M_IX86) || defined(__i386__) | ||||
| #define MY_CPU_X86 | ||||
| #endif | ||||
|  | ||||
| #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) | ||||
| #define MY_CPU_X86_OR_AMD64 | ||||
| #endif | ||||
|  | ||||
| #if defined(MY_CPU_X86) \ | ||||
|     || defined(_M_ARM) \ | ||||
|     || defined(__ARMEL__) \ | ||||
|     || defined(__THUMBEL__) \ | ||||
|     || defined(__ARMEB__) \ | ||||
|     || defined(__THUMBEB__) | ||||
|   #define MY_CPU_32BIT | ||||
| #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) \ | ||||
|     || defined(MY_CPU_ARM_LE) \ | ||||
|     || defined(MY_CPU_IA64_LE) \ | ||||
|     || defined(__LITTLE_ENDIAN__) \ | ||||
|     || defined(__ARMEL__) \ | ||||
|     || defined(__THUMBEL__) \ | ||||
|     || defined(__AARCH64EL__) \ | ||||
|     || defined(__MIPSEL__) \ | ||||
|     || defined(__MIPSEL) \ | ||||
|     || defined(_MIPSEL) \ | ||||
|     || defined(__BFIN__) \ | ||||
|     || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) | ||||
|   #define MY_CPU_LE | ||||
| #endif | ||||
|  | ||||
| #if defined(__BIG_ENDIAN__) \ | ||||
|     || defined(__ARMEB__) \ | ||||
|     || defined(__THUMBEB__) \ | ||||
|     || defined(__AARCH64EB__) \ | ||||
|     || defined(__MIPSEB__) \ | ||||
|     || defined(__MIPSEB) \ | ||||
|     || defined(_MIPSEB) \ | ||||
|     || defined(__m68k__) \ | ||||
|     || defined(__s390__) \ | ||||
|     || defined(__s390x__) \ | ||||
|     || defined(__zarch__) \ | ||||
|     || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) | ||||
|   #define MY_CPU_BE | ||||
| #endif | ||||
|  | ||||
| #if defined(MY_CPU_LE) && defined(MY_CPU_BE) | ||||
| Stop_Compiling_Bad_Endian | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef MY_CPU_LE | ||||
|   #if defined(MY_CPU_X86_OR_AMD64) \ | ||||
|       /* || defined(__AARCH64EL__) */ | ||||
|     #define MY_CPU_LE_UNALIGN | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef MY_CPU_LE_UNALIGN | ||||
|  | ||||
| #define GetUi16(p) (*(const UInt16 *)(const void *)(p)) | ||||
| #define GetUi32(p) (*(const UInt32 *)(const void *)(p)) | ||||
| #define GetUi64(p) (*(const UInt64 *)(const void *)(p)) | ||||
|  | ||||
| #define SetUi16(p, v) { *(UInt16 *)(p) = (v); } | ||||
| #define SetUi32(p, v) { *(UInt32 *)(p) = (v); } | ||||
| #define SetUi64(p, v) { *(UInt64 *)(p) = (v); } | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8)) | ||||
| #define GetUi16(p) ( (UInt16) ( \ | ||||
|              ((const Byte *)(p))[0] | \ | ||||
|     ((UInt16)((const Byte *)(p))[1] << 8) )) | ||||
|  | ||||
| #define GetUi32(p) ( \ | ||||
|              ((const Byte *)(p))[0]        | \ | ||||
| @@ -37,21 +123,43 @@ about these properties of platform. | ||||
|  | ||||
| #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) | ||||
|  | ||||
| #define SetUi32(p, d) { UInt32 _x_ = (d); \ | ||||
|     ((Byte *)(p))[0] = (Byte)_x_; \ | ||||
|     ((Byte *)(p))[1] = (Byte)(_x_ >> 8); \ | ||||
|     ((Byte *)(p))[2] = (Byte)(_x_ >> 16); \ | ||||
|     ((Byte *)(p))[3] = (Byte)(_x_ >> 24); } | ||||
| #define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ | ||||
|     _ppp_[0] = (Byte)_vvv_; \ | ||||
|     _ppp_[1] = (Byte)(_vvv_ >> 8); } | ||||
|  | ||||
| #define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ | ||||
|     _ppp_[0] = (Byte)_vvv_; \ | ||||
|     _ppp_[1] = (Byte)(_vvv_ >> 8); \ | ||||
|     _ppp_[2] = (Byte)(_vvv_ >> 16); \ | ||||
|     _ppp_[3] = (Byte)(_vvv_ >> 24); } | ||||
|  | ||||
| #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ | ||||
|     SetUi32(_ppp2_    , (UInt32)_vvv2_); \ | ||||
|     SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300) | ||||
|  | ||||
| #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300) | ||||
|  | ||||
| /* Note: we use bswap instruction, that is unsupported in 386 cpu */ | ||||
|  | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #pragma intrinsic(_byteswap_ulong) | ||||
| #pragma intrinsic(_byteswap_uint64) | ||||
| #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p)) | ||||
| #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p)) | ||||
|  | ||||
| #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)) | ||||
|  | ||||
| #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p)) | ||||
| #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p)) | ||||
|  | ||||
| #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v) | ||||
|  | ||||
| #else | ||||
|  | ||||
| #define GetBe32(p) ( \ | ||||
| @@ -62,8 +170,54 @@ about these properties of platform. | ||||
|  | ||||
| #define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]) | ||||
| #define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ | ||||
|     _ppp_[0] = (Byte)(_vvv_ >> 24); \ | ||||
|     _ppp_[1] = (Byte)(_vvv_ >> 16); \ | ||||
|     _ppp_[2] = (Byte)(_vvv_ >> 8); \ | ||||
|     _ppp_[3] = (Byte)_vvv_; } | ||||
|  | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #define GetBe16(p) ( (UInt16) ( \ | ||||
|     ((UInt16)((const Byte *)(p))[0] << 8) | \ | ||||
|              ((const Byte *)(p))[1] )) | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifdef MY_CPU_X86_OR_AMD64 | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   UInt32 maxFunc; | ||||
|   UInt32 vendor[3]; | ||||
|   UInt32 ver; | ||||
|   UInt32 b; | ||||
|   UInt32 c; | ||||
|   UInt32 d; | ||||
| } Cx86cpuid; | ||||
|  | ||||
| enum | ||||
| { | ||||
|   CPU_FIRM_INTEL, | ||||
|   CPU_FIRM_AMD, | ||||
|   CPU_FIRM_VIA | ||||
| }; | ||||
|  | ||||
| void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d); | ||||
|  | ||||
| Bool x86cpuid_CheckAndRead(Cx86cpuid *p); | ||||
| int x86cpuid_GetFirm(const Cx86cpuid *p); | ||||
|  | ||||
| #define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF)) | ||||
| #define x86cpuid_GetModel(ver)  (((ver >> 12) &  0xF0) | ((ver >> 4) & 0xF)) | ||||
| #define x86cpuid_GetStepping(ver) (ver & 0xF) | ||||
|  | ||||
| Bool CPU_Is_InOrder(); | ||||
| Bool CPU_Is_Aes_Supported(); | ||||
|  | ||||
| #endif | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| /* LzFind.c -- Match finder for LZ algorithms | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2015-10-15 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #include <string.h> | ||||
|  | ||||
| @@ -9,8 +11,8 @@ | ||||
| #define kEmptyHashValue 0 | ||||
| #define kMaxValForNormalize ((UInt32)0xFFFFFFFF) | ||||
| #define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ | ||||
| #define kNormalizeMask (~(kNormalizeStepMin - 1)) | ||||
| #define kMaxHistorySize ((UInt32)3 << 30) | ||||
| #define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1)) | ||||
| #define kMaxHistorySize ((UInt32)7 << 29) | ||||
|  | ||||
| #define kStartMaxLen 3 | ||||
|  | ||||
| @@ -19,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) | ||||
|   if (!p->directInput) | ||||
|   { | ||||
|     alloc->Free(alloc, p->bufferBase); | ||||
|     p->bufferBase = 0; | ||||
|     p->bufferBase = NULL; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -33,17 +35,16 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a | ||||
|     p->blockSize = blockSize; | ||||
|     return 1; | ||||
|   } | ||||
|   if (p->bufferBase == 0 || p->blockSize != blockSize) | ||||
|   if (!p->bufferBase || p->blockSize != blockSize) | ||||
|   { | ||||
|     LzInWindow_Free(p, alloc); | ||||
|     p->blockSize = blockSize; | ||||
|     p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); | ||||
|   } | ||||
|   return (p->bufferBase != 0); | ||||
|   return (p->bufferBase != NULL); | ||||
| } | ||||
|  | ||||
| Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } | ||||
| Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } | ||||
|  | ||||
| UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } | ||||
|  | ||||
| @@ -58,12 +59,28 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) | ||||
| { | ||||
|   if (p->streamEndWasReached || p->result != SZ_OK) | ||||
|     return; | ||||
|  | ||||
|   /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */ | ||||
|  | ||||
|   if (p->directInput) | ||||
|   { | ||||
|     UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos); | ||||
|     if (curSize > p->directInputRem) | ||||
|       curSize = (UInt32)p->directInputRem; | ||||
|     p->directInputRem -= curSize; | ||||
|     p->streamPos += curSize; | ||||
|     if (p->directInputRem == 0) | ||||
|       p->streamEndWasReached = 1; | ||||
|     return; | ||||
|   } | ||||
|    | ||||
|   for (;;) | ||||
|   { | ||||
|     Byte *dest = p->buffer + (p->streamPos - p->pos); | ||||
|     size_t size = (p->bufferBase + p->blockSize - dest); | ||||
|     if (size == 0) | ||||
|       return; | ||||
|  | ||||
|     p->result = p->stream->Read(p->stream, dest, &size); | ||||
|     if (p->result != SZ_OK) | ||||
|       return; | ||||
| @@ -81,13 +98,15 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) | ||||
| void MatchFinder_MoveBlock(CMatchFinder *p) | ||||
| { | ||||
|   memmove(p->bufferBase, | ||||
|     p->buffer - p->keepSizeBefore, | ||||
|     (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); | ||||
|       p->buffer - p->keepSizeBefore, | ||||
|       (size_t)(p->streamPos - p->pos) + p->keepSizeBefore); | ||||
|   p->buffer = p->bufferBase + p->keepSizeBefore; | ||||
| } | ||||
|  | ||||
| int MatchFinder_NeedMove(CMatchFinder *p) | ||||
| { | ||||
|   if (p->directInput) | ||||
|     return 0; | ||||
|   /* if (p->streamEndWasReached) return 0; */ | ||||
|   return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); | ||||
| } | ||||
| @@ -112,8 +131,6 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p) | ||||
|   p->cutValue = 32; | ||||
|   p->btMode = 1; | ||||
|   p->numHashBytes = 4; | ||||
|   /* p->skipModeBits = 0; */ | ||||
|   p->directInput = 0; | ||||
|   p->bigHash = 0; | ||||
| } | ||||
|  | ||||
| @@ -122,15 +139,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p) | ||||
| void MatchFinder_Construct(CMatchFinder *p) | ||||
| { | ||||
|   UInt32 i; | ||||
|   p->bufferBase = 0; | ||||
|   p->bufferBase = NULL; | ||||
|   p->directInput = 0; | ||||
|   p->hash = 0; | ||||
|   p->hash = NULL; | ||||
|   MatchFinder_SetDefaultSettings(p); | ||||
|  | ||||
|   for (i = 0; i < 256; i++) | ||||
|   { | ||||
|     UInt32 r = i; | ||||
|     int j; | ||||
|     unsigned j; | ||||
|     for (j = 0; j < 8; j++) | ||||
|       r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); | ||||
|     p->crc[i] = r; | ||||
| @@ -140,7 +157,7 @@ void MatchFinder_Construct(CMatchFinder *p) | ||||
| static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) | ||||
| { | ||||
|   alloc->Free(alloc, p->hash); | ||||
|   p->hash = 0; | ||||
|   p->hash = NULL; | ||||
| } | ||||
|  | ||||
| void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) | ||||
| @@ -149,11 +166,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) | ||||
|   LzInWindow_Free(p, alloc); | ||||
| } | ||||
|  | ||||
| static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) | ||||
| static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) | ||||
| { | ||||
|   size_t sizeInBytes = (size_t)num * sizeof(CLzRef); | ||||
|   if (sizeInBytes / sizeof(CLzRef) != num) | ||||
|     return 0; | ||||
|     return NULL; | ||||
|   return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); | ||||
| } | ||||
|  | ||||
| @@ -162,22 +179,27 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, | ||||
|     ISzAlloc *alloc) | ||||
| { | ||||
|   UInt32 sizeReserv; | ||||
|    | ||||
|   if (historySize > kMaxHistorySize) | ||||
|   { | ||||
|     MatchFinder_Free(p, alloc); | ||||
|     return 0; | ||||
|   } | ||||
|    | ||||
|   sizeReserv = historySize >> 1; | ||||
|   if (historySize > ((UInt32)2 << 30)) | ||||
|     sizeReserv = historySize >> 2; | ||||
|        if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3; | ||||
|   else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2; | ||||
|    | ||||
|   sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); | ||||
|  | ||||
|   p->keepSizeBefore = historySize + keepAddBufferBefore + 1; | ||||
|   p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; | ||||
|    | ||||
|   /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ | ||||
|    | ||||
|   if (LzInWindow_Create(p, sizeReserv, alloc)) | ||||
|   { | ||||
|     UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1; | ||||
|     UInt32 newCyclicBufferSize = historySize + 1; | ||||
|     UInt32 hs; | ||||
|     p->matchMaxLen = matchMaxLen; | ||||
|     { | ||||
| @@ -192,7 +214,6 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, | ||||
|         hs |= (hs >> 4); | ||||
|         hs |= (hs >> 8); | ||||
|         hs >>= 1; | ||||
|         /* hs >>= p->skipModeBits; */ | ||||
|         hs |= 0xFFFF; /* don't change it! It's required for Deflate */ | ||||
|         if (hs > (1 << 24)) | ||||
|         { | ||||
| @@ -200,6 +221,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, | ||||
|             hs = (1 << 24) - 1; | ||||
|           else | ||||
|             hs >>= 1; | ||||
|           /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ | ||||
|         } | ||||
|       } | ||||
|       p->hashMask = hs; | ||||
| @@ -211,24 +233,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, | ||||
|     } | ||||
|  | ||||
|     { | ||||
|       UInt32 prevSize = p->hashSizeSum + p->numSons; | ||||
|       UInt32 newSize; | ||||
|       size_t newSize; | ||||
|       size_t numSons; | ||||
|       p->historySize = historySize; | ||||
|       p->hashSizeSum = hs; | ||||
|       p->cyclicBufferSize = newCyclicBufferSize; | ||||
|       p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); | ||||
|       newSize = p->hashSizeSum + p->numSons; | ||||
|       if (p->hash != 0 && prevSize == newSize) | ||||
|        | ||||
|       numSons = newCyclicBufferSize; | ||||
|       if (p->btMode) | ||||
|         numSons <<= 1; | ||||
|       newSize = hs + numSons; | ||||
|  | ||||
|       if (p->hash && p->numRefs == newSize) | ||||
|         return 1; | ||||
|        | ||||
|       MatchFinder_FreeThisClassMemory(p, alloc); | ||||
|       p->numRefs = newSize; | ||||
|       p->hash = AllocRefs(newSize, alloc); | ||||
|       if (p->hash != 0) | ||||
|        | ||||
|       if (p->hash) | ||||
|       { | ||||
|         p->son = p->hash + p->hashSizeSum; | ||||
|         return 1; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   MatchFinder_Free(p, alloc); | ||||
|   return 0; | ||||
| } | ||||
| @@ -237,9 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p) | ||||
| { | ||||
|   UInt32 limit = kMaxValForNormalize - p->pos; | ||||
|   UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; | ||||
|    | ||||
|   if (limit2 < limit) | ||||
|     limit = limit2; | ||||
|   limit2 = p->streamPos - p->pos; | ||||
|    | ||||
|   if (limit2 <= p->keepSizeAfter) | ||||
|   { | ||||
|     if (limit2 > 0) | ||||
| @@ -247,8 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p) | ||||
|   } | ||||
|   else | ||||
|     limit2 -= p->keepSizeAfter; | ||||
|    | ||||
|   if (limit2 < limit) | ||||
|     limit = limit2; | ||||
|    | ||||
|   { | ||||
|     UInt32 lenLimit = p->streamPos - p->pos; | ||||
|     if (lenLimit > p->matchMaxLen) | ||||
| @@ -258,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p) | ||||
|   p->posLimit = p->pos + limit; | ||||
| } | ||||
|  | ||||
| void MatchFinder_Init(CMatchFinder *p) | ||||
| void MatchFinder_Init_2(CMatchFinder *p, int readData) | ||||
| { | ||||
|   UInt32 i; | ||||
|   for (i = 0; i < p->hashSizeSum; i++) | ||||
|     p->hash[i] = kEmptyHashValue; | ||||
|   UInt32 *hash = p->hash; | ||||
|   UInt32 num = p->hashSizeSum; | ||||
|   for (i = 0; i < num; i++) | ||||
|     hash[i] = kEmptyHashValue; | ||||
|    | ||||
|   p->cyclicBufferPos = 0; | ||||
|   p->buffer = p->bufferBase; | ||||
|   p->pos = p->streamPos = p->cyclicBufferSize; | ||||
|   p->result = SZ_OK; | ||||
|   p->streamEndWasReached = 0; | ||||
|   MatchFinder_ReadBlock(p); | ||||
|    | ||||
|   if (readData) | ||||
|     MatchFinder_ReadBlock(p); | ||||
|    | ||||
|   MatchFinder_SetLimits(p); | ||||
| } | ||||
|  | ||||
| void MatchFinder_Init(CMatchFinder *p) | ||||
| { | ||||
|   MatchFinder_Init_2(p, True); | ||||
| } | ||||
|    | ||||
| static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) | ||||
| { | ||||
|   return (p->pos - p->historySize - 1) & kNormalizeMask; | ||||
| } | ||||
|  | ||||
| void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) | ||||
| void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) | ||||
| { | ||||
|   UInt32 i; | ||||
|   size_t i; | ||||
|   for (i = 0; i < numItems; i++) | ||||
|   { | ||||
|     UInt32 value = items[i]; | ||||
| @@ -294,7 +339,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) | ||||
| static void MatchFinder_Normalize(CMatchFinder *p) | ||||
| { | ||||
|   UInt32 subValue = MatchFinder_GetSubValue(p); | ||||
|   MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); | ||||
|   MatchFinder_Normalize3(subValue, p->hash, p->numRefs); | ||||
|   MatchFinder_ReduceOffsets(p, subValue); | ||||
| } | ||||
|  | ||||
| @@ -455,7 +500,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const | ||||
| static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } | ||||
|  | ||||
| #define GET_MATCHES_HEADER2(minLen, ret_op) \ | ||||
|   UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ | ||||
|   UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \ | ||||
|   lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ | ||||
|   cur = p->buffer; | ||||
|  | ||||
| @@ -471,13 +516,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } | ||||
| #define SKIP_FOOTER \ | ||||
|   SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; | ||||
|  | ||||
| #define UPDATE_maxLen { \ | ||||
|     ptrdiff_t diff = (ptrdiff_t)0 - d2; \ | ||||
|     const Byte *c = cur + maxLen; \ | ||||
|     const Byte *lim = cur + lenLimit; \ | ||||
|     for (; c != lim; c++) if (*(c + diff) != *c) break; \ | ||||
|     maxLen = (UInt32)(c - cur); } | ||||
|  | ||||
| static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 offset; | ||||
|   GET_MATCHES_HEADER(2) | ||||
|   HASH2_CALC; | ||||
|   curMatch = p->hash[hashValue]; | ||||
|   p->hash[hashValue] = p->pos; | ||||
|   curMatch = p->hash[hv]; | ||||
|   p->hash[hv] = p->pos; | ||||
|   offset = 0; | ||||
|   GET_MATCHES_FOOTER(offset, 1) | ||||
| } | ||||
| @@ -487,35 +539,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
|   UInt32 offset; | ||||
|   GET_MATCHES_HEADER(3) | ||||
|   HASH_ZIP_CALC; | ||||
|   curMatch = p->hash[hashValue]; | ||||
|   p->hash[hashValue] = p->pos; | ||||
|   curMatch = p->hash[hv]; | ||||
|   p->hash[hv] = p->pos; | ||||
|   offset = 0; | ||||
|   GET_MATCHES_FOOTER(offset, 2) | ||||
| } | ||||
|  | ||||
| static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 hash2Value, delta2, maxLen, offset; | ||||
|   UInt32 h2, d2, maxLen, offset, pos; | ||||
|   UInt32 *hash; | ||||
|   GET_MATCHES_HEADER(3) | ||||
|  | ||||
|   HASH3_CALC; | ||||
|  | ||||
|   delta2 = p->pos - p->hash[hash2Value]; | ||||
|   curMatch = p->hash[kFix3HashSize + hashValue]; | ||||
|    | ||||
|   p->hash[hash2Value] = | ||||
|   p->hash[kFix3HashSize + hashValue] = p->pos; | ||||
|   hash = p->hash; | ||||
|   pos = p->pos; | ||||
|  | ||||
|   d2 = pos - hash[h2]; | ||||
|  | ||||
|   curMatch = hash[kFix3HashSize + hv]; | ||||
|    | ||||
|   hash[h2] = pos; | ||||
|   hash[kFix3HashSize + hv] = pos; | ||||
|  | ||||
|   maxLen = 2; | ||||
|   offset = 0; | ||||
|   if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) | ||||
|  | ||||
|   if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) | ||||
|   { | ||||
|     for (; maxLen != lenLimit; maxLen++) | ||||
|       if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) | ||||
|         break; | ||||
|     UPDATE_maxLen | ||||
|     distances[0] = maxLen; | ||||
|     distances[1] = delta2 - 1; | ||||
|     distances[1] = d2 - 1; | ||||
|     offset = 2; | ||||
|     if (maxLen == lenLimit) | ||||
|     { | ||||
| @@ -523,44 +578,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
|       MOVE_POS_RET; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   GET_MATCHES_FOOTER(offset, maxLen) | ||||
| } | ||||
|  | ||||
| static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; | ||||
|   UInt32 h2, h3, d2, d3, maxLen, offset, pos; | ||||
|   UInt32 *hash; | ||||
|   GET_MATCHES_HEADER(4) | ||||
|  | ||||
|   HASH4_CALC; | ||||
|  | ||||
|   delta2 = p->pos - p->hash[                hash2Value]; | ||||
|   delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; | ||||
|   curMatch = p->hash[kFix4HashSize + hashValue]; | ||||
|    | ||||
|   p->hash[                hash2Value] = | ||||
|   p->hash[kFix3HashSize + hash3Value] = | ||||
|   p->hash[kFix4HashSize + hashValue] = p->pos; | ||||
|   hash = p->hash; | ||||
|   pos = p->pos; | ||||
|  | ||||
|   maxLen = 1; | ||||
|   d2 = pos - hash[                h2]; | ||||
|   d3 = pos - hash[kFix3HashSize + h3]; | ||||
|  | ||||
|   curMatch = hash[kFix4HashSize + hv]; | ||||
|  | ||||
|   hash[                h2] = pos; | ||||
|   hash[kFix3HashSize + h3] = pos; | ||||
|   hash[kFix4HashSize + hv] = pos; | ||||
|  | ||||
|   maxLen = 0; | ||||
|   offset = 0; | ||||
|   if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) | ||||
|    | ||||
|   if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) | ||||
|   { | ||||
|     distances[0] = maxLen = 2; | ||||
|     distances[1] = delta2 - 1; | ||||
|     distances[1] = d2 - 1; | ||||
|     offset = 2; | ||||
|   } | ||||
|   if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) | ||||
|    | ||||
|   if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) | ||||
|   { | ||||
|     maxLen = 3; | ||||
|     distances[offset + 1] = delta3 - 1; | ||||
|     distances[offset + 1] = d3 - 1; | ||||
|     offset += 2; | ||||
|     delta2 = delta3; | ||||
|     d2 = d3; | ||||
|   } | ||||
|    | ||||
|   if (offset != 0) | ||||
|   { | ||||
|     for (; maxLen != lenLimit; maxLen++) | ||||
|       if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) | ||||
|         break; | ||||
|     UPDATE_maxLen | ||||
|     distances[offset - 2] = maxLen; | ||||
|     if (maxLen == lenLimit) | ||||
|     { | ||||
| @@ -568,46 +630,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
|       MOVE_POS_RET; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   if (maxLen < 3) | ||||
|     maxLen = 3; | ||||
|    | ||||
|   GET_MATCHES_FOOTER(offset, maxLen) | ||||
| } | ||||
|  | ||||
| /* | ||||
| static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos; | ||||
|   UInt32 *hash; | ||||
|   GET_MATCHES_HEADER(5) | ||||
|  | ||||
|   HASH5_CALC; | ||||
|  | ||||
|   hash = p->hash; | ||||
|   pos = p->pos; | ||||
|  | ||||
|   d2 = pos - hash[                h2]; | ||||
|   d3 = pos - hash[kFix3HashSize + h3]; | ||||
|   d4 = pos - hash[kFix4HashSize + h4]; | ||||
|  | ||||
|   curMatch = hash[kFix5HashSize + hv]; | ||||
|  | ||||
|   hash[                h2] = pos; | ||||
|   hash[kFix3HashSize + h3] = pos; | ||||
|   hash[kFix4HashSize + h4] = pos; | ||||
|   hash[kFix5HashSize + hv] = pos; | ||||
|  | ||||
|   maxLen = 0; | ||||
|   offset = 0; | ||||
|  | ||||
|   if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) | ||||
|   { | ||||
|     distances[0] = maxLen = 2; | ||||
|     distances[1] = d2 - 1; | ||||
|     offset = 2; | ||||
|     if (*(cur - d2 + 2) == cur[2]) | ||||
|       distances[0] = maxLen = 3; | ||||
|     else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) | ||||
|     { | ||||
|       distances[2] = maxLen = 3; | ||||
|       distances[3] = d3 - 1; | ||||
|       offset = 4; | ||||
|       d2 = d3; | ||||
|     } | ||||
|   } | ||||
|   else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) | ||||
|   { | ||||
|     distances[0] = maxLen = 3; | ||||
|     distances[1] = d3 - 1; | ||||
|     offset = 2; | ||||
|     d2 = d3; | ||||
|   } | ||||
|    | ||||
|   if (d2 != d4 && d4 < p->cyclicBufferSize | ||||
|       && *(cur - d4) == *cur | ||||
|       && *(cur - d4 + 3) == *(cur + 3)) | ||||
|   { | ||||
|     maxLen = 4; | ||||
|     distances[offset + 1] = d4 - 1; | ||||
|     offset += 2; | ||||
|     d2 = d4; | ||||
|   } | ||||
|    | ||||
|   if (offset != 0) | ||||
|   { | ||||
|     UPDATE_maxLen | ||||
|     distances[offset - 2] = maxLen; | ||||
|     if (maxLen == lenLimit) | ||||
|     { | ||||
|       SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); | ||||
|       MOVE_POS_RET; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (maxLen < 4) | ||||
|     maxLen = 4; | ||||
|    | ||||
|   GET_MATCHES_FOOTER(offset, maxLen) | ||||
| } | ||||
| */ | ||||
|  | ||||
| static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; | ||||
|   UInt32 h2, h3, d2, d3, maxLen, offset, pos; | ||||
|   UInt32 *hash; | ||||
|   GET_MATCHES_HEADER(4) | ||||
|  | ||||
|   HASH4_CALC; | ||||
|  | ||||
|   delta2 = p->pos - p->hash[                hash2Value]; | ||||
|   delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; | ||||
|   curMatch = p->hash[kFix4HashSize + hashValue]; | ||||
|   hash = p->hash; | ||||
|   pos = p->pos; | ||||
|    | ||||
|   d2 = pos - hash[                h2]; | ||||
|   d3 = pos - hash[kFix3HashSize + h3]; | ||||
|    | ||||
|   curMatch = hash[kFix4HashSize + hv]; | ||||
|  | ||||
|   p->hash[                hash2Value] = | ||||
|   p->hash[kFix3HashSize + hash3Value] = | ||||
|   p->hash[kFix4HashSize + hashValue] = p->pos; | ||||
|   hash[                h2] = pos; | ||||
|   hash[kFix3HashSize + h3] = pos; | ||||
|   hash[kFix4HashSize + hv] = pos; | ||||
|  | ||||
|   maxLen = 1; | ||||
|   maxLen = 0; | ||||
|   offset = 0; | ||||
|   if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) | ||||
|  | ||||
|   if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) | ||||
|   { | ||||
|     distances[0] = maxLen = 2; | ||||
|     distances[1] = delta2 - 1; | ||||
|     distances[1] = d2 - 1; | ||||
|     offset = 2; | ||||
|   } | ||||
|   if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) | ||||
|    | ||||
|   if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) | ||||
|   { | ||||
|     maxLen = 3; | ||||
|     distances[offset + 1] = delta3 - 1; | ||||
|     distances[offset + 1] = d3 - 1; | ||||
|     offset += 2; | ||||
|     delta2 = delta3; | ||||
|     d2 = d3; | ||||
|   } | ||||
|    | ||||
|   if (offset != 0) | ||||
|   { | ||||
|     for (; maxLen != lenLimit; maxLen++) | ||||
|       if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) | ||||
|         break; | ||||
|     UPDATE_maxLen | ||||
|     distances[offset - 2] = maxLen; | ||||
|     if (maxLen == lenLimit) | ||||
|     { | ||||
| @@ -615,22 +762,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
|       MOVE_POS_RET; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   if (maxLen < 3) | ||||
|     maxLen = 3; | ||||
|  | ||||
|   offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), | ||||
|     distances + offset, maxLen) - (distances)); | ||||
|       distances + offset, maxLen) - (distances)); | ||||
|   MOVE_POS_RET | ||||
| } | ||||
|  | ||||
| /* | ||||
| static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos | ||||
|   UInt32 *hash; | ||||
|   GET_MATCHES_HEADER(5) | ||||
|  | ||||
|   HASH5_CALC; | ||||
|  | ||||
|   hash = p->hash; | ||||
|   pos = p->pos; | ||||
|    | ||||
|   d2 = pos - hash[                h2]; | ||||
|   d3 = pos - hash[kFix3HashSize + h3]; | ||||
|   d4 = pos - hash[kFix4HashSize + h4]; | ||||
|  | ||||
|   curMatch = hash[kFix5HashSize + hv]; | ||||
|  | ||||
|   hash[                h2] = pos; | ||||
|   hash[kFix3HashSize + h3] = pos; | ||||
|   hash[kFix4HashSize + h4] = pos; | ||||
|   hash[kFix5HashSize + hv] = pos; | ||||
|  | ||||
|   maxLen = 0; | ||||
|   offset = 0; | ||||
|  | ||||
|   if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) | ||||
|   { | ||||
|     distances[0] = maxLen = 2; | ||||
|     distances[1] = d2 - 1; | ||||
|     offset = 2; | ||||
|     if (*(cur - d2 + 2) == cur[2]) | ||||
|       distances[0] = maxLen = 3; | ||||
|     else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) | ||||
|     { | ||||
|       distances[2] = maxLen = 3; | ||||
|       distances[3] = d3 - 1; | ||||
|       offset = 4; | ||||
|       d2 = d3; | ||||
|     } | ||||
|   } | ||||
|   else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) | ||||
|   { | ||||
|     distances[0] = maxLen = 3; | ||||
|     distances[1] = d3 - 1; | ||||
|     offset = 2; | ||||
|     d2 = d3; | ||||
|   } | ||||
|    | ||||
|   if (d2 != d4 && d4 < p->cyclicBufferSize | ||||
|       && *(cur - d4) == *cur | ||||
|       && *(cur - d4 + 3) == *(cur + 3)) | ||||
|   { | ||||
|     maxLen = 4; | ||||
|     distances[offset + 1] = d4 - 1; | ||||
|     offset += 2; | ||||
|     d2 = d4; | ||||
|   } | ||||
|    | ||||
|   if (offset != 0) | ||||
|   { | ||||
|     UPDATE_maxLen | ||||
|     distances[offset - 2] = maxLen; | ||||
|     if (maxLen == lenLimit) | ||||
|     { | ||||
|       p->son[p->cyclicBufferPos] = curMatch; | ||||
|       MOVE_POS_RET; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   if (maxLen < 4) | ||||
|     maxLen = 4; | ||||
|  | ||||
|   offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), | ||||
|       distances + offset, maxLen) - (distances)); | ||||
|   MOVE_POS_RET | ||||
| } | ||||
| */ | ||||
|  | ||||
| UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 offset; | ||||
|   GET_MATCHES_HEADER(3) | ||||
|   HASH_ZIP_CALC; | ||||
|   curMatch = p->hash[hashValue]; | ||||
|   p->hash[hashValue] = p->pos; | ||||
|   curMatch = p->hash[hv]; | ||||
|   p->hash[hv] = p->pos; | ||||
|   offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), | ||||
|     distances, 2) - (distances)); | ||||
|       distances, 2) - (distances)); | ||||
|   MOVE_POS_RET | ||||
| } | ||||
|  | ||||
| @@ -640,8 +868,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
|   { | ||||
|     SKIP_HEADER(2) | ||||
|     HASH2_CALC; | ||||
|     curMatch = p->hash[hashValue]; | ||||
|     p->hash[hashValue] = p->pos; | ||||
|     curMatch = p->hash[hv]; | ||||
|     p->hash[hv] = p->pos; | ||||
|     SKIP_FOOTER | ||||
|   } | ||||
|   while (--num != 0); | ||||
| @@ -653,8 +881,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
|   { | ||||
|     SKIP_HEADER(3) | ||||
|     HASH_ZIP_CALC; | ||||
|     curMatch = p->hash[hashValue]; | ||||
|     p->hash[hashValue] = p->pos; | ||||
|     curMatch = p->hash[hv]; | ||||
|     p->hash[hv] = p->pos; | ||||
|     SKIP_FOOTER | ||||
|   } | ||||
|   while (--num != 0); | ||||
| @@ -664,12 +892,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| { | ||||
|   do | ||||
|   { | ||||
|     UInt32 hash2Value; | ||||
|     UInt32 h2; | ||||
|     UInt32 *hash; | ||||
|     SKIP_HEADER(3) | ||||
|     HASH3_CALC; | ||||
|     curMatch = p->hash[kFix3HashSize + hashValue]; | ||||
|     p->hash[hash2Value] = | ||||
|     p->hash[kFix3HashSize + hashValue] = p->pos; | ||||
|     hash = p->hash; | ||||
|     curMatch = hash[kFix3HashSize + hv]; | ||||
|     hash[h2] = | ||||
|     hash[kFix3HashSize + hv] = p->pos; | ||||
|     SKIP_FOOTER | ||||
|   } | ||||
|   while (--num != 0); | ||||
| @@ -679,43 +909,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| { | ||||
|   do | ||||
|   { | ||||
|     UInt32 hash2Value, hash3Value; | ||||
|     UInt32 h2, h3; | ||||
|     UInt32 *hash; | ||||
|     SKIP_HEADER(4) | ||||
|     HASH4_CALC; | ||||
|     curMatch = p->hash[kFix4HashSize + hashValue]; | ||||
|     p->hash[                hash2Value] = | ||||
|     p->hash[kFix3HashSize + hash3Value] = p->pos; | ||||
|     p->hash[kFix4HashSize + hashValue] = p->pos; | ||||
|     hash = p->hash; | ||||
|     curMatch = hash[kFix4HashSize + hv]; | ||||
|     hash[                h2] = | ||||
|     hash[kFix3HashSize + h3] = | ||||
|     hash[kFix4HashSize + hv] = p->pos; | ||||
|     SKIP_FOOTER | ||||
|   } | ||||
|   while (--num != 0); | ||||
| } | ||||
|  | ||||
| /* | ||||
| static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| { | ||||
|   do | ||||
|   { | ||||
|     UInt32 h2, h3, h4; | ||||
|     UInt32 *hash; | ||||
|     SKIP_HEADER(5) | ||||
|     HASH5_CALC; | ||||
|     hash = p->hash; | ||||
|     curMatch = hash[kFix5HashSize + hv]; | ||||
|     hash[                h2] = | ||||
|     hash[kFix3HashSize + h3] = | ||||
|     hash[kFix4HashSize + h4] = | ||||
|     hash[kFix5HashSize + hv] = p->pos; | ||||
|     SKIP_FOOTER | ||||
|   } | ||||
|   while (--num != 0); | ||||
| } | ||||
| */ | ||||
|  | ||||
| static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| { | ||||
|   do | ||||
|   { | ||||
|     UInt32 hash2Value, hash3Value; | ||||
|     UInt32 h2, h3; | ||||
|     UInt32 *hash; | ||||
|     SKIP_HEADER(4) | ||||
|     HASH4_CALC; | ||||
|     curMatch = p->hash[kFix4HashSize + hashValue]; | ||||
|     p->hash[                hash2Value] = | ||||
|     p->hash[kFix3HashSize + hash3Value] = | ||||
|     p->hash[kFix4HashSize + hashValue] = p->pos; | ||||
|     hash = p->hash; | ||||
|     curMatch = hash[kFix4HashSize + hv]; | ||||
|     hash[                h2] = | ||||
|     hash[kFix3HashSize + h3] = | ||||
|     hash[kFix4HashSize + hv] = p->pos; | ||||
|     p->son[p->cyclicBufferPos] = curMatch; | ||||
|     MOVE_POS | ||||
|   } | ||||
|   while (--num != 0); | ||||
| } | ||||
|  | ||||
| /* | ||||
| static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| { | ||||
|   do | ||||
|   { | ||||
|     UInt32 h2, h3, h4; | ||||
|     UInt32 *hash; | ||||
|     SKIP_HEADER(5) | ||||
|     HASH5_CALC; | ||||
|     hash = p->hash; | ||||
|     curMatch = p->hash[kFix5HashSize + hv]; | ||||
|     hash[                h2] = | ||||
|     hash[kFix3HashSize + h3] = | ||||
|     hash[kFix4HashSize + h4] = | ||||
|     hash[kFix5HashSize + hv] = p->pos; | ||||
|     p->son[p->cyclicBufferPos] = curMatch; | ||||
|     MOVE_POS | ||||
|   } | ||||
|   while (--num != 0); | ||||
| } | ||||
| */ | ||||
|  | ||||
| void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| { | ||||
|   do | ||||
|   { | ||||
|     SKIP_HEADER(3) | ||||
|     HASH_ZIP_CALC; | ||||
|     curMatch = p->hash[hashValue]; | ||||
|     p->hash[hashValue] = p->pos; | ||||
|     curMatch = p->hash[hv]; | ||||
|     p->hash[hv] = p->pos; | ||||
|     p->son[p->cyclicBufferPos] = curMatch; | ||||
|     MOVE_POS | ||||
|   } | ||||
| @@ -725,13 +1002,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) | ||||
| void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) | ||||
| { | ||||
|   vTable->Init = (Mf_Init_Func)MatchFinder_Init; | ||||
|   vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; | ||||
|   vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; | ||||
|   vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; | ||||
|   if (!p->btMode) | ||||
|   { | ||||
|     vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; | ||||
|     vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; | ||||
|     /* if (p->numHashBytes <= 4) */ | ||||
|     { | ||||
|       vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; | ||||
|       vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; | ||||
|     } | ||||
|     /* | ||||
|     else | ||||
|     { | ||||
|       vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches; | ||||
|       vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip; | ||||
|     } | ||||
|     */ | ||||
|   } | ||||
|   else if (p->numHashBytes == 2) | ||||
|   { | ||||
| @@ -743,9 +1029,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) | ||||
|     vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; | ||||
|     vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; | ||||
|   } | ||||
|   else | ||||
|   else /* if (p->numHashBytes == 4) */ | ||||
|   { | ||||
|     vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; | ||||
|     vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; | ||||
|   } | ||||
|   /* | ||||
|   else | ||||
|   { | ||||
|     vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches; | ||||
|     vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip; | ||||
|   } | ||||
|   */ | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| /* LzFind.h -- Match finder for LZ algorithms | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2015-10-15 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __LZFIND_H | ||||
| #define __LZFIND_H | ||||
| #ifndef __LZ_FIND_H | ||||
| #define __LZ_FIND_H | ||||
|  | ||||
| #include "Types.h" | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| typedef UInt32 CLzRef; | ||||
|  | ||||
| @@ -19,6 +21,11 @@ typedef struct _CMatchFinder | ||||
|   UInt32 cyclicBufferPos; | ||||
|   UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ | ||||
|  | ||||
|   Byte streamEndWasReached; | ||||
|   Byte btMode; | ||||
|   Byte bigHash; | ||||
|   Byte directInput; | ||||
|  | ||||
|   UInt32 matchMaxLen; | ||||
|   CLzRef *hash; | ||||
|   CLzRef *son; | ||||
| @@ -27,30 +34,30 @@ typedef struct _CMatchFinder | ||||
|  | ||||
|   Byte *bufferBase; | ||||
|   ISeqInStream *stream; | ||||
|   int streamEndWasReached; | ||||
|  | ||||
|    | ||||
|   UInt32 blockSize; | ||||
|   UInt32 keepSizeBefore; | ||||
|   UInt32 keepSizeAfter; | ||||
|  | ||||
|   UInt32 numHashBytes; | ||||
|   int directInput; | ||||
|   int btMode; | ||||
|   /* int skipModeBits; */ | ||||
|   int bigHash; | ||||
|   size_t directInputRem; | ||||
|   UInt32 historySize; | ||||
|   UInt32 fixedHashSize; | ||||
|   UInt32 hashSizeSum; | ||||
|   UInt32 numSons; | ||||
|   SRes result; | ||||
|   UInt32 crc[256]; | ||||
|   size_t numRefs; | ||||
| } CMatchFinder; | ||||
|  | ||||
| #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) | ||||
| #define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) | ||||
|  | ||||
| #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) | ||||
|  | ||||
| #define Inline_MatchFinder_IsFinishedOK(p) \ | ||||
|     ((p)->streamEndWasReached \ | ||||
|         && (p)->streamPos == (p)->pos \ | ||||
|         && (!(p)->directInput || (p)->directInputRem == 0)) | ||||
|        | ||||
| int MatchFinder_NeedMove(CMatchFinder *p); | ||||
| Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); | ||||
| void MatchFinder_MoveBlock(CMatchFinder *p); | ||||
| @@ -66,7 +73,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, | ||||
|     UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, | ||||
|     ISzAlloc *alloc); | ||||
| void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); | ||||
| void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); | ||||
| void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); | ||||
| void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); | ||||
|  | ||||
| UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, | ||||
| @@ -80,7 +87,6 @@ Conditions: | ||||
| */ | ||||
|  | ||||
| typedef void (*Mf_Init_Func)(void *object); | ||||
| typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); | ||||
| typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); | ||||
| typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); | ||||
| typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); | ||||
| @@ -89,7 +95,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32); | ||||
| typedef struct _IMatchFinder | ||||
| { | ||||
|   Mf_Init_Func Init; | ||||
|   Mf_GetIndexByte_Func GetIndexByte; | ||||
|   Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; | ||||
|   Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; | ||||
|   Mf_GetMatches_Func GetMatches; | ||||
| @@ -98,10 +103,15 @@ typedef struct _IMatchFinder | ||||
|  | ||||
| void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); | ||||
|  | ||||
| void MatchFinder_Init_2(CMatchFinder *p, int readData); | ||||
| void MatchFinder_Init(CMatchFinder *p); | ||||
|  | ||||
| UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); | ||||
| UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); | ||||
|  | ||||
| void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); | ||||
| void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| /* LzFindMt.c -- multithreaded Match finder for LZ algorithms | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2015-10-15 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #include "LzHash.h" | ||||
|  | ||||
| #include "LzFindMt.h" | ||||
|  | ||||
| void MtSync_Construct(CMtSync *p) | ||||
| static void MtSync_Construct(CMtSync *p) | ||||
| { | ||||
|   p->wasCreated = False; | ||||
|   p->csWasInitialized = False; | ||||
| @@ -18,7 +20,7 @@ void MtSync_Construct(CMtSync *p) | ||||
|   Semaphore_Construct(&p->filledSemaphore); | ||||
| } | ||||
|  | ||||
| void MtSync_GetNextBlock(CMtSync *p) | ||||
| static void MtSync_GetNextBlock(CMtSync *p) | ||||
| { | ||||
|   if (p->needStart) | ||||
|   { | ||||
| @@ -46,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p) | ||||
|  | ||||
| /* MtSync_StopWriting must be called if Writing was started */ | ||||
|  | ||||
| void MtSync_StopWriting(CMtSync *p) | ||||
| static void MtSync_StopWriting(CMtSync *p) | ||||
| { | ||||
|   UInt32 myNumBlocks = p->numProcessedBlocks; | ||||
|   if (!Thread_WasCreated(&p->thread) || p->needStart) | ||||
| @@ -69,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p) | ||||
|   p->needStart = True; | ||||
| } | ||||
|  | ||||
| void MtSync_Destruct(CMtSync *p) | ||||
| static void MtSync_Destruct(CMtSync *p) | ||||
| { | ||||
|   if (Thread_WasCreated(&p->thread)) | ||||
|   { | ||||
| @@ -97,7 +99,7 @@ void MtSync_Destruct(CMtSync *p) | ||||
|  | ||||
| #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } | ||||
|  | ||||
| static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) | ||||
| static SRes MtSync_Create2(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) | ||||
| { | ||||
|   if (p->wasCreated) | ||||
|     return SZ_OK; | ||||
| @@ -119,7 +121,7 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void | ||||
|   return SZ_OK; | ||||
| } | ||||
|  | ||||
| static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks) | ||||
| static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj, UInt32 numBlocks) | ||||
| { | ||||
|   SRes res = MtSync_Create2(p, startAddress, obj, numBlocks); | ||||
|   if (res != SZ_OK) | ||||
| @@ -132,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; } | ||||
| #define kMtMaxValForNormalize 0xFFFFFFFF | ||||
|  | ||||
| #define DEF_GetHeads2(name, v, action) \ | ||||
| static void GetHeads ## name(const Byte *p, UInt32 pos, \ | ||||
| UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ | ||||
| { action; for (; numHeads != 0; numHeads--) { \ | ||||
| const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } } | ||||
|   static void GetHeads ## name(const Byte *p, UInt32 pos, \ | ||||
|       UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \ | ||||
|     { action; for (; numHeads != 0; numHeads--) { \ | ||||
|       const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++;  } } | ||||
|  | ||||
| #define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;) | ||||
|  | ||||
| DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; ) | ||||
| DEF_GetHeads2(2,  (p[0] | ((UInt32)p[1] << 8)), UNUSED_VAR(hashMask); UNUSED_VAR(crc); ) | ||||
| DEF_GetHeads(3,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask) | ||||
| DEF_GetHeads(4,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask) | ||||
| DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask) | ||||
| DEF_GetHeads(5,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) | ||||
| /* DEF_GetHeads(5,  (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */ | ||||
|  | ||||
| void HashThreadFunc(CMatchFinderMt *mt) | ||||
| static void HashThreadFunc(CMatchFinderMt *mt) | ||||
| { | ||||
|   CMtSync *p = &mt->hashSync; | ||||
|   for (;;) | ||||
| @@ -171,12 +173,12 @@ void HashThreadFunc(CMatchFinderMt *mt) | ||||
|           CriticalSection_Enter(&mt->btSync.cs); | ||||
|           CriticalSection_Enter(&mt->hashSync.cs); | ||||
|           { | ||||
|             const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf); | ||||
|             const Byte *afterPtr; | ||||
|             const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf); | ||||
|             ptrdiff_t offset; | ||||
|             MatchFinder_MoveBlock(mf); | ||||
|             afterPtr = MatchFinder_GetPointerToCurrentPos(mf); | ||||
|             mt->pointerToCurPos -= beforePtr - afterPtr; | ||||
|             mt->buffer -= beforePtr - afterPtr; | ||||
|             offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf); | ||||
|             mt->pointerToCurPos -= offset; | ||||
|             mt->buffer -= offset; | ||||
|           } | ||||
|           CriticalSection_Leave(&mt->btSync.cs); | ||||
|           CriticalSection_Leave(&mt->hashSync.cs); | ||||
| @@ -190,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt) | ||||
|         { | ||||
|           UInt32 subValue = (mf->pos - mf->historySize - 1); | ||||
|           MatchFinder_ReduceOffsets(mf, subValue); | ||||
|           MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1); | ||||
|           MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1); | ||||
|         } | ||||
|         { | ||||
|           UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize; | ||||
| @@ -215,7 +217,7 @@ void HashThreadFunc(CMatchFinderMt *mt) | ||||
|   } | ||||
| } | ||||
|  | ||||
| void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) | ||||
| static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) | ||||
| { | ||||
|   MtSync_GetNextBlock(&p->hashSync); | ||||
|   p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize; | ||||
| @@ -231,7 +233,7 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p) | ||||
|  | ||||
| #define NO_INLINE MY_FAST_CALL | ||||
|  | ||||
| Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, | ||||
| static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son, | ||||
|     UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, | ||||
|     UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes) | ||||
| { | ||||
| @@ -308,12 +310,14 @@ Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CL | ||||
|  | ||||
| #endif | ||||
|  | ||||
| void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
| static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
| { | ||||
|   UInt32 numProcessed = 0; | ||||
|   UInt32 curPos = 2; | ||||
|   UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2); | ||||
|    | ||||
|   distances[1] = p->hashNumAvail; | ||||
|    | ||||
|   while (curPos < limit) | ||||
|   { | ||||
|     if (p->hashBufPos == p->hashBufPosLimit) | ||||
| @@ -322,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|       distances[1] = numProcessed + p->hashNumAvail; | ||||
|       if (p->hashNumAvail >= p->numHashBytes) | ||||
|         continue; | ||||
|       distances[0] = curPos + p->hashNumAvail; | ||||
|       distances += curPos; | ||||
|       for (; p->hashNumAvail != 0; p->hashNumAvail--) | ||||
|         distances[curPos++] = 0; | ||||
|       break; | ||||
|         *distances++ = 0; | ||||
|       return; | ||||
|     } | ||||
|     { | ||||
|       UInt32 size = p->hashBufPosLimit - p->hashBufPos; | ||||
| @@ -341,13 +347,14 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|         if (size2 < size) | ||||
|           size = size2; | ||||
|       } | ||||
|        | ||||
|       #ifndef MFMT_GM_INLINE | ||||
|       while (curPos < limit && size-- != 0) | ||||
|       { | ||||
|         UInt32 *startDistances = distances + curPos; | ||||
|         UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++], | ||||
|           pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, | ||||
|           startDistances + 1, p->numHashBytes - 1) - startDistances); | ||||
|             pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, | ||||
|             startDistances + 1, p->numHashBytes - 1) - startDistances); | ||||
|         *startDistances = num - 1; | ||||
|         curPos += num; | ||||
|         cyclicBufferPos++; | ||||
| @@ -358,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|       { | ||||
|         UInt32 posRes; | ||||
|         curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue, | ||||
|           distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes); | ||||
|             distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes); | ||||
|         p->hashBufPos += posRes - pos; | ||||
|         cyclicBufferPos += posRes - pos; | ||||
|         p->buffer += posRes - pos; | ||||
| @@ -374,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|       p->cyclicBufferPos = cyclicBufferPos; | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   distances[0] = curPos; | ||||
| } | ||||
|  | ||||
| void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) | ||||
| static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) | ||||
| { | ||||
|   CMtSync *sync = &p->hashSync; | ||||
|   if (!sync->needStart) | ||||
| @@ -391,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) | ||||
|   if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize) | ||||
|   { | ||||
|     UInt32 subValue = p->pos - p->cyclicBufferSize; | ||||
|     MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2); | ||||
|     MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2); | ||||
|     p->pos -= subValue; | ||||
|   } | ||||
|  | ||||
| @@ -430,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt) | ||||
|  | ||||
| void MatchFinderMt_Construct(CMatchFinderMt *p) | ||||
| { | ||||
|   p->hashBuf = 0; | ||||
|   p->hashBuf = NULL; | ||||
|   MtSync_Construct(&p->hashSync); | ||||
|   MtSync_Construct(&p->btSync); | ||||
| } | ||||
|  | ||||
| void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) | ||||
| static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc) | ||||
| { | ||||
|   alloc->Free(alloc, p->hashBuf); | ||||
|   p->hashBuf = 0; | ||||
|   p->hashBuf = NULL; | ||||
| } | ||||
|  | ||||
| void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) | ||||
| @@ -451,14 +459,15 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc) | ||||
| #define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks) | ||||
| #define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks) | ||||
|  | ||||
| static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p);  return 0; } | ||||
| static unsigned MY_STD_CALL BtThreadFunc2(void *p) | ||||
| static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p);  return 0; } | ||||
| static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) | ||||
| { | ||||
|   Byte allocaDummy[0x180]; | ||||
|   int i = 0; | ||||
|   unsigned i = 0; | ||||
|   for (i = 0; i < 16; i++) | ||||
|     allocaDummy[i] = (Byte)i; | ||||
|   BtThreadFunc((CMatchFinderMt *)p); | ||||
|     allocaDummy[i] = (Byte)0; | ||||
|   if (allocaDummy[0] == 0) | ||||
|     BtThreadFunc((CMatchFinderMt *)p); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -469,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB | ||||
|   p->historySize = historySize; | ||||
|   if (kMtBtBlockSize <= matchMaxLen * 4) | ||||
|     return SZ_ERROR_PARAM; | ||||
|   if (p->hashBuf == 0) | ||||
|   if (!p->hashBuf) | ||||
|   { | ||||
|     p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32)); | ||||
|     if (p->hashBuf == 0) | ||||
|     if (!p->hashBuf) | ||||
|       return SZ_ERROR_MEM; | ||||
|     p->btBuf = p->hashBuf + kHashBufferSize; | ||||
|   } | ||||
| @@ -492,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p) | ||||
|   CMatchFinder *mf = p->MatchFinder; | ||||
|   p->btBufPos = p->btBufPosLimit = 0; | ||||
|   p->hashBufPos = p->hashBufPosLimit = 0; | ||||
|   MatchFinder_Init(mf); | ||||
|   p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf); | ||||
|  | ||||
|   /* Init without data reading. We don't want to read data in this thread */ | ||||
|   MatchFinder_Init_2(mf, False); | ||||
|    | ||||
|   p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf); | ||||
|   p->btNumAvailBytes = 0; | ||||
|   p->lzPos = p->historySize + 1; | ||||
|  | ||||
| @@ -518,13 +530,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p) | ||||
|   /* p->MatchFinder->ReleaseStream(); */ | ||||
| } | ||||
|  | ||||
| void MatchFinderMt_Normalize(CMatchFinderMt *p) | ||||
| static void MatchFinderMt_Normalize(CMatchFinderMt *p) | ||||
| { | ||||
|   MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize); | ||||
|   p->lzPos = p->historySize + 1; | ||||
| } | ||||
|  | ||||
| void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) | ||||
| static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) | ||||
| { | ||||
|   UInt32 blockIndex; | ||||
|   MtSync_GetNextBlock(&p->btSync); | ||||
| @@ -536,34 +548,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) | ||||
|     MatchFinderMt_Normalize(p); | ||||
| } | ||||
|  | ||||
| const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) | ||||
| static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p) | ||||
| { | ||||
|   return p->pointerToCurPos; | ||||
| } | ||||
|  | ||||
| #define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p); | ||||
|  | ||||
| UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) | ||||
| static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p) | ||||
| { | ||||
|   GET_NEXT_BLOCK_IF_REQUIRED; | ||||
|   return p->btNumAvailBytes; | ||||
| } | ||||
|  | ||||
| Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index) | ||||
| static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
| { | ||||
|   return p->pointerToCurPos[index]; | ||||
| } | ||||
|  | ||||
| UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
| { | ||||
|   UInt32 hash2Value, curMatch2; | ||||
|   UInt32 h2, curMatch2; | ||||
|   UInt32 *hash = p->hash; | ||||
|   const Byte *cur = p->pointerToCurPos; | ||||
|   UInt32 lzPos = p->lzPos; | ||||
|   MT_HASH2_CALC | ||||
|        | ||||
|   curMatch2 = hash[hash2Value]; | ||||
|   hash[hash2Value] = lzPos; | ||||
|   curMatch2 = hash[h2]; | ||||
|   hash[h2] = lzPos; | ||||
|  | ||||
|   if (curMatch2 >= matchMinPos) | ||||
|     if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) | ||||
| @@ -571,23 +578,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
|       *distances++ = 2; | ||||
|       *distances++ = lzPos - curMatch2 - 1; | ||||
|     } | ||||
|    | ||||
|   return distances; | ||||
| } | ||||
|  | ||||
| UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
| static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
| { | ||||
|   UInt32 hash2Value, hash3Value, curMatch2, curMatch3; | ||||
|   UInt32 h2, h3, curMatch2, curMatch3; | ||||
|   UInt32 *hash = p->hash; | ||||
|   const Byte *cur = p->pointerToCurPos; | ||||
|   UInt32 lzPos = p->lzPos; | ||||
|   MT_HASH3_CALC | ||||
|  | ||||
|   curMatch2 = hash[                hash2Value]; | ||||
|   curMatch3 = hash[kFix3HashSize + hash3Value]; | ||||
|   curMatch2 = hash[                h2]; | ||||
|   curMatch3 = hash[kFix3HashSize + h3]; | ||||
|    | ||||
|   hash[                hash2Value] = | ||||
|   hash[kFix3HashSize + hash3Value] = | ||||
|     lzPos; | ||||
|   hash[                h2] = lzPos; | ||||
|   hash[kFix3HashSize + h3] = lzPos; | ||||
|  | ||||
|   if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) | ||||
|   { | ||||
| @@ -600,43 +607,45 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
|     distances[0] = 2; | ||||
|     distances += 2; | ||||
|   } | ||||
|    | ||||
|   if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) | ||||
|   { | ||||
|     *distances++ = 3; | ||||
|     *distances++ = lzPos - curMatch3 - 1; | ||||
|   } | ||||
|    | ||||
|   return distances; | ||||
| } | ||||
|  | ||||
| /* | ||||
| UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
| static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
| { | ||||
|   UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4; | ||||
|   UInt32 h2, h3, h4, curMatch2, curMatch3, curMatch4; | ||||
|   UInt32 *hash = p->hash; | ||||
|   const Byte *cur = p->pointerToCurPos; | ||||
|   UInt32 lzPos = p->lzPos; | ||||
|   MT_HASH4_CALC | ||||
|        | ||||
|   curMatch2 = hash[                hash2Value]; | ||||
|   curMatch3 = hash[kFix3HashSize + hash3Value]; | ||||
|   curMatch4 = hash[kFix4HashSize + hash4Value]; | ||||
|   curMatch2 = hash[                h2]; | ||||
|   curMatch3 = hash[kFix3HashSize + h3]; | ||||
|   curMatch4 = hash[kFix4HashSize + h4]; | ||||
|    | ||||
|   hash[                hash2Value] = | ||||
|   hash[kFix3HashSize + hash3Value] = | ||||
|   hash[kFix4HashSize + hash4Value] = | ||||
|     lzPos; | ||||
|   hash[                h2] = lzPos; | ||||
|   hash[kFix3HashSize + h3] = lzPos; | ||||
|   hash[kFix4HashSize + h4] = lzPos; | ||||
|  | ||||
|   if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0]) | ||||
|   { | ||||
|     distances[1] = lzPos - curMatch2 - 1; | ||||
|     if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2]) | ||||
|     { | ||||
|       distances[0] =  (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3; | ||||
|       distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3; | ||||
|       return distances + 2; | ||||
|     } | ||||
|     distances[0] = 2; | ||||
|     distances += 2; | ||||
|   } | ||||
|    | ||||
|   if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0]) | ||||
|   { | ||||
|     distances[1] = lzPos - curMatch3 - 1; | ||||
| @@ -658,13 +667,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances) | ||||
|       *distances++ = 4; | ||||
|       *distances++ = lzPos - curMatch4 - 1; | ||||
|     } | ||||
|    | ||||
|   return distances; | ||||
| } | ||||
| */ | ||||
|  | ||||
| #define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++; | ||||
|  | ||||
| UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
| static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
| { | ||||
|   const UInt32 *btBuf = p->btBuf + p->btBufPos; | ||||
|   UInt32 len = *btBuf++; | ||||
| @@ -682,7 +692,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|   return len; | ||||
| } | ||||
|  | ||||
| UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
| static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
| { | ||||
|   const UInt32 *btBuf = p->btBuf + p->btBufPos; | ||||
|   UInt32 len = *btBuf++; | ||||
| @@ -690,6 +700,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|  | ||||
|   if (len == 0) | ||||
|   { | ||||
|     /* change for bt5 ! */ | ||||
|     if (p->btNumAvailBytes-- >= 4) | ||||
|       len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances)); | ||||
|   } | ||||
| @@ -705,64 +716,64 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) | ||||
|       *distances2++ = *btBuf++; | ||||
|     } | ||||
|     while ((len -= 2) != 0); | ||||
|     len  = (UInt32)(distances2 - (distances)); | ||||
|     len = (UInt32)(distances2 - (distances)); | ||||
|   } | ||||
|   INCREASE_LZ_POS | ||||
|   return len; | ||||
| } | ||||
|  | ||||
| #define SKIP_HEADER2  do { GET_NEXT_BLOCK_IF_REQUIRED | ||||
| #define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; | ||||
| #define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); | ||||
| #define SKIP_HEADER2_MT  do { GET_NEXT_BLOCK_IF_REQUIRED | ||||
| #define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash; | ||||
| #define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0); | ||||
|  | ||||
| void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| { | ||||
|   SKIP_HEADER2 { p->btNumAvailBytes--; | ||||
|   SKIP_FOOTER | ||||
|   SKIP_HEADER2_MT { p->btNumAvailBytes--; | ||||
|   SKIP_FOOTER_MT | ||||
| } | ||||
|  | ||||
| void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| { | ||||
|   SKIP_HEADER(2) | ||||
|       UInt32 hash2Value; | ||||
|   SKIP_HEADER_MT(2) | ||||
|       UInt32 h2; | ||||
|       MT_HASH2_CALC | ||||
|       hash[hash2Value] = p->lzPos; | ||||
|   SKIP_FOOTER | ||||
|       hash[h2] = p->lzPos; | ||||
|   SKIP_FOOTER_MT | ||||
| } | ||||
|  | ||||
| void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| { | ||||
|   SKIP_HEADER(3) | ||||
|       UInt32 hash2Value, hash3Value; | ||||
|   SKIP_HEADER_MT(3) | ||||
|       UInt32 h2, h3; | ||||
|       MT_HASH3_CALC | ||||
|       hash[kFix3HashSize + hash3Value] = | ||||
|       hash[                hash2Value] = | ||||
|       hash[kFix3HashSize + h3] = | ||||
|       hash[                h2] = | ||||
|         p->lzPos; | ||||
|   SKIP_FOOTER | ||||
|   SKIP_FOOTER_MT | ||||
| } | ||||
|  | ||||
| /* | ||||
| void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) | ||||
| { | ||||
|   SKIP_HEADER(4) | ||||
|       UInt32 hash2Value, hash3Value, hash4Value; | ||||
|   SKIP_HEADER_MT(4) | ||||
|       UInt32 h2, h3, h4; | ||||
|       MT_HASH4_CALC | ||||
|       hash[kFix4HashSize + hash4Value] = | ||||
|       hash[kFix3HashSize + hash3Value] = | ||||
|       hash[                hash2Value] = | ||||
|       hash[kFix4HashSize + h4] = | ||||
|       hash[kFix3HashSize + h3] = | ||||
|       hash[                h2] = | ||||
|         p->lzPos; | ||||
|   SKIP_FOOTER | ||||
|   SKIP_FOOTER_MT | ||||
| } | ||||
| */ | ||||
|  | ||||
| void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) | ||||
| { | ||||
|   vTable->Init = (Mf_Init_Func)MatchFinderMt_Init; | ||||
|   vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte; | ||||
|   vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes; | ||||
|   vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos; | ||||
|   vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches; | ||||
|   switch(p->MatchFinder->numHashBytes) | ||||
|    | ||||
|   switch (p->MatchFinder->numHashBytes) | ||||
|   { | ||||
|     case 2: | ||||
|       p->GetHeadsFunc = GetHeads2; | ||||
| @@ -778,7 +789,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) | ||||
|     default: | ||||
|     /* case 4: */ | ||||
|       p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4; | ||||
|       /* p->GetHeadsFunc = GetHeads4; */ | ||||
|       p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3; | ||||
|       vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip; | ||||
|       break; | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| /* LzFindMt.h -- multithreaded Match finder for LZ algorithms | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2015-05-03 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __LZFINDMT_H | ||||
| #define __LZFINDMT_H | ||||
| #ifndef __LZ_FIND_MT_H | ||||
| #define __LZ_FIND_MT_H | ||||
|  | ||||
| #include "Threads.h" | ||||
| #include "LzFind.h" | ||||
| #include "Threads.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| #define kMtHashBlockSize (1 << 13) | ||||
| #define kMtHashNumBlocks (1 << 3) | ||||
| @@ -73,7 +75,7 @@ typedef struct _CMatchFinderMt | ||||
|   UInt32 matchMaxLen; | ||||
|   UInt32 numHashBytes; | ||||
|   UInt32 pos; | ||||
|   Byte *buffer; | ||||
|   const Byte *buffer; | ||||
|   UInt32 cyclicBufferPos; | ||||
|   UInt32 cyclicBufferSize; /* it must be historySize + 1 */ | ||||
|   UInt32 cutValue; | ||||
| @@ -94,4 +96,6 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB | ||||
| void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable); | ||||
| void MatchFinderMt_ReleaseStream(CMatchFinderMt *p); | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| /* LzHash.h -- HASH functions for LZ algorithms | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2015-04-12 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __LZHASH_H | ||||
| #define __LZHASH_H | ||||
| #ifndef __LZ_HASH_H | ||||
| #define __LZ_HASH_H | ||||
|  | ||||
| #define kHash2Size (1 << 10) | ||||
| #define kHash3Size (1 << 16) | ||||
| @@ -12,43 +12,46 @@ | ||||
| #define kFix4HashSize (kHash2Size + kHash3Size) | ||||
| #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) | ||||
|  | ||||
| #define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); | ||||
| #define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8); | ||||
|  | ||||
| #define HASH3_CALC { \ | ||||
|   UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ | ||||
|   hash2Value = temp & (kHash2Size - 1); \ | ||||
|   hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } | ||||
|   h2 = temp & (kHash2Size - 1); \ | ||||
|   hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } | ||||
|  | ||||
| #define HASH4_CALC { \ | ||||
|   UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ | ||||
|   hash2Value = temp & (kHash2Size - 1); \ | ||||
|   hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ | ||||
|   hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } | ||||
|   h2 = temp & (kHash2Size - 1); \ | ||||
|   temp ^= ((UInt32)cur[2] << 8); \ | ||||
|   h3 = temp & (kHash3Size - 1); \ | ||||
|   hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; } | ||||
|  | ||||
| #define HASH5_CALC { \ | ||||
|   UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ | ||||
|   hash2Value = temp & (kHash2Size - 1); \ | ||||
|   hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ | ||||
|   hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ | ||||
|   hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ | ||||
|   hash4Value &= (kHash4Size - 1); } | ||||
|   h2 = temp & (kHash2Size - 1); \ | ||||
|   temp ^= ((UInt32)cur[2] << 8); \ | ||||
|   h3 = temp & (kHash3Size - 1); \ | ||||
|   temp ^= (p->crc[cur[3]] << 5); \ | ||||
|   h4 = temp & (kHash4Size - 1); \ | ||||
|   hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; } | ||||
|  | ||||
| /* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ | ||||
| #define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; | ||||
| /* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ | ||||
| #define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; | ||||
|  | ||||
|  | ||||
| #define MT_HASH2_CALC \ | ||||
|   hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); | ||||
|   h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); | ||||
|  | ||||
| #define MT_HASH3_CALC { \ | ||||
|   UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ | ||||
|   hash2Value = temp & (kHash2Size - 1); \ | ||||
|   hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } | ||||
|   h2 = temp & (kHash2Size - 1); \ | ||||
|   h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } | ||||
|  | ||||
| #define MT_HASH4_CALC { \ | ||||
|   UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ | ||||
|   hash2Value = temp & (kHash2Size - 1); \ | ||||
|   hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ | ||||
|   hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } | ||||
|   h2 = temp & (kHash2Size - 1); \ | ||||
|   temp ^= ((UInt32)cur[2] << 8); \ | ||||
|   h3 = temp & (kHash3Size - 1); \ | ||||
|   h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| /* LzmaDec.c -- LZMA Decoder | ||||
| 2008-11-06 : Igor Pavlov : Public domain */ | ||||
| 2016-05-16 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #include "LzmaDec.h" | ||||
|  | ||||
| @@ -44,6 +46,13 @@ | ||||
|   i -= 0x40; } | ||||
| #endif | ||||
|  | ||||
| #define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol) | ||||
| #define MATCHED_LITER_DEC \ | ||||
|   matchByte <<= 1; \ | ||||
|   bit = (matchByte & offs); \ | ||||
|   probLit = prob + offs + bit + symbol; \ | ||||
|   GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) | ||||
|  | ||||
| #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } | ||||
|  | ||||
| #define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) | ||||
| @@ -105,19 +114,13 @@ | ||||
| #define Literal (RepLenCoder + kNumLenProbs) | ||||
|  | ||||
| #define LZMA_BASE_SIZE 1846 | ||||
| #define LZMA_LIT_SIZE 768 | ||||
|  | ||||
| #define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) | ||||
| #define LZMA_LIT_SIZE 0x300 | ||||
|  | ||||
| #if Literal != LZMA_BASE_SIZE | ||||
| StopCompilingDueBUG | ||||
| #endif | ||||
|  | ||||
| static const Byte kLiteralNextStates[kNumStates * 2] = | ||||
| { | ||||
|   0, 0, 0, 0, 1, 2, 3,  4,  5,  6,  4,  5, | ||||
|   7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 | ||||
| }; | ||||
| #define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) | ||||
|  | ||||
| #define LZMA_DIC_MIN (1 << 12) | ||||
|  | ||||
| @@ -130,8 +133,8 @@ Out: | ||||
|   p->remainLen: | ||||
|     < kMatchSpecLenStart : normal remain | ||||
|     = kMatchSpecLenStart : finished | ||||
|     = kMatchSpecLenStart + 1 : Flush marker | ||||
|     = kMatchSpecLenStart + 2 : State Init Marker | ||||
|     = 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) | ||||
| @@ -169,39 +172,62 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|       unsigned symbol; | ||||
|       UPDATE_0(prob); | ||||
|       prob = probs + Literal; | ||||
|       if (checkDicSize != 0 || processedPos != 0) | ||||
|         prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + | ||||
|         (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); | ||||
|       if (processedPos != 0 || checkDicSize != 0) | ||||
|         prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + | ||||
|             (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); | ||||
|       processedPos++; | ||||
|  | ||||
|       if (state < kNumLitStates) | ||||
|       { | ||||
|         state -= (state < 4) ? state : 3; | ||||
|         symbol = 1; | ||||
|         do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); | ||||
|         #ifdef _LZMA_SIZE_OPT | ||||
|         do { NORMAL_LITER_DEC } while (symbol < 0x100); | ||||
|         #else | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         NORMAL_LITER_DEC | ||||
|         #endif | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|         unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; | ||||
|         unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; | ||||
|         unsigned offs = 0x100; | ||||
|         state -= (state < 10) ? 3 : 6; | ||||
|         symbol = 1; | ||||
|         #ifdef _LZMA_SIZE_OPT | ||||
|         do | ||||
|         { | ||||
|           unsigned bit; | ||||
|           CLzmaProb *probLit; | ||||
|           matchByte <<= 1; | ||||
|           bit = (matchByte & offs); | ||||
|           probLit = prob + offs + bit + symbol; | ||||
|           GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) | ||||
|           MATCHED_LITER_DEC | ||||
|         } | ||||
|         while (symbol < 0x100); | ||||
|         #else | ||||
|         { | ||||
|           unsigned bit; | ||||
|           CLzmaProb *probLit; | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|           MATCHED_LITER_DEC | ||||
|         } | ||||
|         #endif | ||||
|       } | ||||
|       dic[dicPos++] = (Byte)symbol; | ||||
|       processedPos++; | ||||
|  | ||||
|       state = kLiteralNextStates[state]; | ||||
|       /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ | ||||
|       dic[dicPos++] = (Byte)symbol; | ||||
|       continue; | ||||
|     } | ||||
|     else | ||||
|      | ||||
|     { | ||||
|       UPDATE_1(prob); | ||||
|       prob = probs + IsRep + state; | ||||
| @@ -224,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|           IF_BIT_0(prob) | ||||
|           { | ||||
|             UPDATE_0(prob); | ||||
|             dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; | ||||
|             dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; | ||||
|             dicPos++; | ||||
|             processedPos++; | ||||
|             state = state < kNumLitStates ? 9 : 11; | ||||
| @@ -265,15 +291,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|         state = state < kNumLitStates ? 8 : 11; | ||||
|         prob = probs + RepLenCoder; | ||||
|       } | ||||
|        | ||||
|       #ifdef _LZMA_SIZE_OPT | ||||
|       { | ||||
|         unsigned offset; | ||||
|         unsigned lim, offset; | ||||
|         CLzmaProb *probLen = prob + LenChoice; | ||||
|         IF_BIT_0(probLen) | ||||
|         { | ||||
|           UPDATE_0(probLen); | ||||
|           probLen = prob + LenLow + (posState << kLenNumLowBits); | ||||
|           offset = 0; | ||||
|           limit = (1 << kLenNumLowBits); | ||||
|           lim = (1 << kLenNumLowBits); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
| @@ -284,19 +312,55 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|             UPDATE_0(probLen); | ||||
|             probLen = prob + LenMid + (posState << kLenNumMidBits); | ||||
|             offset = kLenNumLowSymbols; | ||||
|             limit = (1 << kLenNumMidBits); | ||||
|             lim = (1 << kLenNumMidBits); | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             UPDATE_1(probLen); | ||||
|             probLen = prob + LenHigh; | ||||
|             offset = kLenNumLowSymbols + kLenNumMidSymbols; | ||||
|             limit = (1 << kLenNumHighBits); | ||||
|             lim = (1 << kLenNumHighBits); | ||||
|           } | ||||
|         } | ||||
|         TREE_DECODE(probLen, limit, len); | ||||
|         TREE_DECODE(probLen, lim, len); | ||||
|         len += offset; | ||||
|       } | ||||
|       #else | ||||
|       { | ||||
|         CLzmaProb *probLen = prob + LenChoice; | ||||
|         IF_BIT_0(probLen) | ||||
|         { | ||||
|           UPDATE_0(probLen); | ||||
|           probLen = prob + LenLow + (posState << kLenNumLowBits); | ||||
|           len = 1; | ||||
|           TREE_GET_BIT(probLen, len); | ||||
|           TREE_GET_BIT(probLen, len); | ||||
|           TREE_GET_BIT(probLen, len); | ||||
|           len -= 8; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|           UPDATE_1(probLen); | ||||
|           probLen = prob + LenChoice2; | ||||
|           IF_BIT_0(probLen) | ||||
|           { | ||||
|             UPDATE_0(probLen); | ||||
|             probLen = prob + LenMid + (posState << kLenNumMidBits); | ||||
|             len = 1; | ||||
|             TREE_GET_BIT(probLen, len); | ||||
|             TREE_GET_BIT(probLen, len); | ||||
|             TREE_GET_BIT(probLen, len); | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|             UPDATE_1(probLen); | ||||
|             probLen = prob + LenHigh; | ||||
|             TREE_DECODE(probLen, (1 << kLenNumHighBits), len); | ||||
|             len += kLenNumLowSymbols + kLenNumMidSymbols; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       #endif | ||||
|  | ||||
|       if (state >= kNumStates) | ||||
|       { | ||||
| @@ -307,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|         if (distance >= kStartPosModelIndex) | ||||
|         { | ||||
|           unsigned posSlot = (unsigned)distance; | ||||
|           int numDirectBits = (int)(((distance >> 1) - 1)); | ||||
|           unsigned numDirectBits = (unsigned)(((distance >> 1) - 1)); | ||||
|           distance = (2 | (distance & 1)); | ||||
|           if (posSlot < kEndPosModelIndex) | ||||
|           { | ||||
| @@ -366,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         rep3 = rep2; | ||||
|         rep2 = rep1; | ||||
|         rep1 = rep0; | ||||
| @@ -373,27 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|         if (checkDicSize == 0) | ||||
|         { | ||||
|           if (distance >= processedPos) | ||||
|           { | ||||
|             p->dicPos = dicPos; | ||||
|             return SZ_ERROR_DATA; | ||||
|           } | ||||
|         } | ||||
|         else if (distance >= checkDicSize) | ||||
|         { | ||||
|           p->dicPos = dicPos; | ||||
|           return SZ_ERROR_DATA; | ||||
|         } | ||||
|         state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; | ||||
|         /* state = kLiteralNextStates[state]; */ | ||||
|       } | ||||
|  | ||||
|       len += kMatchMinLen; | ||||
|  | ||||
|       if (limit == dicPos) | ||||
|         return SZ_ERROR_DATA; | ||||
|       { | ||||
|         SizeT rem = limit - dicPos; | ||||
|         unsigned curLen = ((rem < len) ? (unsigned)rem : len); | ||||
|         SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); | ||||
|         SizeT rem; | ||||
|         unsigned curLen; | ||||
|         SizeT pos; | ||||
|          | ||||
|         if ((rem = limit - dicPos) == 0) | ||||
|         { | ||||
|           p->dicPos = dicPos; | ||||
|           return SZ_ERROR_DATA; | ||||
|         } | ||||
|          | ||||
|         curLen = ((rem < len) ? (unsigned)rem : len); | ||||
|         pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0); | ||||
|  | ||||
|         processedPos += curLen; | ||||
|  | ||||
|         len -= curLen; | ||||
|         if (pos + curLen <= dicBufSize) | ||||
|         if (curLen <= dicBufSize - pos) | ||||
|         { | ||||
|           Byte *dest = dic + dicPos; | ||||
|           ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; | ||||
| @@ -417,7 +494,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte | ||||
|     } | ||||
|   } | ||||
|   while (dicPos < limit && buf < bufLimit); | ||||
|  | ||||
|   NORMALIZE; | ||||
|    | ||||
|   p->buf = buf; | ||||
|   p->range = range; | ||||
|   p->code = code; | ||||
| @@ -441,18 +520,20 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) | ||||
|     SizeT dicPos = p->dicPos; | ||||
|     SizeT dicBufSize = p->dicBufSize; | ||||
|     unsigned len = p->remainLen; | ||||
|     UInt32 rep0 = p->reps[0]; | ||||
|     if (limit - dicPos < len) | ||||
|       len = (unsigned)(limit - dicPos); | ||||
|     SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */ | ||||
|     SizeT rem = limit - dicPos; | ||||
|     if (rem < len) | ||||
|       len = (unsigned)(rem); | ||||
|  | ||||
|     if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) | ||||
|       p->checkDicSize = p->prop.dicSize; | ||||
|  | ||||
|     p->processedPos += len; | ||||
|     p->remainLen -= len; | ||||
|     while (len-- != 0) | ||||
|     while (len != 0) | ||||
|     { | ||||
|       dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; | ||||
|       len--; | ||||
|       dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)]; | ||||
|       dicPos++; | ||||
|     } | ||||
|     p->dicPos = dicPos; | ||||
| @@ -470,17 +551,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte | ||||
|       if (limit - p->dicPos > rem) | ||||
|         limit2 = p->dicPos + rem; | ||||
|     } | ||||
|      | ||||
|     RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); | ||||
|     if (p->processedPos >= p->prop.dicSize) | ||||
|      | ||||
|     if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize) | ||||
|       p->checkDicSize = p->prop.dicSize; | ||||
|      | ||||
|     LzmaDec_WriteRem(p, limit); | ||||
|   } | ||||
|   while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); | ||||
|  | ||||
|   if (p->remainLen > kMatchSpecLenStart) | ||||
|   { | ||||
|     p->remainLen = kMatchSpecLenStart; | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -497,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS | ||||
|   UInt32 range = p->range; | ||||
|   UInt32 code = p->code; | ||||
|   const Byte *bufLimit = buf + inSize; | ||||
|   CLzmaProb *probs = p->probs; | ||||
|   const CLzmaProb *probs = p->probs; | ||||
|   unsigned state = p->state; | ||||
|   ELzmaDummy res; | ||||
|  | ||||
|   { | ||||
|     CLzmaProb *prob; | ||||
|     const CLzmaProb *prob; | ||||
|     UInt32 bound; | ||||
|     unsigned ttt; | ||||
|     unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); | ||||
| @@ -516,9 +599,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS | ||||
|  | ||||
|       prob = probs + Literal; | ||||
|       if (p->checkDicSize != 0 || p->processedPos != 0) | ||||
|         prob += (LZMA_LIT_SIZE * | ||||
|           ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + | ||||
|           (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); | ||||
|         prob += ((UInt32)LZMA_LIT_SIZE * | ||||
|             ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + | ||||
|             (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); | ||||
|  | ||||
|       if (state < kNumLitStates) | ||||
|       { | ||||
| @@ -528,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS | ||||
|       else | ||||
|       { | ||||
|         unsigned matchByte = p->dic[p->dicPos - p->reps[0] + | ||||
|             ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; | ||||
|             (p->dicPos < p->reps[0] ? p->dicBufSize : 0)]; | ||||
|         unsigned offs = 0x100; | ||||
|         unsigned symbol = 1; | ||||
|         do | ||||
|         { | ||||
|           unsigned bit; | ||||
|           CLzmaProb *probLit; | ||||
|           const CLzmaProb *probLit; | ||||
|           matchByte <<= 1; | ||||
|           bit = (matchByte & offs); | ||||
|           probLit = prob + offs + bit + symbol; | ||||
| @@ -604,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS | ||||
|       } | ||||
|       { | ||||
|         unsigned limit, offset; | ||||
|         CLzmaProb *probLen = prob + LenChoice; | ||||
|         const CLzmaProb *probLen = prob + LenChoice; | ||||
|         IF_BIT_0_CHECK(probLen) | ||||
|         { | ||||
|           UPDATE_0_CHECK; | ||||
| @@ -644,7 +727,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS | ||||
|         TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); | ||||
|         if (posSlot >= kStartPosModelIndex) | ||||
|         { | ||||
|           int numDirectBits = ((posSlot >> 1) - 1); | ||||
|           unsigned numDirectBits = ((posSlot >> 1) - 1); | ||||
|  | ||||
|           /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ | ||||
|  | ||||
| @@ -683,13 +766,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS | ||||
| } | ||||
|  | ||||
|  | ||||
| static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) | ||||
| { | ||||
|   p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); | ||||
|   p->range = 0xFFFFFFFF; | ||||
|   p->needFlush = 0; | ||||
| } | ||||
|  | ||||
| void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) | ||||
| { | ||||
|   p->needFlush = 1; | ||||
| @@ -714,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p) | ||||
|  | ||||
| static void LzmaDec_InitStateReal(CLzmaDec *p) | ||||
| { | ||||
|   UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); | ||||
|   UInt32 i; | ||||
|   SizeT numProbs = LzmaProps_GetNumProbs(&p->prop); | ||||
|   SizeT i; | ||||
|   CLzmaProb *probs = p->probs; | ||||
|   for (i = 0; i < numProbs; i++) | ||||
|     probs[i] = kBitModelTotal >> 1; | ||||
| @@ -737,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr | ||||
|   { | ||||
|       int checkEndMarkNow; | ||||
|  | ||||
|       if (p->needFlush != 0) | ||||
|       if (p->needFlush) | ||||
|       { | ||||
|         for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) | ||||
|           p->tempBuf[p->tempBufSize++] = *src++; | ||||
| @@ -748,8 +824,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr | ||||
|         } | ||||
|         if (p->tempBuf[0] != 0) | ||||
|           return SZ_ERROR_DATA; | ||||
|  | ||||
|         LzmaDec_InitRc(p, p->tempBuf); | ||||
|         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; | ||||
|       } | ||||
|  | ||||
| @@ -833,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr | ||||
|         p->buf = p->tempBuf; | ||||
|         if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) | ||||
|           return SZ_ERROR_DATA; | ||||
|         lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); | ||||
|          | ||||
|         { | ||||
|           unsigned kkk = (unsigned)(p->buf - p->tempBuf); | ||||
|           if (rem < kkk) | ||||
|             return SZ_ERROR_FAIL; /* some internal error */ | ||||
|           rem -= kkk; | ||||
|           if (lookAhead < rem) | ||||
|             return SZ_ERROR_FAIL; /* some internal error */ | ||||
|           lookAhead -= rem; | ||||
|         } | ||||
|         (*srcLen) += lookAhead; | ||||
|         src += lookAhead; | ||||
|         inSize -= lookAhead; | ||||
| @@ -888,13 +978,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr | ||||
| void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) | ||||
| { | ||||
|   alloc->Free(alloc, p->probs); | ||||
|   p->probs = 0; | ||||
|   p->probs = NULL; | ||||
| } | ||||
|  | ||||
| static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) | ||||
| { | ||||
|   alloc->Free(alloc, p->dic); | ||||
|   p->dic = 0; | ||||
|   p->dic = NULL; | ||||
| } | ||||
|  | ||||
| void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) | ||||
| @@ -932,12 +1022,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) | ||||
| static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) | ||||
| { | ||||
|   UInt32 numProbs = LzmaProps_GetNumProbs(propNew); | ||||
|   if (p->probs == 0 || numProbs != p->numProbs) | ||||
|   if (!p->probs || numProbs != p->numProbs) | ||||
|   { | ||||
|     LzmaDec_FreeProbs(p, alloc); | ||||
|     p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); | ||||
|     p->numProbs = numProbs; | ||||
|     if (p->probs == 0) | ||||
|     if (!p->probs) | ||||
|       return SZ_ERROR_MEM; | ||||
|   } | ||||
|   return SZ_OK; | ||||
| @@ -958,12 +1048,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll | ||||
|   SizeT dicBufSize; | ||||
|   RINOK(LzmaProps_Decode(&propNew, props, propsSize)); | ||||
|   RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); | ||||
|   dicBufSize = propNew.dicSize; | ||||
|   if (p->dic == 0 || dicBufSize != p->dicBufSize) | ||||
|  | ||||
|   { | ||||
|     UInt32 dictSize = propNew.dicSize; | ||||
|     SizeT mask = ((UInt32)1 << 12) - 1; | ||||
|          if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; | ||||
|     else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; | ||||
|     dicBufSize = ((SizeT)dictSize + mask) & ~mask; | ||||
|     if (dicBufSize < dictSize) | ||||
|       dicBufSize = dictSize; | ||||
|   } | ||||
|  | ||||
|   if (!p->dic || dicBufSize != p->dicBufSize) | ||||
|   { | ||||
|     LzmaDec_FreeDict(p, alloc); | ||||
|     p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); | ||||
|     if (p->dic == 0) | ||||
|     if (!p->dic) | ||||
|     { | ||||
|       LzmaDec_FreeProbs(p, alloc); | ||||
|       return SZ_ERROR_MEM; | ||||
| @@ -980,28 +1080,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, | ||||
| { | ||||
|   CLzmaDec p; | ||||
|   SRes res; | ||||
|   SizeT inSize = *srcLen; | ||||
|   SizeT outSize = *destLen; | ||||
|   *srcLen = *destLen = 0; | ||||
|   SizeT outSize = *destLen, inSize = *srcLen; | ||||
|   *destLen = *srcLen = 0; | ||||
|   *status = LZMA_STATUS_NOT_SPECIFIED; | ||||
|   if (inSize < RC_INIT_SIZE) | ||||
|     return SZ_ERROR_INPUT_EOF; | ||||
|  | ||||
|   LzmaDec_Construct(&p); | ||||
|   res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); | ||||
|   if (res != 0) | ||||
|     return res; | ||||
|   RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); | ||||
|   p.dic = dest; | ||||
|   p.dicBufSize = outSize; | ||||
|  | ||||
|   LzmaDec_Init(&p); | ||||
|    | ||||
|   *srcLen = inSize; | ||||
|   res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); | ||||
|  | ||||
|   *destLen = p.dicPos; | ||||
|   if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) | ||||
|     res = SZ_ERROR_INPUT_EOF; | ||||
|  | ||||
|   (*destLen) = p.dicPos; | ||||
|   LzmaDec_FreeProbs(&p, alloc); | ||||
|   return res; | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,12 @@ | ||||
| /* LzmaDec.h -- LZMA Decoder | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2013-01-18 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __LZMADEC_H | ||||
| #define __LZMADEC_H | ||||
| #ifndef __LZMA_DEC_H | ||||
| #define __LZMA_DEC_H | ||||
|  | ||||
| #include "Types.h" | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| /* #define _LZMA_PROB32 */ | ||||
| /* _LZMA_PROB32 can increase the speed on some CPUs, | ||||
| @@ -220,4 +222,6 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, | ||||
|     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, | ||||
|     ELzmaStatus *status, ISzAlloc *alloc); | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,10 +1,12 @@ | ||||
| /*  LzmaEnc.h -- LZMA Encoder | ||||
| 2008-10-04 : Igor Pavlov : Public domain */ | ||||
| 2013-01-18 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __LZMAENC_H | ||||
| #define __LZMAENC_H | ||||
| #ifndef __LZMA_ENC_H | ||||
| #define __LZMA_ENC_H | ||||
|  | ||||
| #include "Types.h" | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| #define LZMA_PROPS_SIZE 5 | ||||
|  | ||||
| @@ -14,6 +16,8 @@ typedef struct _CLzmaEncProps | ||||
|   UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version | ||||
|                       (1 << 12) <= dictSize <= (1 << 30) for 64-bit version | ||||
|                        default = (1 << 24) */ | ||||
|   UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF. | ||||
|                         Encoder uses this value to reduce dictionary size */ | ||||
|   int lc;          /* 0 <= lc <= 8, default = 3 */ | ||||
|   int lp;          /* 0 <= lp <= 4, default = 0 */ | ||||
|   int pb;          /* 0 <= pb <= 4, default = 2 */ | ||||
| @@ -69,4 +73,6 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, | ||||
|     const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, | ||||
|     ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); | ||||
|  | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										10
									
								
								BaseTools/Source/C/LzmaCompress/Sdk/C/Precomp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								BaseTools/Source/C/LzmaCompress/Sdk/C/Precomp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| /* Precomp.h -- StdAfx | ||||
| 2013-11-12 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __7Z_PRECOMP_H | ||||
| #define __7Z_PRECOMP_H | ||||
|  | ||||
| #include "Compiler.h" | ||||
| /* #include "7zTypes.h" */ | ||||
|  | ||||
| #endif | ||||
| @@ -1,10 +1,13 @@ | ||||
| /* Threads.c -- multithreading library | ||||
| 2008-08-05 | ||||
| Igor Pavlov | ||||
| Public domain */ | ||||
| 2014-09-21 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #include "Precomp.h" | ||||
|  | ||||
| #ifndef UNDER_CE | ||||
| #include <process.h> | ||||
| #endif | ||||
|  | ||||
| #include "Threads.h" | ||||
| #include <process.h> | ||||
|  | ||||
| static WRes GetError() | ||||
| { | ||||
| @@ -15,95 +18,76 @@ static WRes GetError() | ||||
| WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); } | ||||
| WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); } | ||||
|  | ||||
| static WRes MyCloseHandle(HANDLE *h) | ||||
| WRes HandlePtr_Close(HANDLE *p) | ||||
| { | ||||
|   if (*h != NULL) | ||||
|     if (!CloseHandle(*h)) | ||||
|   if (*p != NULL) | ||||
|     if (!CloseHandle(*p)) | ||||
|       return GetError(); | ||||
|   *h = NULL; | ||||
|   *p = NULL; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter) | ||||
| WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); } | ||||
|  | ||||
| WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) | ||||
| { | ||||
|   unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ | ||||
|   thread->handle = | ||||
|     /* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */ | ||||
|     (HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId); | ||||
|     /* maybe we must use errno here, but probably GetLastError() is also OK. */ | ||||
|   return HandleToWRes(thread->handle); | ||||
|   /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */ | ||||
|    | ||||
|   #ifdef UNDER_CE | ||||
|    | ||||
|   DWORD threadId; | ||||
|   *p = CreateThread(0, 0, func, param, 0, &threadId); | ||||
|  | ||||
|   #else | ||||
|  | ||||
|   unsigned threadId; | ||||
|   *p = (HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId); | ||||
|     | ||||
|   #endif | ||||
|  | ||||
|   /* maybe we must use errno here, but probably GetLastError() is also OK. */ | ||||
|   return HandleToWRes(*p); | ||||
| } | ||||
|  | ||||
| WRes WaitObject(HANDLE h) | ||||
| WRes Event_Create(CEvent *p, BOOL manualReset, int signaled) | ||||
| { | ||||
|   return (WRes)WaitForSingleObject(h, INFINITE); | ||||
|   *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL); | ||||
|   return HandleToWRes(*p); | ||||
| } | ||||
|  | ||||
| WRes Thread_Wait(CThread *thread) | ||||
| WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); } | ||||
| WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); } | ||||
|  | ||||
| WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); } | ||||
| WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); } | ||||
| WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); } | ||||
| WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); } | ||||
|  | ||||
|  | ||||
| WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) | ||||
| { | ||||
|   if (thread->handle == NULL) | ||||
|     return 1; | ||||
|   return WaitObject(thread->handle); | ||||
|   *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL); | ||||
|   return HandleToWRes(*p); | ||||
| } | ||||
|  | ||||
| WRes Thread_Close(CThread *thread) | ||||
| { | ||||
|   return MyCloseHandle(&thread->handle); | ||||
| } | ||||
|  | ||||
| WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled) | ||||
| { | ||||
|   p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL); | ||||
|   return HandleToWRes(p->handle); | ||||
| } | ||||
|  | ||||
| WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled) | ||||
|   { return Event_Create(p, TRUE, initialSignaled); } | ||||
| WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) | ||||
|   { return ManualResetEvent_Create(p, 0); } | ||||
|  | ||||
| WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled) | ||||
|   { return Event_Create(p, FALSE, initialSignaled); } | ||||
| WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) | ||||
|   { return AutoResetEvent_Create(p, 0); } | ||||
|  | ||||
| WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); } | ||||
| WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); } | ||||
| WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); } | ||||
| WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); } | ||||
|  | ||||
|  | ||||
| WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount) | ||||
| { | ||||
|   p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL); | ||||
|   return HandleToWRes(p->handle); | ||||
| } | ||||
|  | ||||
| WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) | ||||
| { | ||||
|   return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount)); | ||||
| } | ||||
| WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) | ||||
| { | ||||
|   return Semaphore_Release(p, (LONG)releaseCount, NULL); | ||||
| } | ||||
| WRes Semaphore_Release1(CSemaphore *p) | ||||
| { | ||||
|   return Semaphore_ReleaseN(p, 1); | ||||
| } | ||||
|  | ||||
| WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); } | ||||
| WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); } | ||||
| static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount) | ||||
|   { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); } | ||||
| WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num) | ||||
|   { return Semaphore_Release(p, (LONG)num, NULL); } | ||||
| WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); } | ||||
|  | ||||
| WRes CriticalSection_Init(CCriticalSection *p) | ||||
| { | ||||
|   /* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */ | ||||
|   #ifdef _MSC_VER | ||||
|   __try | ||||
|   #endif | ||||
|   { | ||||
|     InitializeCriticalSection(p); | ||||
|     /* InitializeCriticalSectionAndSpinCount(p, 0); */ | ||||
|   } | ||||
|   #ifdef _MSC_VER | ||||
|   __except (EXCEPTION_EXECUTE_HANDLER) { return 1; } | ||||
|   #endif | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,68 +1,67 @@ | ||||
| /* Threads.h -- multithreading library | ||||
| 2008-11-22 : Igor Pavlov : Public domain */ | ||||
| 2013-11-12 : Igor Pavlov : Public domain */ | ||||
|  | ||||
| #ifndef __7Z_THRESDS_H | ||||
| #define __7Z_THRESDS_H | ||||
| #ifndef __7Z_THREADS_H | ||||
| #define __7Z_THREADS_H | ||||
|  | ||||
| #include "Types.h" | ||||
| #ifdef _WIN32 | ||||
| #include <windows.h> | ||||
| #endif | ||||
|  | ||||
| typedef struct _CThread | ||||
| { | ||||
|   HANDLE handle; | ||||
| } CThread; | ||||
| #include "7zTypes.h" | ||||
|  | ||||
| EXTERN_C_BEGIN | ||||
|  | ||||
| WRes HandlePtr_Close(HANDLE *h); | ||||
| WRes Handle_WaitObject(HANDLE h); | ||||
|  | ||||
| typedef HANDLE CThread; | ||||
| #define Thread_Construct(p) *(p) = NULL | ||||
| #define Thread_WasCreated(p) (*(p) != NULL) | ||||
| #define Thread_Close(p) HandlePtr_Close(p) | ||||
| #define Thread_Wait(p) Handle_WaitObject(*(p)) | ||||
|  | ||||
| typedef | ||||
| #ifdef UNDER_CE | ||||
|   DWORD | ||||
| #else | ||||
|   unsigned | ||||
| #endif | ||||
|   THREAD_FUNC_RET_TYPE; | ||||
|  | ||||
| #define Thread_Construct(thread) (thread)->handle = NULL | ||||
| #define Thread_WasCreated(thread) ((thread)->handle != NULL) | ||||
|   | ||||
| typedef unsigned THREAD_FUNC_RET_TYPE; | ||||
| #define THREAD_FUNC_CALL_TYPE MY_STD_CALL | ||||
| #define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE | ||||
| typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *); | ||||
| WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param); | ||||
|  | ||||
| WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter); | ||||
| WRes Thread_Wait(CThread *thread); | ||||
| WRes Thread_Close(CThread *thread); | ||||
|  | ||||
| typedef struct _CEvent | ||||
| { | ||||
|   HANDLE handle; | ||||
| } CEvent; | ||||
|  | ||||
| typedef HANDLE CEvent; | ||||
| typedef CEvent CAutoResetEvent; | ||||
| typedef CEvent CManualResetEvent; | ||||
| #define Event_Construct(p) *(p) = NULL | ||||
| #define Event_IsCreated(p) (*(p) != NULL) | ||||
| #define Event_Close(p) HandlePtr_Close(p) | ||||
| #define Event_Wait(p) Handle_WaitObject(*(p)) | ||||
| WRes Event_Set(CEvent *p); | ||||
| WRes Event_Reset(CEvent *p); | ||||
| WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); | ||||
| WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); | ||||
| WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); | ||||
| WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); | ||||
|  | ||||
| #define Event_Construct(event) (event)->handle = NULL | ||||
| #define Event_IsCreated(event) ((event)->handle != NULL) | ||||
|  | ||||
| WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled); | ||||
| WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event); | ||||
| WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled); | ||||
| WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event); | ||||
| WRes Event_Set(CEvent *event); | ||||
| WRes Event_Reset(CEvent *event); | ||||
| WRes Event_Wait(CEvent *event); | ||||
| WRes Event_Close(CEvent *event); | ||||
|  | ||||
|  | ||||
| typedef struct _CSemaphore | ||||
| { | ||||
|   HANDLE handle; | ||||
| } CSemaphore; | ||||
|  | ||||
| #define Semaphore_Construct(p) (p)->handle = NULL | ||||
|  | ||||
| WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount); | ||||
| typedef HANDLE CSemaphore; | ||||
| #define Semaphore_Construct(p) (*p) = NULL | ||||
| #define Semaphore_Close(p) HandlePtr_Close(p) | ||||
| #define Semaphore_Wait(p) Handle_WaitObject(*(p)) | ||||
| WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount); | ||||
| WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num); | ||||
| WRes Semaphore_Release1(CSemaphore *p); | ||||
| WRes Semaphore_Wait(CSemaphore *p); | ||||
| WRes Semaphore_Close(CSemaphore *p); | ||||
|  | ||||
|  | ||||
| typedef CRITICAL_SECTION CCriticalSection; | ||||
|  | ||||
| WRes CriticalSection_Init(CCriticalSection *p); | ||||
| #define CriticalSection_Delete(p) DeleteCriticalSection(p) | ||||
| #define CriticalSection_Enter(p) EnterCriticalSection(p) | ||||
| #define CriticalSection_Leave(p) LeaveCriticalSection(p) | ||||
|  | ||||
| #endif | ||||
| EXTERN_C_END | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,6 +1,133 @@ | ||||
| HISTORY of the LZMA SDK | ||||
| ----------------------- | ||||
| 
 | ||||
| 16.04          2016-10-04 | ||||
| ------------------------- | ||||
| - The bug was fixed in DllSecur.c. | ||||
| 
 | ||||
| 
 | ||||
| 16.03          2016-09-28 | ||||
| ------------------------- | ||||
| - SFX modules now use some protection against DLL preloading attack. | ||||
| - Some bugs in 7z code were fixed. | ||||
| 
 | ||||
| 
 | ||||
| 16.02          2016-05-21 | ||||
| ------------------------- | ||||
| - The BUG in 16.00 - 16.01 was fixed: | ||||
|   Split Handler (SplitHandler.cpp) returned incorrect  | ||||
|   total size value (kpidSize) for split archives. | ||||
| 
 | ||||
| 
 | ||||
| 16.01          2016-05-19 | ||||
| -------------------------	 | ||||
| - Some internal changes to reduce the number of compiler warnings. | ||||
| 
 | ||||
| 
 | ||||
| 16.00          2016-05-10 | ||||
| -------------------------	 | ||||
| - Some bugs were fixed. | ||||
| 
 | ||||
| 
 | ||||
| 15.12          2015-11-19 | ||||
| -------------------------	 | ||||
| - The BUG in C version of 7z decoder was fixed: | ||||
|   7zDec.c : SzDecodeLzma2() | ||||
|   7z decoder could mistakenly report about decoding error for some 7z archives | ||||
|   that use LZMA2 compression method. | ||||
|   The probability to get that mistaken decoding error report was about  | ||||
|   one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size).  | ||||
| - The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: | ||||
|   7zArcIn.c : SzReadHeader2() | ||||
|   7z decoder worked incorrectly for 7z archives that contain  | ||||
|   empty solid blocks, that can be placed to 7z archive, if some file is  | ||||
|   unavailable for reading during archive creation. | ||||
| 
 | ||||
| 
 | ||||
| 15.09 beta     2015-10-16 | ||||
| -------------------------	 | ||||
| - The BUG in LZMA / LZMA2 encoding code was fixed. | ||||
|   The BUG in LzFind.c::MatchFinder_ReadBlock() function. | ||||
|   If input data size is larger than (4 GiB - dictionary_size), | ||||
|   the following code worked incorrectly: | ||||
|   -  LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions  | ||||
|      for compressing from memory to memory.  | ||||
|      That BUG is not related to LZMA encoder version that works via streams. | ||||
|   -  LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if  | ||||
|      default value of chunk size (CLzma2EncProps::blockSize) is changed  | ||||
|      to value larger than (4 GiB - dictionary_size). | ||||
| 
 | ||||
| 
 | ||||
| 9.38 beta      2015-01-03 | ||||
| -------------------------	 | ||||
| - The BUG in 9.31-9.37 was fixed: | ||||
|   IArchiveGetRawProps interface was disabled for 7z archives. | ||||
| - The BUG in 9.26-9.36 was fixed: | ||||
|   Some code in CPP\7zip\Archive\7z\ worked correctly only under Windows. | ||||
| 
 | ||||
| 
 | ||||
| 9.36 beta      2014-12-26 | ||||
| -------------------------	 | ||||
| - The BUG in command line version was fixed: | ||||
|   7-Zip created temporary archive in current folder during update archive | ||||
|   operation, if -w{Path} switch was not specified.  | ||||
|   The fixed 7-Zip creates temporary archive in folder that contains updated archive. | ||||
| - The BUG in 9.33-9.35 was fixed: | ||||
|   7-Zip silently ignored file reading errors during 7z or gz archive creation, | ||||
|   and the created archive contained only part of file that was read before error. | ||||
|   The fixed 7-Zip stops archive creation and it reports about error. | ||||
| 
 | ||||
| 
 | ||||
| 9.35 beta      2014-12-07 | ||||
| -------------------------	 | ||||
| - 7zr.exe now support AES encryption. | ||||
| - SFX mudules were added to LZMA SDK | ||||
| - Some bugs were fixed. | ||||
| 
 | ||||
| 
 | ||||
| 9.21 beta      2011-04-11 | ||||
| -------------------------	 | ||||
| - New class FString for file names at file systems. | ||||
| - Speed optimization in CRC code for big-endian CPUs. | ||||
| - The BUG in Lzma2Dec.c was fixed: | ||||
|     Lzma2Decode function didn't work. | ||||
| 
 | ||||
| 
 | ||||
| 9.18 beta      2010-11-02 | ||||
| -------------------------	 | ||||
| - New small SFX module for installers (SfxSetup). | ||||
| 
 | ||||
| 
 | ||||
| 9.12 beta      2010-03-24 | ||||
| ------------------------- | ||||
| - The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work, | ||||
|   if more than 10 threads were used (or more than 20 threads in some modes). | ||||
| 
 | ||||
| 
 | ||||
| 9.11 beta      2010-03-15 | ||||
| ------------------------- | ||||
| - PPMd compression method support | ||||
|     | ||||
| 
 | ||||
| 9.09           2009-12-12 | ||||
| ------------------------- | ||||
| - The bug was fixed: | ||||
|    Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c | ||||
|    incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8. | ||||
| - Some bugs were fixed | ||||
| 
 | ||||
| 
 | ||||
| 9.06           2009-08-17 | ||||
| ------------------------- | ||||
| - Some changes in ANSI-C 7z Decoder interfaces. | ||||
| 
 | ||||
| 
 | ||||
| 9.04           2009-05-30 | ||||
| ------------------------- | ||||
| - LZMA2 compression method support | ||||
| - xz format support | ||||
| 
 | ||||
| 
 | ||||
| 4.65           2009-02-03 | ||||
| ------------------------- | ||||
| - Some minor fixes | ||||
| @@ -41,7 +168,7 @@ HISTORY of the LZMA SDK | ||||
| 
 | ||||
| 4.57           2007-12-12 | ||||
| ------------------------- | ||||
| - Speed optimizations in Ñ++ LZMA Decoder.  | ||||
| - Speed optimizations in C++ LZMA Decoder.  | ||||
| - Small changes for more compatibility with some C/C++ compilers. | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										357
									
								
								BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										357
									
								
								BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,357 @@ | ||||
| LZMA SDK 16.04 | ||||
| -------------- | ||||
|  | ||||
| LZMA SDK provides the documentation, samples, header files, | ||||
| libraries, and tools you need to develop applications that  | ||||
| use 7z / LZMA / LZMA2 / XZ compression. | ||||
|  | ||||
| LZMA is an improved version of famous LZ77 compression algorithm.  | ||||
| It was improved in way of maximum increasing of compression ratio, | ||||
| keeping high decompression speed and low memory requirements for  | ||||
| decompressing. | ||||
|  | ||||
| LZMA2 is a LZMA based compression method. LZMA2 provides better  | ||||
| multithreading support for compression than LZMA and some other improvements. | ||||
|  | ||||
| 7z is a file format for data compression and file archiving. | ||||
| 7z is a main file format for 7-Zip compression program (www.7-zip.org). | ||||
| 7z format supports different compression methods: LZMA, LZMA2 and others. | ||||
| 7z also supports AES-256 based encryption. | ||||
|  | ||||
| XZ is a file format for data compression that uses LZMA2 compression. | ||||
| XZ format provides additional features: SHA/CRC check, filters for  | ||||
| improved compression ratio, splitting to blocks and streams, | ||||
|  | ||||
|  | ||||
|  | ||||
| LICENSE | ||||
| ------- | ||||
|  | ||||
| LZMA SDK is written and placed in the public domain by Igor Pavlov. | ||||
|  | ||||
| Some code in LZMA SDK is based on public domain code from another developers: | ||||
|   1) PPMd var.H (2001): Dmitry Shkarin | ||||
|   2) SHA-256: Wei Dai (Crypto++ library) | ||||
|  | ||||
| Anyone is free to copy, modify, publish, use, compile, sell, or distribute the  | ||||
| original LZMA SDK code, either in source code form or as a compiled binary, for  | ||||
| any purpose, commercial or non-commercial, and by any means. | ||||
|  | ||||
| LZMA SDK code is compatible with open source licenses, for example, you can  | ||||
| include it to GNU GPL or GNU LGPL code. | ||||
|  | ||||
|  | ||||
| LZMA SDK Contents | ||||
| ----------------- | ||||
|  | ||||
|   Source code: | ||||
|  | ||||
|     - C / C++ / C# / Java   - LZMA compression and decompression | ||||
|     - C / C++               - LZMA2 compression and decompression | ||||
|     - C / C++               - XZ compression and decompression | ||||
|     - C                     - 7z decompression | ||||
|     -     C++               - 7z compression and decompression | ||||
|     - C                     - small SFXs for installers (7z decompression) | ||||
|     -     C++               - SFXs and SFXs for installers (7z decompression) | ||||
|  | ||||
|   Precomiled binaries: | ||||
|  | ||||
|     - console programs for lzma / 7z / xz compression and decompression | ||||
|     - SFX modules for installers. | ||||
|  | ||||
|  | ||||
| UNIX/Linux version  | ||||
| ------------------ | ||||
| To compile C++ version of file->file LZMA encoding, go to directory | ||||
| CPP/7zip/Bundles/LzmaCon | ||||
| and call make to recompile it: | ||||
|   make -f makefile.gcc clean all | ||||
|  | ||||
| In some UNIX/Linux versions you must compile LZMA with static libraries. | ||||
| To compile with static libraries, you can use  | ||||
| LIB = -lm -static | ||||
|  | ||||
| Also you can use p7zip (port of 7-Zip for POSIX systems like Unix or Linux): | ||||
|    | ||||
|   http://p7zip.sourceforge.net/ | ||||
|  | ||||
|  | ||||
| Files | ||||
| ----- | ||||
|  | ||||
| DOC/7zC.txt          - 7z ANSI-C Decoder description | ||||
| DOC/7zFormat.txt     - 7z Format description | ||||
| DOC/installer.txt    - information about 7-Zip for installers | ||||
| DOC/lzma.txt         - LZMA compression description | ||||
| DOC/lzma-sdk.txt     - LZMA SDK description (this file) | ||||
| DOC/lzma-history.txt - history of LZMA SDK | ||||
| DOC/lzma-specification.txt - Specification of LZMA | ||||
| DOC/Methods.txt      - Compression method IDs for .7z | ||||
|  | ||||
| bin/installer/   - example script to create installer that uses SFX module, | ||||
|  | ||||
| bin/7zdec.exe    - simplified 7z archive decoder | ||||
| bin/7zr.exe      - 7-Zip console program (reduced version) | ||||
| bin/x64/7zr.exe  - 7-Zip console program (reduced version) (x64 version) | ||||
| bin/lzma.exe     - file->file LZMA encoder/decoder for Windows | ||||
| bin/7zS2.sfx     - small SFX module for installers (GUI version) | ||||
| bin/7zS2con.sfx  - small SFX module for installers (Console version) | ||||
| bin/7zSD.sfx     - SFX module for installers. | ||||
|  | ||||
|  | ||||
| 7zDec.exe | ||||
| --------- | ||||
| 7zDec.exe is simplified 7z archive decoder. | ||||
| It supports only LZMA, LZMA2, and PPMd methods. | ||||
| 7zDec decodes whole solid block from 7z archive to RAM. | ||||
| The RAM consumption can be high. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| Source code structure | ||||
| --------------------- | ||||
|  | ||||
|  | ||||
| Asm/ - asm files (optimized code for CRC calculation and Intel-AES encryption) | ||||
|  | ||||
| C/  - C files (compression / decompression and other) | ||||
|   Util/ | ||||
|     7z       - 7z decoder program (decoding 7z files) | ||||
|     Lzma     - LZMA program (file->file LZMA encoder/decoder). | ||||
|     LzmaLib  - LZMA library (.DLL for Windows) | ||||
|     SfxSetup - small SFX module for installers  | ||||
|  | ||||
| CPP/ -- CPP files | ||||
|  | ||||
|   Common  - common files for C++ projects | ||||
|   Windows - common files for Windows related code | ||||
|  | ||||
|   7zip    - files related to 7-Zip | ||||
|  | ||||
|     Archive - files related to archiving | ||||
|  | ||||
|       Common   - common files for archive handling | ||||
|       7z       - 7z C++ Encoder/Decoder | ||||
|  | ||||
|     Bundles  - Modules that are bundles of other modules (files) | ||||
|    | ||||
|       Alone7z       - 7zr.exe: Standalone 7-Zip console program (reduced version) | ||||
|       Format7zExtractR  - 7zxr.dll: Reduced version of 7z DLL: extracting from 7z/LZMA/BCJ/BCJ2. | ||||
|       Format7zR         - 7zr.dll:  Reduced version of 7z DLL: extracting/compressing to 7z/LZMA/BCJ/BCJ2 | ||||
|       LzmaCon       - lzma.exe: LZMA compression/decompression | ||||
|       LzmaSpec      - example code for LZMA Specification | ||||
|       SFXCon        - 7zCon.sfx: Console 7z SFX module | ||||
|       SFXSetup      - 7zS.sfx: 7z SFX module for installers | ||||
|       SFXWin        - 7z.sfx: GUI 7z SFX module | ||||
|  | ||||
|     Common   - common files for 7-Zip | ||||
|  | ||||
|     Compress - files for compression/decompression | ||||
|  | ||||
|     Crypto   - files for encryption / decompression | ||||
|  | ||||
|     UI       - User Interface files | ||||
|           | ||||
|       Client7z - Test application for 7za.dll, 7zr.dll, 7zxr.dll | ||||
|       Common   - Common UI files | ||||
|       Console  - Code for console program (7z.exe) | ||||
|       Explorer    - Some code from 7-Zip Shell extension | ||||
|       FileManager - Some GUI code from 7-Zip File Manager | ||||
|       GUI         - Some GUI code from 7-Zip | ||||
|  | ||||
|  | ||||
| CS/ - C# files | ||||
|   7zip | ||||
|     Common   - some common files for 7-Zip | ||||
|     Compress - files related to compression/decompression | ||||
|       LZ     - files related to LZ (Lempel-Ziv) compression algorithm | ||||
|       LZMA         - LZMA compression/decompression | ||||
|       LzmaAlone    - file->file LZMA compression/decompression | ||||
|       RangeCoder   - Range Coder (special code of compression/decompression) | ||||
|  | ||||
| Java/  - Java files | ||||
|   SevenZip | ||||
|     Compression    - files related to compression/decompression | ||||
|       LZ           - files related to LZ (Lempel-Ziv) compression algorithm | ||||
|       LZMA         - LZMA compression/decompression | ||||
|       RangeCoder   - Range Coder (special code of compression/decompression) | ||||
|  | ||||
|  | ||||
| Note:  | ||||
|   Asm / C / C++ source code of LZMA SDK is part of 7-Zip's source code. | ||||
|   7-Zip's source code can be downloaded from 7-Zip's SourceForge page: | ||||
|  | ||||
|   http://sourceforge.net/projects/sevenzip/ | ||||
|  | ||||
|  | ||||
|  | ||||
| LZMA features | ||||
| ------------- | ||||
|   - Variable dictionary size (up to 1 GB) | ||||
|   - Estimated compressing speed: about 2 MB/s on 2 GHz CPU | ||||
|   - Estimated decompressing speed:  | ||||
|       - 20-30 MB/s on modern 2 GHz cpu | ||||
|       - 1-2 MB/s on 200 MHz simple RISC cpu: (ARM, MIPS, PowerPC) | ||||
|   - Small memory requirements for decompressing (16 KB + DictionarySize) | ||||
|   - Small code size for decompressing: 5-8 KB | ||||
|  | ||||
| LZMA decoder uses only integer operations and can be  | ||||
| implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions). | ||||
|  | ||||
| Some critical operations that affect the speed of LZMA decompression: | ||||
|   1) 32*16 bit integer multiply | ||||
|   2) Mispredicted branches (penalty mostly depends from pipeline length) | ||||
|   3) 32-bit shift and arithmetic operations | ||||
|  | ||||
| The speed of LZMA decompressing mostly depends from CPU speed. | ||||
| Memory speed has no big meaning. But if your CPU has small data cache,  | ||||
| overall weight of memory speed will slightly increase. | ||||
|  | ||||
|  | ||||
| How To Use | ||||
| ---------- | ||||
|  | ||||
| Using LZMA encoder/decoder executable | ||||
| -------------------------------------- | ||||
|  | ||||
| Usage:  LZMA <e|d> inputFile outputFile [<switches>...] | ||||
|  | ||||
|   e: encode file | ||||
|  | ||||
|   d: decode file | ||||
|  | ||||
|   b: Benchmark. There are two tests: compressing and decompressing  | ||||
|      with LZMA method. Benchmark shows rating in MIPS (million  | ||||
|      instructions per second). Rating value is calculated from  | ||||
|      measured speed and it is normalized with Intel's Core 2 results. | ||||
|      Also Benchmark checks possible hardware errors (RAM  | ||||
|      errors in most cases). Benchmark uses these settings: | ||||
|      (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.  | ||||
|      Also you can change the number of iterations. Example for 30 iterations: | ||||
|        LZMA b 30 | ||||
|      Default number of iterations is 10. | ||||
|  | ||||
| <Switches> | ||||
|    | ||||
|  | ||||
|   -a{N}:  set compression mode 0 = fast, 1 = normal | ||||
|           default: 1 (normal) | ||||
|  | ||||
|   d{N}:   Sets Dictionary size - [0, 30], default: 23 (8MB) | ||||
|           The maximum value for dictionary size is 1 GB = 2^30 bytes. | ||||
|           Dictionary size is calculated as DictionarySize = 2^N bytes.  | ||||
|           For decompressing file compressed by LZMA method with dictionary  | ||||
|           size D = 2^N you need about D bytes of memory (RAM). | ||||
|  | ||||
|   -fb{N}: set number of fast bytes - [5, 273], default: 128 | ||||
|           Usually big number gives a little bit better compression ratio  | ||||
|           and slower compression process. | ||||
|  | ||||
|   -lc{N}: set number of literal context bits - [0, 8], default: 3 | ||||
|           Sometimes lc=4 gives gain for big files. | ||||
|  | ||||
|   -lp{N}: set number of literal pos bits - [0, 4], default: 0 | ||||
|           lp switch is intended for periodical data when period is  | ||||
|           equal 2^N. For example, for 32-bit (4 bytes)  | ||||
|           periodical data you can use lp=2. Often it's better to set lc0,  | ||||
|           if you change lp switch. | ||||
|  | ||||
|   -pb{N}: set number of pos bits - [0, 4], default: 2 | ||||
|           pb switch is intended for periodical data  | ||||
|           when period is equal 2^N. | ||||
|  | ||||
|   -mf{MF_ID}: set Match Finder. Default: bt4.  | ||||
|               Algorithms from hc* group doesn't provide good compression  | ||||
|               ratio, but they often works pretty fast in combination with  | ||||
|               fast mode (-a0). | ||||
|  | ||||
|               Memory requirements depend from dictionary size  | ||||
|               (parameter "d" in table below).  | ||||
|  | ||||
|                MF_ID     Memory                   Description | ||||
|  | ||||
|                 bt2    d *  9.5 + 4MB  Binary Tree with 2 bytes hashing. | ||||
|                 bt3    d * 11.5 + 4MB  Binary Tree with 3 bytes hashing. | ||||
|                 bt4    d * 11.5 + 4MB  Binary Tree with 4 bytes hashing. | ||||
|                 hc4    d *  7.5 + 4MB  Hash Chain with 4 bytes hashing. | ||||
|  | ||||
|   -eos:   write End Of Stream marker. By default LZMA doesn't write  | ||||
|           eos marker, since LZMA decoder knows uncompressed size  | ||||
|           stored in .lzma file header. | ||||
|  | ||||
|   -si:    Read data from stdin (it will write End Of Stream marker). | ||||
|   -so:    Write data to stdout | ||||
|  | ||||
|  | ||||
| Examples: | ||||
|  | ||||
| 1) LZMA e file.bin file.lzma -d16 -lc0  | ||||
|  | ||||
| compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)   | ||||
| and 0 literal context bits. -lc0 allows to reduce memory requirements  | ||||
| for decompression. | ||||
|  | ||||
|  | ||||
| 2) LZMA e file.bin file.lzma -lc0 -lp2 | ||||
|  | ||||
| compresses file.bin to file.lzma with settings suitable  | ||||
| for 32-bit periodical data (for example, ARM or MIPS code). | ||||
|  | ||||
| 3) LZMA d file.lzma file.bin | ||||
|  | ||||
| decompresses file.lzma to file.bin. | ||||
|  | ||||
|  | ||||
| Compression ratio hints | ||||
| ----------------------- | ||||
|  | ||||
| Recommendations | ||||
| --------------- | ||||
|  | ||||
| To increase the compression ratio for LZMA compressing it's desirable  | ||||
| to have aligned data (if it's possible) and also it's desirable to locate | ||||
| data in such order, where code is grouped in one place and data is  | ||||
| grouped in other place (it's better than such mixing: code, data, code, | ||||
| data, ...). | ||||
|  | ||||
|  | ||||
| Filters | ||||
| ------- | ||||
| You can increase the compression ratio for some data types, using | ||||
| special filters before compressing. For example, it's possible to  | ||||
| increase the compression ratio on 5-10% for code for those CPU ISAs:  | ||||
| x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC. | ||||
|  | ||||
| You can find C source code of such filters in C/Bra*.* files | ||||
|  | ||||
| You can check the compression ratio gain of these filters with such  | ||||
| 7-Zip commands (example for ARM code): | ||||
| No filter: | ||||
|   7z a a1.7z a.bin -m0=lzma | ||||
|  | ||||
| With filter for little-endian ARM code: | ||||
|   7z a a2.7z a.bin -m0=arm -m1=lzma         | ||||
|  | ||||
| It works in such manner: | ||||
| Compressing    = Filter_encoding + LZMA_encoding | ||||
| Decompressing  = LZMA_decoding + Filter_decoding | ||||
|  | ||||
| Compressing and decompressing speed of such filters is very high, | ||||
| so it will not increase decompressing time too much. | ||||
| Moreover, it reduces decompression time for LZMA_decoding,  | ||||
| since compression ratio with filtering is higher. | ||||
|  | ||||
| These filters convert CALL (calling procedure) instructions  | ||||
| from relative offsets to absolute addresses, so such data becomes more  | ||||
| compressible. | ||||
|  | ||||
| For some ISAs (for example, for MIPS) it's impossible to get gain from such filter. | ||||
|  | ||||
|  | ||||
|  | ||||
| --- | ||||
|  | ||||
| http://www.7-zip.org | ||||
| http://www.7-zip.org/sdk.html | ||||
| http://www.7-zip.org/support.html | ||||
| @@ -1,594 +0,0 @@ | ||||
| LZMA SDK 4.65 | ||||
| ------------- | ||||
|  | ||||
| LZMA SDK provides the documentation, samples, header files, libraries,  | ||||
| and tools you need to develop applications that use LZMA compression. | ||||
|  | ||||
| LZMA is default and general compression method of 7z format | ||||
| in 7-Zip compression program (www.7-zip.org). LZMA provides high  | ||||
| compression ratio and very fast decompression. | ||||
|  | ||||
| LZMA is an improved version of famous LZ77 compression algorithm.  | ||||
| It was improved in way of maximum increasing of compression ratio, | ||||
| keeping high decompression speed and low memory requirements for  | ||||
| decompressing. | ||||
|  | ||||
|  | ||||
|  | ||||
| LICENSE | ||||
| ------- | ||||
|  | ||||
| LZMA SDK is written and placed in the public domain by Igor Pavlov. | ||||
|  | ||||
|  | ||||
| LZMA SDK Contents | ||||
| ----------------- | ||||
|  | ||||
| LZMA SDK includes: | ||||
|  | ||||
|   - ANSI-C/C++/C#/Java source code for LZMA compressing and decompressing | ||||
|   - Compiled file->file LZMA compressing/decompressing program for Windows system | ||||
|  | ||||
|  | ||||
| UNIX/Linux version  | ||||
| ------------------ | ||||
| To compile C++ version of file->file LZMA encoding, go to directory | ||||
| C++/7zip/Compress/LZMA_Alone  | ||||
| and call make to recompile it: | ||||
|   make -f makefile.gcc clean all | ||||
|  | ||||
| In some UNIX/Linux versions you must compile LZMA with static libraries. | ||||
| To compile with static libraries, you can use  | ||||
| LIB = -lm -static | ||||
|  | ||||
|  | ||||
| Files | ||||
| --------------------- | ||||
| lzma.txt     - LZMA SDK description (this file) | ||||
| 7zFormat.txt - 7z Format description | ||||
| 7zC.txt      - 7z ANSI-C Decoder description | ||||
| methods.txt  - Compression method IDs for .7z | ||||
| lzma.exe     - Compiled file->file LZMA encoder/decoder for Windows | ||||
| history.txt  - history of the LZMA SDK | ||||
|  | ||||
|  | ||||
| Source code structure | ||||
| --------------------- | ||||
|  | ||||
| C/  - C files | ||||
|         7zCrc*.*   - CRC code | ||||
|         Alloc.*    - Memory allocation functions | ||||
|         Bra*.*     - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code | ||||
|         LzFind.*   - Match finder for LZ (LZMA) encoders  | ||||
|         LzFindMt.* - Match finder for LZ (LZMA) encoders for multithreading encoding | ||||
|         LzHash.h   - Additional file for LZ match finder | ||||
|         LzmaDec.*  - LZMA decoding | ||||
|         LzmaEnc.*  - LZMA encoding | ||||
|         LzmaLib.*  - LZMA Library for DLL calling | ||||
|         Types.h    - Basic types for another .c files | ||||
| 	Threads.*  - The code for multithreading. | ||||
|  | ||||
|     LzmaLib  - LZMA Library (.DLL for Windows) | ||||
|      | ||||
|     LzmaUtil - LZMA Utility (file->file LZMA encoder/decoder). | ||||
|  | ||||
|     Archive - files related to archiving | ||||
|       7z     - 7z ANSI-C Decoder | ||||
|  | ||||
| CPP/ -- CPP files | ||||
|  | ||||
|   Common  - common files for C++ projects | ||||
|   Windows - common files for Windows related code | ||||
|  | ||||
|   7zip    - files related to 7-Zip Project | ||||
|  | ||||
|     Common   - common files for 7-Zip | ||||
|  | ||||
|     Compress - files related to compression/decompression | ||||
|  | ||||
|       Copy         - Copy coder | ||||
|       RangeCoder   - Range Coder (special code of compression/decompression) | ||||
|       LZMA         - LZMA compression/decompression on C++ | ||||
|       LZMA_Alone   - file->file LZMA compression/decompression | ||||
|       Branch       - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code | ||||
|  | ||||
|     Archive - files related to archiving | ||||
|  | ||||
|       Common   - common files for archive handling | ||||
|       7z       - 7z C++ Encoder/Decoder | ||||
|  | ||||
|     Bundles    - Modules that are bundles of other modules | ||||
|    | ||||
|       Alone7z           - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2 | ||||
|       Format7zR         - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2 | ||||
|       Format7zExtractR  - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2. | ||||
|  | ||||
|     UI        - User Interface files | ||||
|           | ||||
|       Client7z - Test application for 7za.dll,  7zr.dll, 7zxr.dll | ||||
|       Common   - Common UI files | ||||
|       Console  - Code for console archiver | ||||
|  | ||||
|  | ||||
|  | ||||
| CS/ - C# files | ||||
|   7zip | ||||
|     Common   - some common files for 7-Zip | ||||
|     Compress - files related to compression/decompression | ||||
|       LZ     - files related to LZ (Lempel-Ziv) compression algorithm | ||||
|       LZMA         - LZMA compression/decompression | ||||
|       LzmaAlone    - file->file LZMA compression/decompression | ||||
|       RangeCoder   - Range Coder (special code of compression/decompression) | ||||
|  | ||||
| Java/  - Java files | ||||
|   SevenZip | ||||
|     Compression    - files related to compression/decompression | ||||
|       LZ           - files related to LZ (Lempel-Ziv) compression algorithm | ||||
|       LZMA         - LZMA compression/decompression | ||||
|       RangeCoder   - Range Coder (special code of compression/decompression) | ||||
|  | ||||
|  | ||||
| C/C++ source code of LZMA SDK is part of 7-Zip project. | ||||
| 7-Zip source code can be downloaded from 7-Zip's SourceForge page: | ||||
|  | ||||
|   http://sourceforge.net/projects/sevenzip/ | ||||
|  | ||||
|  | ||||
|  | ||||
| LZMA features | ||||
| ------------- | ||||
|   - Variable dictionary size (up to 1 GB) | ||||
|   - Estimated compressing speed: about 2 MB/s on 2 GHz CPU | ||||
|   - Estimated decompressing speed:  | ||||
|       - 20-30 MB/s on 2 GHz Core 2 or AMD Athlon 64 | ||||
|       - 1-2 MB/s on 200 MHz ARM, MIPS, PowerPC or other simple RISC | ||||
|   - Small memory requirements for decompressing (16 KB + DictionarySize) | ||||
|   - Small code size for decompressing: 5-8 KB | ||||
|  | ||||
| LZMA decoder uses only integer operations and can be  | ||||
| implemented in any modern 32-bit CPU (or on 16-bit CPU with some conditions). | ||||
|  | ||||
| Some critical operations that affect the speed of LZMA decompression: | ||||
|   1) 32*16 bit integer multiply | ||||
|   2) Misspredicted branches (penalty mostly depends from pipeline length) | ||||
|   3) 32-bit shift and arithmetic operations | ||||
|  | ||||
| The speed of LZMA decompressing mostly depends from CPU speed. | ||||
| Memory speed has no big meaning. But if your CPU has small data cache,  | ||||
| overall weight of memory speed will slightly increase. | ||||
|  | ||||
|  | ||||
| How To Use | ||||
| ---------- | ||||
|  | ||||
| Using LZMA encoder/decoder executable | ||||
| -------------------------------------- | ||||
|  | ||||
| Usage:  LZMA <e|d> inputFile outputFile [<switches>...] | ||||
|  | ||||
|   e: encode file | ||||
|  | ||||
|   d: decode file | ||||
|  | ||||
|   b: Benchmark. There are two tests: compressing and decompressing  | ||||
|      with LZMA method. Benchmark shows rating in MIPS (million  | ||||
|      instructions per second). Rating value is calculated from  | ||||
|      measured speed and it is normalized with Intel's Core 2 results. | ||||
|      Also Benchmark checks possible hardware errors (RAM  | ||||
|      errors in most cases). Benchmark uses these settings: | ||||
|      (-a1, -d21, -fb32, -mfbt4). You can change only -d parameter.  | ||||
|      Also you can change the number of iterations. Example for 30 iterations: | ||||
|        LZMA b 30 | ||||
|      Default number of iterations is 10. | ||||
|  | ||||
| <Switches> | ||||
|    | ||||
|  | ||||
|   -a{N}:  set compression mode 0 = fast, 1 = normal | ||||
|           default: 1 (normal) | ||||
|  | ||||
|   d{N}:   Sets Dictionary size - [0, 30], default: 23 (8MB) | ||||
|           The maximum value for dictionary size is 1 GB = 2^30 bytes. | ||||
|           Dictionary size is calculated as DictionarySize = 2^N bytes.  | ||||
|           For decompressing file compressed by LZMA method with dictionary  | ||||
|           size D = 2^N you need about D bytes of memory (RAM). | ||||
|  | ||||
|   -fb{N}: set number of fast bytes - [5, 273], default: 128 | ||||
|           Usually big number gives a little bit better compression ratio  | ||||
|           and slower compression process. | ||||
|  | ||||
|   -lc{N}: set number of literal context bits - [0, 8], default: 3 | ||||
|           Sometimes lc=4 gives gain for big files. | ||||
|  | ||||
|   -lp{N}: set number of literal pos bits - [0, 4], default: 0 | ||||
|           lp switch is intended for periodical data when period is  | ||||
|           equal 2^N. For example, for 32-bit (4 bytes)  | ||||
|           periodical data you can use lp=2. Often it's better to set lc0,  | ||||
|           if you change lp switch. | ||||
|  | ||||
|   -pb{N}: set number of pos bits - [0, 4], default: 2 | ||||
|           pb switch is intended for periodical data  | ||||
|           when period is equal 2^N. | ||||
|  | ||||
|   -mf{MF_ID}: set Match Finder. Default: bt4.  | ||||
|               Algorithms from hc* group doesn't provide good compression  | ||||
|               ratio, but they often works pretty fast in combination with  | ||||
|               fast mode (-a0). | ||||
|  | ||||
|               Memory requirements depend from dictionary size  | ||||
|               (parameter "d" in table below).  | ||||
|  | ||||
|                MF_ID     Memory                   Description | ||||
|  | ||||
|                 bt2    d *  9.5 + 4MB  Binary Tree with 2 bytes hashing. | ||||
|                 bt3    d * 11.5 + 4MB  Binary Tree with 3 bytes hashing. | ||||
|                 bt4    d * 11.5 + 4MB  Binary Tree with 4 bytes hashing. | ||||
|                 hc4    d *  7.5 + 4MB  Hash Chain with 4 bytes hashing. | ||||
|  | ||||
|   -eos:   write End Of Stream marker. By default LZMA doesn't write  | ||||
|           eos marker, since LZMA decoder knows uncompressed size  | ||||
|           stored in .lzma file header. | ||||
|  | ||||
|   -si:    Read data from stdin (it will write End Of Stream marker). | ||||
|   -so:    Write data to stdout | ||||
|  | ||||
|  | ||||
| Examples: | ||||
|  | ||||
| 1) LZMA e file.bin file.lzma -d16 -lc0  | ||||
|  | ||||
| compresses file.bin to file.lzma with 64 KB dictionary (2^16=64K)   | ||||
| and 0 literal context bits. -lc0 allows to reduce memory requirements  | ||||
| for decompression. | ||||
|  | ||||
|  | ||||
| 2) LZMA e file.bin file.lzma -lc0 -lp2 | ||||
|  | ||||
| compresses file.bin to file.lzma with settings suitable  | ||||
| for 32-bit periodical data (for example, ARM or MIPS code). | ||||
|  | ||||
| 3) LZMA d file.lzma file.bin | ||||
|  | ||||
| decompresses file.lzma to file.bin. | ||||
|  | ||||
|  | ||||
| Compression ratio hints | ||||
| ----------------------- | ||||
|  | ||||
| Recommendations | ||||
| --------------- | ||||
|  | ||||
| To increase the compression ratio for LZMA compressing it's desirable  | ||||
| to have aligned data (if it's possible) and also it's desirable to locate | ||||
| data in such order, where code is grouped in one place and data is  | ||||
| grouped in other place (it's better than such mixing: code, data, code, | ||||
| data, ...). | ||||
|  | ||||
|  | ||||
| Filters | ||||
| ------- | ||||
| You can increase the compression ratio for some data types, using | ||||
| special filters before compressing. For example, it's possible to  | ||||
| increase the compression ratio on 5-10% for code for those CPU ISAs:  | ||||
| x86, IA-64, ARM, ARM-Thumb, PowerPC, SPARC. | ||||
|  | ||||
| You can find C source code of such filters in C/Bra*.* files | ||||
|  | ||||
| You can check the compression ratio gain of these filters with such  | ||||
| 7-Zip commands (example for ARM code): | ||||
| No filter: | ||||
|   7z a a1.7z a.bin -m0=lzma | ||||
|  | ||||
| With filter for little-endian ARM code: | ||||
|   7z a a2.7z a.bin -m0=arm -m1=lzma         | ||||
|  | ||||
| It works in such manner: | ||||
| Compressing    = Filter_encoding + LZMA_encoding | ||||
| Decompressing  = LZMA_decoding + Filter_decoding | ||||
|  | ||||
| Compressing and decompressing speed of such filters is very high, | ||||
| so it will not increase decompressing time too much. | ||||
| Moreover, it reduces decompression time for LZMA_decoding,  | ||||
| since compression ratio with filtering is higher. | ||||
|  | ||||
| These filters convert CALL (calling procedure) instructions  | ||||
| from relative offsets to absolute addresses, so such data becomes more  | ||||
| compressible. | ||||
|  | ||||
| For some ISAs (for example, for MIPS) it's impossible to get gain from such filter. | ||||
|  | ||||
|  | ||||
| LZMA compressed file format | ||||
| --------------------------- | ||||
| Offset Size Description | ||||
|   0     1   Special LZMA properties (lc,lp, pb in encoded form) | ||||
|   1     4   Dictionary size (little endian) | ||||
|   5     8   Uncompressed size (little endian). -1 means unknown size | ||||
|  13         Compressed data | ||||
|  | ||||
|  | ||||
| ANSI-C LZMA Decoder | ||||
| ~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Please note that interfaces for ANSI-C code were changed in LZMA SDK 4.58. | ||||
| If you want to use old interfaces you can download previous version of LZMA SDK | ||||
| from sourceforge.net site. | ||||
|  | ||||
| To use ANSI-C LZMA Decoder you need the following files: | ||||
| 1) LzmaDec.h + LzmaDec.c + Types.h | ||||
| LzmaUtil/LzmaUtil.c is example application that uses these files. | ||||
|  | ||||
|  | ||||
| Memory requirements for LZMA decoding | ||||
| ------------------------------------- | ||||
|  | ||||
| Stack usage of LZMA decoding function for local variables is not  | ||||
| larger than 200-400 bytes. | ||||
|  | ||||
| LZMA Decoder uses dictionary buffer and internal state structure. | ||||
| Internal state structure consumes | ||||
|   state_size = (4 + (1.5 << (lc + lp))) KB | ||||
| by default (lc=3, lp=0), state_size = 16 KB. | ||||
|  | ||||
|  | ||||
| How To decompress data | ||||
| ---------------------- | ||||
|  | ||||
| LZMA Decoder (ANSI-C version) now supports 2 interfaces: | ||||
| 1) Single-call Decompressing | ||||
| 2) Multi-call State Decompressing (zlib-like interface) | ||||
|  | ||||
| You must use external allocator: | ||||
| Example: | ||||
| void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } | ||||
| void SzFree(void *p, void *address) { p = p; free(address); } | ||||
| ISzAlloc alloc = { SzAlloc, SzFree }; | ||||
|  | ||||
| You can use p = p; operator to disable compiler warnings. | ||||
|  | ||||
|  | ||||
| Single-call Decompressing | ||||
| ------------------------- | ||||
| When to use: RAM->RAM decompressing | ||||
| Compile files: LzmaDec.h + LzmaDec.c + Types.h | ||||
| Compile defines: no defines | ||||
| Memory Requirements: | ||||
|   - Input buffer: compressed size | ||||
|   - Output buffer: uncompressed size | ||||
|   - LZMA Internal Structures: state_size (16 KB for default settings)  | ||||
|  | ||||
| Interface: | ||||
|   int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, | ||||
|       const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,  | ||||
|       ELzmaStatus *status, ISzAlloc *alloc); | ||||
|   In:  | ||||
|     dest     - output data | ||||
|     destLen  - output data size | ||||
|     src      - input data | ||||
|     srcLen   - input data size | ||||
|     propData - LZMA properties  (5 bytes) | ||||
|     propSize - size of propData buffer (5 bytes) | ||||
|     finishMode - It has meaning only if the decoding reaches output limit (*destLen). | ||||
| 	 LZMA_FINISH_ANY - Decode just destLen bytes. | ||||
| 	 LZMA_FINISH_END - Stream must be finished after (*destLen). | ||||
|                            You can use LZMA_FINISH_END, when you know that  | ||||
|                            current output buffer covers last bytes of stream.  | ||||
|     alloc    - Memory allocator. | ||||
|  | ||||
|   Out:  | ||||
|     destLen  - processed output size  | ||||
|     srcLen   - processed input size  | ||||
|  | ||||
|   Output: | ||||
|     SZ_OK | ||||
|       status: | ||||
|         LZMA_STATUS_FINISHED_WITH_MARK | ||||
|         LZMA_STATUS_NOT_FINISHED  | ||||
|         LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK | ||||
|     SZ_ERROR_DATA - Data error | ||||
|     SZ_ERROR_MEM  - Memory allocation error | ||||
|     SZ_ERROR_UNSUPPORTED - Unsupported properties | ||||
|     SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). | ||||
|  | ||||
|   If LZMA decoder sees end_marker before reaching output limit, it returns OK result, | ||||
|   and output value of destLen will be less than output buffer size limit. | ||||
|  | ||||
|   You can use multiple checks to test data integrity after full decompression: | ||||
|     1) Check Result and "status" variable. | ||||
|     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. | ||||
|     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.  | ||||
|        You must use correct finish mode in that case. */  | ||||
|  | ||||
|  | ||||
| Multi-call State Decompressing (zlib-like interface) | ||||
| ---------------------------------------------------- | ||||
|  | ||||
| When to use: file->file decompressing  | ||||
| Compile files: LzmaDec.h + LzmaDec.c + Types.h | ||||
|  | ||||
| Memory Requirements: | ||||
|  - Buffer for input stream: any size (for example, 16 KB) | ||||
|  - Buffer for output stream: any size (for example, 16 KB) | ||||
|  - LZMA Internal Structures: state_size (16 KB for default settings)  | ||||
|  - LZMA dictionary (dictionary size is encoded in LZMA properties header) | ||||
|  | ||||
| 1) read LZMA properties (5 bytes) and uncompressed size (8 bytes, little-endian) to header: | ||||
|    unsigned char header[LZMA_PROPS_SIZE + 8]; | ||||
|    ReadFile(inFile, header, sizeof(header) | ||||
|  | ||||
| 2) Allocate CLzmaDec structures (state + dictionary) using LZMA properties | ||||
|  | ||||
|   CLzmaDec state; | ||||
|   LzmaDec_Constr(&state); | ||||
|   res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); | ||||
|   if (res != SZ_OK) | ||||
|     return res; | ||||
|  | ||||
| 3) Init LzmaDec structure before any new LZMA stream. And call LzmaDec_DecodeToBuf in loop | ||||
|  | ||||
|   LzmaDec_Init(&state); | ||||
|   for (;;) | ||||
|   { | ||||
|     ...  | ||||
|     int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,  | ||||
|     	const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); | ||||
|     ... | ||||
|   } | ||||
|  | ||||
|  | ||||
| 4) Free all allocated structures | ||||
|   LzmaDec_Free(&state, &g_Alloc); | ||||
|  | ||||
| For full code example, look at C/LzmaUtil/LzmaUtil.c code. | ||||
|  | ||||
|  | ||||
| How To compress data | ||||
| -------------------- | ||||
|  | ||||
| Compile files: LzmaEnc.h + LzmaEnc.c + Types.h + | ||||
| LzFind.c + LzFind.h + LzFindMt.c + LzFindMt.h + LzHash.h | ||||
|  | ||||
| Memory Requirements: | ||||
|   - (dictSize * 11.5 + 6 MB) + state_size | ||||
|  | ||||
| Lzma Encoder can use two memory allocators: | ||||
| 1) alloc - for small arrays. | ||||
| 2) allocBig - for big arrays. | ||||
|  | ||||
| For example, you can use Large RAM Pages (2 MB) in allocBig allocator for  | ||||
| better compression speed. Note that Windows has bad implementation for  | ||||
| Large RAM Pages.  | ||||
| It's OK to use same allocator for alloc and allocBig. | ||||
|  | ||||
|  | ||||
| Single-call Compression with callbacks | ||||
| -------------------------------------- | ||||
|  | ||||
| Check C/LzmaUtil/LzmaUtil.c as example,  | ||||
|  | ||||
| When to use: file->file decompressing  | ||||
|  | ||||
| 1) you must implement callback structures for interfaces: | ||||
| ISeqInStream | ||||
| ISeqOutStream | ||||
| ICompressProgress | ||||
| ISzAlloc | ||||
|  | ||||
| static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } | ||||
| static void SzFree(void *p, void *address) {  p = p; MyFree(address); } | ||||
| static ISzAlloc g_Alloc = { SzAlloc, SzFree }; | ||||
|  | ||||
|   CFileSeqInStream inStream; | ||||
|   CFileSeqOutStream outStream; | ||||
|  | ||||
|   inStream.funcTable.Read = MyRead; | ||||
|   inStream.file = inFile; | ||||
|   outStream.funcTable.Write = MyWrite; | ||||
|   outStream.file = outFile; | ||||
|  | ||||
|  | ||||
| 2) Create CLzmaEncHandle object; | ||||
|  | ||||
|   CLzmaEncHandle enc; | ||||
|  | ||||
|   enc = LzmaEnc_Create(&g_Alloc); | ||||
|   if (enc == 0) | ||||
|     return SZ_ERROR_MEM; | ||||
|  | ||||
|  | ||||
| 3) initialize CLzmaEncProps properties; | ||||
|  | ||||
|   LzmaEncProps_Init(&props); | ||||
|  | ||||
|   Then you can change some properties in that structure. | ||||
|  | ||||
| 4) Send LZMA properties to LZMA Encoder | ||||
|  | ||||
|   res = LzmaEnc_SetProps(enc, &props); | ||||
|  | ||||
| 5) Write encoded properties to header | ||||
|  | ||||
|     Byte header[LZMA_PROPS_SIZE + 8]; | ||||
|     size_t headerSize = LZMA_PROPS_SIZE; | ||||
|     UInt64 fileSize; | ||||
|     int i; | ||||
|  | ||||
|     res = LzmaEnc_WriteProperties(enc, header, &headerSize); | ||||
|     fileSize = MyGetFileLength(inFile); | ||||
|     for (i = 0; i < 8; i++) | ||||
|       header[headerSize++] = (Byte)(fileSize >> (8 * i)); | ||||
|     MyWriteFileAndCheck(outFile, header, headerSize) | ||||
|  | ||||
| 6) Call encoding function: | ||||
|       res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable,  | ||||
|         NULL, &g_Alloc, &g_Alloc); | ||||
|  | ||||
| 7) Destroy LZMA Encoder Object | ||||
|   LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); | ||||
|  | ||||
|  | ||||
| If callback function return some error code, LzmaEnc_Encode also returns that code. | ||||
|  | ||||
|  | ||||
| Single-call RAM->RAM Compression | ||||
| -------------------------------- | ||||
|  | ||||
| Single-call RAM->RAM Compression is similar to Compression with callbacks, | ||||
| but you provide pointers to buffers instead of pointers to stream callbacks: | ||||
|  | ||||
| HRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, | ||||
|     CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,  | ||||
|     ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); | ||||
|  | ||||
| Return code: | ||||
|   SZ_OK               - OK | ||||
|   SZ_ERROR_MEM        - Memory allocation error  | ||||
|   SZ_ERROR_PARAM      - Incorrect paramater | ||||
|   SZ_ERROR_OUTPUT_EOF - output buffer overflow | ||||
|   SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version) | ||||
|  | ||||
|  | ||||
|  | ||||
| LZMA Defines | ||||
| ------------ | ||||
|  | ||||
| _LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code. | ||||
|  | ||||
| _LZMA_PROB32   - It can increase the speed on some 32-bit CPUs, but memory usage for  | ||||
|                  some structures will be doubled in that case. | ||||
|  | ||||
| _LZMA_UINT32_IS_ULONG  - Define it if int is 16-bit on your compiler and long is 32-bit. | ||||
|  | ||||
| _LZMA_NO_SYSTEM_SIZE_T  - Define it if you don't want to use size_t type. | ||||
|  | ||||
|  | ||||
| C++ LZMA Encoder/Decoder  | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| C++ LZMA code use COM-like interfaces. So if you want to use it,  | ||||
| you can study basics of COM/OLE. | ||||
| C++ LZMA code is just wrapper over ANSI-C code. | ||||
|  | ||||
|  | ||||
| C++ Notes | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| If you use some C++ code folders in 7-Zip (for example, C++ code for .7z handling), | ||||
| you must check that you correctly work with "new" operator. | ||||
| 7-Zip can be compiled with MSVC 6.0 that doesn't throw "exception" from "new" operator. | ||||
| So 7-Zip uses "CPP\Common\NewHandler.cpp" that redefines "new" operator: | ||||
| operator new(size_t size) | ||||
| { | ||||
|   void *p = ::malloc(size); | ||||
|   if (p == 0) | ||||
|     throw CNewException(); | ||||
|   return p; | ||||
| } | ||||
| If you use MSCV that throws exception for "new" operator, you can compile without  | ||||
| "NewHandler.cpp". So standard exception will be used. Actually some code of  | ||||
| 7-Zip catches any exception in internal code and converts it to HRESULT code. | ||||
| So you don't need to catch CNewException, if you call COM interfaces of 7-Zip. | ||||
|  | ||||
| --- | ||||
|  | ||||
| http://www.7-zip.org | ||||
| http://www.7-zip.org/sdk.html | ||||
| http://www.7-zip.org/support.html | ||||
		Reference in New Issue
	
	Block a user