mirror of https://github.com/acidanthera/audk.git
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:
parent
756a514aa4
commit
c4ab09ef2f
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# GNU/Linux makefile for 'LzmaCompress' module build.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
# which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -29,3 +29,4 @@ OBJECTS = \
|
||||||
|
|
||||||
include $(MAKEROOT)/Makefiles/app.makefile
|
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
|
LzmaCompress is based on the LZMA SDK 16.04. LZMA SDK 16.04
|
||||||
was placed in the public domain on 2009-02-03. It was
|
was placed in the public domain on 2016-10-04. It was
|
||||||
released on the http://www.7-zip.org/sdk.html website.
|
released on the http://www.7-zip.org/sdk.html website.
|
|
@ -1,11 +1,11 @@
|
||||||
/** @file
|
/** @file
|
||||||
LZMA Compress/Decompress tool (LzmaCompress)
|
LZMA Compress/Decompress tool (LzmaCompress)
|
||||||
|
|
||||||
Based on LZMA SDK 4.65:
|
Based on LZMA SDK 16.04:
|
||||||
LzmaUtil.c -- Test application for LZMA compression
|
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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
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 *kCantAllocateMessage = "Can not allocate memory";
|
||||||
const char *kDataErrorMessage = "Data error";
|
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 Bool mQuietMode = False;
|
||||||
static CONVERTER_TYPE mConType = NoConverter;
|
static CONVERTER_TYPE mConType = NoConverter;
|
||||||
|
|
||||||
|
@ -54,7 +50,7 @@ static CONVERTER_TYPE mConType = NoConverter;
|
||||||
#define UTILITY_MAJOR_VERSION 0
|
#define UTILITY_MAJOR_VERSION 0
|
||||||
#define UTILITY_MINOR_VERSION 2
|
#define UTILITY_MINOR_VERSION 2
|
||||||
#define INTEL_COPYRIGHT \
|
#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)
|
void PrintHelp(char *buffer)
|
||||||
{
|
{
|
||||||
strcat(buffer,
|
strcat(buffer,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# Windows makefile for 'LzmaCompress' module build.
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
# which accompanies this distribution. The full text of the license may be found at
|
# 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)\LzmaEnc.obj \
|
||||||
$(SDK_C)\7zFile.obj \
|
$(SDK_C)\7zFile.obj \
|
||||||
$(SDK_C)\7zStream.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
|
!INCLUDE ..\Makefiles\ms.app
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
/* 7zFile.c -- File IO
|
/* 7zFile.c -- File IO
|
||||||
2008-11-22 : Igor Pavlov : Public domain */
|
2009-11-24 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "7zFile.h"
|
#include "7zFile.h"
|
||||||
|
|
||||||
#ifndef USE_WINDOWS_FILE
|
#ifndef USE_WINDOWS_FILE
|
||||||
|
|
||||||
|
#ifndef UNDER_CE
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_FILE
|
#else
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ReadFile and WriteFile functions in Windows have BUG:
|
ReadFile and WriteFile functions in Windows have BUG:
|
||||||
|
@ -34,6 +36,7 @@ void File_Construct(CSzFile *p)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||||
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
||||||
{
|
{
|
||||||
#ifdef USE_WINDOWS_FILE
|
#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();
|
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||||
#else
|
#else
|
||||||
p->file = fopen(name, writeMode ? "wb+" : "rb");
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
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); }
|
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)
|
WRes File_Close(CSzFile *p)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* 7zFile.h -- File IO
|
/* 7zFile.h -- File IO
|
||||||
2008-11-22 : Igor Pavlov : Public domain */
|
2013-01-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_FILE_H
|
#ifndef __7Z_FILE_H
|
||||||
#define __7Z_FILE_H
|
#define __7Z_FILE_H
|
||||||
|
@ -14,8 +14,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Types.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/* ---------- File ---------- */
|
/* ---------- File ---------- */
|
||||||
|
|
||||||
|
@ -29,8 +30,14 @@ typedef struct
|
||||||
} CSzFile;
|
} CSzFile;
|
||||||
|
|
||||||
void File_Construct(CSzFile *p);
|
void File_Construct(CSzFile *p);
|
||||||
|
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
|
||||||
WRes InFile_Open(CSzFile *p, const char *name);
|
WRes InFile_Open(CSzFile *p, const char *name);
|
||||||
WRes OutFile_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);
|
WRes File_Close(CSzFile *p);
|
||||||
|
|
||||||
/* reads max(*size, remain file's size) bytes */
|
/* reads max(*size, remain file's size) bytes */
|
||||||
|
@ -71,4 +78,6 @@ typedef struct
|
||||||
|
|
||||||
void FileOutStream_CreateVTable(CFileOutStream *p);
|
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
/* 7zStream.c -- 7z Stream functions
|
/* 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 <string.h>
|
||||||
|
|
||||||
#include "Types.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
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)
|
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||||
{
|
{
|
||||||
void *lookBuf;
|
const void *lookBuf;
|
||||||
if (*size == 0)
|
if (*size == 0)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
RINOK(stream->Look(stream, &lookBuf, size));
|
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);
|
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;
|
SRes res = SZ_OK;
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
@ -84,7 +86,7 @@ static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
|
||||||
return res;
|
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;
|
SRes res = SZ_OK;
|
||||||
CLookToRead *p = (CLookToRead *)pp;
|
CLookToRead *p = (CLookToRead *)pp;
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
/* Types.h -- Basic types
|
/* 7zTypes.h -- Basic types
|
||||||
2008-11-23 : Igor Pavlov : Public domain */
|
2013-11-12 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_TYPES_H
|
#ifndef __7Z_TYPES_H
|
||||||
#define __7Z_TYPES_H
|
#define __7Z_TYPES_H
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* #include <windows.h> */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifndef EXTERN_C_BEGIN
|
||||||
#include <windows.h>
|
#ifdef __cplusplus
|
||||||
|
#define EXTERN_C_BEGIN extern "C" {
|
||||||
|
#define EXTERN_C_END }
|
||||||
|
#else
|
||||||
|
#define EXTERN_C_BEGIN
|
||||||
|
#define EXTERN_C_END
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define SZ_OK 0
|
#define SZ_OK 0
|
||||||
|
|
||||||
|
@ -31,7 +43,8 @@
|
||||||
typedef int SRes;
|
typedef int SRes;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef DWORD WRes;
|
/* typedef DWORD WRes; */
|
||||||
|
typedef unsigned WRes;
|
||||||
#else
|
#else
|
||||||
typedef int WRes;
|
typedef int WRes;
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,9 +78,11 @@ typedef unsigned long UInt64;
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||||
typedef __int64 Int64;
|
typedef __int64 Int64;
|
||||||
typedef unsigned __int64 UInt64;
|
typedef unsigned __int64 UInt64;
|
||||||
|
#define UINT64_CONST(n) n
|
||||||
#else
|
#else
|
||||||
typedef long long int Int64;
|
typedef long long int Int64;
|
||||||
typedef unsigned long long int UInt64;
|
typedef unsigned long long int UInt64;
|
||||||
|
#define UINT64_CONST(n) n ## ULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -83,6 +98,12 @@ typedef int Bool;
|
||||||
#define False 0
|
#define False 0
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define MY_STD_CALL __stdcall
|
||||||
|
#else
|
||||||
|
#define MY_STD_CALL
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
#if _MSC_VER >= 1300
|
#if _MSC_VER >= 1300
|
||||||
|
@ -92,13 +113,12 @@ typedef int Bool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MY_CDECL __cdecl
|
#define MY_CDECL __cdecl
|
||||||
#define MY_STD_CALL __stdcall
|
#define MY_FAST_CALL __fastcall
|
||||||
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#define MY_NO_INLINE
|
||||||
#define MY_CDECL
|
#define MY_CDECL
|
||||||
#define MY_STD_CALL
|
|
||||||
#define MY_FAST_CALL
|
#define MY_FAST_CALL
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,6 +126,16 @@ typedef int Bool;
|
||||||
|
|
||||||
/* The following interfaces use first parameter as pointer to structure */
|
/* 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
|
typedef struct
|
||||||
{
|
{
|
||||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||||
|
@ -140,7 +170,7 @@ typedef struct
|
||||||
|
|
||||||
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.
|
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||||
(output(*size) > input(*size)) is not allowed
|
(output(*size) > input(*size)) is not allowed
|
||||||
(output(*size) < input(*size)) is allowed */
|
(output(*size) < input(*size)) is allowed */
|
||||||
|
@ -205,4 +235,22 @@ typedef struct
|
||||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
#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
|
#endif
|
|
@ -1,7 +1,19 @@
|
||||||
#define MY_VER_MAJOR 4
|
#define MY_VER_MAJOR 16
|
||||||
#define MY_VER_MINOR 65
|
#define MY_VER_MINOR 04
|
||||||
#define MY_VER_BUILD 0
|
#define MY_VER_BUILD 0
|
||||||
#define MY_VERSION "4.65"
|
#define MY_VERSION_NUMBERS "16.04"
|
||||||
#define MY_DATE "2009-02-03"
|
#define MY_VERSION "16.04"
|
||||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
#define MY_DATE "2016-10-04"
|
||||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
#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
|
/* Alloc.c -- Memory allocation functions
|
||||||
2008-09-24
|
2015-02-21 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
#include "Precomp.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -125,3 +125,12 @@ void BigFree(void *address)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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
|
/* Alloc.h -- Memory allocation functions
|
||||||
2008-03-13
|
2015-02-21 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#ifndef __COMMON_ALLOC_H
|
#ifndef __COMMON_ALLOC_H
|
||||||
#define __COMMON_ALLOC_H
|
#define __COMMON_ALLOC_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
void *MyAlloc(size_t size);
|
void *MyAlloc(size_t size);
|
||||||
void MyFree(void *address);
|
void MyFree(void *address);
|
||||||
|
@ -29,4 +29,9 @@ void BigFree(void *address);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern ISzAlloc g_Alloc;
|
||||||
|
extern ISzAlloc g_BigAlloc;
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
/* Bra.h -- Branch converters for executables
|
/* Bra.h -- Branch converters for executables
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2013-01-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __BRA_H
|
#ifndef __BRA_H
|
||||||
#define __BRA_H
|
#define __BRA_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These functions convert relative addresses to absolute addresses
|
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 SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,85 +1,82 @@
|
||||||
/* Bra86.c -- Converter for x86 code (BCJ)
|
/* 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"
|
#include "Bra.h"
|
||||||
|
|
||||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
|
||||||
|
|
||||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
|
||||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
|
||||||
|
|
||||||
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
|
||||||
{
|
{
|
||||||
SizeT bufferPos = 0, prevPosT;
|
SizeT pos = 0;
|
||||||
UInt32 prevMask = *state & 0x7;
|
UInt32 mask = *state & 7;
|
||||||
if (size < 5)
|
if (size < 5)
|
||||||
return 0;
|
return 0;
|
||||||
|
size -= 4;
|
||||||
ip += 5;
|
ip += 5;
|
||||||
prevPosT = (SizeT)0 - 1;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *p = data + bufferPos;
|
Byte *p = data + pos;
|
||||||
Byte *limit = data + size - 4;
|
const Byte *limit = data + size;
|
||||||
for (; p < limit; p++)
|
for (; p < limit; p++)
|
||||||
if ((*p & 0xFE) == 0xE8)
|
if ((*p & 0xFE) == 0xE8)
|
||||||
break;
|
break;
|
||||||
bufferPos = (SizeT)(p - data);
|
|
||||||
if (p >= limit)
|
|
||||||
break;
|
|
||||||
prevPosT = bufferPos - prevPosT;
|
|
||||||
if (prevPosT > 3)
|
|
||||||
prevMask = 0;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
SizeT d = (SizeT)(p - data - pos);
|
||||||
if (prevMask != 0)
|
pos = (SizeT)(p - data);
|
||||||
|
if (p >= limit)
|
||||||
{
|
{
|
||||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
*state = (d > 2 ? 0 : mask >> (unsigned)d);
|
||||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
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;
|
mask = (mask >> 1) | 4;
|
||||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
pos++;
|
||||||
bufferPos++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevPosT = bufferPos;
|
|
||||||
|
|
||||||
if (Test86MSByte(p[4]))
|
if (Test86MSByte(p[4]))
|
||||||
{
|
{
|
||||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||||
UInt32 dest;
|
UInt32 cur = ip + (UInt32)pos;
|
||||||
for (;;)
|
pos += 5;
|
||||||
|
if (encoding)
|
||||||
|
v += cur;
|
||||||
|
else
|
||||||
|
v -= cur;
|
||||||
|
if (mask != 0)
|
||||||
{
|
{
|
||||||
Byte b;
|
unsigned sh = (mask & 6) << 2;
|
||||||
int index;
|
if (Test86MSByte((Byte)(v >> sh)))
|
||||||
if (encoding)
|
{
|
||||||
dest = (ip + (UInt32)bufferPos) + src;
|
v ^= (((UInt32)0x100 << sh) - 1);
|
||||||
else
|
if (encoding)
|
||||||
dest = src - (ip + (UInt32)bufferPos);
|
v += cur;
|
||||||
if (prevMask == 0)
|
else
|
||||||
break;
|
v -= cur;
|
||||||
index = kMaskToBitNumber[prevMask] * 8;
|
}
|
||||||
b = (Byte)(dest >> (24 - index));
|
mask = 0;
|
||||||
if (!Test86MSByte(b))
|
|
||||||
break;
|
|
||||||
src = dest ^ ((1 << (32 - index)) - 1);
|
|
||||||
}
|
}
|
||||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
p[1] = (Byte)v;
|
||||||
p[3] = (Byte)(dest >> 16);
|
p[2] = (Byte)(v >> 8);
|
||||||
p[2] = (Byte)(dest >> 8);
|
p[3] = (Byte)(v >> 16);
|
||||||
p[1] = (Byte)dest;
|
p[4] = (Byte)(0 - ((v >> 24) & 1));
|
||||||
bufferPos += 5;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
mask = (mask >> 1) | 4;
|
||||||
bufferPos++;
|
pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevPosT = bufferPos - prevPosT;
|
|
||||||
*state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
|
||||||
return bufferPos;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
/* CpuArch.h -- CPU specific code
|
||||||
2008-08-05
|
2016-06-09: Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#ifndef __CPUARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __CPUARCH_H
|
#define __CPU_ARCH_H
|
||||||
|
|
||||||
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LITTLE_ENDIAN_UNALIGN means:
|
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||||
1) CPU is LITTLE_ENDIAN
|
MY_CPU_BE means that CPU is BIG ENDIAN.
|
||||||
2) it's allowed to make unaligned memory accesses
|
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
|
||||||
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
|
||||||
about these properties 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__)
|
#if defined(_M_X64) \
|
||||||
#define LITTLE_ENDIAN_UNALIGN
|
|| defined(_M_AMD64) \
|
||||||
|
|| defined(__x86_64__) \
|
||||||
|
|| defined(__AMD64__) \
|
||||||
|
|| defined(__amd64__)
|
||||||
|
#define MY_CPU_AMD64
|
||||||
#endif
|
#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))
|
#if defined(_M_IX86) || defined(__i386__)
|
||||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
#define MY_CPU_X86
|
||||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
#endif
|
||||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
|
||||||
|
#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
|
#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) ( \
|
#define GetUi32(p) ( \
|
||||||
((const Byte *)(p))[0] | \
|
((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 GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||||
|
|
||||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||||
((Byte *)(p))[0] = (Byte)_x_; \
|
_ppp_[0] = (Byte)_vvv_; \
|
||||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
_ppp_[1] = (Byte)(_vvv_ >> 8); }
|
||||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
|
||||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
#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
|
#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_ulong)
|
||||||
#pragma intrinsic(_byteswap_uint64)
|
#pragma intrinsic(_byteswap_uint64)
|
||||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
|
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
||||||
|
|
||||||
|
#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
|
#else
|
||||||
|
|
||||||
#define GetBe32(p) ( \
|
#define GetBe32(p) ( \
|
||||||
|
@ -62,8 +170,54 @@ about these properties of platform.
|
||||||
|
|
||||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||||
|
|
||||||
#endif
|
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||||
|
_ppp_[0] = (Byte)(_vvv_ >> 24); \
|
||||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
_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
|
#endif
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* LzFind.c -- Match finder for LZ algorithms
|
/* 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>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -9,8 +11,8 @@
|
||||||
#define kEmptyHashValue 0
|
#define kEmptyHashValue 0
|
||||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
|
||||||
#define kMaxHistorySize ((UInt32)3 << 30)
|
#define kMaxHistorySize ((UInt32)7 << 29)
|
||||||
|
|
||||||
#define kStartMaxLen 3
|
#define kStartMaxLen 3
|
||||||
|
|
||||||
|
@ -19,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
if (!p->directInput)
|
if (!p->directInput)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->bufferBase);
|
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;
|
p->blockSize = blockSize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
if (!p->bufferBase || p->blockSize != blockSize)
|
||||||
{
|
{
|
||||||
LzInWindow_Free(p, alloc);
|
LzInWindow_Free(p, alloc);
|
||||||
p->blockSize = blockSize;
|
p->blockSize = blockSize;
|
||||||
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
||||||
}
|
}
|
||||||
return (p->bufferBase != 0);
|
return (p->bufferBase != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
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; }
|
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)
|
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||||
return;
|
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 (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||||
size_t size = (p->bufferBase + p->blockSize - dest);
|
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p->result = p->stream->Read(p->stream, dest, &size);
|
p->result = p->stream->Read(p->stream, dest, &size);
|
||||||
if (p->result != SZ_OK)
|
if (p->result != SZ_OK)
|
||||||
return;
|
return;
|
||||||
|
@ -81,13 +98,15 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||||
void MatchFinder_MoveBlock(CMatchFinder *p)
|
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
memmove(p->bufferBase,
|
memmove(p->bufferBase,
|
||||||
p->buffer - p->keepSizeBefore,
|
p->buffer - p->keepSizeBefore,
|
||||||
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
(size_t)(p->streamPos - p->pos) + p->keepSizeBefore);
|
||||||
p->buffer = p->bufferBase + p->keepSizeBefore;
|
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MatchFinder_NeedMove(CMatchFinder *p)
|
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
|
if (p->directInput)
|
||||||
|
return 0;
|
||||||
/* if (p->streamEndWasReached) return 0; */
|
/* if (p->streamEndWasReached) return 0; */
|
||||||
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
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->cutValue = 32;
|
||||||
p->btMode = 1;
|
p->btMode = 1;
|
||||||
p->numHashBytes = 4;
|
p->numHashBytes = 4;
|
||||||
/* p->skipModeBits = 0; */
|
|
||||||
p->directInput = 0;
|
|
||||||
p->bigHash = 0;
|
p->bigHash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,15 +139,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
||||||
void MatchFinder_Construct(CMatchFinder *p)
|
void MatchFinder_Construct(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
p->bufferBase = 0;
|
p->bufferBase = NULL;
|
||||||
p->directInput = 0;
|
p->directInput = 0;
|
||||||
p->hash = 0;
|
p->hash = NULL;
|
||||||
MatchFinder_SetDefaultSettings(p);
|
MatchFinder_SetDefaultSettings(p);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = i;
|
UInt32 r = i;
|
||||||
int j;
|
unsigned j;
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
p->crc[i] = r;
|
p->crc[i] = r;
|
||||||
|
@ -140,7 +157,7 @@ void MatchFinder_Construct(CMatchFinder *p)
|
||||||
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->hash);
|
alloc->Free(alloc, p->hash);
|
||||||
p->hash = 0;
|
p->hash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
|
@ -149,11 +166,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
LzInWindow_Free(p, 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);
|
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||||
if (sizeInBytes / sizeof(CLzRef) != num)
|
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||||
return 0;
|
return NULL;
|
||||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,22 +179,27 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
ISzAlloc *alloc)
|
ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt32 sizeReserv;
|
UInt32 sizeReserv;
|
||||||
|
|
||||||
if (historySize > kMaxHistorySize)
|
if (historySize > kMaxHistorySize)
|
||||||
{
|
{
|
||||||
MatchFinder_Free(p, alloc);
|
MatchFinder_Free(p, alloc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeReserv = historySize >> 1;
|
sizeReserv = historySize >> 1;
|
||||||
if (historySize > ((UInt32)2 << 30))
|
if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
|
||||||
sizeReserv = historySize >> 2;
|
else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
|
||||||
|
|
||||||
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||||
|
|
||||||
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||||
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||||
|
|
||||||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||||
|
|
||||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||||
{
|
{
|
||||||
UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
|
UInt32 newCyclicBufferSize = historySize + 1;
|
||||||
UInt32 hs;
|
UInt32 hs;
|
||||||
p->matchMaxLen = matchMaxLen;
|
p->matchMaxLen = matchMaxLen;
|
||||||
{
|
{
|
||||||
|
@ -192,7 +214,6 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
hs |= (hs >> 4);
|
hs |= (hs >> 4);
|
||||||
hs |= (hs >> 8);
|
hs |= (hs >> 8);
|
||||||
hs >>= 1;
|
hs >>= 1;
|
||||||
/* hs >>= p->skipModeBits; */
|
|
||||||
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||||
if (hs > (1 << 24))
|
if (hs > (1 << 24))
|
||||||
{
|
{
|
||||||
|
@ -200,6 +221,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
hs = (1 << 24) - 1;
|
hs = (1 << 24) - 1;
|
||||||
else
|
else
|
||||||
hs >>= 1;
|
hs >>= 1;
|
||||||
|
/* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->hashMask = hs;
|
p->hashMask = hs;
|
||||||
|
@ -211,24 +233,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
size_t newSize;
|
||||||
UInt32 newSize;
|
size_t numSons;
|
||||||
p->historySize = historySize;
|
p->historySize = historySize;
|
||||||
p->hashSizeSum = hs;
|
p->hashSizeSum = hs;
|
||||||
p->cyclicBufferSize = newCyclicBufferSize;
|
p->cyclicBufferSize = newCyclicBufferSize;
|
||||||
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
|
||||||
newSize = p->hashSizeSum + p->numSons;
|
numSons = newCyclicBufferSize;
|
||||||
if (p->hash != 0 && prevSize == newSize)
|
if (p->btMode)
|
||||||
|
numSons <<= 1;
|
||||||
|
newSize = hs + numSons;
|
||||||
|
|
||||||
|
if (p->hash && p->numRefs == newSize)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
|
p->numRefs = newSize;
|
||||||
p->hash = AllocRefs(newSize, alloc);
|
p->hash = AllocRefs(newSize, alloc);
|
||||||
if (p->hash != 0)
|
|
||||||
|
if (p->hash)
|
||||||
{
|
{
|
||||||
p->son = p->hash + p->hashSizeSum;
|
p->son = p->hash + p->hashSizeSum;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchFinder_Free(p, alloc);
|
MatchFinder_Free(p, alloc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -237,9 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
UInt32 limit = kMaxValForNormalize - p->pos;
|
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||||
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||||
|
|
||||||
if (limit2 < limit)
|
if (limit2 < limit)
|
||||||
limit = limit2;
|
limit = limit2;
|
||||||
limit2 = p->streamPos - p->pos;
|
limit2 = p->streamPos - p->pos;
|
||||||
|
|
||||||
if (limit2 <= p->keepSizeAfter)
|
if (limit2 <= p->keepSizeAfter)
|
||||||
{
|
{
|
||||||
if (limit2 > 0)
|
if (limit2 > 0)
|
||||||
|
@ -247,8 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
limit2 -= p->keepSizeAfter;
|
limit2 -= p->keepSizeAfter;
|
||||||
|
|
||||||
if (limit2 < limit)
|
if (limit2 < limit)
|
||||||
limit = limit2;
|
limit = limit2;
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 lenLimit = p->streamPos - p->pos;
|
UInt32 lenLimit = p->streamPos - p->pos;
|
||||||
if (lenLimit > p->matchMaxLen)
|
if (lenLimit > p->matchMaxLen)
|
||||||
|
@ -258,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||||
p->posLimit = p->pos + limit;
|
p->posLimit = p->pos + limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Init(CMatchFinder *p)
|
void MatchFinder_Init_2(CMatchFinder *p, int readData)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < p->hashSizeSum; i++)
|
UInt32 *hash = p->hash;
|
||||||
p->hash[i] = kEmptyHashValue;
|
UInt32 num = p->hashSizeSum;
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
hash[i] = kEmptyHashValue;
|
||||||
|
|
||||||
p->cyclicBufferPos = 0;
|
p->cyclicBufferPos = 0;
|
||||||
p->buffer = p->bufferBase;
|
p->buffer = p->bufferBase;
|
||||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||||
p->result = SZ_OK;
|
p->result = SZ_OK;
|
||||||
p->streamEndWasReached = 0;
|
p->streamEndWasReached = 0;
|
||||||
MatchFinder_ReadBlock(p);
|
|
||||||
|
if (readData)
|
||||||
|
MatchFinder_ReadBlock(p);
|
||||||
|
|
||||||
MatchFinder_SetLimits(p);
|
MatchFinder_SetLimits(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MatchFinder_Init(CMatchFinder *p)
|
||||||
|
{
|
||||||
|
MatchFinder_Init_2(p, True);
|
||||||
|
}
|
||||||
|
|
||||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
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++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 value = items[i];
|
UInt32 value = items[i];
|
||||||
|
@ -294,7 +339,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||||
static void MatchFinder_Normalize(CMatchFinder *p)
|
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
UInt32 subValue = MatchFinder_GetSubValue(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);
|
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; }
|
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||||
|
|
||||||
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
#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; }} \
|
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||||
cur = p->buffer;
|
cur = p->buffer;
|
||||||
|
|
||||||
|
@ -471,13 +516,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||||
#define SKIP_FOOTER \
|
#define SKIP_FOOTER \
|
||||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
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)
|
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 offset;
|
UInt32 offset;
|
||||||
GET_MATCHES_HEADER(2)
|
GET_MATCHES_HEADER(2)
|
||||||
HASH2_CALC;
|
HASH2_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
GET_MATCHES_FOOTER(offset, 1)
|
GET_MATCHES_FOOTER(offset, 1)
|
||||||
}
|
}
|
||||||
|
@ -487,35 +539,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
UInt32 offset;
|
UInt32 offset;
|
||||||
GET_MATCHES_HEADER(3)
|
GET_MATCHES_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
GET_MATCHES_FOOTER(offset, 2)
|
GET_MATCHES_FOOTER(offset, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
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)
|
GET_MATCHES_HEADER(3)
|
||||||
|
|
||||||
HASH3_CALC;
|
HASH3_CALC;
|
||||||
|
|
||||||
delta2 = p->pos - p->hash[hash2Value];
|
hash = p->hash;
|
||||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
pos = p->pos;
|
||||||
|
|
||||||
p->hash[hash2Value] =
|
d2 = pos - hash[h2];
|
||||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
|
||||||
|
|
||||||
|
curMatch = hash[kFix3HashSize + hv];
|
||||||
|
|
||||||
|
hash[h2] = pos;
|
||||||
|
hash[kFix3HashSize + hv] = pos;
|
||||||
|
|
||||||
maxLen = 2;
|
maxLen = 2;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
|
||||||
|
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||||
{
|
{
|
||||||
for (; maxLen != lenLimit; maxLen++)
|
UPDATE_maxLen
|
||||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
|
||||||
break;
|
|
||||||
distances[0] = maxLen;
|
distances[0] = maxLen;
|
||||||
distances[1] = delta2 - 1;
|
distances[1] = d2 - 1;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
|
@ -523,44 +578,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_MATCHES_FOOTER(offset, maxLen)
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
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)
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
|
|
||||||
delta2 = p->pos - p->hash[ hash2Value];
|
hash = p->hash;
|
||||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
pos = p->pos;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
|
||||||
|
|
||||||
p->hash[ hash2Value] =
|
d2 = pos - hash[ h2];
|
||||||
p->hash[kFix3HashSize + hash3Value] =
|
d3 = pos - hash[kFix3HashSize + h3];
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
|
||||||
|
|
||||||
maxLen = 1;
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
|
|
||||||
|
hash[ h2] = pos;
|
||||||
|
hash[kFix3HashSize + h3] = pos;
|
||||||
|
hash[kFix4HashSize + hv] = pos;
|
||||||
|
|
||||||
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
|
||||||
|
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||||
{
|
{
|
||||||
distances[0] = maxLen = 2;
|
distances[0] = maxLen = 2;
|
||||||
distances[1] = delta2 - 1;
|
distances[1] = d2 - 1;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
}
|
}
|
||||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
|
||||||
|
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
||||||
{
|
{
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
distances[offset + 1] = delta3 - 1;
|
distances[offset + 1] = d3 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
delta2 = delta3;
|
d2 = d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
for (; maxLen != lenLimit; maxLen++)
|
UPDATE_maxLen
|
||||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
|
||||||
break;
|
|
||||||
distances[offset - 2] = maxLen;
|
distances[offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
|
@ -568,46 +630,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxLen < 3)
|
if (maxLen < 3)
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
|
|
||||||
GET_MATCHES_FOOTER(offset, maxLen)
|
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)
|
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)
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
|
|
||||||
delta2 = p->pos - p->hash[ hash2Value];
|
hash = p->hash;
|
||||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
pos = p->pos;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
|
||||||
|
|
||||||
p->hash[ hash2Value] =
|
d2 = pos - hash[ h2];
|
||||||
p->hash[kFix3HashSize + hash3Value] =
|
d3 = pos - hash[kFix3HashSize + h3];
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
|
||||||
|
|
||||||
maxLen = 1;
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
|
|
||||||
|
hash[ h2] = pos;
|
||||||
|
hash[kFix3HashSize + h3] = pos;
|
||||||
|
hash[kFix4HashSize + hv] = pos;
|
||||||
|
|
||||||
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
|
||||||
|
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||||
{
|
{
|
||||||
distances[0] = maxLen = 2;
|
distances[0] = maxLen = 2;
|
||||||
distances[1] = delta2 - 1;
|
distances[1] = d2 - 1;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
}
|
}
|
||||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
|
||||||
|
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
||||||
{
|
{
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
distances[offset + 1] = delta3 - 1;
|
distances[offset + 1] = d3 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
delta2 = delta3;
|
d2 = d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
for (; maxLen != lenLimit; maxLen++)
|
UPDATE_maxLen
|
||||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
|
||||||
break;
|
|
||||||
distances[offset - 2] = maxLen;
|
distances[offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
|
@ -615,22 +762,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxLen < 3)
|
if (maxLen < 3)
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
|
|
||||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
distances + offset, maxLen) - (distances));
|
distances + offset, maxLen) - (distances));
|
||||||
MOVE_POS_RET
|
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 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 offset;
|
UInt32 offset;
|
||||||
GET_MATCHES_HEADER(3)
|
GET_MATCHES_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
distances, 2) - (distances));
|
distances, 2) - (distances));
|
||||||
MOVE_POS_RET
|
MOVE_POS_RET
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,8 +868,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(2)
|
SKIP_HEADER(2)
|
||||||
HASH2_CALC;
|
HASH2_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
|
@ -653,8 +881,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
|
@ -664,12 +892,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value;
|
UInt32 h2;
|
||||||
|
UInt32 *hash;
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH3_CALC;
|
HASH3_CALC;
|
||||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
hash = p->hash;
|
||||||
p->hash[hash2Value] =
|
curMatch = hash[kFix3HashSize + hv];
|
||||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
hash[h2] =
|
||||||
|
hash[kFix3HashSize + hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
|
@ -679,43 +909,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 h2, h3;
|
||||||
|
UInt32 *hash;
|
||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
hash = p->hash;
|
||||||
p->hash[ hash2Value] =
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
hash[ h2] =
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
hash[kFix3HashSize + h3] =
|
||||||
|
hash[kFix4HashSize + hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
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)
|
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 h2, h3;
|
||||||
|
UInt32 *hash;
|
||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
hash = p->hash;
|
||||||
p->hash[ hash2Value] =
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
p->hash[kFix3HashSize + hash3Value] =
|
hash[ h2] =
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
hash[kFix3HashSize + h3] =
|
||||||
|
hash[kFix4HashSize + hv] = p->pos;
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS
|
MOVE_POS
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
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)
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS
|
MOVE_POS
|
||||||
}
|
}
|
||||||
|
@ -725,13 +1002,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||||
{
|
{
|
||||||
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
|
||||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||||
if (!p->btMode)
|
if (!p->btMode)
|
||||||
{
|
{
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
/* if (p->numHashBytes <= 4) */
|
||||||
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
{
|
||||||
|
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)
|
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->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||||
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||||
}
|
}
|
||||||
else
|
else /* if (p->numHashBytes == 4) */
|
||||||
{
|
{
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||||
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
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
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2015-10-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZFIND_H
|
#ifndef __LZ_FIND_H
|
||||||
#define __LZFIND_H
|
#define __LZ_FIND_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
typedef UInt32 CLzRef;
|
typedef UInt32 CLzRef;
|
||||||
|
|
||||||
|
@ -19,6 +21,11 @@ typedef struct _CMatchFinder
|
||||||
UInt32 cyclicBufferPos;
|
UInt32 cyclicBufferPos;
|
||||||
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||||
|
|
||||||
|
Byte streamEndWasReached;
|
||||||
|
Byte btMode;
|
||||||
|
Byte bigHash;
|
||||||
|
Byte directInput;
|
||||||
|
|
||||||
UInt32 matchMaxLen;
|
UInt32 matchMaxLen;
|
||||||
CLzRef *hash;
|
CLzRef *hash;
|
||||||
CLzRef *son;
|
CLzRef *son;
|
||||||
|
@ -27,30 +34,30 @@ typedef struct _CMatchFinder
|
||||||
|
|
||||||
Byte *bufferBase;
|
Byte *bufferBase;
|
||||||
ISeqInStream *stream;
|
ISeqInStream *stream;
|
||||||
int streamEndWasReached;
|
|
||||||
|
|
||||||
UInt32 blockSize;
|
UInt32 blockSize;
|
||||||
UInt32 keepSizeBefore;
|
UInt32 keepSizeBefore;
|
||||||
UInt32 keepSizeAfter;
|
UInt32 keepSizeAfter;
|
||||||
|
|
||||||
UInt32 numHashBytes;
|
UInt32 numHashBytes;
|
||||||
int directInput;
|
size_t directInputRem;
|
||||||
int btMode;
|
|
||||||
/* int skipModeBits; */
|
|
||||||
int bigHash;
|
|
||||||
UInt32 historySize;
|
UInt32 historySize;
|
||||||
UInt32 fixedHashSize;
|
UInt32 fixedHashSize;
|
||||||
UInt32 hashSizeSum;
|
UInt32 hashSizeSum;
|
||||||
UInt32 numSons;
|
|
||||||
SRes result;
|
SRes result;
|
||||||
UInt32 crc[256];
|
UInt32 crc[256];
|
||||||
|
size_t numRefs;
|
||||||
} CMatchFinder;
|
} CMatchFinder;
|
||||||
|
|
||||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
#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_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);
|
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||||
|
@ -66,7 +73,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAlloc *alloc);
|
ISzAlloc *alloc);
|
||||||
void MatchFinder_Free(CMatchFinder *p, 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);
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
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 void (*Mf_Init_Func)(void *object);
|
||||||
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
|
||||||
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||||
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||||
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||||
|
@ -89,7 +95,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||||
typedef struct _IMatchFinder
|
typedef struct _IMatchFinder
|
||||||
{
|
{
|
||||||
Mf_Init_Func Init;
|
Mf_Init_Func Init;
|
||||||
Mf_GetIndexByte_Func GetIndexByte;
|
|
||||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||||
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||||
Mf_GetMatches_Func GetMatches;
|
Mf_GetMatches_Func GetMatches;
|
||||||
|
@ -98,10 +103,15 @@ typedef struct _IMatchFinder
|
||||||
|
|
||||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||||
|
|
||||||
|
void MatchFinder_Init_2(CMatchFinder *p, int readData);
|
||||||
void MatchFinder_Init(CMatchFinder *p);
|
void MatchFinder_Init(CMatchFinder *p);
|
||||||
|
|
||||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||||
|
|
||||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
/* 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 "LzHash.h"
|
||||||
|
|
||||||
#include "LzFindMt.h"
|
#include "LzFindMt.h"
|
||||||
|
|
||||||
void MtSync_Construct(CMtSync *p)
|
static void MtSync_Construct(CMtSync *p)
|
||||||
{
|
{
|
||||||
p->wasCreated = False;
|
p->wasCreated = False;
|
||||||
p->csWasInitialized = False;
|
p->csWasInitialized = False;
|
||||||
|
@ -18,7 +20,7 @@ void MtSync_Construct(CMtSync *p)
|
||||||
Semaphore_Construct(&p->filledSemaphore);
|
Semaphore_Construct(&p->filledSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MtSync_GetNextBlock(CMtSync *p)
|
static void MtSync_GetNextBlock(CMtSync *p)
|
||||||
{
|
{
|
||||||
if (p->needStart)
|
if (p->needStart)
|
||||||
{
|
{
|
||||||
|
@ -46,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p)
|
||||||
|
|
||||||
/* MtSync_StopWriting must be called if Writing was started */
|
/* MtSync_StopWriting must be called if Writing was started */
|
||||||
|
|
||||||
void MtSync_StopWriting(CMtSync *p)
|
static void MtSync_StopWriting(CMtSync *p)
|
||||||
{
|
{
|
||||||
UInt32 myNumBlocks = p->numProcessedBlocks;
|
UInt32 myNumBlocks = p->numProcessedBlocks;
|
||||||
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
||||||
|
@ -69,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p)
|
||||||
p->needStart = True;
|
p->needStart = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MtSync_Destruct(CMtSync *p)
|
static void MtSync_Destruct(CMtSync *p)
|
||||||
{
|
{
|
||||||
if (Thread_WasCreated(&p->thread))
|
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; }
|
#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)
|
if (p->wasCreated)
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
|
@ -119,7 +121,7 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void
|
||||||
return SZ_OK;
|
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);
|
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
|
@ -132,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; }
|
||||||
#define kMtMaxValForNormalize 0xFFFFFFFF
|
#define kMtMaxValForNormalize 0xFFFFFFFF
|
||||||
|
|
||||||
#define DEF_GetHeads2(name, v, action) \
|
#define DEF_GetHeads2(name, v, action) \
|
||||||
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
||||||
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
||||||
{ action; for (; numHeads != 0; numHeads--) { \
|
{ action; for (; numHeads != 0; numHeads--) { \
|
||||||
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
||||||
|
|
||||||
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
|
#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(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(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(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;
|
CMtSync *p = &mt->hashSync;
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -171,12 +173,12 @@ void HashThreadFunc(CMatchFinderMt *mt)
|
||||||
CriticalSection_Enter(&mt->btSync.cs);
|
CriticalSection_Enter(&mt->btSync.cs);
|
||||||
CriticalSection_Enter(&mt->hashSync.cs);
|
CriticalSection_Enter(&mt->hashSync.cs);
|
||||||
{
|
{
|
||||||
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
|
const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
const Byte *afterPtr;
|
ptrdiff_t offset;
|
||||||
MatchFinder_MoveBlock(mf);
|
MatchFinder_MoveBlock(mf);
|
||||||
afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
|
offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||||
mt->pointerToCurPos -= beforePtr - afterPtr;
|
mt->pointerToCurPos -= offset;
|
||||||
mt->buffer -= beforePtr - afterPtr;
|
mt->buffer -= offset;
|
||||||
}
|
}
|
||||||
CriticalSection_Leave(&mt->btSync.cs);
|
CriticalSection_Leave(&mt->btSync.cs);
|
||||||
CriticalSection_Leave(&mt->hashSync.cs);
|
CriticalSection_Leave(&mt->hashSync.cs);
|
||||||
|
@ -190,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
|
||||||
{
|
{
|
||||||
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
||||||
MatchFinder_ReduceOffsets(mf, subValue);
|
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;
|
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);
|
MtSync_GetNextBlock(&p->hashSync);
|
||||||
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
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
|
#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 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
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
|
#endif
|
||||||
|
|
||||||
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 numProcessed = 0;
|
UInt32 numProcessed = 0;
|
||||||
UInt32 curPos = 2;
|
UInt32 curPos = 2;
|
||||||
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
||||||
|
|
||||||
distances[1] = p->hashNumAvail;
|
distances[1] = p->hashNumAvail;
|
||||||
|
|
||||||
while (curPos < limit)
|
while (curPos < limit)
|
||||||
{
|
{
|
||||||
if (p->hashBufPos == p->hashBufPosLimit)
|
if (p->hashBufPos == p->hashBufPosLimit)
|
||||||
|
@ -322,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
distances[1] = numProcessed + p->hashNumAvail;
|
distances[1] = numProcessed + p->hashNumAvail;
|
||||||
if (p->hashNumAvail >= p->numHashBytes)
|
if (p->hashNumAvail >= p->numHashBytes)
|
||||||
continue;
|
continue;
|
||||||
|
distances[0] = curPos + p->hashNumAvail;
|
||||||
|
distances += curPos;
|
||||||
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
||||||
distances[curPos++] = 0;
|
*distances++ = 0;
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
||||||
|
@ -341,13 +347,14 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
if (size2 < size)
|
if (size2 < size)
|
||||||
size = size2;
|
size = size2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MFMT_GM_INLINE
|
#ifndef MFMT_GM_INLINE
|
||||||
while (curPos < limit && size-- != 0)
|
while (curPos < limit && size-- != 0)
|
||||||
{
|
{
|
||||||
UInt32 *startDistances = distances + curPos;
|
UInt32 *startDistances = distances + curPos;
|
||||||
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
||||||
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||||
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
||||||
*startDistances = num - 1;
|
*startDistances = num - 1;
|
||||||
curPos += num;
|
curPos += num;
|
||||||
cyclicBufferPos++;
|
cyclicBufferPos++;
|
||||||
|
@ -358,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 posRes;
|
UInt32 posRes;
|
||||||
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
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;
|
p->hashBufPos += posRes - pos;
|
||||||
cyclicBufferPos += posRes - pos;
|
cyclicBufferPos += posRes - pos;
|
||||||
p->buffer += posRes - pos;
|
p->buffer += posRes - pos;
|
||||||
|
@ -374,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
p->cyclicBufferPos = cyclicBufferPos;
|
p->cyclicBufferPos = cyclicBufferPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
distances[0] = curPos;
|
distances[0] = curPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
||||||
{
|
{
|
||||||
CMtSync *sync = &p->hashSync;
|
CMtSync *sync = &p->hashSync;
|
||||||
if (!sync->needStart)
|
if (!sync->needStart)
|
||||||
|
@ -391,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
||||||
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
||||||
{
|
{
|
||||||
UInt32 subValue = p->pos - p->cyclicBufferSize;
|
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;
|
p->pos -= subValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt)
|
||||||
|
|
||||||
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
p->hashBuf = 0;
|
p->hashBuf = NULL;
|
||||||
MtSync_Construct(&p->hashSync);
|
MtSync_Construct(&p->hashSync);
|
||||||
MtSync_Construct(&p->btSync);
|
MtSync_Construct(&p->btSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->hashBuf);
|
alloc->Free(alloc, p->hashBuf);
|
||||||
p->hashBuf = 0;
|
p->hashBuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
|
@ -451,14 +459,15 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
|
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
|
||||||
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
||||||
|
|
||||||
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE 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 BtThreadFunc2(void *p)
|
||||||
{
|
{
|
||||||
Byte allocaDummy[0x180];
|
Byte allocaDummy[0x180];
|
||||||
int i = 0;
|
unsigned i = 0;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
allocaDummy[i] = (Byte)i;
|
allocaDummy[i] = (Byte)0;
|
||||||
BtThreadFunc((CMatchFinderMt *)p);
|
if (allocaDummy[0] == 0)
|
||||||
|
BtThreadFunc((CMatchFinderMt *)p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
||||||
p->historySize = historySize;
|
p->historySize = historySize;
|
||||||
if (kMtBtBlockSize <= matchMaxLen * 4)
|
if (kMtBtBlockSize <= matchMaxLen * 4)
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
if (p->hashBuf == 0)
|
if (!p->hashBuf)
|
||||||
{
|
{
|
||||||
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
||||||
if (p->hashBuf == 0)
|
if (!p->hashBuf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->btBuf = p->hashBuf + kHashBufferSize;
|
p->btBuf = p->hashBuf + kHashBufferSize;
|
||||||
}
|
}
|
||||||
|
@ -492,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||||
CMatchFinder *mf = p->MatchFinder;
|
CMatchFinder *mf = p->MatchFinder;
|
||||||
p->btBufPos = p->btBufPosLimit = 0;
|
p->btBufPos = p->btBufPosLimit = 0;
|
||||||
p->hashBufPos = p->hashBufPosLimit = 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->btNumAvailBytes = 0;
|
||||||
p->lzPos = p->historySize + 1;
|
p->lzPos = p->historySize + 1;
|
||||||
|
|
||||||
|
@ -518,13 +530,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
||||||
/* p->MatchFinder->ReleaseStream(); */
|
/* 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);
|
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
|
||||||
p->lzPos = p->historySize + 1;
|
p->lzPos = p->historySize + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
UInt32 blockIndex;
|
UInt32 blockIndex;
|
||||||
MtSync_GetNextBlock(&p->btSync);
|
MtSync_GetNextBlock(&p->btSync);
|
||||||
|
@ -536,34 +548,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
||||||
MatchFinderMt_Normalize(p);
|
MatchFinderMt_Normalize(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
return p->pointerToCurPos;
|
return p->pointerToCurPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
#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;
|
GET_NEXT_BLOCK_IF_REQUIRED;
|
||||||
return p->btNumAvailBytes;
|
return p->btNumAvailBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
{
|
{
|
||||||
return p->pointerToCurPos[index];
|
UInt32 h2, curMatch2;
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|
||||||
{
|
|
||||||
UInt32 hash2Value, curMatch2;
|
|
||||||
UInt32 *hash = p->hash;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH2_CALC
|
MT_HASH2_CALC
|
||||||
|
|
||||||
curMatch2 = hash[hash2Value];
|
curMatch2 = hash[h2];
|
||||||
hash[hash2Value] = lzPos;
|
hash[h2] = lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos)
|
if (curMatch2 >= matchMinPos)
|
||||||
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
|
@ -571,23 +578,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
*distances++ = 2;
|
*distances++ = 2;
|
||||||
*distances++ = lzPos - curMatch2 - 1;
|
*distances++ = lzPos - curMatch2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distances;
|
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;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ hash2Value];
|
curMatch2 = hash[ h2];
|
||||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
curMatch3 = hash[kFix3HashSize + h3];
|
||||||
|
|
||||||
hash[ hash2Value] =
|
hash[ h2] = lzPos;
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] = lzPos;
|
||||||
lzPos;
|
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
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[0] = 2;
|
||||||
distances += 2;
|
distances += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
*distances++ = 3;
|
*distances++ = 3;
|
||||||
*distances++ = lzPos - curMatch3 - 1;
|
*distances++ = lzPos - curMatch3 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distances;
|
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;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ hash2Value];
|
curMatch2 = hash[ h2];
|
||||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
curMatch3 = hash[kFix3HashSize + h3];
|
||||||
curMatch4 = hash[kFix4HashSize + hash4Value];
|
curMatch4 = hash[kFix4HashSize + h4];
|
||||||
|
|
||||||
hash[ hash2Value] =
|
hash[ h2] = lzPos;
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] = lzPos;
|
||||||
hash[kFix4HashSize + hash4Value] =
|
hash[kFix4HashSize + h4] = lzPos;
|
||||||
lzPos;
|
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
distances[1] = lzPos - curMatch2 - 1;
|
distances[1] = lzPos - curMatch2 - 1;
|
||||||
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
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;
|
return distances + 2;
|
||||||
}
|
}
|
||||||
distances[0] = 2;
|
distances[0] = 2;
|
||||||
distances += 2;
|
distances += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
distances[1] = lzPos - curMatch3 - 1;
|
distances[1] = lzPos - curMatch3 - 1;
|
||||||
|
@ -658,13 +667,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
*distances++ = 4;
|
*distances++ = 4;
|
||||||
*distances++ = lzPos - curMatch4 - 1;
|
*distances++ = lzPos - curMatch4 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distances;
|
return distances;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
#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;
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
UInt32 len = *btBuf++;
|
UInt32 len = *btBuf++;
|
||||||
|
@ -682,7 +692,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
UInt32 len = *btBuf++;
|
UInt32 len = *btBuf++;
|
||||||
|
@ -690,6 +700,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
|
/* change for bt5 ! */
|
||||||
if (p->btNumAvailBytes-- >= 4)
|
if (p->btNumAvailBytes-- >= 4)
|
||||||
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
||||||
}
|
}
|
||||||
|
@ -705,64 +716,64 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
*distances2++ = *btBuf++;
|
*distances2++ = *btBuf++;
|
||||||
}
|
}
|
||||||
while ((len -= 2) != 0);
|
while ((len -= 2) != 0);
|
||||||
len = (UInt32)(distances2 - (distances));
|
len = (UInt32)(distances2 - (distances));
|
||||||
}
|
}
|
||||||
INCREASE_LZ_POS
|
INCREASE_LZ_POS
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED
|
#define SKIP_HEADER2_MT 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_HEADER_MT(n) SKIP_HEADER2_MT 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_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_HEADER2_MT { p->btNumAvailBytes--;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(2)
|
SKIP_HEADER_MT(2)
|
||||||
UInt32 hash2Value;
|
UInt32 h2;
|
||||||
MT_HASH2_CALC
|
MT_HASH2_CALC
|
||||||
hash[hash2Value] = p->lzPos;
|
hash[h2] = p->lzPos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER_MT(3)
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 h2, h3;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] =
|
||||||
hash[ hash2Value] =
|
hash[ h2] =
|
||||||
p->lzPos;
|
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)
|
SKIP_HEADER_MT(4)
|
||||||
UInt32 hash2Value, hash3Value, hash4Value;
|
UInt32 h2, h3, h4;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
hash[kFix4HashSize + hash4Value] =
|
hash[kFix4HashSize + h4] =
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] =
|
||||||
hash[ hash2Value] =
|
hash[ h2] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
||||||
{
|
{
|
||||||
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
||||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
|
|
||||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
||||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
||||||
switch(p->MatchFinder->numHashBytes)
|
|
||||||
|
switch (p->MatchFinder->numHashBytes)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p->GetHeadsFunc = GetHeads2;
|
p->GetHeadsFunc = GetHeads2;
|
||||||
|
@ -778,7 +789,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
||||||
default:
|
default:
|
||||||
/* case 4: */
|
/* case 4: */
|
||||||
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
||||||
/* p->GetHeadsFunc = GetHeads4; */
|
|
||||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
||||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
/* 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
|
#ifndef __LZ_FIND_MT_H
|
||||||
#define __LZFINDMT_H
|
#define __LZ_FIND_MT_H
|
||||||
|
|
||||||
#include "Threads.h"
|
|
||||||
#include "LzFind.h"
|
#include "LzFind.h"
|
||||||
|
#include "Threads.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define kMtHashBlockSize (1 << 13)
|
#define kMtHashBlockSize (1 << 13)
|
||||||
#define kMtHashNumBlocks (1 << 3)
|
#define kMtHashNumBlocks (1 << 3)
|
||||||
|
@ -73,7 +75,7 @@ typedef struct _CMatchFinderMt
|
||||||
UInt32 matchMaxLen;
|
UInt32 matchMaxLen;
|
||||||
UInt32 numHashBytes;
|
UInt32 numHashBytes;
|
||||||
UInt32 pos;
|
UInt32 pos;
|
||||||
Byte *buffer;
|
const Byte *buffer;
|
||||||
UInt32 cyclicBufferPos;
|
UInt32 cyclicBufferPos;
|
||||||
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
||||||
UInt32 cutValue;
|
UInt32 cutValue;
|
||||||
|
@ -94,4 +96,6 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
||||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/* LzHash.h -- HASH functions for LZ algorithms
|
/* LzHash.h -- HASH functions for LZ algorithms
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2015-04-12 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZHASH_H
|
#ifndef __LZ_HASH_H
|
||||||
#define __LZHASH_H
|
#define __LZ_HASH_H
|
||||||
|
|
||||||
#define kHash2Size (1 << 10)
|
#define kHash2Size (1 << 10)
|
||||||
#define kHash3Size (1 << 16)
|
#define kHash3Size (1 << 16)
|
||||||
|
@ -12,43 +12,46 @@
|
||||||
#define kFix4HashSize (kHash2Size + kHash3Size)
|
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||||
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
#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 { \
|
#define HASH3_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||||
|
|
||||||
#define HASH4_CALC { \
|
#define HASH4_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
temp ^= ((UInt32)cur[2] << 8); \
|
||||||
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
h3 = temp & (kHash3Size - 1); \
|
||||||
|
hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||||
|
|
||||||
#define HASH5_CALC { \
|
#define HASH5_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
temp ^= ((UInt32)cur[2] << 8); \
|
||||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
h3 = temp & (kHash3Size - 1); \
|
||||||
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
temp ^= (p->crc[cur[3]] << 5); \
|
||||||
hash4Value &= (kHash4Size - 1); }
|
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 hv = ((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[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
#define MT_HASH2_CALC \
|
#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 { \
|
#define MT_HASH3_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||||
|
|
||||||
#define MT_HASH4_CALC { \
|
#define MT_HASH4_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
temp ^= ((UInt32)cur[2] << 8); \
|
||||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
h3 = temp & (kHash3Size - 1); \
|
||||||
|
h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2008-11-06 : Igor Pavlov : Public domain */
|
2016-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
|
|
||||||
|
@ -44,6 +46,13 @@
|
||||||
i -= 0x40; }
|
i -= 0x40; }
|
||||||
#endif
|
#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 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)
|
#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 Literal (RepLenCoder + kNumLenProbs)
|
||||||
|
|
||||||
#define LZMA_BASE_SIZE 1846
|
#define LZMA_BASE_SIZE 1846
|
||||||
#define LZMA_LIT_SIZE 768
|
#define LZMA_LIT_SIZE 0x300
|
||||||
|
|
||||||
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
|
||||||
|
|
||||||
#if Literal != LZMA_BASE_SIZE
|
#if Literal != LZMA_BASE_SIZE
|
||||||
StopCompilingDueBUG
|
StopCompilingDueBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const Byte kLiteralNextStates[kNumStates * 2] =
|
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
||||||
{
|
|
||||||
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 LZMA_DIC_MIN (1 << 12)
|
#define LZMA_DIC_MIN (1 << 12)
|
||||||
|
|
||||||
|
@ -130,8 +133,8 @@ Out:
|
||||||
p->remainLen:
|
p->remainLen:
|
||||||
< kMatchSpecLenStart : normal remain
|
< kMatchSpecLenStart : normal remain
|
||||||
= kMatchSpecLenStart : finished
|
= kMatchSpecLenStart : finished
|
||||||
= kMatchSpecLenStart + 1 : Flush marker
|
= kMatchSpecLenStart + 1 : Flush marker (unused now)
|
||||||
= kMatchSpecLenStart + 2 : State Init Marker
|
= kMatchSpecLenStart + 2 : State Init Marker (unused now)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
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;
|
unsigned symbol;
|
||||||
UPDATE_0(prob);
|
UPDATE_0(prob);
|
||||||
prob = probs + Literal;
|
prob = probs + Literal;
|
||||||
if (checkDicSize != 0 || processedPos != 0)
|
if (processedPos != 0 || checkDicSize != 0)
|
||||||
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
||||||
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
||||||
|
processedPos++;
|
||||||
|
|
||||||
if (state < kNumLitStates)
|
if (state < kNumLitStates)
|
||||||
{
|
{
|
||||||
|
state -= (state < 4) ? state : 3;
|
||||||
symbol = 1;
|
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
|
else
|
||||||
{
|
{
|
||||||
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||||
unsigned offs = 0x100;
|
unsigned offs = 0x100;
|
||||||
|
state -= (state < 10) ? 3 : 6;
|
||||||
symbol = 1;
|
symbol = 1;
|
||||||
|
#ifdef _LZMA_SIZE_OPT
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned bit;
|
unsigned bit;
|
||||||
CLzmaProb *probLit;
|
CLzmaProb *probLit;
|
||||||
matchByte <<= 1;
|
MATCHED_LITER_DEC
|
||||||
bit = (matchByte & offs);
|
|
||||||
probLit = prob + offs + bit + symbol;
|
|
||||||
GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
|
|
||||||
}
|
}
|
||||||
while (symbol < 0x100);
|
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];
|
dic[dicPos++] = (Byte)symbol;
|
||||||
/* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
{
|
||||||
UPDATE_1(prob);
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRep + state;
|
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)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob);
|
UPDATE_0(prob);
|
||||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||||
dicPos++;
|
dicPos++;
|
||||||
processedPos++;
|
processedPos++;
|
||||||
state = state < kNumLitStates ? 9 : 11;
|
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;
|
state = state < kNumLitStates ? 8 : 11;
|
||||||
prob = probs + RepLenCoder;
|
prob = probs + RepLenCoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _LZMA_SIZE_OPT
|
||||||
{
|
{
|
||||||
unsigned offset;
|
unsigned lim, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0(probLen)
|
IF_BIT_0(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0(probLen);
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
limit = (1 << kLenNumLowBits);
|
lim = (1 << kLenNumLowBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -284,19 +312,55 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
||||||
UPDATE_0(probLen);
|
UPDATE_0(probLen);
|
||||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||||
offset = kLenNumLowSymbols;
|
offset = kLenNumLowSymbols;
|
||||||
limit = (1 << kLenNumMidBits);
|
lim = (1 << kLenNumMidBits);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UPDATE_1(probLen);
|
UPDATE_1(probLen);
|
||||||
probLen = prob + LenHigh;
|
probLen = prob + LenHigh;
|
||||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||||
limit = (1 << kLenNumHighBits);
|
lim = (1 << kLenNumHighBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TREE_DECODE(probLen, limit, len);
|
TREE_DECODE(probLen, lim, len);
|
||||||
len += offset;
|
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)
|
if (state >= kNumStates)
|
||||||
{
|
{
|
||||||
|
@ -307,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
||||||
if (distance >= kStartPosModelIndex)
|
if (distance >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
unsigned posSlot = (unsigned)distance;
|
unsigned posSlot = (unsigned)distance;
|
||||||
int numDirectBits = (int)(((distance >> 1) - 1));
|
unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
|
||||||
distance = (2 | (distance & 1));
|
distance = (2 | (distance & 1));
|
||||||
if (posSlot < kEndPosModelIndex)
|
if (posSlot < kEndPosModelIndex)
|
||||||
{
|
{
|
||||||
|
@ -366,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rep3 = rep2;
|
rep3 = rep2;
|
||||||
rep2 = rep1;
|
rep2 = rep1;
|
||||||
rep1 = rep0;
|
rep1 = rep0;
|
||||||
|
@ -373,27 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
||||||
if (checkDicSize == 0)
|
if (checkDicSize == 0)
|
||||||
{
|
{
|
||||||
if (distance >= processedPos)
|
if (distance >= processedPos)
|
||||||
|
{
|
||||||
|
p->dicPos = dicPos;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (distance >= checkDicSize)
|
else if (distance >= checkDicSize)
|
||||||
|
{
|
||||||
|
p->dicPos = dicPos;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||||
/* state = kLiteralNextStates[state]; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len += kMatchMinLen;
|
len += kMatchMinLen;
|
||||||
|
|
||||||
if (limit == dicPos)
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
{
|
{
|
||||||
SizeT rem = limit - dicPos;
|
SizeT rem;
|
||||||
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
|
unsigned curLen;
|
||||||
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
|
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;
|
processedPos += curLen;
|
||||||
|
|
||||||
len -= curLen;
|
len -= curLen;
|
||||||
if (pos + curLen <= dicBufSize)
|
if (curLen <= dicBufSize - pos)
|
||||||
{
|
{
|
||||||
Byte *dest = dic + dicPos;
|
Byte *dest = dic + dicPos;
|
||||||
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)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);
|
while (dicPos < limit && buf < bufLimit);
|
||||||
|
|
||||||
NORMALIZE;
|
NORMALIZE;
|
||||||
|
|
||||||
p->buf = buf;
|
p->buf = buf;
|
||||||
p->range = range;
|
p->range = range;
|
||||||
p->code = code;
|
p->code = code;
|
||||||
|
@ -441,18 +520,20 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
||||||
SizeT dicPos = p->dicPos;
|
SizeT dicPos = p->dicPos;
|
||||||
SizeT dicBufSize = p->dicBufSize;
|
SizeT dicBufSize = p->dicBufSize;
|
||||||
unsigned len = p->remainLen;
|
unsigned len = p->remainLen;
|
||||||
UInt32 rep0 = p->reps[0];
|
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
|
||||||
if (limit - dicPos < len)
|
SizeT rem = limit - dicPos;
|
||||||
len = (unsigned)(limit - dicPos);
|
if (rem < len)
|
||||||
|
len = (unsigned)(rem);
|
||||||
|
|
||||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||||
p->checkDicSize = p->prop.dicSize;
|
p->checkDicSize = p->prop.dicSize;
|
||||||
|
|
||||||
p->processedPos += len;
|
p->processedPos += len;
|
||||||
p->remainLen -= 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++;
|
dicPos++;
|
||||||
}
|
}
|
||||||
p->dicPos = 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)
|
if (limit - p->dicPos > rem)
|
||||||
limit2 = p->dicPos + rem;
|
limit2 = p->dicPos + rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
|
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;
|
p->checkDicSize = p->prop.dicSize;
|
||||||
|
|
||||||
LzmaDec_WriteRem(p, limit);
|
LzmaDec_WriteRem(p, limit);
|
||||||
}
|
}
|
||||||
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
||||||
|
|
||||||
if (p->remainLen > kMatchSpecLenStart)
|
if (p->remainLen > kMatchSpecLenStart)
|
||||||
{
|
|
||||||
p->remainLen = kMatchSpecLenStart;
|
p->remainLen = kMatchSpecLenStart;
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,12 +580,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
||||||
UInt32 range = p->range;
|
UInt32 range = p->range;
|
||||||
UInt32 code = p->code;
|
UInt32 code = p->code;
|
||||||
const Byte *bufLimit = buf + inSize;
|
const Byte *bufLimit = buf + inSize;
|
||||||
CLzmaProb *probs = p->probs;
|
const CLzmaProb *probs = p->probs;
|
||||||
unsigned state = p->state;
|
unsigned state = p->state;
|
||||||
ELzmaDummy res;
|
ELzmaDummy res;
|
||||||
|
|
||||||
{
|
{
|
||||||
CLzmaProb *prob;
|
const CLzmaProb *prob;
|
||||||
UInt32 bound;
|
UInt32 bound;
|
||||||
unsigned ttt;
|
unsigned ttt;
|
||||||
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
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;
|
prob = probs + Literal;
|
||||||
if (p->checkDicSize != 0 || p->processedPos != 0)
|
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||||
prob += (LZMA_LIT_SIZE *
|
prob += ((UInt32)LZMA_LIT_SIZE *
|
||||||
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||||
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||||
|
|
||||||
if (state < kNumLitStates)
|
if (state < kNumLitStates)
|
||||||
{
|
{
|
||||||
|
@ -528,13 +611,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
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 offs = 0x100;
|
||||||
unsigned symbol = 1;
|
unsigned symbol = 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned bit;
|
unsigned bit;
|
||||||
CLzmaProb *probLit;
|
const CLzmaProb *probLit;
|
||||||
matchByte <<= 1;
|
matchByte <<= 1;
|
||||||
bit = (matchByte & offs);
|
bit = (matchByte & offs);
|
||||||
probLit = prob + offs + bit + symbol;
|
probLit = prob + offs + bit + symbol;
|
||||||
|
@ -604,7 +687,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
unsigned limit, offset;
|
unsigned limit, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
const CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0_CHECK(probLen)
|
IF_BIT_0_CHECK(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK;
|
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);
|
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||||
if (posSlot >= kStartPosModelIndex)
|
if (posSlot >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
int numDirectBits = ((posSlot >> 1) - 1);
|
unsigned numDirectBits = ((posSlot >> 1) - 1);
|
||||||
|
|
||||||
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
/* 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)
|
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||||
{
|
{
|
||||||
p->needFlush = 1;
|
p->needFlush = 1;
|
||||||
|
@ -714,8 +790,8 @@ void LzmaDec_Init(CLzmaDec *p)
|
||||||
|
|
||||||
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
||||||
{
|
{
|
||||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
|
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
|
||||||
UInt32 i;
|
SizeT i;
|
||||||
CLzmaProb *probs = p->probs;
|
CLzmaProb *probs = p->probs;
|
||||||
for (i = 0; i < numProbs; i++)
|
for (i = 0; i < numProbs; i++)
|
||||||
probs[i] = kBitModelTotal >> 1;
|
probs[i] = kBitModelTotal >> 1;
|
||||||
|
@ -737,7 +813,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
||||||
{
|
{
|
||||||
int checkEndMarkNow;
|
int checkEndMarkNow;
|
||||||
|
|
||||||
if (p->needFlush != 0)
|
if (p->needFlush)
|
||||||
{
|
{
|
||||||
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
||||||
p->tempBuf[p->tempBufSize++] = *src++;
|
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)
|
if (p->tempBuf[0] != 0)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
p->code =
|
||||||
LzmaDec_InitRc(p, p->tempBuf);
|
((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;
|
p->tempBufSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -833,7 +914,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
||||||
p->buf = p->tempBuf;
|
p->buf = p->tempBuf;
|
||||||
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
||||||
return SZ_ERROR_DATA;
|
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;
|
(*srcLen) += lookAhead;
|
||||||
src += lookAhead;
|
src += lookAhead;
|
||||||
inSize -= 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)
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->probs);
|
alloc->Free(alloc, p->probs);
|
||||||
p->probs = 0;
|
p->probs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->dic);
|
alloc->Free(alloc, p->dic);
|
||||||
p->dic = 0;
|
p->dic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
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)
|
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
||||||
if (p->probs == 0 || numProbs != p->numProbs)
|
if (!p->probs || numProbs != p->numProbs)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
||||||
p->numProbs = numProbs;
|
p->numProbs = numProbs;
|
||||||
if (p->probs == 0)
|
if (!p->probs)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
|
@ -958,12 +1048,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
|
||||||
SizeT dicBufSize;
|
SizeT dicBufSize;
|
||||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
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);
|
LzmaDec_FreeDict(p, alloc);
|
||||||
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
||||||
if (p->dic == 0)
|
if (!p->dic)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
@ -980,28 +1080,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||||
{
|
{
|
||||||
CLzmaDec p;
|
CLzmaDec p;
|
||||||
SRes res;
|
SRes res;
|
||||||
SizeT inSize = *srcLen;
|
SizeT outSize = *destLen, inSize = *srcLen;
|
||||||
SizeT outSize = *destLen;
|
*destLen = *srcLen = 0;
|
||||||
*srcLen = *destLen = 0;
|
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||||
if (inSize < RC_INIT_SIZE)
|
if (inSize < RC_INIT_SIZE)
|
||||||
return SZ_ERROR_INPUT_EOF;
|
return SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
LzmaDec_Construct(&p);
|
LzmaDec_Construct(&p);
|
||||||
res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
|
RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
|
||||||
if (res != 0)
|
|
||||||
return res;
|
|
||||||
p.dic = dest;
|
p.dic = dest;
|
||||||
p.dicBufSize = outSize;
|
p.dicBufSize = outSize;
|
||||||
|
|
||||||
LzmaDec_Init(&p);
|
LzmaDec_Init(&p);
|
||||||
|
|
||||||
*srcLen = inSize;
|
*srcLen = inSize;
|
||||||
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
|
||||||
|
*destLen = p.dicPos;
|
||||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||||
res = SZ_ERROR_INPUT_EOF;
|
res = SZ_ERROR_INPUT_EOF;
|
||||||
|
|
||||||
(*destLen) = p.dicPos;
|
|
||||||
LzmaDec_FreeProbs(&p, alloc);
|
LzmaDec_FreeProbs(&p, alloc);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
/* LzmaDec.h -- LZMA Decoder
|
/* LzmaDec.h -- LZMA Decoder
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2013-01-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMADEC_H
|
#ifndef __LZMA_DEC_H
|
||||||
#define __LZMADEC_H
|
#define __LZMA_DEC_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
/* #define _LZMA_PROB32 */
|
/* #define _LZMA_PROB32 */
|
||||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
/* _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,
|
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||||
ELzmaStatus *status, ISzAlloc *alloc);
|
ELzmaStatus *status, ISzAlloc *alloc);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,12 @@
|
||||||
/* LzmaEnc.h -- LZMA Encoder
|
/* LzmaEnc.h -- LZMA Encoder
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2013-01-18 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMAENC_H
|
#ifndef __LZMA_ENC_H
|
||||||
#define __LZMAENC_H
|
#define __LZMA_ENC_H
|
||||||
|
|
||||||
#include "Types.h"
|
#include "7zTypes.h"
|
||||||
|
|
||||||
|
EXTERN_C_BEGIN
|
||||||
|
|
||||||
#define LZMA_PROPS_SIZE 5
|
#define LZMA_PROPS_SIZE 5
|
||||||
|
|
||||||
|
@ -14,6 +16,8 @@ typedef struct _CLzmaEncProps
|
||||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||||
default = (1 << 24) */
|
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 lc; /* 0 <= lc <= 8, default = 3 */
|
||||||
int lp; /* 0 <= lp <= 4, default = 0 */
|
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||||
int pb; /* 0 <= pb <= 4, default = 2 */
|
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,
|
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||||
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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
|
/* Threads.c -- multithreading library
|
||||||
2008-08-05
|
2014-09-21 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#ifndef UNDER_CE
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "Threads.h"
|
#include "Threads.h"
|
||||||
#include <process.h>
|
|
||||||
|
|
||||||
static WRes GetError()
|
static WRes GetError()
|
||||||
{
|
{
|
||||||
|
@ -15,95 +18,76 @@ static WRes GetError()
|
||||||
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
||||||
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
||||||
|
|
||||||
static WRes MyCloseHandle(HANDLE *h)
|
WRes HandlePtr_Close(HANDLE *p)
|
||||||
{
|
{
|
||||||
if (*h != NULL)
|
if (*p != NULL)
|
||||||
if (!CloseHandle(*h))
|
if (!CloseHandle(*p))
|
||||||
return GetError();
|
return GetError();
|
||||||
*h = NULL;
|
*p = NULL;
|
||||||
return 0;
|
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 */
|
/* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
||||||
thread->handle =
|
|
||||||
/* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
|
#ifdef UNDER_CE
|
||||||
(HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
|
|
||||||
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
DWORD threadId;
|
||||||
return HandleToWRes(thread->handle);
|
*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)
|
*p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
|
||||||
return 1;
|
return HandleToWRes(*p);
|
||||||
return WaitObject(thread->handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WRes Thread_Close(CThread *thread)
|
static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||||
{
|
{ return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
|
||||||
return MyCloseHandle(&thread->handle);
|
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 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); }
|
|
||||||
|
|
||||||
WRes CriticalSection_Init(CCriticalSection *p)
|
WRes CriticalSection_Init(CCriticalSection *p)
|
||||||
{
|
{
|
||||||
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
||||||
|
#ifdef _MSC_VER
|
||||||
__try
|
__try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(p);
|
InitializeCriticalSection(p);
|
||||||
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
||||||
}
|
}
|
||||||
|
#ifdef _MSC_VER
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,68 +1,67 @@
|
||||||
/* Threads.h -- multithreading library
|
/* Threads.h -- multithreading library
|
||||||
2008-11-22 : Igor Pavlov : Public domain */
|
2013-11-12 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_THRESDS_H
|
#ifndef __7Z_THREADS_H
|
||||||
#define __7Z_THRESDS_H
|
#define __7Z_THREADS_H
|
||||||
|
|
||||||
#include "Types.h"
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _CThread
|
#include "7zTypes.h"
|
||||||
{
|
|
||||||
HANDLE handle;
|
|
||||||
} CThread;
|
|
||||||
|
|
||||||
#define Thread_Construct(thread) (thread)->handle = NULL
|
EXTERN_C_BEGIN
|
||||||
#define Thread_WasCreated(thread) ((thread)->handle != NULL)
|
|
||||||
|
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;
|
||||||
|
|
||||||
typedef unsigned THREAD_FUNC_RET_TYPE;
|
|
||||||
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
|
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
|
||||||
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
|
#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);
|
typedef HANDLE CEvent;
|
||||||
WRes Thread_Wait(CThread *thread);
|
|
||||||
WRes Thread_Close(CThread *thread);
|
|
||||||
|
|
||||||
typedef struct _CEvent
|
|
||||||
{
|
|
||||||
HANDLE handle;
|
|
||||||
} CEvent;
|
|
||||||
|
|
||||||
typedef CEvent CAutoResetEvent;
|
typedef CEvent CAutoResetEvent;
|
||||||
typedef CEvent CManualResetEvent;
|
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
|
typedef HANDLE CSemaphore;
|
||||||
#define Event_IsCreated(event) ((event)->handle != NULL)
|
#define Semaphore_Construct(p) (*p) = NULL
|
||||||
|
#define Semaphore_Close(p) HandlePtr_Close(p)
|
||||||
WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
|
#define Semaphore_Wait(p) Handle_WaitObject(*(p))
|
||||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
|
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
|
||||||
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);
|
|
||||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
||||||
WRes Semaphore_Release1(CSemaphore *p);
|
WRes Semaphore_Release1(CSemaphore *p);
|
||||||
WRes Semaphore_Wait(CSemaphore *p);
|
|
||||||
WRes Semaphore_Close(CSemaphore *p);
|
|
||||||
|
|
||||||
|
|
||||||
typedef CRITICAL_SECTION CCriticalSection;
|
typedef CRITICAL_SECTION CCriticalSection;
|
||||||
|
|
||||||
WRes CriticalSection_Init(CCriticalSection *p);
|
WRes CriticalSection_Init(CCriticalSection *p);
|
||||||
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
|
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
|
||||||
#define CriticalSection_Enter(p) EnterCriticalSection(p)
|
#define CriticalSection_Enter(p) EnterCriticalSection(p)
|
||||||
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
|
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
|
||||||
|
|
||||||
#endif
|
EXTERN_C_END
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,6 +1,133 @@
|
||||||
HISTORY of the LZMA SDK
|
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
|
4.65 2009-02-03
|
||||||
-------------------------
|
-------------------------
|
||||||
- Some minor fixes
|
- Some minor fixes
|
||||||
|
@ -41,7 +168,7 @@ HISTORY of the LZMA SDK
|
||||||
|
|
||||||
4.57 2007-12-12
|
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.
|
- Small changes for more compatibility with some C/C++ compilers.
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
Loading…
Reference in New Issue