| From 5ec5a236d1fe64b2c40075b6738b74bdf7e1acdc Mon Sep 17 00:00:00 2001 |
| From: Liming Gao <liming.gao@intel.com> |
| Date: Wed, 29 Aug 2018 08:51:28 +0800 |
| Subject: [PATCH] BaseTools Lzma: Update LZMA SDK version to 18.05 |
| |
| https://bugzilla.tianocore.org/show_bug.cgi?id=1006 |
| New formal release in https://www.7-zip.org/sdk.html is 18.05. |
| |
| Contributed-under: TianoCore Contribution Agreement 1.1 |
| Signed-off-by: Liming Gao <liming.gao@intel.com> |
| Reviewed-by: Star Zeng <star.zeng@intel.com> |
| --- |
| .../Source/C/LzmaCompress/LZMA-SDK-README.txt | 4 +- |
| .../Source/C/LzmaCompress/LzmaCompress.c | 8 +- |
| .../Source/C/LzmaCompress/Sdk/C/7zFile.c | 28 +- |
| .../Source/C/LzmaCompress/Sdk/C/7zFile.h | 8 +- |
| .../Source/C/LzmaCompress/Sdk/C/7zStream.c | 111 +- |
| .../Source/C/LzmaCompress/Sdk/C/7zTypes.h | 220 +- |
| .../Source/C/LzmaCompress/Sdk/C/7zVersion.h | 22 +- |
| BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c | 399 ++- |
| BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h | 20 +- |
| BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c | 4 +- |
| .../Source/C/LzmaCompress/Sdk/C/Compiler.h | 3 +- |
| .../Source/C/LzmaCompress/Sdk/C/CpuArch.h | 166 +- |
| .../Source/C/LzmaCompress/Sdk/C/LzFind.c | 163 +- |
| .../Source/C/LzmaCompress/Sdk/C/LzFind.h | 12 +- |
| .../Source/C/LzmaCompress/Sdk/C/LzFindMt.c | 67 +- |
| .../Source/C/LzmaCompress/Sdk/C/LzFindMt.h | 6 +- |
| .../Source/C/LzmaCompress/Sdk/C/LzmaDec.c | 401 +-- |
| .../Source/C/LzmaCompress/Sdk/C/LzmaDec.h | 47 +- |
| .../Source/C/LzmaCompress/Sdk/C/LzmaEnc.c | 2334 ++++++++++------- |
| .../Source/C/LzmaCompress/Sdk/C/LzmaEnc.h | 48 +- |
| .../Source/C/LzmaCompress/Sdk/C/Threads.c | 14 +- |
| .../Source/C/LzmaCompress/Sdk/C/Threads.h | 5 +- |
| .../C/LzmaCompress/Sdk/DOC/lzma-history.txt | 63 +- |
| .../C/LzmaCompress/Sdk/DOC/lzma-sdk.txt | 2 +- |
| 24 files changed, 2684 insertions(+), 1471 deletions(-) |
| |
| diff --git a/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt b/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt |
| index bc9e29fd9f..7cf967a774 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt |
| +++ b/BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt |
| @@ -1,3 +1,3 @@ |
| -LzmaCompress is based on the LZMA SDK 16.04. LZMA SDK 16.04
|
| -was placed in the public domain on 2016-10-04. It was
|
| +LzmaCompress is based on the LZMA SDK 18.05. LZMA SDK 18.05
|
| +was placed in the public domain on 2018-04-30. It was
|
| released on the http://www.7-zip.org/sdk.html website.
|
| diff --git a/BaseTools/Source/C/LzmaCompress/LzmaCompress.c b/BaseTools/Source/C/LzmaCompress/LzmaCompress.c |
| index ceb6a5bc77..da09b9f748 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/LzmaCompress.c |
| +++ b/BaseTools/Source/C/LzmaCompress/LzmaCompress.c |
| @@ -1,9 +1,9 @@ |
| /** @file
|
| LZMA Compress/Decompress tool (LzmaCompress)
|
|
|
| - Based on LZMA SDK 16.04:
|
| + Based on LZMA SDK 18.05:
|
| LzmaUtil.c -- Test application for LZMA compression
|
| - 2016-10-04 : Igor Pavlov : Public domain
|
| + 2018-04-30 : Igor Pavlov : Public domain
|
|
|
| Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
| This program and the accompanying materials
|
| @@ -341,14 +341,14 @@ int main2(int numArgs, const char *args[], char *rs) |
| if (!mQuietMode) {
|
| printf("Encoding\n");
|
| }
|
| - res = Encode(&outStream.s, &inStream.s, fileSize);
|
| + res = Encode(&outStream.vt, &inStream.vt, fileSize);
|
| }
|
| else
|
| {
|
| if (!mQuietMode) {
|
| printf("Decoding\n");
|
| }
|
| - res = Decode(&outStream.s, &inStream.s, fileSize);
|
| + res = Decode(&outStream.vt, &inStream.vt, fileSize);
|
| }
|
|
|
| File_Close(&outStream.file);
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c |
| index b2fed368a4..e486901e30 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c |
| @@ -1,5 +1,5 @@ |
| /* 7zFile.c -- File IO
|
| -2009-11-24 : Igor Pavlov : Public domain */
|
| +2017-04-03 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -213,7 +213,7 @@ WRes File_GetLength(CSzFile *p, UInt64 *length) |
| {
|
| #ifdef USE_WINDOWS_FILE
|
|
|
| - DWORD sizeHigh = 0;
|
| + DWORD sizeHigh;
|
| DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
|
| if (sizeLow == 0xFFFFFFFF)
|
| {
|
| @@ -238,49 +238,49 @@ WRes File_GetLength(CSzFile *p, UInt64 *length) |
|
|
| /* ---------- FileSeqInStream ---------- */
|
|
|
| -static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
|
| +static SRes FileSeqInStream_Read(const ISeqInStream *pp, void *buf, size_t *size)
|
| {
|
| - CFileSeqInStream *p = (CFileSeqInStream *)pp;
|
| + CFileSeqInStream *p = CONTAINER_FROM_VTBL(pp, CFileSeqInStream, vt);
|
| return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
|
| }
|
|
|
| void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
| {
|
| - p->s.Read = FileSeqInStream_Read;
|
| + p->vt.Read = FileSeqInStream_Read;
|
| }
|
|
|
|
|
| /* ---------- FileInStream ---------- */
|
|
|
| -static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
|
| +static SRes FileInStream_Read(const ISeekInStream *pp, void *buf, size_t *size)
|
| {
|
| - CFileInStream *p = (CFileInStream *)pp;
|
| + CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
|
| return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
|
| }
|
|
|
| -static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
| +static SRes FileInStream_Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
|
| {
|
| - CFileInStream *p = (CFileInStream *)pp;
|
| + CFileInStream *p = CONTAINER_FROM_VTBL(pp, CFileInStream, vt);
|
| return File_Seek(&p->file, pos, origin);
|
| }
|
|
|
| void FileInStream_CreateVTable(CFileInStream *p)
|
| {
|
| - p->s.Read = FileInStream_Read;
|
| - p->s.Seek = FileInStream_Seek;
|
| + p->vt.Read = FileInStream_Read;
|
| + p->vt.Seek = FileInStream_Seek;
|
| }
|
|
|
|
|
| /* ---------- FileOutStream ---------- */
|
|
|
| -static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
|
| +static size_t FileOutStream_Write(const ISeqOutStream *pp, const void *data, size_t size)
|
| {
|
| - CFileOutStream *p = (CFileOutStream *)pp;
|
| + CFileOutStream *p = CONTAINER_FROM_VTBL(pp, CFileOutStream, vt);
|
| File_Write(&p->file, data, &size);
|
| return size;
|
| }
|
|
|
| void FileOutStream_CreateVTable(CFileOutStream *p)
|
| {
|
| - p->s.Write = FileOutStream_Write;
|
| + p->vt.Write = FileOutStream_Write;
|
| }
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h |
| index d62a192609..7e263bea1b 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h |
| @@ -1,5 +1,5 @@ |
| /* 7zFile.h -- File IO
|
| -2013-01-18 : Igor Pavlov : Public domain */
|
| +2017-04-03 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __7Z_FILE_H
|
| #define __7Z_FILE_H
|
| @@ -54,7 +54,7 @@ WRes File_GetLength(CSzFile *p, UInt64 *length); |
|
|
| typedef struct
|
| {
|
| - ISeqInStream s;
|
| + ISeqInStream vt;
|
| CSzFile file;
|
| } CFileSeqInStream;
|
|
|
| @@ -63,7 +63,7 @@ void FileSeqInStream_CreateVTable(CFileSeqInStream *p); |
|
|
| typedef struct
|
| {
|
| - ISeekInStream s;
|
| + ISeekInStream vt;
|
| CSzFile file;
|
| } CFileInStream;
|
|
|
| @@ -72,7 +72,7 @@ void FileInStream_CreateVTable(CFileInStream *p); |
|
|
| typedef struct
|
| {
|
| - ISeqOutStream s;
|
| + ISeqOutStream vt;
|
| CSzFile file;
|
| } CFileOutStream;
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c |
| index 5a92d532cc..579741fadc 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c |
| @@ -1,5 +1,5 @@ |
| /* 7zStream.c -- 7z Stream functions
|
| -2013-11-12 : Igor Pavlov : Public domain */
|
| +2017-04-03 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -7,12 +7,12 @@ |
|
|
| #include "7zTypes.h"
|
|
|
| -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
| +SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
| {
|
| while (size != 0)
|
| {
|
| size_t processed = size;
|
| - RINOK(stream->Read(stream, buf, &processed));
|
| + RINOK(ISeqInStream_Read(stream, buf, &processed));
|
| if (processed == 0)
|
| return errorType;
|
| buf = (void *)((Byte *)buf + processed);
|
| @@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT |
| return SZ_OK;
|
| }
|
|
|
| -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
| +SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
|
| {
|
| return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
| }
|
|
|
| -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
| +SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
|
| {
|
| size_t processed = 1;
|
| - RINOK(stream->Read(stream, buf, &processed));
|
| + RINOK(ISeqInStream_Read(stream, buf, &processed));
|
| return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
| }
|
|
|
| -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
| +
|
| +
|
| +SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
|
| {
|
| Int64 t = offset;
|
| - return stream->Seek(stream, &t, SZ_SEEK_SET);
|
| + return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
|
| }
|
|
|
| -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
| +SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
|
| {
|
| const void *lookBuf;
|
| if (*size == 0)
|
| return SZ_OK;
|
| - RINOK(stream->Look(stream, &lookBuf, size));
|
| + RINOK(ILookInStream_Look(stream, &lookBuf, size));
|
| memcpy(buf, lookBuf, *size);
|
| - return stream->Skip(stream, *size);
|
| + return ILookInStream_Skip(stream, *size);
|
| }
|
|
|
| -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
| +SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
| {
|
| while (size != 0)
|
| {
|
| size_t processed = size;
|
| - RINOK(stream->Read(stream, buf, &processed));
|
| + RINOK(ILookInStream_Read(stream, buf, &processed));
|
| if (processed == 0)
|
| return errorType;
|
| buf = (void *)((Byte *)buf + processed);
|
| @@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro |
| return SZ_OK;
|
| }
|
|
|
| -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
| +SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
|
| {
|
| return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
| }
|
|
|
| -static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
| +
|
| +
|
| +#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
|
| +
|
| +static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
|
| {
|
| SRes res = SZ_OK;
|
| - CLookToRead *p = (CLookToRead *)pp;
|
| + GET_LookToRead2
|
| size_t size2 = p->size - p->pos;
|
| - if (size2 == 0 && *size > 0)
|
| + if (size2 == 0 && *size != 0)
|
| {
|
| p->pos = 0;
|
| - size2 = LookToRead_BUF_SIZE;
|
| - res = p->realStream->Read(p->realStream, p->buf, &size2);
|
| + p->size = 0;
|
| + size2 = p->bufSize;
|
| + res = ISeekInStream_Read(p->realStream, p->buf, &size2);
|
| p->size = size2;
|
| }
|
| - if (size2 < *size)
|
| + if (*size > size2)
|
| *size = size2;
|
| *buf = p->buf + p->pos;
|
| return res;
|
| }
|
|
|
| -static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
| +static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
|
| {
|
| SRes res = SZ_OK;
|
| - CLookToRead *p = (CLookToRead *)pp;
|
| + GET_LookToRead2
|
| size_t size2 = p->size - p->pos;
|
| - if (size2 == 0 && *size > 0)
|
| + if (size2 == 0 && *size != 0)
|
| {
|
| p->pos = 0;
|
| - if (*size > LookToRead_BUF_SIZE)
|
| - *size = LookToRead_BUF_SIZE;
|
| - res = p->realStream->Read(p->realStream, p->buf, size);
|
| + p->size = 0;
|
| + if (*size > p->bufSize)
|
| + *size = p->bufSize;
|
| + res = ISeekInStream_Read(p->realStream, p->buf, size);
|
| size2 = p->size = *size;
|
| }
|
| - if (size2 < *size)
|
| + if (*size > size2)
|
| *size = size2;
|
| *buf = p->buf + p->pos;
|
| return res;
|
| }
|
|
|
| -static SRes LookToRead_Skip(void *pp, size_t offset)
|
| +static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
|
| {
|
| - CLookToRead *p = (CLookToRead *)pp;
|
| + GET_LookToRead2
|
| p->pos += offset;
|
| return SZ_OK;
|
| }
|
|
|
| -static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
| +static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
|
| {
|
| - CLookToRead *p = (CLookToRead *)pp;
|
| + GET_LookToRead2
|
| size_t rem = p->size - p->pos;
|
| if (rem == 0)
|
| - return p->realStream->Read(p->realStream, buf, size);
|
| + return ISeekInStream_Read(p->realStream, buf, size);
|
| if (rem > *size)
|
| rem = *size;
|
| memcpy(buf, p->buf + p->pos, rem);
|
| @@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size) |
| return SZ_OK;
|
| }
|
|
|
| -static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
| +static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
|
| {
|
| - CLookToRead *p = (CLookToRead *)pp;
|
| + GET_LookToRead2
|
| p->pos = p->size = 0;
|
| - return p->realStream->Seek(p->realStream, pos, origin);
|
| + return ISeekInStream_Seek(p->realStream, pos, origin);
|
| }
|
|
|
| -void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
| +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
|
| {
|
| - p->s.Look = lookahead ?
|
| - LookToRead_Look_Lookahead :
|
| - LookToRead_Look_Exact;
|
| - p->s.Skip = LookToRead_Skip;
|
| - p->s.Read = LookToRead_Read;
|
| - p->s.Seek = LookToRead_Seek;
|
| + p->vt.Look = lookahead ?
|
| + LookToRead2_Look_Lookahead :
|
| + LookToRead2_Look_Exact;
|
| + p->vt.Skip = LookToRead2_Skip;
|
| + p->vt.Read = LookToRead2_Read;
|
| + p->vt.Seek = LookToRead2_Seek;
|
| }
|
|
|
| -void LookToRead_Init(CLookToRead *p)
|
| -{
|
| - p->pos = p->size = 0;
|
| -}
|
|
|
| -static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
| +
|
| +static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
|
| {
|
| - CSecToLook *p = (CSecToLook *)pp;
|
| + CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
|
| return LookInStream_LookRead(p->realStream, buf, size);
|
| }
|
|
|
| void SecToLook_CreateVTable(CSecToLook *p)
|
| {
|
| - p->s.Read = SecToLook_Read;
|
| + p->vt.Read = SecToLook_Read;
|
| }
|
|
|
| -static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
| +static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
|
| {
|
| - CSecToRead *p = (CSecToRead *)pp;
|
| - return p->realStream->Read(p->realStream, buf, size);
|
| + CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
|
| + return ILookInStream_Read(p->realStream, buf, size);
|
| }
|
|
|
| void SecToRead_CreateVTable(CSecToRead *p)
|
| {
|
| - p->s.Read = SecToRead_Read;
|
| + p->vt.Read = SecToRead_Read;
|
| }
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h |
| index 903047b10f..4977cdaa66 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h |
| @@ -1,5 +1,5 @@ |
| /* 7zTypes.h -- Basic types
|
| -2013-11-12 : Igor Pavlov : Public domain */
|
| +2017-07-17 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __7Z_TYPES_H
|
| #define __7Z_TYPES_H
|
| @@ -42,13 +42,23 @@ EXTERN_C_BEGIN |
|
|
| typedef int SRes;
|
|
|
| +
|
| #ifdef _WIN32
|
| +
|
| /* typedef DWORD WRes; */
|
| typedef unsigned WRes;
|
| +#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
|
| +
|
| #else
|
| +
|
| typedef int WRes;
|
| +#define MY__FACILITY_WIN32 7
|
| +#define MY__FACILITY__WRes MY__FACILITY_WIN32
|
| +#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
|
| +
|
| #endif
|
|
|
| +
|
| #ifndef RINOK
|
| #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
| #endif
|
| @@ -112,48 +122,72 @@ typedef int Bool; |
| #define MY_NO_INLINE
|
| #endif
|
|
|
| +#define MY_FORCE_INLINE __forceinline
|
| +
|
| #define MY_CDECL __cdecl
|
| #define MY_FAST_CALL __fastcall
|
|
|
| #else
|
|
|
| #define MY_NO_INLINE
|
| +#define MY_FORCE_INLINE
|
| #define MY_CDECL
|
| #define MY_FAST_CALL
|
|
|
| +/* inline keyword : for C++ / C99 */
|
| +
|
| +/* GCC, clang: */
|
| +/*
|
| +#if defined (__GNUC__) && (__GNUC__ >= 4)
|
| +#define MY_FORCE_INLINE __attribute__((always_inline))
|
| +#define MY_NO_INLINE __attribute__((noinline))
|
| +#endif
|
| +*/
|
| +
|
| #endif
|
|
|
|
|
| /* The following interfaces use first parameter as pointer to structure */
|
|
|
| -typedef struct
|
| +typedef struct IByteIn IByteIn;
|
| +struct IByteIn
|
| {
|
| - Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
| -} IByteIn;
|
| + Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
|
| +};
|
| +#define IByteIn_Read(p) (p)->Read(p)
|
|
|
| -typedef struct
|
| +
|
| +typedef struct IByteOut IByteOut;
|
| +struct IByteOut
|
| {
|
| - void (*Write)(void *p, Byte b);
|
| -} IByteOut;
|
| + void (*Write)(const IByteOut *p, Byte b);
|
| +};
|
| +#define IByteOut_Write(p, b) (p)->Write(p, b)
|
|
|
| -typedef struct
|
| +
|
| +typedef struct ISeqInStream ISeqInStream;
|
| +struct ISeqInStream
|
| {
|
| - SRes (*Read)(void *p, void *buf, size_t *size);
|
| + SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
|
| /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
| (output(*size) < input(*size)) is allowed */
|
| -} ISeqInStream;
|
| +};
|
| +#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
|
|
| /* it can return SZ_ERROR_INPUT_EOF */
|
| -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
| -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
| -SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
| +SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
|
| +SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
| +SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
|
|
|
| -typedef struct
|
| +
|
| +typedef struct ISeqOutStream ISeqOutStream;
|
| +struct ISeqOutStream
|
| {
|
| - size_t (*Write)(void *p, const void *buf, size_t size);
|
| + size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
|
| /* Returns: result - the number of actually written bytes.
|
| (result < size) means error */
|
| -} ISeqOutStream;
|
| +};
|
| +#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
|
|
|
| typedef enum
|
| {
|
| @@ -162,78 +196,162 @@ typedef enum |
| SZ_SEEK_END = 2
|
| } ESzSeek;
|
|
|
| -typedef struct
|
| +
|
| +typedef struct ISeekInStream ISeekInStream;
|
| +struct ISeekInStream
|
| {
|
| - SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
| - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
| -} ISeekInStream;
|
| + SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
| + SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
|
| +};
|
| +#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
| +#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
|
|
| -typedef struct
|
| +
|
| +typedef struct ILookInStream ILookInStream;
|
| +struct ILookInStream
|
| {
|
| - SRes (*Look)(void *p, const void **buf, size_t *size);
|
| + SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
|
| /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
| (output(*size) > input(*size)) is not allowed
|
| (output(*size) < input(*size)) is allowed */
|
| - SRes (*Skip)(void *p, size_t offset);
|
| + SRes (*Skip)(const ILookInStream *p, size_t offset);
|
| /* offset must be <= output(*size) of Look */
|
|
|
| - SRes (*Read)(void *p, void *buf, size_t *size);
|
| + SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
|
| /* reads directly (without buffer). It's same as ISeqInStream::Read */
|
| - SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
| -} ILookInStream;
|
| + SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
|
| +};
|
|
|
| -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
| -SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
| +#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
|
| +#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
|
| +#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
|
| +#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
|
| +
|
| +
|
| +SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
|
| +SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
|
|
|
| /* reads via ILookInStream::Read */
|
| -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
| -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
| +SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
| +SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
|
| +
|
|
|
| -#define LookToRead_BUF_SIZE (1 << 14)
|
|
|
| typedef struct
|
| {
|
| - ILookInStream s;
|
| - ISeekInStream *realStream;
|
| + ILookInStream vt;
|
| + const ISeekInStream *realStream;
|
| +
|
| size_t pos;
|
| - size_t size;
|
| - Byte buf[LookToRead_BUF_SIZE];
|
| -} CLookToRead;
|
| + size_t size; /* it's data size */
|
| +
|
| + /* the following variables must be set outside */
|
| + Byte *buf;
|
| + size_t bufSize;
|
| +} CLookToRead2;
|
| +
|
| +void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
|
| +
|
| +#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
|
|
|
| -void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
| -void LookToRead_Init(CLookToRead *p);
|
|
|
| typedef struct
|
| {
|
| - ISeqInStream s;
|
| - ILookInStream *realStream;
|
| + ISeqInStream vt;
|
| + const ILookInStream *realStream;
|
| } CSecToLook;
|
|
|
| void SecToLook_CreateVTable(CSecToLook *p);
|
|
|
| +
|
| +
|
| typedef struct
|
| {
|
| - ISeqInStream s;
|
| - ILookInStream *realStream;
|
| + ISeqInStream vt;
|
| + const ILookInStream *realStream;
|
| } CSecToRead;
|
|
|
| void SecToRead_CreateVTable(CSecToRead *p);
|
|
|
| -typedef struct
|
| +
|
| +typedef struct ICompressProgress ICompressProgress;
|
| +
|
| +struct ICompressProgress
|
| {
|
| - SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
| + SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
|
| /* Returns: result. (result != SZ_OK) means break.
|
| Value (UInt64)(Int64)-1 for size means unknown value. */
|
| -} ICompressProgress;
|
| +};
|
| +#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
|
|
|
| -typedef struct
|
| +
|
| +
|
| +typedef struct ISzAlloc ISzAlloc;
|
| +typedef const ISzAlloc * ISzAllocPtr;
|
| +
|
| +struct ISzAlloc
|
| {
|
| - void *(*Alloc)(void *p, size_t size);
|
| - void (*Free)(void *p, void *address); /* address can be 0 */
|
| -} ISzAlloc;
|
| + void *(*Alloc)(ISzAllocPtr p, size_t size);
|
| + void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
|
| +};
|
| +
|
| +#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
|
| +#define ISzAlloc_Free(p, a) (p)->Free(p, a)
|
| +
|
| +/* deprecated */
|
| +#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
|
| +#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
|
| +
|
| +
|
| +
|
| +
|
| +
|
| +#ifndef MY_offsetof
|
| + #ifdef offsetof
|
| + #define MY_offsetof(type, m) offsetof(type, m)
|
| + /*
|
| + #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
|
| + */
|
| + #else
|
| + #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
|
| + #endif
|
| +#endif
|
| +
|
| +
|
| +
|
| +#ifndef MY_container_of
|
| +
|
| +/*
|
| +#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
|
| +#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
|
| +#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
|
| +#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
|
| +*/
|
| +
|
| +/*
|
| + GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
|
| + GCC 3.4.4 : classes with constructor
|
| + GCC 4.8.1 : classes with non-public variable members"
|
| +*/
|
| +
|
| +#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
|
| +
|
| +
|
| +#endif
|
| +
|
| +#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
|
| +
|
| +/*
|
| +#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
| +*/
|
| +#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
|
| +
|
| +#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
|
| +/*
|
| +#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
|
| +*/
|
| +
|
|
|
| -#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
| -#define IAlloc_Free(p, a) (p)->Free((p), a)
|
|
|
| #ifdef _WIN32
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h |
| index acb67a94e5..ed3aa94270 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h |
| @@ -1,14 +1,21 @@ |
| -#define MY_VER_MAJOR 16
|
| -#define MY_VER_MINOR 04
|
| +#define MY_VER_MAJOR 18
|
| +#define MY_VER_MINOR 05
|
| #define MY_VER_BUILD 0
|
| -#define MY_VERSION_NUMBERS "16.04"
|
| -#define MY_VERSION "16.04"
|
| -#define MY_DATE "2016-10-04"
|
| +#define MY_VERSION_NUMBERS "18.05"
|
| +#define MY_VERSION MY_VERSION_NUMBERS
|
| +
|
| +#ifdef MY_CPU_NAME
|
| + #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
|
| +#else
|
| + #define MY_VERSION_CPU MY_VERSION
|
| +#endif
|
| +
|
| +#define MY_DATE "2018-04-30"
|
| #undef MY_COPYRIGHT
|
| #undef MY_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"
|
| +#define MY_COPYRIGHT_CR "Copyright (c) 1999-2018 Igor Pavlov"
|
|
|
| #ifdef USE_COPYRIGHT_CR
|
| #define MY_COPYRIGHT MY_COPYRIGHT_CR
|
| @@ -16,4 +23,5 @@ |
| #define MY_COPYRIGHT MY_COPYRIGHT_PD
|
| #endif
|
|
|
| -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
|
| +#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
|
| +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c |
| index 9f1d036afe..30b499e5ff 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c |
| @@ -1,8 +1,10 @@ |
| /* Alloc.c -- Memory allocation functions
|
| -2015-02-21 : Igor Pavlov : Public domain */
|
| +2018-04-27 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| +#include <stdio.h>
|
| +
|
| #ifdef _WIN32
|
| #include <windows.h>
|
| #endif
|
| @@ -14,20 +16,127 @@ |
|
|
| /* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
| #ifdef _SZ_ALLOC_DEBUG
|
| +
|
| #include <stdio.h>
|
| int g_allocCount = 0;
|
| int g_allocCountMid = 0;
|
| int g_allocCountBig = 0;
|
| +
|
| +
|
| +#define CONVERT_INT_TO_STR(charType, tempSize) \
|
| + unsigned char temp[tempSize]; unsigned i = 0; \
|
| + while (val >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(val % 10)); val /= 10; } \
|
| + *s++ = (charType)('0' + (unsigned)val); \
|
| + while (i != 0) { i--; *s++ = temp[i]; } \
|
| + *s = 0;
|
| +
|
| +static void ConvertUInt64ToString(UInt64 val, char *s)
|
| +{
|
| + CONVERT_INT_TO_STR(char, 24);
|
| +}
|
| +
|
| +#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
|
| +
|
| +static void ConvertUInt64ToHex(UInt64 val, char *s)
|
| +{
|
| + UInt64 v = val;
|
| + unsigned i;
|
| + for (i = 1;; i++)
|
| + {
|
| + v >>= 4;
|
| + if (v == 0)
|
| + break;
|
| + }
|
| + s[i] = 0;
|
| + do
|
| + {
|
| + unsigned t = (unsigned)(val & 0xF);
|
| + val >>= 4;
|
| + s[--i] = GET_HEX_CHAR(t);
|
| + }
|
| + while (i);
|
| +}
|
| +
|
| +#define DEBUG_OUT_STREAM stderr
|
| +
|
| +static void Print(const char *s)
|
| +{
|
| + fputs(s, DEBUG_OUT_STREAM);
|
| +}
|
| +
|
| +static void PrintAligned(const char *s, size_t align)
|
| +{
|
| + size_t len = strlen(s);
|
| + for(;;)
|
| + {
|
| + fputc(' ', DEBUG_OUT_STREAM);
|
| + if (len >= align)
|
| + break;
|
| + ++len;
|
| + }
|
| + Print(s);
|
| +}
|
| +
|
| +static void PrintLn()
|
| +{
|
| + Print("\n");
|
| +}
|
| +
|
| +static void PrintHex(UInt64 v, size_t align)
|
| +{
|
| + char s[32];
|
| + ConvertUInt64ToHex(v, s);
|
| + PrintAligned(s, align);
|
| +}
|
| +
|
| +static void PrintDec(UInt64 v, size_t align)
|
| +{
|
| + char s[32];
|
| + ConvertUInt64ToString(v, s);
|
| + PrintAligned(s, align);
|
| +}
|
| +
|
| +static void PrintAddr(void *p)
|
| +{
|
| + PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12);
|
| +}
|
| +
|
| +
|
| +#define PRINT_ALLOC(name, cnt, size, ptr) \
|
| + Print(name " "); \
|
| + PrintDec(cnt++, 10); \
|
| + PrintHex(size, 10); \
|
| + PrintAddr(ptr); \
|
| + PrintLn();
|
| +
|
| +#define PRINT_FREE(name, cnt, ptr) if (ptr) { \
|
| + Print(name " "); \
|
| + PrintDec(--cnt, 10); \
|
| + PrintAddr(ptr); \
|
| + PrintLn(); }
|
| +
|
| +#else
|
| +
|
| +#define PRINT_ALLOC(name, cnt, size, ptr)
|
| +#define PRINT_FREE(name, cnt, ptr)
|
| +#define Print(s)
|
| +#define PrintLn()
|
| +#define PrintHex(v, align)
|
| +#define PrintDec(v, align)
|
| +#define PrintAddr(p)
|
| +
|
| #endif
|
|
|
| +
|
| +
|
| void *MyAlloc(size_t size)
|
| {
|
| if (size == 0)
|
| - return 0;
|
| + return NULL;
|
| #ifdef _SZ_ALLOC_DEBUG
|
| {
|
| void *p = malloc(size);
|
| - fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
| + PRINT_ALLOC("Alloc ", g_allocCount, size, p);
|
| return p;
|
| }
|
| #else
|
| @@ -37,10 +146,8 @@ void *MyAlloc(size_t size) |
|
|
| void MyFree(void *address)
|
| {
|
| - #ifdef _SZ_ALLOC_DEBUG
|
| - if (address != 0)
|
| - fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
| - #endif
|
| + PRINT_FREE("Free ", g_allocCount, address);
|
| +
|
| free(address);
|
| }
|
|
|
| @@ -49,20 +156,18 @@ void MyFree(void *address) |
| void *MidAlloc(size_t size)
|
| {
|
| if (size == 0)
|
| - return 0;
|
| - #ifdef _SZ_ALLOC_DEBUG
|
| - fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
| - #endif
|
| - return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
| + return NULL;
|
| +
|
| + PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, NULL);
|
| +
|
| + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
|
| }
|
|
|
| void MidFree(void *address)
|
| {
|
| - #ifdef _SZ_ALLOC_DEBUG
|
| - if (address != 0)
|
| - fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
| - #endif
|
| - if (address == 0)
|
| + PRINT_FREE("Free-Mid", g_allocCountMid, address);
|
| +
|
| + if (!address)
|
| return;
|
| VirtualFree(address, 0, MEM_RELEASE);
|
| }
|
| @@ -79,10 +184,10 @@ typedef SIZE_T (WINAPI *GetLargePageMinimumP)(); |
| void SetLargePageSize()
|
| {
|
| #ifdef _7ZIP_LARGE_PAGES
|
| - SIZE_T size = 0;
|
| + SIZE_T size;
|
| GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
| GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
| - if (largePageMinimum == 0)
|
| + if (!largePageMinimum)
|
| return;
|
| size = largePageMinimum();
|
| if (size == 0 || (size & (size - 1)) != 0)
|
| @@ -95,31 +200,36 @@ void SetLargePageSize() |
| void *BigAlloc(size_t size)
|
| {
|
| if (size == 0)
|
| - return 0;
|
| - #ifdef _SZ_ALLOC_DEBUG
|
| - fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
| - #endif
|
| + return NULL;
|
| +
|
| + PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL);
|
|
|
| #ifdef _7ZIP_LARGE_PAGES
|
| - if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
| {
|
| - void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
| - MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
| - if (res != 0)
|
| - return res;
|
| + SIZE_T ps = g_LargePageSize;
|
| + if (ps != 0 && ps <= (1 << 30) && size > (ps / 2))
|
| + {
|
| + size_t size2;
|
| + ps--;
|
| + size2 = (size + ps) & ~ps;
|
| + if (size2 >= size)
|
| + {
|
| + void *res = VirtualAlloc(NULL, size2, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
| + if (res)
|
| + return res;
|
| + }
|
| + }
|
| }
|
| #endif
|
| - return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
| +
|
| + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
|
| }
|
|
|
| void BigFree(void *address)
|
| {
|
| - #ifdef _SZ_ALLOC_DEBUG
|
| - if (address != 0)
|
| - fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
| - #endif
|
| + PRINT_FREE("Free-Big", g_allocCountBig, address);
|
|
|
| - if (address == 0)
|
| + if (!address)
|
| return;
|
| VirtualFree(address, 0, MEM_RELEASE);
|
| }
|
| @@ -127,10 +237,219 @@ void BigFree(void *address) |
| #endif
|
|
|
|
|
| -static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
| -static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
| -ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
| +static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
|
| +static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MyFree(address); }
|
| +const ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
| +
|
| +static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return MidAlloc(size); }
|
| +static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); MidFree(address); }
|
| +const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree };
|
| +
|
| +static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
|
| +static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p); BigFree(address); }
|
| +const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
|
| +
|
| +
|
| +/*
|
| + uintptr_t : <stdint.h> C99 (optional)
|
| + : unsupported in VS6
|
| +*/
|
| +
|
| +#ifdef _WIN32
|
| + typedef UINT_PTR UIntPtr;
|
| +#else
|
| + /*
|
| + typedef uintptr_t UIntPtr;
|
| + */
|
| + typedef ptrdiff_t UIntPtr;
|
| +#endif
|
| +
|
| +
|
| +#define ADJUST_ALLOC_SIZE 0
|
| +/*
|
| +#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1)
|
| +*/
|
| +/*
|
| + Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if
|
| + MyAlloc() can return address that is NOT multiple of sizeof(void *).
|
| +*/
|
| +
|
| +
|
| +/*
|
| +#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1))))
|
| +*/
|
| +#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1))))
|
| +
|
| +#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align)
|
| +
|
| +
|
| +#if (_POSIX_C_SOURCE >= 200112L) && !defined(_WIN32)
|
| + #define USE_posix_memalign
|
| +#endif
|
| +
|
| +/*
|
| + This posix_memalign() is for test purposes only.
|
| + We also need special Free() function instead of free(),
|
| + if this posix_memalign() is used.
|
| +*/
|
| +
|
| +/*
|
| +static int posix_memalign(void **ptr, size_t align, size_t size)
|
| +{
|
| + size_t newSize = size + align;
|
| + void *p;
|
| + void *pAligned;
|
| + *ptr = NULL;
|
| + if (newSize < size)
|
| + return 12; // ENOMEM
|
| + p = MyAlloc(newSize);
|
| + if (!p)
|
| + return 12; // ENOMEM
|
| + pAligned = MY_ALIGN_PTR_UP_PLUS(p, align);
|
| + ((void **)pAligned)[-1] = p;
|
| + *ptr = pAligned;
|
| + return 0;
|
| +}
|
| +*/
|
| +
|
| +/*
|
| + ALLOC_ALIGN_SIZE >= sizeof(void *)
|
| + ALLOC_ALIGN_SIZE >= cache_line_size
|
| +*/
|
| +
|
| +#define ALLOC_ALIGN_SIZE ((size_t)1 << 7)
|
| +
|
| +static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size)
|
| +{
|
| + #ifndef USE_posix_memalign
|
| +
|
| + void *p;
|
| + void *pAligned;
|
| + size_t newSize;
|
| + UNUSED_VAR(pp);
|
| +
|
| + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
|
| + block to prevent cache line sharing with another allocated blocks */
|
| +
|
| + newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE;
|
| + if (newSize < size)
|
| + return NULL;
|
| +
|
| + p = MyAlloc(newSize);
|
| +
|
| + if (!p)
|
| + return NULL;
|
| + pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE);
|
| +
|
| + Print(" size="); PrintHex(size, 8);
|
| + Print(" a_size="); PrintHex(newSize, 8);
|
| + Print(" ptr="); PrintAddr(p);
|
| + Print(" a_ptr="); PrintAddr(pAligned);
|
| + PrintLn();
|
| +
|
| + ((void **)pAligned)[-1] = p;
|
| +
|
| + return pAligned;
|
| +
|
| + #else
|
| +
|
| + void *p;
|
| + UNUSED_VAR(pp);
|
| + if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size))
|
| + return NULL;
|
| +
|
| + Print(" posix_memalign="); PrintAddr(p);
|
| + PrintLn();
|
| +
|
| + return p;
|
| +
|
| + #endif
|
| +}
|
| +
|
| +
|
| +static void SzAlignedFree(ISzAllocPtr pp, void *address)
|
| +{
|
| + UNUSED_VAR(pp);
|
| + #ifndef USE_posix_memalign
|
| + if (address)
|
| + MyFree(((void **)address)[-1]);
|
| + #else
|
| + free(address);
|
| + #endif
|
| +}
|
| +
|
| +
|
| +const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree };
|
| +
|
| +
|
| +
|
| +#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *))
|
| +
|
| +/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */
|
| +#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1]
|
| +/*
|
| +#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1]
|
| +*/
|
| +
|
| +static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size)
|
| +{
|
| + CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
|
| + void *adr;
|
| + void *pAligned;
|
| + size_t newSize;
|
| + size_t extra;
|
| + size_t alignSize = (size_t)1 << p->numAlignBits;
|
| +
|
| + if (alignSize < sizeof(void *))
|
| + alignSize = sizeof(void *);
|
| +
|
| + if (p->offset >= alignSize)
|
| + return NULL;
|
| +
|
| + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned
|
| + block to prevent cache line sharing with another allocated blocks */
|
| + extra = p->offset & (sizeof(void *) - 1);
|
| + newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE;
|
| + if (newSize < size)
|
| + return NULL;
|
|
|
| -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 };
|
| + adr = ISzAlloc_Alloc(p->baseAlloc, newSize);
|
| +
|
| + if (!adr)
|
| + return NULL;
|
| +
|
| + pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr +
|
| + alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset;
|
| +
|
| + PrintLn();
|
| + Print("- Aligned: ");
|
| + Print(" size="); PrintHex(size, 8);
|
| + Print(" a_size="); PrintHex(newSize, 8);
|
| + Print(" ptr="); PrintAddr(adr);
|
| + Print(" a_ptr="); PrintAddr(pAligned);
|
| + PrintLn();
|
| +
|
| + REAL_BLOCK_PTR_VAR(pAligned) = adr;
|
| +
|
| + return pAligned;
|
| +}
|
| +
|
| +
|
| +static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address)
|
| +{
|
| + if (address)
|
| + {
|
| + CAlignOffsetAlloc *p = CONTAINER_FROM_VTBL(pp, CAlignOffsetAlloc, vt);
|
| + PrintLn();
|
| + Print("- Aligned Free: ");
|
| + PrintLn();
|
| + ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address));
|
| + }
|
| +}
|
| +
|
| +
|
| +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p)
|
| +{
|
| + p->vt.Alloc = AlignOffsetAlloc_Alloc;
|
| + p->vt.Free = AlignOffsetAlloc_Free;
|
| +}
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h |
| index 73b282a071..3d796e5eee 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h |
| @@ -1,5 +1,5 @@ |
| /* Alloc.h -- Memory allocation functions
|
| -2015-02-21 : Igor Pavlov : Public domain */
|
| +2018-02-19 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __COMMON_ALLOC_H
|
| #define __COMMON_ALLOC_H
|
| @@ -29,8 +29,22 @@ void BigFree(void *address); |
|
|
| #endif
|
|
|
| -extern ISzAlloc g_Alloc;
|
| -extern ISzAlloc g_BigAlloc;
|
| +extern const ISzAlloc g_Alloc;
|
| +extern const ISzAlloc g_BigAlloc;
|
| +extern const ISzAlloc g_MidAlloc;
|
| +extern const ISzAlloc g_AlignedAlloc;
|
| +
|
| +
|
| +typedef struct
|
| +{
|
| + ISzAlloc vt;
|
| + ISzAllocPtr baseAlloc;
|
| + unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
|
| + size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
|
| +} CAlignOffsetAlloc;
|
| +
|
| +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
|
| +
|
|
|
| EXTERN_C_END
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c |
| index 8dd3ed48d9..a6463c63ba 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c |
| @@ -1,5 +1,5 @@ |
| /* Bra86.c -- Converter for x86 code (BCJ)
|
| -2013-11-12 : Igor Pavlov : Public domain */
|
| +2017-04-03 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding |
| else
|
| {
|
| mask >>= (unsigned)d;
|
| - if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
|
| + if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
|
| {
|
| mask = (mask >> 1) | 4;
|
| pos++;
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h |
| index de8fab3749..c788648cd2 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h |
| @@ -1,5 +1,5 @@ |
| /* Compiler.h
|
| -2015-08-02 : Igor Pavlov : Public domain */
|
| +2017-04-03 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __7Z_COMPILER_H
|
| #define __7Z_COMPILER_H
|
| @@ -21,6 +21,7 @@ |
| #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 : 4714) // function marked as __forceinline not inlined
|
| #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
| #endif
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h |
| index ef6083c3b8..7fb27282c7 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h |
| @@ -1,5 +1,5 @@ |
| /* CpuArch.h -- CPU specific code
|
| -2016-06-09: Igor Pavlov : Public domain */
|
| +2017-09-04 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __CPU_ARCH_H
|
| #define __CPU_ARCH_H
|
| @@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl |
| MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
| */
|
|
|
| -#if defined(_M_X64) \
|
| - || defined(_M_AMD64) \
|
| - || defined(__x86_64__) \
|
| - || defined(__AMD64__) \
|
| - || defined(__amd64__)
|
| +#if defined(_M_X64) \
|
| + || defined(_M_AMD64) \
|
| + || defined(__x86_64__) \
|
| + || defined(__AMD64__) \
|
| + || defined(__amd64__)
|
| #define MY_CPU_AMD64
|
| + #ifdef __ILP32__
|
| + #define MY_CPU_NAME "x32"
|
| + #else
|
| + #define MY_CPU_NAME "x64"
|
| + #endif
|
| + #define MY_CPU_64BIT
|
| #endif
|
|
|
| -#if defined(MY_CPU_AMD64) \
|
| - || defined(_M_IA64) \
|
| - || defined(__AARCH64EL__) \
|
| - || defined(__AARCH64EB__)
|
| +
|
| +#if defined(_M_IX86) \
|
| + || defined(__i386__)
|
| + #define MY_CPU_X86
|
| + #define MY_CPU_NAME "x86"
|
| + #define MY_CPU_32BIT
|
| +#endif
|
| +
|
| +
|
| +#if defined(_M_ARM64) \
|
| + || defined(__AARCH64EL__) \
|
| + || defined(__AARCH64EB__) \
|
| + || defined(__aarch64__)
|
| + #define MY_CPU_ARM64
|
| + #define MY_CPU_NAME "arm64"
|
| #define MY_CPU_64BIT
|
| #endif
|
|
|
| -#if defined(_M_IX86) || defined(__i386__)
|
| -#define MY_CPU_X86
|
| +
|
| +#if defined(_M_ARM) \
|
| + || defined(_M_ARM_NT) \
|
| + || defined(_M_ARMT) \
|
| + || defined(__arm__) \
|
| + || defined(__thumb__) \
|
| + || defined(__ARMEL__) \
|
| + || defined(__ARMEB__) \
|
| + || defined(__THUMBEL__) \
|
| + || defined(__THUMBEB__)
|
| + #define MY_CPU_ARM
|
| + #define MY_CPU_NAME "arm"
|
| + #define MY_CPU_32BIT
|
| #endif
|
|
|
| -#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
| -#define MY_CPU_X86_OR_AMD64
|
| +
|
| +#if defined(_M_IA64) \
|
| + || defined(__ia64__)
|
| + #define MY_CPU_IA64
|
| + #define MY_CPU_NAME "ia64"
|
| + #define MY_CPU_64BIT
|
| #endif
|
|
|
| -#if defined(MY_CPU_X86) \
|
| - || defined(_M_ARM) \
|
| - || defined(__ARMEL__) \
|
| - || defined(__THUMBEL__) \
|
| - || defined(__ARMEB__) \
|
| - || defined(__THUMBEB__)
|
| +
|
| +#if defined(__mips64) \
|
| + || defined(__mips64__) \
|
| + || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
|
| + #define MY_CPU_NAME "mips64"
|
| + #define MY_CPU_64BIT
|
| +#elif defined(__mips__)
|
| + #define MY_CPU_NAME "mips"
|
| + /* #define MY_CPU_32BIT */
|
| +#endif
|
| +
|
| +
|
| +#if defined(__ppc64__) \
|
| + || defined(__powerpc64__)
|
| + #ifdef __ILP32__
|
| + #define MY_CPU_NAME "ppc64-32"
|
| + #else
|
| + #define MY_CPU_NAME "ppc64"
|
| + #endif
|
| + #define MY_CPU_64BIT
|
| +#elif defined(__ppc__) \
|
| + || defined(__powerpc__)
|
| + #define MY_CPU_NAME "ppc"
|
| #define MY_CPU_32BIT
|
| #endif
|
|
|
| -#if defined(_WIN32) && defined(_M_ARM)
|
| -#define MY_CPU_ARM_LE
|
| +
|
| +#if defined(__sparc64__)
|
| + #define MY_CPU_NAME "sparc64"
|
| + #define MY_CPU_64BIT
|
| +#elif defined(__sparc__)
|
| + #define MY_CPU_NAME "sparc"
|
| + /* #define MY_CPU_32BIT */
|
| #endif
|
|
|
| -#if defined(_WIN32) && defined(_M_IA64)
|
| -#define MY_CPU_IA64_LE
|
| +
|
| +#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
| +#define MY_CPU_X86_OR_AMD64
|
| #endif
|
|
|
| +
|
| +#ifdef _WIN32
|
| +
|
| + #ifdef MY_CPU_ARM
|
| + #define MY_CPU_ARM_LE
|
| + #endif
|
| +
|
| + #ifdef MY_CPU_ARM64
|
| + #define MY_CPU_ARM64_LE
|
| + #endif
|
| +
|
| + #ifdef _M_IA64
|
| + #define MY_CPU_IA64_LE
|
| + #endif
|
| +
|
| +#endif
|
| +
|
| +
|
| #if defined(MY_CPU_X86_OR_AMD64) \
|
| || defined(MY_CPU_ARM_LE) \
|
| + || defined(MY_CPU_ARM64_LE) \
|
| || defined(MY_CPU_IA64_LE) \
|
| || defined(__LITTLE_ENDIAN__) \
|
| || defined(__ARMEL__) \
|
| @@ -86,14 +160,37 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem |
| #define MY_CPU_BE
|
| #endif
|
|
|
| +
|
| #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
| -Stop_Compiling_Bad_Endian
|
| + #error Stop_Compiling_Bad_Endian
|
| +#endif
|
| +
|
| +
|
| +#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
|
| + #error Stop_Compiling_Bad_32_64_BIT
|
| #endif
|
|
|
|
|
| +#ifndef MY_CPU_NAME
|
| + #ifdef MY_CPU_LE
|
| + #define MY_CPU_NAME "LE"
|
| + #elif defined(MY_CPU_BE)
|
| + #define MY_CPU_NAME "BE"
|
| + #else
|
| + /*
|
| + #define MY_CPU_NAME ""
|
| + */
|
| + #endif
|
| +#endif
|
| +
|
| +
|
| +
|
| +
|
| +
|
| #ifdef MY_CPU_LE
|
| #if defined(MY_CPU_X86_OR_AMD64) \
|
| - /* || defined(__AARCH64EL__) */
|
| + || defined(MY_CPU_ARM64) \
|
| + || defined(__ARM_FEATURE_UNALIGNED)
|
| #define MY_CPU_LE_UNALIGN
|
| #endif
|
| #endif
|
| @@ -139,6 +236,11 @@ Stop_Compiling_Bad_Endian |
|
|
| #endif
|
|
|
| +#ifdef __has_builtin
|
| + #define MY__has_builtin(x) __has_builtin(x)
|
| +#else
|
| + #define MY__has_builtin(x) 0
|
| +#endif
|
|
|
| #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
|
|
|
| @@ -146,15 +248,21 @@ Stop_Compiling_Bad_Endian |
|
|
| #include <stdlib.h>
|
|
|
| +#pragma intrinsic(_byteswap_ushort)
|
| #pragma intrinsic(_byteswap_ulong)
|
| #pragma intrinsic(_byteswap_uint64)
|
| +
|
| +/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
|
| #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
| #define 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))
|
| +#elif defined(MY_CPU_LE_UNALIGN) && ( \
|
| + (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|
| + || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
|
|
|
| +/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
|
| #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
|
| #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
|
|
|
| @@ -179,10 +287,14 @@ Stop_Compiling_Bad_Endian |
| #endif
|
|
|
|
|
| +#ifndef GetBe16
|
| +
|
| #define GetBe16(p) ( (UInt16) ( \
|
| ((UInt16)((const Byte *)(p))[0] << 8) | \
|
| ((const Byte *)(p))[1] ))
|
|
|
| +#endif
|
| +
|
|
|
|
|
| #ifdef MY_CPU_X86_OR_AMD64
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c |
| index c335d363ce..6ea82a9b53 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c |
| @@ -1,5 +1,5 @@ |
| /* LzFind.c -- Match finder for LZ algorithms
|
| -2015-10-15 : Igor Pavlov : Public domain */
|
| +2017-06-10 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -16,18 +16,18 @@ |
|
|
| #define kStartMaxLen 3
|
|
|
| -static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
| +static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
|
| {
|
| if (!p->directInput)
|
| {
|
| - alloc->Free(alloc, p->bufferBase);
|
| + ISzAlloc_Free(alloc, p->bufferBase);
|
| p->bufferBase = NULL;
|
| }
|
| }
|
|
|
| /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
|
|
| -static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
| +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
|
| {
|
| UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
| if (p->directInput)
|
| @@ -39,7 +39,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a |
| {
|
| LzInWindow_Free(p, alloc);
|
| p->blockSize = blockSize;
|
| - p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
| + p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
|
| }
|
| return (p->bufferBase != NULL);
|
| }
|
| @@ -81,7 +81,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) |
| if (size == 0)
|
| return;
|
|
|
| - p->result = p->stream->Read(p->stream, dest, &size);
|
| + p->result = ISeqInStream_Read(p->stream, dest, &size);
|
| if (p->result != SZ_OK)
|
| return;
|
| if (size == 0)
|
| @@ -142,6 +142,7 @@ void MatchFinder_Construct(CMatchFinder *p) |
| p->bufferBase = NULL;
|
| p->directInput = 0;
|
| p->hash = NULL;
|
| + p->expectedDataSize = (UInt64)(Int64)-1;
|
| MatchFinder_SetDefaultSettings(p);
|
|
|
| for (i = 0; i < 256; i++)
|
| @@ -149,34 +150,34 @@ void MatchFinder_Construct(CMatchFinder *p) |
| UInt32 r = i;
|
| unsigned j;
|
| for (j = 0; j < 8; j++)
|
| - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
| + r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
|
| p->crc[i] = r;
|
| }
|
| }
|
|
|
| -static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
| +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
|
| {
|
| - alloc->Free(alloc, p->hash);
|
| + ISzAlloc_Free(alloc, p->hash);
|
| p->hash = NULL;
|
| }
|
|
|
| -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
| +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
|
| {
|
| MatchFinder_FreeThisClassMemory(p, alloc);
|
| LzInWindow_Free(p, alloc);
|
| }
|
|
|
| -static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
|
| +static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
|
| {
|
| size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
| if (sizeInBytes / sizeof(CLzRef) != num)
|
| return NULL;
|
| - return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
| + return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
|
| }
|
|
|
| int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
| UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
| - ISzAlloc *alloc)
|
| + ISzAllocPtr alloc)
|
| {
|
| UInt32 sizeReserv;
|
|
|
| @@ -208,7 +209,11 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, |
| hs = (1 << 16) - 1;
|
| else
|
| {
|
| - hs = historySize - 1;
|
| + hs = historySize;
|
| + if (hs > p->expectedDataSize)
|
| + hs = (UInt32)p->expectedDataSize;
|
| + if (hs != 0)
|
| + hs--;
|
| hs |= (hs >> 1);
|
| hs |= (hs >> 2);
|
| hs |= (hs >> 4);
|
| @@ -292,17 +297,33 @@ static void MatchFinder_SetLimits(CMatchFinder *p) |
| p->posLimit = p->pos + limit;
|
| }
|
|
|
| -void MatchFinder_Init_2(CMatchFinder *p, int readData)
|
| +
|
| +void MatchFinder_Init_LowHash(CMatchFinder *p)
|
| +{
|
| + size_t i;
|
| + CLzRef *items = p->hash;
|
| + size_t numItems = p->fixedHashSize;
|
| + for (i = 0; i < numItems; i++)
|
| + items[i] = kEmptyHashValue;
|
| +}
|
| +
|
| +
|
| +void MatchFinder_Init_HighHash(CMatchFinder *p)
|
| +{
|
| + size_t i;
|
| + CLzRef *items = p->hash + p->fixedHashSize;
|
| + size_t numItems = (size_t)p->hashMask + 1;
|
| + for (i = 0; i < numItems; i++)
|
| + items[i] = kEmptyHashValue;
|
| +}
|
| +
|
| +
|
| +void MatchFinder_Init_3(CMatchFinder *p, int readData)
|
| {
|
| - UInt32 i;
|
| - UInt32 *hash = p->hash;
|
| - UInt32 num = p->hashSizeSum;
|
| - for (i = 0; i < num; i++)
|
| - hash[i] = kEmptyHashValue;
|
| -
|
| p->cyclicBufferPos = 0;
|
| p->buffer = p->bufferBase;
|
| - p->pos = p->streamPos = p->cyclicBufferSize;
|
| + p->pos =
|
| + p->streamPos = p->cyclicBufferSize;
|
| p->result = SZ_OK;
|
| p->streamEndWasReached = 0;
|
|
|
| @@ -312,10 +333,14 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData) |
| MatchFinder_SetLimits(p);
|
| }
|
|
|
| +
|
| void MatchFinder_Init(CMatchFinder *p)
|
| {
|
| - MatchFinder_Init_2(p, True);
|
| + MatchFinder_Init_HighHash(p);
|
| + MatchFinder_Init_LowHash(p);
|
| + MatchFinder_Init_3(p, True);
|
| }
|
| +
|
|
|
| static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
| {
|
| @@ -558,10 +583,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
|
|
| d2 = pos - hash[h2];
|
|
|
| - curMatch = hash[kFix3HashSize + hv];
|
| + curMatch = (hash + kFix3HashSize)[hv];
|
|
|
| hash[h2] = pos;
|
| - hash[kFix3HashSize + hv] = pos;
|
| + (hash + kFix3HashSize)[hv] = pos;
|
|
|
| maxLen = 2;
|
| offset = 0;
|
| @@ -594,13 +619,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| pos = p->pos;
|
|
|
| d2 = pos - hash[ h2];
|
| - d3 = pos - hash[kFix3HashSize + h3];
|
| + d3 = pos - (hash + kFix3HashSize)[h3];
|
|
|
| - curMatch = hash[kFix4HashSize + hv];
|
| + curMatch = (hash + kFix4HashSize)[hv];
|
|
|
| hash[ h2] = pos;
|
| - hash[kFix3HashSize + h3] = pos;
|
| - hash[kFix4HashSize + hv] = pos;
|
| + (hash + kFix3HashSize)[h3] = pos;
|
| + (hash + kFix4HashSize)[hv] = pos;
|
|
|
| maxLen = 0;
|
| offset = 0;
|
| @@ -615,7 +640,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
| {
|
| maxLen = 3;
|
| - distances[offset + 1] = d3 - 1;
|
| + distances[(size_t)offset + 1] = d3 - 1;
|
| offset += 2;
|
| d2 = d3;
|
| }
|
| @@ -623,7 +648,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| if (offset != 0)
|
| {
|
| UPDATE_maxLen
|
| - distances[offset - 2] = maxLen;
|
| + distances[(size_t)offset - 2] = maxLen;
|
| if (maxLen == lenLimit)
|
| {
|
| SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
| @@ -650,15 +675,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| pos = p->pos;
|
|
|
| d2 = pos - hash[ h2];
|
| - d3 = pos - hash[kFix3HashSize + h3];
|
| - d4 = pos - hash[kFix4HashSize + h4];
|
| + d3 = pos - (hash + kFix3HashSize)[h3];
|
| + d4 = pos - (hash + kFix4HashSize)[h4];
|
|
|
| - curMatch = hash[kFix5HashSize + hv];
|
| + curMatch = (hash + kFix5HashSize)[hv];
|
|
|
| hash[ h2] = pos;
|
| - hash[kFix3HashSize + h3] = pos;
|
| - hash[kFix4HashSize + h4] = pos;
|
| - hash[kFix5HashSize + hv] = pos;
|
| + (hash + kFix3HashSize)[h3] = pos;
|
| + (hash + kFix4HashSize)[h4] = pos;
|
| + (hash + kFix5HashSize)[hv] = pos;
|
|
|
| maxLen = 0;
|
| offset = 0;
|
| @@ -691,7 +716,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| && *(cur - d4 + 3) == *(cur + 3))
|
| {
|
| maxLen = 4;
|
| - distances[offset + 1] = d4 - 1;
|
| + distances[(size_t)offset + 1] = d4 - 1;
|
| offset += 2;
|
| d2 = d4;
|
| }
|
| @@ -699,7 +724,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| if (offset != 0)
|
| {
|
| UPDATE_maxLen
|
| - distances[offset - 2] = maxLen;
|
| + distances[(size_t)offset - 2] = maxLen;
|
| if (maxLen == lenLimit)
|
| {
|
| SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
| @@ -726,13 +751,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| pos = p->pos;
|
|
|
| d2 = pos - hash[ h2];
|
| - d3 = pos - hash[kFix3HashSize + h3];
|
| + d3 = pos - (hash + kFix3HashSize)[h3];
|
|
|
| - curMatch = hash[kFix4HashSize + hv];
|
| + curMatch = (hash + kFix4HashSize)[hv];
|
|
|
| hash[ h2] = pos;
|
| - hash[kFix3HashSize + h3] = pos;
|
| - hash[kFix4HashSize + hv] = pos;
|
| + (hash + kFix3HashSize)[h3] = pos;
|
| + (hash + kFix4HashSize)[hv] = pos;
|
|
|
| maxLen = 0;
|
| offset = 0;
|
| @@ -747,7 +772,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
| {
|
| maxLen = 3;
|
| - distances[offset + 1] = d3 - 1;
|
| + distances[(size_t)offset + 1] = d3 - 1;
|
| offset += 2;
|
| d2 = d3;
|
| }
|
| @@ -755,7 +780,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| if (offset != 0)
|
| {
|
| UPDATE_maxLen
|
| - distances[offset - 2] = maxLen;
|
| + distances[(size_t)offset - 2] = maxLen;
|
| if (maxLen == lenLimit)
|
| {
|
| p->son[p->cyclicBufferPos] = curMatch;
|
| @@ -784,15 +809,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| pos = p->pos;
|
|
|
| d2 = pos - hash[ h2];
|
| - d3 = pos - hash[kFix3HashSize + h3];
|
| - d4 = pos - hash[kFix4HashSize + h4];
|
| + d3 = pos - (hash + kFix3HashSize)[h3];
|
| + d4 = pos - (hash + kFix4HashSize)[h4];
|
|
|
| - curMatch = hash[kFix5HashSize + hv];
|
| + curMatch = (hash + kFix5HashSize)[hv];
|
|
|
| hash[ h2] = pos;
|
| - hash[kFix3HashSize + h3] = pos;
|
| - hash[kFix4HashSize + h4] = pos;
|
| - hash[kFix5HashSize + hv] = pos;
|
| + (hash + kFix3HashSize)[h3] = pos;
|
| + (hash + kFix4HashSize)[h4] = pos;
|
| + (hash + kFix5HashSize)[hv] = pos;
|
|
|
| maxLen = 0;
|
| offset = 0;
|
| @@ -825,7 +850,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| && *(cur - d4 + 3) == *(cur + 3))
|
| {
|
| maxLen = 4;
|
| - distances[offset + 1] = d4 - 1;
|
| + distances[(size_t)offset + 1] = d4 - 1;
|
| offset += 2;
|
| d2 = d4;
|
| }
|
| @@ -833,7 +858,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
| if (offset != 0)
|
| {
|
| UPDATE_maxLen
|
| - distances[offset - 2] = maxLen;
|
| + distances[(size_t)offset - 2] = maxLen;
|
| if (maxLen == lenLimit)
|
| {
|
| p->son[p->cyclicBufferPos] = curMatch;
|
| @@ -897,9 +922,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
| SKIP_HEADER(3)
|
| HASH3_CALC;
|
| hash = p->hash;
|
| - curMatch = hash[kFix3HashSize + hv];
|
| + curMatch = (hash + kFix3HashSize)[hv];
|
| hash[h2] =
|
| - hash[kFix3HashSize + hv] = p->pos;
|
| + (hash + kFix3HashSize)[hv] = p->pos;
|
| SKIP_FOOTER
|
| }
|
| while (--num != 0);
|
| @@ -914,10 +939,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
| SKIP_HEADER(4)
|
| HASH4_CALC;
|
| hash = p->hash;
|
| - curMatch = hash[kFix4HashSize + hv];
|
| + curMatch = (hash + kFix4HashSize)[hv];
|
| hash[ h2] =
|
| - hash[kFix3HashSize + h3] =
|
| - hash[kFix4HashSize + hv] = p->pos;
|
| + (hash + kFix3HashSize)[h3] =
|
| + (hash + kFix4HashSize)[hv] = p->pos;
|
| SKIP_FOOTER
|
| }
|
| while (--num != 0);
|
| @@ -933,11 +958,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
| SKIP_HEADER(5)
|
| HASH5_CALC;
|
| hash = p->hash;
|
| - curMatch = hash[kFix5HashSize + hv];
|
| + curMatch = (hash + kFix5HashSize)[hv];
|
| hash[ h2] =
|
| - hash[kFix3HashSize + h3] =
|
| - hash[kFix4HashSize + h4] =
|
| - hash[kFix5HashSize + hv] = p->pos;
|
| + (hash + kFix3HashSize)[h3] =
|
| + (hash + kFix4HashSize)[h4] =
|
| + (hash + kFix5HashSize)[hv] = p->pos;
|
| SKIP_FOOTER
|
| }
|
| while (--num != 0);
|
| @@ -953,10 +978,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
| SKIP_HEADER(4)
|
| HASH4_CALC;
|
| hash = p->hash;
|
| - curMatch = hash[kFix4HashSize + hv];
|
| + curMatch = (hash + kFix4HashSize)[hv];
|
| hash[ h2] =
|
| - hash[kFix3HashSize + h3] =
|
| - hash[kFix4HashSize + hv] = p->pos;
|
| + (hash + kFix3HashSize)[h3] =
|
| + (hash + kFix4HashSize)[hv] = p->pos;
|
| p->son[p->cyclicBufferPos] = curMatch;
|
| MOVE_POS
|
| }
|
| @@ -973,11 +998,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
| SKIP_HEADER(5)
|
| HASH5_CALC;
|
| hash = p->hash;
|
| - curMatch = p->hash[kFix5HashSize + hv];
|
| + curMatch = hash + kFix5HashSize)[hv];
|
| hash[ h2] =
|
| - hash[kFix3HashSize + h3] =
|
| - hash[kFix4HashSize + h4] =
|
| - hash[kFix5HashSize + hv] = p->pos;
|
| + (hash + kFix3HashSize)[h3] =
|
| + (hash + kFix4HashSize)[h4] =
|
| + (hash + kFix5HashSize)[hv] = p->pos;
|
| p->son[p->cyclicBufferPos] = curMatch;
|
| MOVE_POS
|
| }
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h |
| index 2ff6673771..c77added7b 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h |
| @@ -1,5 +1,5 @@ |
| /* LzFind.h -- Match finder for LZ algorithms
|
| -2015-10-15 : Igor Pavlov : Public domain */
|
| +2017-06-10 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __LZ_FIND_H
|
| #define __LZ_FIND_H
|
| @@ -47,6 +47,8 @@ typedef struct _CMatchFinder |
| SRes result;
|
| UInt32 crc[256];
|
| size_t numRefs;
|
| +
|
| + UInt64 expectedDataSize;
|
| } CMatchFinder;
|
|
|
| #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
| @@ -71,8 +73,8 @@ void MatchFinder_Construct(CMatchFinder *p); |
| */
|
| int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
| UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
| - ISzAlloc *alloc);
|
| -void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
| + ISzAllocPtr alloc);
|
| +void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
|
| void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
|
| void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
|
|
| @@ -103,7 +105,9 @@ typedef struct _IMatchFinder |
|
|
| void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
|
|
| -void MatchFinder_Init_2(CMatchFinder *p, int readData);
|
| +void MatchFinder_Init_LowHash(CMatchFinder *p);
|
| +void MatchFinder_Init_HighHash(CMatchFinder *p);
|
| +void MatchFinder_Init_3(CMatchFinder *p, int readData);
|
| void MatchFinder_Init(CMatchFinder *p);
|
|
|
| UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c |
| index cb61e0953a..2563824fcd 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c |
| @@ -1,5 +1,5 @@ |
| /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
| -2015-10-15 : Igor Pavlov : Public domain */
|
| +2017-06-10 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -33,6 +33,8 @@ static void MtSync_GetNextBlock(CMtSync *p) |
|
|
| Event_Set(&p->canStart);
|
| Event_Wait(&p->wasStarted);
|
| +
|
| + // if (mt) MatchFinder_Init_LowHash(mt->MatchFinder);
|
| }
|
| else
|
| {
|
| @@ -155,6 +157,9 @@ static void HashThreadFunc(CMatchFinderMt *mt) |
| UInt32 numProcessedBlocks = 0;
|
| Event_Wait(&p->canStart);
|
| Event_Set(&p->wasStarted);
|
| +
|
| + MatchFinder_Init_HighHash(mt->MatchFinder);
|
| +
|
| for (;;)
|
| {
|
| if (p->exit)
|
| @@ -205,7 +210,7 @@ static void HashThreadFunc(CMatchFinderMt *mt) |
| if (num > kMtHashBlockSize - 2)
|
| num = kMtHashBlockSize - 2;
|
| mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
|
| - heads[0] += num;
|
| + heads[0] = 2 + num;
|
| }
|
| mf->pos += num;
|
| mf->buffer += num;
|
| @@ -443,13 +448,13 @@ void MatchFinderMt_Construct(CMatchFinderMt *p) |
| MtSync_Construct(&p->btSync);
|
| }
|
|
|
| -static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
| +static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc)
|
| {
|
| - alloc->Free(alloc, p->hashBuf);
|
| + ISzAlloc_Free(alloc, p->hashBuf);
|
| p->hashBuf = NULL;
|
| }
|
|
|
| -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
| +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
|
| {
|
| MtSync_Destruct(&p->hashSync);
|
| MtSync_Destruct(&p->btSync);
|
| @@ -472,7 +477,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p) |
| }
|
|
|
| SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
| - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
| + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
|
| {
|
| CMatchFinder *mf = p->MatchFinder;
|
| p->historySize = historySize;
|
| @@ -480,7 +485,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB |
| return SZ_ERROR_PARAM;
|
| if (!p->hashBuf)
|
| {
|
| - p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
| + p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
| if (!p->hashBuf)
|
| return SZ_ERROR_MEM;
|
| p->btBuf = p->hashBuf + kHashBufferSize;
|
| @@ -496,14 +501,18 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB |
| }
|
|
|
| /* Call it after ReleaseStream / SetStream */
|
| -void MatchFinderMt_Init(CMatchFinderMt *p)
|
| +static void MatchFinderMt_Init(CMatchFinderMt *p)
|
| {
|
| CMatchFinder *mf = p->MatchFinder;
|
| - p->btBufPos = p->btBufPosLimit = 0;
|
| - p->hashBufPos = p->hashBufPosLimit = 0;
|
| +
|
| + p->btBufPos =
|
| + p->btBufPosLimit = 0;
|
| + p->hashBufPos =
|
| + p->hashBufPosLimit = 0;
|
|
|
| /* Init without data reading. We don't want to read data in this thread */
|
| - MatchFinder_Init_2(mf, False);
|
| + MatchFinder_Init_3(mf, False);
|
| + MatchFinder_Init_LowHash(mf);
|
|
|
| p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
| p->btNumAvailBytes = 0;
|
| @@ -591,10 +600,10 @@ static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *dista |
| MT_HASH3_CALC
|
|
|
| curMatch2 = hash[ h2];
|
| - curMatch3 = hash[kFix3HashSize + h3];
|
| + curMatch3 = (hash + kFix3HashSize)[h3];
|
|
|
| hash[ h2] = lzPos;
|
| - hash[kFix3HashSize + h3] = lzPos;
|
| + (hash + kFix3HashSize)[h3] = lzPos;
|
|
|
| if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
| {
|
| @@ -627,12 +636,12 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distan |
| MT_HASH4_CALC
|
|
|
| curMatch2 = hash[ h2];
|
| - curMatch3 = hash[kFix3HashSize + h3];
|
| - curMatch4 = hash[kFix4HashSize + h4];
|
| + curMatch3 = (hash + kFix3HashSize)[h3];
|
| + curMatch4 = (hash + kFix4HashSize)[h4];
|
|
|
| hash[ h2] = lzPos;
|
| - hash[kFix3HashSize + h3] = lzPos;
|
| - hash[kFix4HashSize + h4] = lzPos;
|
| + (hash + kFix3HashSize)[h3] = lzPos;
|
| + (hash + kFix4HashSize)[h4] = lzPos;
|
|
|
| if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
| {
|
| @@ -684,8 +693,12 @@ static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances) |
| UInt32 i;
|
| for (i = 0; i < len; i += 2)
|
| {
|
| - *distances++ = *btBuf++;
|
| - *distances++ = *btBuf++;
|
| + UInt32 v0 = btBuf[0];
|
| + UInt32 v1 = btBuf[1];
|
| + btBuf += 2;
|
| + distances[0] = v0;
|
| + distances[1] = v1;
|
| + distances += 2;
|
| }
|
| }
|
| INCREASE_LZ_POS
|
| @@ -712,8 +725,12 @@ static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances) |
| distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
| do
|
| {
|
| - *distances2++ = *btBuf++;
|
| - *distances2++ = *btBuf++;
|
| + UInt32 v0 = btBuf[0];
|
| + UInt32 v1 = btBuf[1];
|
| + btBuf += 2;
|
| + distances2[0] = v0;
|
| + distances2[1] = v1;
|
| + distances2 += 2;
|
| }
|
| while ((len -= 2) != 0);
|
| len = (UInt32)(distances2 - (distances));
|
| @@ -746,7 +763,7 @@ static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num) |
| SKIP_HEADER_MT(3)
|
| UInt32 h2, h3;
|
| MT_HASH3_CALC
|
| - hash[kFix3HashSize + h3] =
|
| + (hash + kFix3HashSize)[h3] =
|
| hash[ h2] =
|
| p->lzPos;
|
| SKIP_FOOTER_MT
|
| @@ -758,8 +775,8 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num) |
| SKIP_HEADER_MT(4)
|
| UInt32 h2, h3, h4;
|
| MT_HASH4_CALC
|
| - hash[kFix4HashSize + h4] =
|
| - hash[kFix3HashSize + h3] =
|
| + (hash + kFix4HashSize)[h4] =
|
| + (hash + kFix3HashSize)[h3] =
|
| hash[ h2] =
|
| p->lzPos;
|
| SKIP_FOOTER_MT
|
| @@ -777,7 +794,7 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable) |
| {
|
| case 2:
|
| p->GetHeadsFunc = GetHeads2;
|
| - p->MixMatchesFunc = (Mf_Mix_Matches)0;
|
| + p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
|
| vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
|
| vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
|
| break;
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h |
| index 46b6924ad7..3d86c788f3 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h |
| @@ -1,5 +1,5 @@ |
| /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
| -2015-05-03 : Igor Pavlov : Public domain */
|
| +2017-04-03 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __LZ_FIND_MT_H
|
| #define __LZ_FIND_MT_H
|
| @@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt |
| } CMatchFinderMt;
|
|
|
| void MatchFinderMt_Construct(CMatchFinderMt *p);
|
| -void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
| +void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
|
| SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
| - UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
| + UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
|
| void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
| void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c |
| index 64f1164f3d..962b94bb63 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c |
| @@ -1,8 +1,9 @@ |
| /* LzmaDec.c -- LZMA Decoder
|
| -2016-05-16 : Igor Pavlov : Public domain */
|
| +2018-02-28 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| +/* #include "CpuArch.h" */
|
| #include "LzmaDec.h"
|
|
|
| #include <string.h>
|
| @@ -24,9 +25,16 @@ |
| #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
|
| { UPDATE_0(p); i = (i + i); A0; } else \
|
| { UPDATE_1(p); i = (i + i) + 1; A1; }
|
| -#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
|
|
|
| -#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
|
| +#define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); }
|
| +
|
| +#define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \
|
| + { UPDATE_0(p + i); A0; } else \
|
| + { UPDATE_1(p + i); A1; }
|
| +#define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; )
|
| +#define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; )
|
| +#define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; )
|
| +
|
| #define TREE_DECODE(probs, limit, i) \
|
| { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
|
|
|
| @@ -46,12 +54,15 @@ |
| i -= 0x40; }
|
| #endif
|
|
|
| -#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
|
| +#define NORMAL_LITER_DEC TREE_GET_BIT(prob, symbol)
|
| #define MATCHED_LITER_DEC \
|
| - matchByte <<= 1; \
|
| - bit = (matchByte & offs); \
|
| - probLit = prob + offs + bit + symbol; \
|
| - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
|
| + matchByte += matchByte; \
|
| + bit = offs; \
|
| + offs &= matchByte; \
|
| + probLit = prob + (offs + bit + symbol); \
|
| + GET_BIT2(probLit, symbol, offs ^= bit; , ;)
|
| +
|
| +
|
|
|
| #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
|
|
|
| @@ -66,25 +77,28 @@ |
| { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
|
|
|
|
|
| +#define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \
|
| + { UPDATE_0_CHECK; i += m; m += m; } else \
|
| + { UPDATE_1_CHECK; m += m; i += m; }
|
| +
|
| +
|
| #define kNumPosBitsMax 4
|
| #define kNumPosStatesMax (1 << kNumPosBitsMax)
|
|
|
| #define kLenNumLowBits 3
|
| #define kLenNumLowSymbols (1 << kLenNumLowBits)
|
| -#define kLenNumMidBits 3
|
| -#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
| #define kLenNumHighBits 8
|
| #define kLenNumHighSymbols (1 << kLenNumHighBits)
|
|
|
| -#define LenChoice 0
|
| -#define LenChoice2 (LenChoice + 1)
|
| -#define LenLow (LenChoice2 + 1)
|
| -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
| -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
| +#define LenLow 0
|
| +#define LenHigh (LenLow + 2 * (kNumPosStatesMax << kLenNumLowBits))
|
| #define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
|
|
| +#define LenChoice LenLow
|
| +#define LenChoice2 (LenLow + (1 << kLenNumLowBits))
|
|
|
| #define kNumStates 12
|
| +#define kNumStates2 16
|
| #define kNumLitStates 7
|
|
|
| #define kStartPosModelIndex 4
|
| @@ -98,54 +112,117 @@ |
| #define kAlignTableSize (1 << kNumAlignBits)
|
|
|
| #define kMatchMinLen 2
|
| -#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
|
| +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols * 2 + kLenNumHighSymbols)
|
|
|
| -#define IsMatch 0
|
| -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
| +/* External ASM code needs same CLzmaProb array layout. So don't change it. */
|
| +
|
| +/* (probs_1664) is faster and better for code size at some platforms */
|
| +/*
|
| +#ifdef MY_CPU_X86_OR_AMD64
|
| +*/
|
| +#define kStartOffset 1664
|
| +#define GET_PROBS p->probs_1664
|
| +/*
|
| +#define GET_PROBS p->probs + kStartOffset
|
| +#else
|
| +#define kStartOffset 0
|
| +#define GET_PROBS p->probs
|
| +#endif
|
| +*/
|
| +
|
| +#define SpecPos (-kStartOffset)
|
| +#define IsRep0Long (SpecPos + kNumFullDistances)
|
| +#define RepLenCoder (IsRep0Long + (kNumStates2 << kNumPosBitsMax))
|
| +#define LenCoder (RepLenCoder + kNumLenProbs)
|
| +#define IsMatch (LenCoder + kNumLenProbs)
|
| +#define Align (IsMatch + (kNumStates2 << kNumPosBitsMax))
|
| +#define IsRep (Align + kAlignTableSize)
|
| #define IsRepG0 (IsRep + kNumStates)
|
| #define IsRepG1 (IsRepG0 + kNumStates)
|
| #define IsRepG2 (IsRepG1 + kNumStates)
|
| -#define IsRep0Long (IsRepG2 + kNumStates)
|
| -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
| -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
| -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
| -#define LenCoder (Align + kAlignTableSize)
|
| -#define RepLenCoder (LenCoder + kNumLenProbs)
|
| -#define Literal (RepLenCoder + kNumLenProbs)
|
| -
|
| -#define LZMA_BASE_SIZE 1846
|
| -#define LZMA_LIT_SIZE 0x300
|
| +#define PosSlot (IsRepG2 + kNumStates)
|
| +#define Literal (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
| +#define NUM_BASE_PROBS (Literal + kStartOffset)
|
|
|
| -#if Literal != LZMA_BASE_SIZE
|
| -StopCompilingDueBUG
|
| +#if Align != 0 && kStartOffset != 0
|
| + #error Stop_Compiling_Bad_LZMA_kAlign
|
| #endif
|
|
|
| -#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
| +#if NUM_BASE_PROBS != 1984
|
| + #error Stop_Compiling_Bad_LZMA_PROBS
|
| +#endif
|
| +
|
| +
|
| +#define LZMA_LIT_SIZE 0x300
|
| +
|
| +#define LzmaProps_GetNumProbs(p) (NUM_BASE_PROBS + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
| +
|
| +
|
| +#define CALC_POS_STATE(processedPos, pbMask) (((processedPos) & (pbMask)) << 4)
|
| +#define COMBINED_PS_STATE (posState + state)
|
| +#define GET_LEN_STATE (posState)
|
|
|
| #define LZMA_DIC_MIN (1 << 12)
|
|
|
| -/* First LZMA-symbol is always decoded.
|
| -And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
|
| +/*
|
| +p->remainLen : shows status of LZMA decoder:
|
| + < kMatchSpecLenStart : normal remain
|
| + = kMatchSpecLenStart : finished
|
| + = kMatchSpecLenStart + 1 : need init range coder
|
| + = kMatchSpecLenStart + 2 : need init range coder and state
|
| +*/
|
| +
|
| +/* ---------- LZMA_DECODE_REAL ---------- */
|
| +/*
|
| +LzmaDec_DecodeReal_3() can be implemented in external ASM file.
|
| +3 - is the code compatibility version of that function for check at link time.
|
| +*/
|
| +
|
| +#define LZMA_DECODE_REAL LzmaDec_DecodeReal_3
|
| +
|
| +/*
|
| +LZMA_DECODE_REAL()
|
| +In:
|
| + RangeCoder is normalized
|
| + if (p->dicPos == limit)
|
| + {
|
| + LzmaDec_TryDummy() was called before to exclude LITERAL and MATCH-REP cases.
|
| + So first symbol can be only MATCH-NON-REP. And if that MATCH-NON-REP symbol
|
| + is not END_OF_PAYALOAD_MARKER, then function returns error code.
|
| + }
|
| +
|
| +Processing:
|
| + first LZMA symbol will be decoded in any case
|
| + All checks for limits are at the end of main loop,
|
| + It will decode new LZMA-symbols while (p->buf < bufLimit && dicPos < limit),
|
| + RangeCoder is still without last normalization when (p->buf < bufLimit) is being checked.
|
| +
|
| Out:
|
| + RangeCoder is normalized
|
| Result:
|
| SZ_OK - OK
|
| SZ_ERROR_DATA - Error
|
| p->remainLen:
|
| < kMatchSpecLenStart : normal remain
|
| = kMatchSpecLenStart : finished
|
| - = kMatchSpecLenStart + 1 : Flush marker (unused now)
|
| - = kMatchSpecLenStart + 2 : State Init Marker (unused now)
|
| */
|
|
|
| -static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
| -{
|
| - CLzmaProb *probs = p->probs;
|
|
|
| - unsigned state = p->state;
|
| +#ifdef _LZMA_DEC_OPT
|
| +
|
| +int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit);
|
| +
|
| +#else
|
| +
|
| +static
|
| +int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
| +{
|
| + CLzmaProb *probs = GET_PROBS;
|
| + unsigned state = (unsigned)p->state;
|
| UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
|
| unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
|
| - unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
|
| unsigned lc = p->prop.lc;
|
| + unsigned lpMask = ((unsigned)0x100 << p->prop.lp) - ((unsigned)0x100 >> lc);
|
|
|
| Byte *dic = p->dic;
|
| SizeT dicBufSize = p->dicBufSize;
|
| @@ -164,17 +241,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| CLzmaProb *prob;
|
| UInt32 bound;
|
| unsigned ttt;
|
| - unsigned posState = processedPos & pbMask;
|
| + unsigned posState = CALC_POS_STATE(processedPos, pbMask);
|
|
|
| - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
| + prob = probs + IsMatch + COMBINED_PS_STATE;
|
| IF_BIT_0(prob)
|
| {
|
| unsigned symbol;
|
| UPDATE_0(prob);
|
| prob = probs + Literal;
|
| if (processedPos != 0 || checkDicSize != 0)
|
| - prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
| - (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
| + prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc);
|
| processedPos++;
|
|
|
| if (state < kNumLitStates)
|
| @@ -240,13 +316,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| else
|
| {
|
| UPDATE_1(prob);
|
| + /*
|
| + // that case was checked before with kBadRepCode
|
| if (checkDicSize == 0 && processedPos == 0)
|
| return SZ_ERROR_DATA;
|
| + */
|
| prob = probs + IsRepG0 + state;
|
| IF_BIT_0(prob)
|
| {
|
| UPDATE_0(prob);
|
| - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
| + prob = probs + IsRep0Long + COMBINED_PS_STATE;
|
| IF_BIT_0(prob)
|
| {
|
| UPDATE_0(prob);
|
| @@ -299,7 +378,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| IF_BIT_0(probLen)
|
| {
|
| UPDATE_0(probLen);
|
| - probLen = prob + LenLow + (posState << kLenNumLowBits);
|
| + probLen = prob + LenLow + GET_LEN_STATE;
|
| offset = 0;
|
| lim = (1 << kLenNumLowBits);
|
| }
|
| @@ -310,15 +389,15 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| IF_BIT_0(probLen)
|
| {
|
| UPDATE_0(probLen);
|
| - probLen = prob + LenMid + (posState << kLenNumMidBits);
|
| + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
| offset = kLenNumLowSymbols;
|
| - lim = (1 << kLenNumMidBits);
|
| + lim = (1 << kLenNumLowBits);
|
| }
|
| else
|
| {
|
| UPDATE_1(probLen);
|
| probLen = prob + LenHigh;
|
| - offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
| + offset = kLenNumLowSymbols * 2;
|
| lim = (1 << kLenNumHighBits);
|
| }
|
| }
|
| @@ -331,7 +410,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| IF_BIT_0(probLen)
|
| {
|
| UPDATE_0(probLen);
|
| - probLen = prob + LenLow + (posState << kLenNumLowBits);
|
| + probLen = prob + LenLow + GET_LEN_STATE;
|
| len = 1;
|
| TREE_GET_BIT(probLen, len);
|
| TREE_GET_BIT(probLen, len);
|
| @@ -345,7 +424,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| IF_BIT_0(probLen)
|
| {
|
| UPDATE_0(probLen);
|
| - probLen = prob + LenMid + (posState << kLenNumMidBits);
|
| + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
| len = 1;
|
| TREE_GET_BIT(probLen, len);
|
| TREE_GET_BIT(probLen, len);
|
| @@ -356,7 +435,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| UPDATE_1(probLen);
|
| probLen = prob + LenHigh;
|
| TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
|
| - len += kLenNumLowSymbols + kLenNumMidSymbols;
|
| + len += kLenNumLowSymbols * 2;
|
| }
|
| }
|
| }
|
| @@ -376,16 +455,16 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| if (posSlot < kEndPosModelIndex)
|
| {
|
| distance <<= numDirectBits;
|
| - prob = probs + SpecPos + distance - posSlot - 1;
|
| + prob = probs + SpecPos;
|
| {
|
| - UInt32 mask = 1;
|
| - unsigned i = 1;
|
| + UInt32 m = 1;
|
| + distance++;
|
| do
|
| {
|
| - GET_BIT2(prob + i, i, ; , distance |= mask);
|
| - mask <<= 1;
|
| + REV_BIT_VAR(prob, distance, m);
|
| }
|
| - while (--numDirectBits != 0);
|
| + while (--numDirectBits);
|
| + distance -= m;
|
| }
|
| }
|
| else
|
| @@ -412,19 +491,20 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| }
|
| */
|
| }
|
| - while (--numDirectBits != 0);
|
| + while (--numDirectBits);
|
| prob = probs + Align;
|
| distance <<= kNumAlignBits;
|
| {
|
| unsigned i = 1;
|
| - GET_BIT2(prob + i, i, ; , distance |= 1);
|
| - GET_BIT2(prob + i, i, ; , distance |= 2);
|
| - GET_BIT2(prob + i, i, ; , distance |= 4);
|
| - GET_BIT2(prob + i, i, ; , distance |= 8);
|
| + REV_BIT_CONST(prob, i, 1);
|
| + REV_BIT_CONST(prob, i, 2);
|
| + REV_BIT_CONST(prob, i, 4);
|
| + REV_BIT_LAST (prob, i, 8);
|
| + distance |= i;
|
| }
|
| if (distance == (UInt32)0xFFFFFFFF)
|
| {
|
| - len += kMatchSpecLenStart;
|
| + len = kMatchSpecLenStart;
|
| state -= kNumStates;
|
| break;
|
| }
|
| @@ -435,20 +515,12 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
| rep2 = rep1;
|
| rep1 = rep0;
|
| rep0 = distance + 1;
|
| - if (checkDicSize == 0)
|
| - {
|
| - if (distance >= processedPos)
|
| - {
|
| - p->dicPos = dicPos;
|
| - return SZ_ERROR_DATA;
|
| - }
|
| - }
|
| - else if (distance >= checkDicSize)
|
| + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
| + if (distance >= (checkDicSize == 0 ? processedPos: checkDicSize))
|
| {
|
| p->dicPos = dicPos;
|
| return SZ_ERROR_DATA;
|
| }
|
| - state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
| }
|
|
|
| len += kMatchMinLen;
|
| @@ -511,6 +583,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte |
|
|
| return SZ_OK;
|
| }
|
| +#endif
|
|
|
| static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
| {
|
| @@ -519,7 +592,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) |
| Byte *dic = p->dic;
|
| SizeT dicPos = p->dicPos;
|
| SizeT dicBufSize = p->dicBufSize;
|
| - unsigned len = p->remainLen;
|
| + unsigned len = (unsigned)p->remainLen;
|
| SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
|
| SizeT rem = limit - dicPos;
|
| if (rem < len)
|
| @@ -540,6 +613,14 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) |
| }
|
| }
|
|
|
| +
|
| +#define kRange0 0xFFFFFFFF
|
| +#define kBound0 ((kRange0 >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1))
|
| +#define kBadRepCode (kBound0 + (((kRange0 - kBound0) >> kNumBitModelTotalBits) << (kNumBitModelTotalBits - 1)))
|
| +#if kBadRepCode != (0xC0000000 - 0x400)
|
| + #error Stop_Compiling_Bad_LZMA_Check
|
| +#endif
|
| +
|
| static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
| {
|
| do
|
| @@ -550,9 +631,13 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte |
| UInt32 rem = p->prop.dicSize - p->processedPos;
|
| if (limit - p->dicPos > rem)
|
| limit2 = p->dicPos + rem;
|
| +
|
| + if (p->processedPos == 0)
|
| + if (p->code >= kBadRepCode)
|
| + return SZ_ERROR_DATA;
|
| }
|
| -
|
| - RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
|
| +
|
| + RINOK(LZMA_DECODE_REAL(p, limit2, bufLimit));
|
|
|
| if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
|
| p->checkDicSize = p->prop.dicSize;
|
| @@ -561,9 +646,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte |
| }
|
| while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
|
|
| - if (p->remainLen > kMatchSpecLenStart)
|
| - p->remainLen = kMatchSpecLenStart;
|
| -
|
| return 0;
|
| }
|
|
|
| @@ -580,17 +662,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| UInt32 range = p->range;
|
| UInt32 code = p->code;
|
| const Byte *bufLimit = buf + inSize;
|
| - const CLzmaProb *probs = p->probs;
|
| - unsigned state = p->state;
|
| + const CLzmaProb *probs = GET_PROBS;
|
| + unsigned state = (unsigned)p->state;
|
| ELzmaDummy res;
|
|
|
| {
|
| const CLzmaProb *prob;
|
| UInt32 bound;
|
| unsigned ttt;
|
| - unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
| + unsigned posState = CALC_POS_STATE(p->processedPos, (1 << p->prop.pb) - 1);
|
|
|
| - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
|
| + prob = probs + IsMatch + COMBINED_PS_STATE;
|
| IF_BIT_0_CHECK(prob)
|
| {
|
| UPDATE_0_CHECK
|
| @@ -618,10 +700,11 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| {
|
| unsigned bit;
|
| const CLzmaProb *probLit;
|
| - matchByte <<= 1;
|
| - bit = (matchByte & offs);
|
| - probLit = prob + offs + bit + symbol;
|
| - GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
|
| + matchByte += matchByte;
|
| + bit = offs;
|
| + offs &= matchByte;
|
| + probLit = prob + (offs + bit + symbol);
|
| + GET_BIT2_CHECK(probLit, symbol, offs ^= bit; , ; )
|
| }
|
| while (symbol < 0x100);
|
| }
|
| @@ -648,7 +731,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| IF_BIT_0_CHECK(prob)
|
| {
|
| UPDATE_0_CHECK;
|
| - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
|
| + prob = probs + IsRep0Long + COMBINED_PS_STATE;
|
| IF_BIT_0_CHECK(prob)
|
| {
|
| UPDATE_0_CHECK;
|
| @@ -691,7 +774,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| IF_BIT_0_CHECK(probLen)
|
| {
|
| UPDATE_0_CHECK;
|
| - probLen = prob + LenLow + (posState << kLenNumLowBits);
|
| + probLen = prob + LenLow + GET_LEN_STATE;
|
| offset = 0;
|
| limit = 1 << kLenNumLowBits;
|
| }
|
| @@ -702,15 +785,15 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| IF_BIT_0_CHECK(probLen)
|
| {
|
| UPDATE_0_CHECK;
|
| - probLen = prob + LenMid + (posState << kLenNumMidBits);
|
| + probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits);
|
| offset = kLenNumLowSymbols;
|
| - limit = 1 << kLenNumMidBits;
|
| + limit = 1 << kLenNumLowBits;
|
| }
|
| else
|
| {
|
| UPDATE_1_CHECK;
|
| probLen = prob + LenHigh;
|
| - offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
| + offset = kLenNumLowSymbols * 2;
|
| limit = 1 << kLenNumHighBits;
|
| }
|
| }
|
| @@ -722,7 +805,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| {
|
| unsigned posSlot;
|
| prob = probs + PosSlot +
|
| - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
|
| + ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) <<
|
| kNumPosSlotBits);
|
| TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
| if (posSlot >= kStartPosModelIndex)
|
| @@ -733,7 +816,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
|
|
| if (posSlot < kEndPosModelIndex)
|
| {
|
| - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
|
| + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits);
|
| }
|
| else
|
| {
|
| @@ -745,17 +828,18 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
| code -= range & (((code - range) >> 31) - 1);
|
| /* if (code >= range) code -= range; */
|
| }
|
| - while (--numDirectBits != 0);
|
| + while (--numDirectBits);
|
| prob = probs + Align;
|
| numDirectBits = kNumAlignBits;
|
| }
|
| {
|
| unsigned i = 1;
|
| + unsigned m = 1;
|
| do
|
| {
|
| - GET_BIT_CHECK(prob + i, i);
|
| + REV_BIT_CHECK(prob, i, m);
|
| }
|
| - while (--numDirectBits != 0);
|
| + while (--numDirectBits);
|
| }
|
| }
|
| }
|
| @@ -768,18 +852,17 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS |
|
|
| void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
| {
|
| - p->needFlush = 1;
|
| - p->remainLen = 0;
|
| + p->remainLen = kMatchSpecLenStart + 1;
|
| p->tempBufSize = 0;
|
|
|
| if (initDic)
|
| {
|
| p->processedPos = 0;
|
| p->checkDicSize = 0;
|
| - p->needInitState = 1;
|
| + p->remainLen = kMatchSpecLenStart + 2;
|
| }
|
| if (initState)
|
| - p->needInitState = 1;
|
| + p->remainLen = kMatchSpecLenStart + 2;
|
| }
|
|
|
| void LzmaDec_Init(CLzmaDec *p)
|
| @@ -788,53 +871,54 @@ void LzmaDec_Init(CLzmaDec *p) |
| LzmaDec_InitDicAndState(p, True, True);
|
| }
|
|
|
| -static void LzmaDec_InitStateReal(CLzmaDec *p)
|
| -{
|
| - SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
|
| - SizeT i;
|
| - CLzmaProb *probs = p->probs;
|
| - for (i = 0; i < numProbs; i++)
|
| - probs[i] = kBitModelTotal >> 1;
|
| - p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
| - p->state = 0;
|
| - p->needInitState = 0;
|
| -}
|
|
|
| SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
| ELzmaFinishMode finishMode, ELzmaStatus *status)
|
| {
|
| SizeT inSize = *srcLen;
|
| (*srcLen) = 0;
|
| - LzmaDec_WriteRem(p, dicLimit);
|
|
|
| *status = LZMA_STATUS_NOT_SPECIFIED;
|
|
|
| - while (p->remainLen != kMatchSpecLenStart)
|
| + if (p->remainLen > kMatchSpecLenStart)
|
| {
|
| - int checkEndMarkNow;
|
| + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
| + p->tempBuf[p->tempBufSize++] = *src++;
|
| + if (p->tempBufSize != 0 && p->tempBuf[0] != 0)
|
| + return SZ_ERROR_DATA;
|
| + if (p->tempBufSize < RC_INIT_SIZE)
|
| + {
|
| + *status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
| + return SZ_OK;
|
| + }
|
| + p->code =
|
| + ((UInt32)p->tempBuf[1] << 24)
|
| + | ((UInt32)p->tempBuf[2] << 16)
|
| + | ((UInt32)p->tempBuf[3] << 8)
|
| + | ((UInt32)p->tempBuf[4]);
|
| + p->range = 0xFFFFFFFF;
|
| + p->tempBufSize = 0;
|
| +
|
| + if (p->remainLen > kMatchSpecLenStart + 1)
|
| + {
|
| + SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
|
| + SizeT i;
|
| + CLzmaProb *probs = p->probs;
|
| + for (i = 0; i < numProbs; i++)
|
| + probs[i] = kBitModelTotal >> 1;
|
| + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
|
| + p->state = 0;
|
| + }
|
|
|
| - if (p->needFlush)
|
| - {
|
| - for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
| - p->tempBuf[p->tempBufSize++] = *src++;
|
| - if (p->tempBufSize < RC_INIT_SIZE)
|
| - {
|
| - *status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
| - return SZ_OK;
|
| - }
|
| - if (p->tempBuf[0] != 0)
|
| - return SZ_ERROR_DATA;
|
| - p->code =
|
| - ((UInt32)p->tempBuf[1] << 24)
|
| - | ((UInt32)p->tempBuf[2] << 16)
|
| - | ((UInt32)p->tempBuf[3] << 8)
|
| - | ((UInt32)p->tempBuf[4]);
|
| - p->range = 0xFFFFFFFF;
|
| - p->needFlush = 0;
|
| - p->tempBufSize = 0;
|
| - }
|
| + p->remainLen = 0;
|
| + }
|
| +
|
| + LzmaDec_WriteRem(p, dicLimit);
|
| +
|
| + while (p->remainLen != kMatchSpecLenStart)
|
| + {
|
| + int checkEndMarkNow = 0;
|
|
|
| - checkEndMarkNow = 0;
|
| if (p->dicPos >= dicLimit)
|
| {
|
| if (p->remainLen == 0 && p->code == 0)
|
| @@ -855,9 +939,6 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr |
| checkEndMarkNow = 1;
|
| }
|
|
|
| - if (p->needInitState)
|
| - LzmaDec_InitStateReal(p);
|
| -
|
| if (p->tempBufSize == 0)
|
| {
|
| SizeT processed;
|
| @@ -930,11 +1011,14 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr |
| p->tempBufSize = 0;
|
| }
|
| }
|
| - if (p->code == 0)
|
| - *status = LZMA_STATUS_FINISHED_WITH_MARK;
|
| - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
| +
|
| + if (p->code != 0)
|
| + return SZ_ERROR_DATA;
|
| + *status = LZMA_STATUS_FINISHED_WITH_MARK;
|
| + return SZ_OK;
|
| }
|
|
|
| +
|
| SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
| {
|
| SizeT outSize = *destLen;
|
| @@ -975,19 +1059,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr |
| }
|
| }
|
|
|
| -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
| +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
|
| {
|
| - alloc->Free(alloc, p->probs);
|
| + ISzAlloc_Free(alloc, p->probs);
|
| p->probs = NULL;
|
| }
|
|
|
| -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
| +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
|
| {
|
| - alloc->Free(alloc, p->dic);
|
| + ISzAlloc_Free(alloc, p->dic);
|
| p->dic = NULL;
|
| }
|
|
|
| -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
| +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
|
| {
|
| LzmaDec_FreeProbs(p, alloc);
|
| LzmaDec_FreeDict(p, alloc);
|
| @@ -1011,29 +1095,30 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) |
| if (d >= (9 * 5 * 5))
|
| return SZ_ERROR_UNSUPPORTED;
|
|
|
| - p->lc = d % 9;
|
| + p->lc = (Byte)(d % 9);
|
| d /= 9;
|
| - p->pb = d / 5;
|
| - p->lp = d % 5;
|
| + p->pb = (Byte)(d / 5);
|
| + p->lp = (Byte)(d % 5);
|
|
|
| return SZ_OK;
|
| }
|
|
|
| -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
| +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
|
| {
|
| UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
| if (!p->probs || numProbs != p->numProbs)
|
| {
|
| LzmaDec_FreeProbs(p, alloc);
|
| - p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
| - p->numProbs = numProbs;
|
| + p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
| if (!p->probs)
|
| return SZ_ERROR_MEM;
|
| + p->probs_1664 = p->probs + 1664;
|
| + p->numProbs = numProbs;
|
| }
|
| return SZ_OK;
|
| }
|
|
|
| -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
| +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
|
| {
|
| CLzmaProps propNew;
|
| RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
| @@ -1042,7 +1127,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I |
| return SZ_OK;
|
| }
|
|
|
| -SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
| +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
|
| {
|
| CLzmaProps propNew;
|
| SizeT dicBufSize;
|
| @@ -1062,7 +1147,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll |
| if (!p->dic || dicBufSize != p->dicBufSize)
|
| {
|
| LzmaDec_FreeDict(p, alloc);
|
| - p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
| + p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
|
| if (!p->dic)
|
| {
|
| LzmaDec_FreeProbs(p, alloc);
|
| @@ -1076,7 +1161,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll |
|
|
| SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
| const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
| - ELzmaStatus *status, ISzAlloc *alloc)
|
| + ELzmaStatus *status, ISzAllocPtr alloc)
|
| {
|
| CLzmaDec p;
|
| SRes res;
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h |
| index 2633abeac9..28ce60c3ea 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h |
| @@ -1,5 +1,5 @@ |
| /* LzmaDec.h -- LZMA Decoder
|
| -2013-01-18 : Igor Pavlov : Public domain */
|
| +2018-04-21 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __LZMA_DEC_H
|
| #define __LZMA_DEC_H
|
| @@ -12,11 +12,13 @@ EXTERN_C_BEGIN |
| /* _LZMA_PROB32 can increase the speed on some CPUs,
|
| but memory usage for CLzmaDec::probs will be doubled in that case */
|
|
|
| +typedef
|
| #ifdef _LZMA_PROB32
|
| -#define CLzmaProb UInt32
|
| + UInt32
|
| #else
|
| -#define CLzmaProb UInt16
|
| + UInt16
|
| #endif
|
| + CLzmaProb;
|
|
|
|
|
| /* ---------- LZMA Properties ---------- */
|
| @@ -25,7 +27,10 @@ EXTERN_C_BEGIN |
|
|
| typedef struct _CLzmaProps
|
| {
|
| - unsigned lc, lp, pb;
|
| + Byte lc;
|
| + Byte lp;
|
| + Byte pb;
|
| + Byte _pad_;
|
| UInt32 dicSize;
|
| } CLzmaProps;
|
|
|
| @@ -47,32 +52,34 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); |
|
|
| typedef struct
|
| {
|
| + /* Don't change this structure. ASM code can use it. */
|
| CLzmaProps prop;
|
| CLzmaProb *probs;
|
| + CLzmaProb *probs_1664;
|
| Byte *dic;
|
| - const Byte *buf;
|
| - UInt32 range, code;
|
| - SizeT dicPos;
|
| SizeT dicBufSize;
|
| + SizeT dicPos;
|
| + const Byte *buf;
|
| + UInt32 range;
|
| + UInt32 code;
|
| UInt32 processedPos;
|
| UInt32 checkDicSize;
|
| - unsigned state;
|
| UInt32 reps[4];
|
| - unsigned remainLen;
|
| - int needFlush;
|
| - int needInitState;
|
| + UInt32 state;
|
| + UInt32 remainLen;
|
| +
|
| UInt32 numProbs;
|
| unsigned tempBufSize;
|
| Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
| } CLzmaDec;
|
|
|
| -#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
| +#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; }
|
|
|
| void LzmaDec_Init(CLzmaDec *p);
|
|
|
| /* There are two types of LZMA streams:
|
| - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
| - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
| + - Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
| + - Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
|
|
| typedef enum
|
| {
|
| @@ -129,11 +136,11 @@ LzmaDec_Allocate* can return: |
| SZ_ERROR_UNSUPPORTED - Unsupported properties
|
| */
|
|
|
| -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
| -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
| +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
|
| +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
|
|
|
| -SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
| -void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
| +SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
|
| +void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
|
|
|
| /* ---------- Dictionary Interface ---------- */
|
|
|
| @@ -142,7 +149,7 @@ void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); |
| You must work with CLzmaDec variables directly in this interface.
|
|
|
| STEPS:
|
| - LzmaDec_Constr()
|
| + LzmaDec_Construct()
|
| LzmaDec_Allocate()
|
| for (each new stream)
|
| {
|
| @@ -220,7 +227,7 @@ Returns: |
|
|
| SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
| const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
| - ELzmaStatus *status, ISzAlloc *alloc);
|
| + ELzmaStatus *status, ISzAllocPtr alloc);
|
|
|
| EXTERN_C_END
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c |
| index 462ca67565..bebe664d3e 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c |
| @@ -1,5 +1,5 @@ |
| /* LzmaEnc.c -- LZMA Encoder
|
| -2016-05-16 : Igor Pavlov : Public domain */
|
| +2018-04-29 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -23,17 +23,8 @@ |
| static unsigned g_STAT_OFFSET = 0;
|
| #endif
|
|
|
| -#define kMaxHistorySize ((UInt32)3 << 29)
|
| -/* #define kMaxHistorySize ((UInt32)7 << 29) */
|
| -
|
| -#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
|
| -
|
| -#define kBlockSize (9 << 10)
|
| -#define kUnpackBlockSize (1 << 18)
|
| -#define kMatchArraySize (1 << 21)
|
| -#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
|
| -
|
| -#define kNumMaxDirectBits (31)
|
| +#define kLzmaMaxHistorySize ((UInt32)3 << 29)
|
| +/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
|
|
|
| #define kNumTopBits 24
|
| #define kTopValue ((UInt32)1 << kNumTopBits)
|
| @@ -62,14 +53,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) |
| if (level < 0) level = 5;
|
| p->level = level;
|
|
|
| - if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
|
| + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26)));
|
| if (p->dictSize > p->reduceSize)
|
| {
|
| unsigned i;
|
| + UInt32 reduceSize = (UInt32)p->reduceSize;
|
| for (i = 11; i <= 30; i++)
|
| {
|
| - if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
|
| - if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
|
| + if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
|
| + if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
|
| }
|
| }
|
|
|
| @@ -110,9 +102,9 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) |
|
|
| #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
|
|
|
| -static UInt32 GetPosSlot1(UInt32 pos)
|
| +static unsigned GetPosSlot1(UInt32 pos)
|
| {
|
| - UInt32 res;
|
| + unsigned res;
|
| BSR2_RET(pos, res);
|
| return res;
|
| }
|
| @@ -145,18 +137,18 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos) |
|
|
| /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
|
| /*
|
| -#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
|
| +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
|
| (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
| res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
| */
|
|
|
| /*
|
| -#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
|
| +#define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
|
| (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
|
| res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
| */
|
|
|
| -#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
|
| +#define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
|
| res = p->g_FastPos[pos >> zz] + (zz * 2); }
|
|
|
| /*
|
| @@ -167,32 +159,32 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos) |
|
|
| #define GetPosSlot1(pos) p->g_FastPos[pos]
|
| #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
|
| -#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
|
| +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }
|
|
|
| #endif
|
|
|
|
|
| #define LZMA_NUM_REPS 4
|
|
|
| -typedef unsigned CState;
|
| +typedef UInt16 CState;
|
| +typedef UInt16 CExtra;
|
|
|
| typedef struct
|
| {
|
| UInt32 price;
|
| -
|
| CState state;
|
| - int prev1IsChar;
|
| - int prev2;
|
| -
|
| - UInt32 posPrev2;
|
| - UInt32 backPrev2;
|
| -
|
| - UInt32 posPrev;
|
| - UInt32 backPrev;
|
| - UInt32 backs[LZMA_NUM_REPS];
|
| + CExtra extra;
|
| + // 0 : normal
|
| + // 1 : LIT : MATCH
|
| + // > 1 : MATCH (extra-1) : LIT : REP0 (len)
|
| + UInt32 len;
|
| + UInt32 dist;
|
| + UInt32 reps[LZMA_NUM_REPS];
|
| } COptimal;
|
|
|
| +
|
| #define kNumOpts (1 << 12)
|
| +#define kPackReserve (1 + kNumOpts * 2)
|
|
|
| #define kNumLenToPosStates 4
|
| #define kNumPosSlotBits 6
|
| @@ -200,22 +192,21 @@ typedef struct |
| #define kDicLogSizeMax 32
|
| #define kDistTableSizeMax (kDicLogSizeMax * 2)
|
|
|
| -
|
| #define kNumAlignBits 4
|
| #define kAlignTableSize (1 << kNumAlignBits)
|
| #define kAlignMask (kAlignTableSize - 1)
|
|
|
| #define kStartPosModelIndex 4
|
| #define kEndPosModelIndex 14
|
| -#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
|
| -
|
| #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
|
|
| +typedef
|
| #ifdef _LZMA_PROB32
|
| -#define CLzmaProb UInt32
|
| + UInt32
|
| #else
|
| -#define CLzmaProb UInt16
|
| + UInt16
|
| #endif
|
| + CLzmaProb;
|
|
|
| #define LZMA_PB_MAX 4
|
| #define LZMA_LC_MAX 8
|
| @@ -223,15 +214,11 @@ typedef struct |
|
|
| #define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
|
|
|
| -
|
| #define kLenNumLowBits 3
|
| #define kLenNumLowSymbols (1 << kLenNumLowBits)
|
| -#define kLenNumMidBits 3
|
| -#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
| #define kLenNumHighBits 8
|
| #define kLenNumHighSymbols (1 << kLenNumHighBits)
|
| -
|
| -#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
|
| +#define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols)
|
|
|
| #define LZMA_MATCH_LEN_MIN 2
|
| #define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
|
| @@ -241,27 +228,23 @@ typedef struct |
|
|
| typedef struct
|
| {
|
| - CLzmaProb choice;
|
| - CLzmaProb choice2;
|
| - CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
|
| - CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
|
| + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)];
|
| CLzmaProb high[kLenNumHighSymbols];
|
| } CLenEnc;
|
|
|
|
|
| typedef struct
|
| {
|
| - CLenEnc p;
|
| - UInt32 tableSize;
|
| + unsigned tableSize;
|
| + unsigned counters[LZMA_NUM_PB_STATES_MAX];
|
| UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
|
| - UInt32 counters[LZMA_NUM_PB_STATES_MAX];
|
| } CLenPriceEnc;
|
|
|
|
|
| typedef struct
|
| {
|
| UInt32 range;
|
| - Byte cache;
|
| + unsigned cache;
|
| UInt64 low;
|
| UInt64 cacheSize;
|
| Byte *buf;
|
| @@ -277,48 +260,54 @@ typedef struct |
| {
|
| CLzmaProb *litProbs;
|
|
|
| - UInt32 state;
|
| + unsigned state;
|
| UInt32 reps[LZMA_NUM_REPS];
|
|
|
| - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
| + CLzmaProb posAlignEncoder[1 << kNumAlignBits];
|
| CLzmaProb isRep[kNumStates];
|
| CLzmaProb isRepG0[kNumStates];
|
| CLzmaProb isRepG1[kNumStates];
|
| CLzmaProb isRepG2[kNumStates];
|
| + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
| CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
|
|
| CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
|
| - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
|
| - CLzmaProb posAlignEncoder[1 << kNumAlignBits];
|
| + CLzmaProb posEncoders[kNumFullDistances];
|
|
|
| - CLenPriceEnc lenEnc;
|
| - CLenPriceEnc repLenEnc;
|
| + CLenEnc lenProbs;
|
| + CLenEnc repLenProbs;
|
| +
|
| } CSaveState;
|
|
|
|
|
| +typedef UInt32 CProbPrice;
|
| +
|
| +
|
| typedef struct
|
| {
|
| void *matchFinderObj;
|
| IMatchFinder matchFinder;
|
|
|
| - UInt32 optimumEndIndex;
|
| - UInt32 optimumCurrentIndex;
|
| + unsigned optCur;
|
| + unsigned optEnd;
|
|
|
| - UInt32 longestMatchLength;
|
| - UInt32 numPairs;
|
| + unsigned longestMatchLen;
|
| + unsigned numPairs;
|
| UInt32 numAvail;
|
|
|
| - UInt32 numFastBytes;
|
| - UInt32 additionalOffset;
|
| + unsigned state;
|
| + unsigned numFastBytes;
|
| + unsigned additionalOffset;
|
| UInt32 reps[LZMA_NUM_REPS];
|
| - UInt32 state;
|
| + unsigned lpMask, pbMask;
|
| + CLzmaProb *litProbs;
|
| + CRangeEnc rc;
|
| +
|
| + UInt32 backRes;
|
|
|
| unsigned lc, lp, pb;
|
| - unsigned lpMask, pbMask;
|
| unsigned lclp;
|
|
|
| - CLzmaProb *litProbs;
|
| -
|
| Bool fastMode;
|
| Bool writeEndMark;
|
| Bool finished;
|
| @@ -327,19 +316,19 @@ typedef struct |
|
|
| UInt64 nowPos64;
|
|
|
| - UInt32 matchPriceCount;
|
| - UInt32 alignPriceCount;
|
| + unsigned matchPriceCount;
|
| + unsigned alignPriceCount;
|
|
|
| - UInt32 distTableSize;
|
| + unsigned distTableSize;
|
|
|
| UInt32 dictSize;
|
| SRes result;
|
|
|
| - CRangeEnc rc;
|
| -
|
| #ifndef _7ZIP_ST
|
| Bool mtMode;
|
| + // begin of CMatchFinderMt is used in LZ thread
|
| CMatchFinderMt matchFinderMt;
|
| + // end of CMatchFinderMt is used in BT and HASH threads
|
| #endif
|
|
|
| CMatchFinder matchFinderBase;
|
| @@ -348,33 +337,37 @@ typedef struct |
| Byte pad[128];
|
| #endif
|
|
|
| - COptimal opt[kNumOpts];
|
| -
|
| - #ifndef LZMA_LOG_BSR
|
| - Byte g_FastPos[1 << kNumLogBits];
|
| - #endif
|
| + // LZ thread
|
| + CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
|
|
| - UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
| UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
|
|
|
| + UInt32 alignPrices[kAlignTableSize];
|
| UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
|
| UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
|
| - UInt32 alignPrices[kAlignTableSize];
|
|
|
| - CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
| + CLzmaProb posAlignEncoder[1 << kNumAlignBits];
|
| CLzmaProb isRep[kNumStates];
|
| CLzmaProb isRepG0[kNumStates];
|
| CLzmaProb isRepG1[kNumStates];
|
| CLzmaProb isRepG2[kNumStates];
|
| + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
| CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
| -
|
| CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
|
| - CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
|
| - CLzmaProb posAlignEncoder[1 << kNumAlignBits];
|
| + CLzmaProb posEncoders[kNumFullDistances];
|
|
|
| + CLenEnc lenProbs;
|
| + CLenEnc repLenProbs;
|
| +
|
| + #ifndef LZMA_LOG_BSR
|
| + Byte g_FastPos[1 << kNumLogBits];
|
| + #endif
|
| +
|
| CLenPriceEnc lenEnc;
|
| CLenPriceEnc repLenEnc;
|
|
|
| + COptimal opt[kNumOpts];
|
| +
|
| CSaveState saveState;
|
|
|
| #ifndef _7ZIP_ST
|
| @@ -383,58 +376,62 @@ typedef struct |
| } CLzmaEnc;
|
|
|
|
|
| +
|
| +#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr));
|
| +
|
| void LzmaEnc_SaveState(CLzmaEncHandle pp)
|
| {
|
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
| CSaveState *dest = &p->saveState;
|
| - int i;
|
| - dest->lenEnc = p->lenEnc;
|
| - dest->repLenEnc = p->repLenEnc;
|
| +
|
| dest->state = p->state;
|
| +
|
| + dest->lenProbs = p->lenProbs;
|
| + dest->repLenProbs = p->repLenProbs;
|
| +
|
| + COPY_ARR(dest, p, reps);
|
| +
|
| + COPY_ARR(dest, p, posAlignEncoder);
|
| + COPY_ARR(dest, p, isRep);
|
| + COPY_ARR(dest, p, isRepG0);
|
| + COPY_ARR(dest, p, isRepG1);
|
| + COPY_ARR(dest, p, isRepG2);
|
| + COPY_ARR(dest, p, isMatch);
|
| + COPY_ARR(dest, p, isRep0Long);
|
| + COPY_ARR(dest, p, posSlotEncoder);
|
| + COPY_ARR(dest, p, posEncoders);
|
|
|
| - for (i = 0; i < kNumStates; i++)
|
| - {
|
| - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
|
| - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
|
| - }
|
| - for (i = 0; i < kNumLenToPosStates; i++)
|
| - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
|
| - memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
|
| - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
|
| - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
|
| - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
|
| - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
|
| - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
|
| - memcpy(dest->reps, p->reps, sizeof(p->reps));
|
| memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
|
| }
|
|
|
| +
|
| void LzmaEnc_RestoreState(CLzmaEncHandle pp)
|
| {
|
| CLzmaEnc *dest = (CLzmaEnc *)pp;
|
| const CSaveState *p = &dest->saveState;
|
| - int i;
|
| - dest->lenEnc = p->lenEnc;
|
| - dest->repLenEnc = p->repLenEnc;
|
| +
|
| dest->state = p->state;
|
|
|
| - for (i = 0; i < kNumStates; i++)
|
| - {
|
| - memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
|
| - memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
|
| - }
|
| - for (i = 0; i < kNumLenToPosStates; i++)
|
| - memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
|
| - memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
|
| - memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
|
| - memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
|
| - memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
|
| - memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
|
| - memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
|
| - memcpy(dest->reps, p->reps, sizeof(p->reps));
|
| + dest->lenProbs = p->lenProbs;
|
| + dest->repLenProbs = p->repLenProbs;
|
| +
|
| + COPY_ARR(dest, p, reps);
|
| +
|
| + COPY_ARR(dest, p, posAlignEncoder);
|
| + COPY_ARR(dest, p, isRep);
|
| + COPY_ARR(dest, p, isRepG0);
|
| + COPY_ARR(dest, p, isRepG1);
|
| + COPY_ARR(dest, p, isRepG2);
|
| + COPY_ARR(dest, p, isMatch);
|
| + COPY_ARR(dest, p, isRep0Long);
|
| + COPY_ARR(dest, p, posSlotEncoder);
|
| + COPY_ARR(dest, p, posEncoders);
|
| +
|
| memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
|
| }
|
|
|
| +
|
| +
|
| SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
| {
|
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
| @@ -445,7 +442,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) |
| || props.lp > LZMA_LP_MAX
|
| || props.pb > LZMA_PB_MAX
|
| || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|
| - || props.dictSize > kMaxHistorySize)
|
| + || props.dictSize > kLzmaMaxHistorySize)
|
| return SZ_ERROR_PARAM;
|
|
|
| p->dictSize = props.dictSize;
|
| @@ -463,7 +460,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) |
| p->fastMode = (props.algo == 0);
|
| p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
|
| {
|
| - UInt32 numHashBytes = 4;
|
| + unsigned numHashBytes = 4;
|
| if (props.btMode)
|
| {
|
| if (props.numHashBytes < 2)
|
| @@ -492,13 +489,27 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) |
| return SZ_OK;
|
| }
|
|
|
| -static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
| -static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
| -static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
| -static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
|
|
| -#define IsCharState(s) ((s) < 7)
|
| +void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
|
| +{
|
| + CLzmaEnc *p = (CLzmaEnc *)pp;
|
| + p->matchFinderBase.expectedDataSize = expectedDataSiize;
|
| +}
|
| +
|
|
|
| +#define kState_Start 0
|
| +#define kState_LitAfterMatch 4
|
| +#define kState_LitAfterRep 5
|
| +#define kState_MatchAfterLit 7
|
| +#define kState_RepAfterLit 8
|
| +
|
| +static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
|
| +static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
|
| +static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
|
| +static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
|
| +
|
| +#define IsLitState(s) ((s) < 7)
|
| +#define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1)
|
| #define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
|
|
|
| #define kInfinityPrice (1 << 30)
|
| @@ -509,14 +520,16 @@ static void RangeEnc_Construct(CRangeEnc *p) |
| p->bufBase = NULL;
|
| }
|
|
|
| -#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
|
| +#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
|
| +#define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + ((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize)
|
|
|
| #define RC_BUF_SIZE (1 << 16)
|
| -static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
|
| +
|
| +static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
|
| {
|
| if (!p->bufBase)
|
| {
|
| - p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
|
| + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
|
| if (!p->bufBase)
|
| return 0;
|
| p->bufLim = p->bufBase + RC_BUF_SIZE;
|
| @@ -524,19 +537,19 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) |
| return 1;
|
| }
|
|
|
| -static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
|
| +static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
|
| {
|
| - alloc->Free(alloc, p->bufBase);
|
| + ISzAlloc_Free(alloc, p->bufBase);
|
| p->bufBase = 0;
|
| }
|
|
|
| static void RangeEnc_Init(CRangeEnc *p)
|
| {
|
| /* Stream.Init(); */
|
| - p->low = 0;
|
| p->range = 0xFFFFFFFF;
|
| - p->cacheSize = 1;
|
| p->cache = 0;
|
| + p->low = 0;
|
| + p->cacheSize = 0;
|
|
|
| p->buf = p->bufBase;
|
|
|
| @@ -544,37 +557,48 @@ static void RangeEnc_Init(CRangeEnc *p) |
| p->res = SZ_OK;
|
| }
|
|
|
| -static void RangeEnc_FlushStream(CRangeEnc *p)
|
| +MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)
|
| {
|
| size_t num;
|
| if (p->res != SZ_OK)
|
| return;
|
| num = p->buf - p->bufBase;
|
| - if (num != p->outStream->Write(p->outStream, p->bufBase, num))
|
| + if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
|
| p->res = SZ_ERROR_WRITE;
|
| p->processed += num;
|
| p->buf = p->bufBase;
|
| }
|
|
|
| -static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
|
| +MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
|
| {
|
| - if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)
|
| + UInt32 low = (UInt32)p->low;
|
| + unsigned high = (unsigned)(p->low >> 32);
|
| + p->low = (UInt32)(low << 8);
|
| + if (low < (UInt32)0xFF000000 || high != 0)
|
| {
|
| - Byte temp = p->cache;
|
| - do
|
| {
|
| Byte *buf = p->buf;
|
| - *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
|
| + *buf++ = (Byte)(p->cache + high);
|
| + p->cache = (unsigned)(low >> 24);
|
| p->buf = buf;
|
| if (buf == p->bufLim)
|
| RangeEnc_FlushStream(p);
|
| - temp = 0xFF;
|
| + if (p->cacheSize == 0)
|
| + return;
|
| + }
|
| + high += 0xFF;
|
| + for (;;)
|
| + {
|
| + Byte *buf = p->buf;
|
| + *buf++ = (Byte)(high);
|
| + p->buf = buf;
|
| + if (buf == p->bufLim)
|
| + RangeEnc_FlushStream(p);
|
| + if (--p->cacheSize == 0)
|
| + return;
|
| }
|
| - while (--p->cacheSize != 0);
|
| - p->cache = (Byte)((UInt32)p->low >> 24);
|
| }
|
| p->cacheSize++;
|
| - p->low = (UInt32)p->low << 8;
|
| }
|
|
|
| static void RangeEnc_FlushData(CRangeEnc *p)
|
| @@ -584,78 +608,121 @@ static void RangeEnc_FlushData(CRangeEnc *p) |
| RangeEnc_ShiftLow(p);
|
| }
|
|
|
| -static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)
|
| -{
|
| - do
|
| - {
|
| - p->range >>= 1;
|
| - p->low += p->range & (0 - ((value >> --numBits) & 1));
|
| - if (p->range < kTopValue)
|
| - {
|
| - p->range <<= 8;
|
| - RangeEnc_ShiftLow(p);
|
| - }
|
| - }
|
| - while (numBits != 0);
|
| -}
|
| +#define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); }
|
|
|
| -static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
|
| -{
|
| - UInt32 ttt = *prob;
|
| - UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
|
| - if (symbol == 0)
|
| - {
|
| - p->range = newBound;
|
| - ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
|
| - }
|
| - else
|
| - {
|
| - p->low += newBound;
|
| - p->range -= newBound;
|
| - ttt -= ttt >> kNumMoveBits;
|
| +#define RC_BIT_PRE(p, prob) \
|
| + ttt = *(prob); \
|
| + newBound = (range >> kNumBitModelTotalBits) * ttt;
|
| +
|
| +// #define _LZMA_ENC_USE_BRANCH
|
| +
|
| +#ifdef _LZMA_ENC_USE_BRANCH
|
| +
|
| +#define RC_BIT(p, prob, symbol) { \
|
| + RC_BIT_PRE(p, prob) \
|
| + if (symbol == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \
|
| + else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \
|
| + *(prob) = (CLzmaProb)ttt; \
|
| + RC_NORM(p) \
|
| }
|
| - *prob = (CLzmaProb)ttt;
|
| - if (p->range < kTopValue)
|
| - {
|
| - p->range <<= 8;
|
| - RangeEnc_ShiftLow(p);
|
| +
|
| +#else
|
| +
|
| +#define RC_BIT(p, prob, symbol) { \
|
| + UInt32 mask; \
|
| + RC_BIT_PRE(p, prob) \
|
| + mask = 0 - (UInt32)symbol; \
|
| + range &= mask; \
|
| + mask &= newBound; \
|
| + range -= mask; \
|
| + (p)->low += mask; \
|
| + mask = (UInt32)symbol - 1; \
|
| + range += newBound & mask; \
|
| + mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \
|
| + mask += ((1 << kNumMoveBits) - 1); \
|
| + ttt += (Int32)(mask - ttt) >> kNumMoveBits; \
|
| + *(prob) = (CLzmaProb)ttt; \
|
| + RC_NORM(p) \
|
| }
|
| +
|
| +#endif
|
| +
|
| +
|
| +
|
| +
|
| +#define RC_BIT_0_BASE(p, prob) \
|
| + range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
| +
|
| +#define RC_BIT_1_BASE(p, prob) \
|
| + range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \
|
| +
|
| +#define RC_BIT_0(p, prob) \
|
| + RC_BIT_0_BASE(p, prob) \
|
| + RC_NORM(p)
|
| +
|
| +#define RC_BIT_1(p, prob) \
|
| + RC_BIT_1_BASE(p, prob) \
|
| + RC_NORM(p)
|
| +
|
| +static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob)
|
| +{
|
| + UInt32 range, ttt, newBound;
|
| + range = p->range;
|
| + RC_BIT_PRE(p, prob)
|
| + RC_BIT_0(p, prob)
|
| + p->range = range;
|
| }
|
|
|
| static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
|
| {
|
| + UInt32 range = p->range;
|
| symbol |= 0x100;
|
| do
|
| {
|
| - RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
|
| + UInt32 ttt, newBound;
|
| + // RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
|
| + CLzmaProb *prob = probs + (symbol >> 8);
|
| + UInt32 bit = (symbol >> 7) & 1;
|
| symbol <<= 1;
|
| + RC_BIT(p, prob, bit);
|
| }
|
| while (symbol < 0x10000);
|
| + p->range = range;
|
| }
|
|
|
| static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
|
| {
|
| + UInt32 range = p->range;
|
| UInt32 offs = 0x100;
|
| symbol |= 0x100;
|
| do
|
| {
|
| + UInt32 ttt, newBound;
|
| + CLzmaProb *prob;
|
| + UInt32 bit;
|
| matchByte <<= 1;
|
| - RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
|
| + // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
|
| + prob = probs + (offs + (matchByte & offs) + (symbol >> 8));
|
| + bit = (symbol >> 7) & 1;
|
| symbol <<= 1;
|
| offs &= ~(matchByte ^ symbol);
|
| + RC_BIT(p, prob, bit);
|
| }
|
| while (symbol < 0x10000);
|
| + p->range = range;
|
| }
|
|
|
| -static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
|
| +
|
| +
|
| +static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices)
|
| {
|
| UInt32 i;
|
| - for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
|
| + for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++)
|
| {
|
| - const int kCyclesBits = kNumBitPriceShiftBits;
|
| - UInt32 w = i;
|
| - UInt32 bitCount = 0;
|
| - int j;
|
| + const unsigned kCyclesBits = kNumBitPriceShiftBits;
|
| + UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1));
|
| + unsigned bitCount = 0;
|
| + unsigned j;
|
| for (j = 0; j < kCyclesBits; j++)
|
| {
|
| w = w * w;
|
| @@ -666,37 +733,41 @@ static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) |
| bitCount++;
|
| }
|
| }
|
| - ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
|
| + ProbPrices[i] = (CProbPrice)((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
|
| + // printf("\n%3d: %5d", i, ProbPrices[i]);
|
| }
|
| }
|
|
|
|
|
| #define GET_PRICE(prob, symbol) \
|
| - p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
|
| + p->ProbPrices[((prob) ^ (unsigned)(((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
|
|
|
| #define GET_PRICEa(prob, symbol) \
|
| - ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
|
| + ProbPrices[((prob) ^ (unsigned)((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
|
|
|
| #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
|
| #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
|
|
|
| -#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
|
| -#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
|
| +#define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
|
| +#define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
|
| +
|
|
|
| -static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)
|
| +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const CProbPrice *ProbPrices)
|
| {
|
| UInt32 price = 0;
|
| symbol |= 0x100;
|
| do
|
| {
|
| - price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
|
| - symbol <<= 1;
|
| + unsigned bit = symbol & 1;
|
| + symbol >>= 1;
|
| + price += GET_PRICEa(probs[symbol], bit);
|
| }
|
| - while (symbol < 0x10000);
|
| + while (symbol >= 2);
|
| return price;
|
| }
|
|
|
| -static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)
|
| +
|
| +static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const CProbPrice *ProbPrices)
|
| {
|
| UInt32 price = 0;
|
| UInt32 offs = 0x100;
|
| @@ -713,520 +784,525 @@ static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt |
| }
|
|
|
|
|
| -static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
|
| +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, UInt32 symbol)
|
| {
|
| - UInt32 m = 1;
|
| - int i;
|
| - for (i = numBitLevels; i != 0;)
|
| - {
|
| - UInt32 bit;
|
| - i--;
|
| - bit = (symbol >> i) & 1;
|
| - RangeEnc_EncodeBit(rc, probs + m, bit);
|
| - m = (m << 1) | bit;
|
| - }
|
| -}
|
| -
|
| -static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
|
| -{
|
| - UInt32 m = 1;
|
| - int i;
|
| - for (i = 0; i < numBitLevels; i++)
|
| - {
|
| - UInt32 bit = symbol & 1;
|
| - RangeEnc_EncodeBit(rc, probs + m, bit);
|
| - m = (m << 1) | bit;
|
| - symbol >>= 1;
|
| - }
|
| -}
|
| -
|
| -static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
|
| -{
|
| - UInt32 price = 0;
|
| - symbol |= (1 << numBitLevels);
|
| - while (symbol != 1)
|
| - {
|
| - price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
|
| - symbol >>= 1;
|
| - }
|
| - return price;
|
| -}
|
| -
|
| -static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
|
| -{
|
| - UInt32 price = 0;
|
| - UInt32 m = 1;
|
| - int i;
|
| - for (i = numBitLevels; i != 0; i--)
|
| + UInt32 range = rc->range;
|
| + unsigned m = 1;
|
| + do
|
| {
|
| - UInt32 bit = symbol & 1;
|
| + UInt32 ttt, newBound;
|
| + unsigned bit = symbol & 1;
|
| + // RangeEnc_EncodeBit(rc, probs + m, bit);
|
| symbol >>= 1;
|
| - price += GET_PRICEa(probs[m], bit);
|
| + RC_BIT(rc, probs + m, bit);
|
| m = (m << 1) | bit;
|
| }
|
| - return price;
|
| + while (--numBits);
|
| + rc->range = range;
|
| }
|
|
|
|
|
| +
|
| static void LenEnc_Init(CLenEnc *p)
|
| {
|
| unsigned i;
|
| - p->choice = p->choice2 = kProbInitValue;
|
| - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
|
| + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++)
|
| p->low[i] = kProbInitValue;
|
| - for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
|
| - p->mid[i] = kProbInitValue;
|
| for (i = 0; i < kLenNumHighSymbols; i++)
|
| p->high[i] = kProbInitValue;
|
| }
|
|
|
| -static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
|
| +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned symbol, unsigned posState)
|
| {
|
| - if (symbol < kLenNumLowSymbols)
|
| + UInt32 range, ttt, newBound;
|
| + CLzmaProb *probs = p->low;
|
| + range = rc->range;
|
| + RC_BIT_PRE(rc, probs);
|
| + if (symbol >= kLenNumLowSymbols)
|
| {
|
| - RangeEnc_EncodeBit(rc, &p->choice, 0);
|
| - RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
|
| - }
|
| - else
|
| - {
|
| - RangeEnc_EncodeBit(rc, &p->choice, 1);
|
| - if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
|
| + RC_BIT_1(rc, probs);
|
| + probs += kLenNumLowSymbols;
|
| + RC_BIT_PRE(rc, probs);
|
| + if (symbol >= kLenNumLowSymbols * 2)
|
| {
|
| - RangeEnc_EncodeBit(rc, &p->choice2, 0);
|
| - RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
|
| - }
|
| - else
|
| - {
|
| - RangeEnc_EncodeBit(rc, &p->choice2, 1);
|
| - RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
|
| + RC_BIT_1(rc, probs);
|
| + rc->range = range;
|
| + // RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols * 2);
|
| + LitEnc_Encode(rc, p->high, symbol - kLenNumLowSymbols * 2);
|
| + return;
|
| }
|
| + symbol -= kLenNumLowSymbols;
|
| }
|
| -}
|
|
|
| -static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)
|
| -{
|
| - UInt32 a0 = GET_PRICE_0a(p->choice);
|
| - UInt32 a1 = GET_PRICE_1a(p->choice);
|
| - UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
|
| - UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
|
| - UInt32 i = 0;
|
| - for (i = 0; i < kLenNumLowSymbols; i++)
|
| + // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
|
| {
|
| - if (i >= numSymbols)
|
| - return;
|
| - prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
|
| + unsigned m;
|
| + unsigned bit;
|
| + RC_BIT_0(rc, probs);
|
| + probs += (posState << (1 + kLenNumLowBits));
|
| + bit = (symbol >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit;
|
| + bit = (symbol >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit;
|
| + bit = symbol & 1; RC_BIT(rc, probs + m, bit);
|
| + rc->range = range;
|
| }
|
| - for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
|
| - {
|
| - if (i >= numSymbols)
|
| - return;
|
| - prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
|
| - }
|
| - for (; i < numSymbols; i++)
|
| - prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
|
| }
|
|
|
| -static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)
|
| +static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices)
|
| {
|
| - LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
|
| - p->counters[posState] = p->tableSize;
|
| + unsigned i;
|
| + for (i = 0; i < 8; i += 2)
|
| + {
|
| + UInt32 price = startPrice;
|
| + UInt32 prob;
|
| + price += GET_PRICEa(probs[1 ], (i >> 2));
|
| + price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1);
|
| + prob = probs[4 + (i >> 1)];
|
| + prices[i ] = price + GET_PRICEa_0(prob);
|
| + prices[i + 1] = price + GET_PRICEa_1(prob);
|
| + }
|
| }
|
|
|
| -static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)
|
| +
|
| +MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTable(
|
| + CLenPriceEnc *p, unsigned posState,
|
| + const CLenEnc *enc,
|
| + const CProbPrice *ProbPrices)
|
| {
|
| - UInt32 posState;
|
| - for (posState = 0; posState < numPosStates; posState++)
|
| - LenPriceEnc_UpdateTable(p, posState, ProbPrices);
|
| + // int y; for (y = 0; y < 100; y++) {
|
| + UInt32 a;
|
| + unsigned i, numSymbols;
|
| +
|
| + UInt32 *prices = p->prices[posState];
|
| + {
|
| + const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits));
|
| + SetPrices_3(probs, GET_PRICEa_0(enc->low[0]), prices, ProbPrices);
|
| + a = GET_PRICEa_1(enc->low[0]);
|
| + SetPrices_3(probs + kLenNumLowSymbols, a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]), prices + kLenNumLowSymbols, ProbPrices);
|
| + a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
|
| + }
|
| + numSymbols = p->tableSize;
|
| + p->counters[posState] = numSymbols;
|
| + for (i = kLenNumLowSymbols * 2; i < numSymbols; i += 1)
|
| + {
|
| + prices[i] = a +
|
| + // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices);
|
| + LitEnc_GetPrice(enc->high, i - kLenNumLowSymbols * 2, ProbPrices);
|
| + /*
|
| + unsigned sym = (i - kLenNumLowSymbols * 2) >> 1;
|
| + UInt32 price = a + RcTree_GetPrice(enc->high, kLenNumHighBits - 1, sym, ProbPrices);
|
| + UInt32 prob = enc->high[(1 << 7) + sym];
|
| + prices[i ] = price + GET_PRICEa_0(prob);
|
| + prices[i + 1] = price + GET_PRICEa_1(prob);
|
| + */
|
| + }
|
| + // }
|
| }
|
|
|
| -static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)
|
| +static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, unsigned numPosStates,
|
| + const CLenEnc *enc,
|
| + const CProbPrice *ProbPrices)
|
| {
|
| - LenEnc_Encode(&p->p, rc, symbol, posState);
|
| - if (updatePrice)
|
| - if (--p->counters[posState] == 0)
|
| - LenPriceEnc_UpdateTable(p, posState, ProbPrices);
|
| + unsigned posState;
|
| + for (posState = 0; posState < numPosStates; posState++)
|
| + LenPriceEnc_UpdateTable(p, posState, enc, ProbPrices);
|
| }
|
|
|
|
|
| -
|
| -
|
| -static void MovePos(CLzmaEnc *p, UInt32 num)
|
| -{
|
| +/*
|
| #ifdef SHOW_STAT
|
| g_STAT_OFFSET += num;
|
| printf("\n MovePos %u", num);
|
| #endif
|
| +*/
|
|
|
| - if (num != 0)
|
| - {
|
| - p->additionalOffset += num;
|
| - p->matchFinder.Skip(p->matchFinderObj, num);
|
| - }
|
| -}
|
| +#define MOVE_POS(p, num) { \
|
| + p->additionalOffset += (num); \
|
| + p->matchFinder.Skip(p->matchFinderObj, (num)); }
|
| +
|
|
|
| -static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
|
| +static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
|
| {
|
| - UInt32 lenRes = 0, numPairs;
|
| + unsigned numPairs;
|
| +
|
| + p->additionalOffset++;
|
| p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
|
| numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
|
| + *numPairsRes = numPairs;
|
|
|
| #ifdef SHOW_STAT
|
| printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
|
| g_STAT_OFFSET++;
|
| {
|
| - UInt32 i;
|
| + unsigned i;
|
| for (i = 0; i < numPairs; i += 2)
|
| printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
|
| }
|
| #endif
|
|
|
| - if (numPairs > 0)
|
| + if (numPairs == 0)
|
| + return 0;
|
| {
|
| - lenRes = p->matches[numPairs - 2];
|
| - if (lenRes == p->numFastBytes)
|
| + unsigned len = p->matches[(size_t)numPairs - 2];
|
| + if (len != p->numFastBytes)
|
| + return len;
|
| {
|
| UInt32 numAvail = p->numAvail;
|
| if (numAvail > LZMA_MATCH_LEN_MAX)
|
| numAvail = LZMA_MATCH_LEN_MAX;
|
| {
|
| - const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| - const Byte *pby = pbyCur + lenRes;
|
| - ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
|
| - const Byte *pbyLim = pbyCur + numAvail;
|
| - for (; pby != pbyLim && *pby == pby[dif]; pby++);
|
| - lenRes = (UInt32)(pby - pbyCur);
|
| + const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| + const Byte *p2 = p1 + len;
|
| + ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
|
| + const Byte *lim = p1 + numAvail;
|
| + for (; p2 != lim && *p2 == p2[dif]; p2++);
|
| + return (unsigned)(p2 - p1);
|
| }
|
| }
|
| }
|
| - p->additionalOffset++;
|
| - *numDistancePairsRes = numPairs;
|
| - return lenRes;
|
| }
|
|
|
| +#define MARK_LIT ((UInt32)(Int32)-1)
|
|
|
| -#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
|
| -#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
|
| -#define IsShortRep(p) ((p)->backPrev == 0)
|
| +#define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; }
|
| +#define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; }
|
| +#define IsShortRep(p) ((p)->dist == 0)
|
|
|
| -static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
|
| -{
|
| - return
|
| - GET_PRICE_0(p->isRepG0[state]) +
|
| - GET_PRICE_0(p->isRep0Long[state][posState]);
|
| -}
|
|
|
| -static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
|
| +#define GetPrice_ShortRep(p, state, posState) \
|
| + ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState]))
|
| +
|
| +#define GetPrice_Rep_0(p, state, posState) ( \
|
| + GET_PRICE_1(p->isMatch[state][posState]) \
|
| + + GET_PRICE_1(p->isRep0Long[state][posState])) \
|
| + + GET_PRICE_1(p->isRep[state]) \
|
| + + GET_PRICE_0(p->isRepG0[state])
|
| +
|
| +
|
| +static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState)
|
| {
|
| UInt32 price;
|
| + UInt32 prob = p->isRepG0[state];
|
| if (repIndex == 0)
|
| {
|
| - price = GET_PRICE_0(p->isRepG0[state]);
|
| + price = GET_PRICE_0(prob);
|
| price += GET_PRICE_1(p->isRep0Long[state][posState]);
|
| }
|
| else
|
| {
|
| - price = GET_PRICE_1(p->isRepG0[state]);
|
| + price = GET_PRICE_1(prob);
|
| + prob = p->isRepG1[state];
|
| if (repIndex == 1)
|
| - price += GET_PRICE_0(p->isRepG1[state]);
|
| + price += GET_PRICE_0(prob);
|
| else
|
| {
|
| - price += GET_PRICE_1(p->isRepG1[state]);
|
| + price += GET_PRICE_1(prob);
|
| price += GET_PRICE(p->isRepG2[state], repIndex - 2);
|
| }
|
| }
|
| return price;
|
| }
|
|
|
| -static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
|
| -{
|
| - return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
|
| - GetPureRepPrice(p, repIndex, state, posState);
|
| -}
|
|
|
| -static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
|
| +static unsigned Backward(CLzmaEnc *p, unsigned cur)
|
| {
|
| - UInt32 posMem = p->opt[cur].posPrev;
|
| - UInt32 backMem = p->opt[cur].backPrev;
|
| - p->optimumEndIndex = cur;
|
| - do
|
| + unsigned wr = cur + 1;
|
| + p->optEnd = wr;
|
| +
|
| + for (;;)
|
| {
|
| - if (p->opt[cur].prev1IsChar)
|
| + UInt32 dist = p->opt[cur].dist;
|
| + UInt32 len = p->opt[cur].len;
|
| + UInt32 extra = p->opt[cur].extra;
|
| + cur -= len;
|
| +
|
| + if (extra)
|
| {
|
| - MakeAsChar(&p->opt[posMem])
|
| - p->opt[posMem].posPrev = posMem - 1;
|
| - if (p->opt[cur].prev2)
|
| + wr--;
|
| + p->opt[wr].len = len;
|
| + cur -= extra;
|
| + len = extra;
|
| + if (extra == 1)
|
| + {
|
| + p->opt[wr].dist = dist;
|
| + dist = MARK_LIT;
|
| + }
|
| + else
|
| {
|
| - p->opt[posMem - 1].prev1IsChar = False;
|
| - p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
|
| - p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
|
| + p->opt[wr].dist = 0;
|
| + len--;
|
| + wr--;
|
| + p->opt[wr].dist = MARK_LIT;
|
| + p->opt[wr].len = 1;
|
| }
|
| }
|
| +
|
| + if (cur == 0)
|
| {
|
| - UInt32 posPrev = posMem;
|
| - UInt32 backCur = backMem;
|
| -
|
| - backMem = p->opt[posPrev].backPrev;
|
| - posMem = p->opt[posPrev].posPrev;
|
| -
|
| - p->opt[posPrev].backPrev = backCur;
|
| - p->opt[posPrev].posPrev = cur;
|
| - cur = posPrev;
|
| + p->backRes = dist;
|
| + p->optCur = wr;
|
| + return len;
|
| }
|
| +
|
| + wr--;
|
| + p->opt[wr].dist = dist;
|
| + p->opt[wr].len = len;
|
| }
|
| - while (cur != 0);
|
| - *backRes = p->opt[0].backPrev;
|
| - p->optimumCurrentIndex = p->opt[0].posPrev;
|
| - return p->optimumCurrentIndex;
|
| }
|
|
|
| -#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)
|
|
|
| -static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
| -{
|
| - UInt32 lenEnd, cur;
|
| - UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
|
| - UInt32 *matches;
|
|
|
| - {
|
| +#define LIT_PROBS(pos, prevByte) \
|
| + (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc))
|
|
|
| - UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
|
| - UInt32 matchPrice, repMatchPrice, normalMatchPrice;
|
| - const Byte *data;
|
| - Byte curByte, matchByte;
|
|
|
| - if (p->optimumEndIndex != p->optimumCurrentIndex)
|
| - {
|
| - const COptimal *opt = &p->opt[p->optimumCurrentIndex];
|
| - UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
|
| - *backRes = opt->backPrev;
|
| - p->optimumCurrentIndex = opt->posPrev;
|
| - return lenRes;
|
| - }
|
| - p->optimumCurrentIndex = p->optimumEndIndex = 0;
|
| -
|
| - if (p->additionalOffset == 0)
|
| - mainLen = ReadMatchDistances(p, &numPairs);
|
| - else
|
| - {
|
| - mainLen = p->longestMatchLength;
|
| - numPairs = p->numPairs;
|
| - }
|
| -
|
| - numAvail = p->numAvail;
|
| - if (numAvail < 2)
|
| - {
|
| - *backRes = (UInt32)(-1);
|
| - return 1;
|
| - }
|
| - if (numAvail > LZMA_MATCH_LEN_MAX)
|
| - numAvail = LZMA_MATCH_LEN_MAX;
|
| +static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
|
| +{
|
| + unsigned last, cur;
|
| + UInt32 reps[LZMA_NUM_REPS];
|
| + unsigned repLens[LZMA_NUM_REPS];
|
| + UInt32 *matches;
|
|
|
| - data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| - repMaxIndex = 0;
|
| - for (i = 0; i < LZMA_NUM_REPS; i++)
|
| {
|
| - UInt32 lenTest;
|
| - const Byte *data2;
|
| - reps[i] = p->reps[i];
|
| - data2 = data - reps[i] - 1;
|
| - if (data[0] != data2[0] || data[1] != data2[1])
|
| + UInt32 numAvail;
|
| + unsigned numPairs, mainLen, repMaxIndex, i, posState;
|
| + UInt32 matchPrice, repMatchPrice;
|
| + const Byte *data;
|
| + Byte curByte, matchByte;
|
| +
|
| + p->optCur = p->optEnd = 0;
|
| +
|
| + if (p->additionalOffset == 0)
|
| + mainLen = ReadMatchDistances(p, &numPairs);
|
| + else
|
| {
|
| - repLens[i] = 0;
|
| - continue;
|
| + mainLen = p->longestMatchLen;
|
| + numPairs = p->numPairs;
|
| }
|
| - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
|
| - repLens[i] = lenTest;
|
| - if (lenTest > repLens[repMaxIndex])
|
| - repMaxIndex = i;
|
| - }
|
| - if (repLens[repMaxIndex] >= p->numFastBytes)
|
| - {
|
| - UInt32 lenRes;
|
| - *backRes = repMaxIndex;
|
| - lenRes = repLens[repMaxIndex];
|
| - MovePos(p, lenRes - 1);
|
| - return lenRes;
|
| - }
|
| -
|
| - matches = p->matches;
|
| - if (mainLen >= p->numFastBytes)
|
| - {
|
| - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
|
| - MovePos(p, mainLen - 1);
|
| - return mainLen;
|
| - }
|
| - curByte = *data;
|
| - matchByte = *(data - (reps[0] + 1));
|
| -
|
| - if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
|
| - {
|
| - *backRes = (UInt32)-1;
|
| - return 1;
|
| - }
|
| -
|
| - p->opt[0].state = (CState)p->state;
|
| -
|
| - posState = (position & p->pbMask);
|
| -
|
| - {
|
| - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
|
| - p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
|
| - (!IsCharState(p->state) ?
|
| - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
|
| - LitEnc_GetPrice(probs, curByte, p->ProbPrices));
|
| - }
|
| -
|
| - MakeAsChar(&p->opt[1]);
|
| -
|
| - matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
|
| - repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
|
| -
|
| - if (matchByte == curByte)
|
| - {
|
| - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
|
| - if (shortRepPrice < p->opt[1].price)
|
| +
|
| + numAvail = p->numAvail;
|
| + if (numAvail < 2)
|
| {
|
| - p->opt[1].price = shortRepPrice;
|
| - MakeAsShortRep(&p->opt[1]);
|
| + p->backRes = MARK_LIT;
|
| + return 1;
|
| }
|
| - }
|
| - lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
|
| -
|
| - if (lenEnd < 2)
|
| - {
|
| - *backRes = p->opt[1].backPrev;
|
| - return 1;
|
| - }
|
| -
|
| - p->opt[1].posPrev = 0;
|
| - for (i = 0; i < LZMA_NUM_REPS; i++)
|
| - p->opt[0].backs[i] = reps[i];
|
| -
|
| - len = lenEnd;
|
| - do
|
| - p->opt[len--].price = kInfinityPrice;
|
| - while (len >= 2);
|
| -
|
| - for (i = 0; i < LZMA_NUM_REPS; i++)
|
| - {
|
| - UInt32 repLen = repLens[i];
|
| - UInt32 price;
|
| - if (repLen < 2)
|
| - continue;
|
| - price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
|
| - do
|
| + if (numAvail > LZMA_MATCH_LEN_MAX)
|
| + numAvail = LZMA_MATCH_LEN_MAX;
|
| +
|
| + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| + repMaxIndex = 0;
|
| +
|
| + for (i = 0; i < LZMA_NUM_REPS; i++)
|
| {
|
| - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
|
| - COptimal *opt = &p->opt[repLen];
|
| - if (curAndLenPrice < opt->price)
|
| + unsigned len;
|
| + const Byte *data2;
|
| + reps[i] = p->reps[i];
|
| + data2 = data - reps[i];
|
| + if (data[0] != data2[0] || data[1] != data2[1])
|
| {
|
| - opt->price = curAndLenPrice;
|
| - opt->posPrev = 0;
|
| - opt->backPrev = i;
|
| - opt->prev1IsChar = False;
|
| + repLens[i] = 0;
|
| + continue;
|
| }
|
| + for (len = 2; len < numAvail && data[len] == data2[len]; len++);
|
| + repLens[i] = len;
|
| + if (len > repLens[repMaxIndex])
|
| + repMaxIndex = i;
|
| }
|
| - while (--repLen >= 2);
|
| - }
|
| -
|
| - normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
|
| -
|
| - len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
|
| - if (len <= mainLen)
|
| - {
|
| - UInt32 offs = 0;
|
| - while (len > matches[offs])
|
| - offs += 2;
|
| - for (; ; len++)
|
| +
|
| + if (repLens[repMaxIndex] >= p->numFastBytes)
|
| {
|
| - COptimal *opt;
|
| - UInt32 distance = matches[offs + 1];
|
| -
|
| - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
|
| - UInt32 lenToPosState = GetLenToPosState(len);
|
| - if (distance < kNumFullDistances)
|
| - curAndLenPrice += p->distancesPrices[lenToPosState][distance];
|
| - else
|
| + unsigned len;
|
| + p->backRes = repMaxIndex;
|
| + len = repLens[repMaxIndex];
|
| + MOVE_POS(p, len - 1)
|
| + return len;
|
| + }
|
| +
|
| + matches = p->matches;
|
| +
|
| + if (mainLen >= p->numFastBytes)
|
| + {
|
| + p->backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
|
| + MOVE_POS(p, mainLen - 1)
|
| + return mainLen;
|
| + }
|
| +
|
| + curByte = *data;
|
| + matchByte = *(data - reps[0]);
|
| +
|
| + if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
|
| + {
|
| + p->backRes = MARK_LIT;
|
| + return 1;
|
| + }
|
| +
|
| + p->opt[0].state = (CState)p->state;
|
| +
|
| + posState = (position & p->pbMask);
|
| +
|
| + {
|
| + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
|
| + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
|
| + (!IsLitState(p->state) ?
|
| + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
|
| + LitEnc_GetPrice(probs, curByte, p->ProbPrices));
|
| + }
|
| +
|
| + MakeAs_Lit(&p->opt[1]);
|
| +
|
| + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
|
| + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
|
| +
|
| + if (matchByte == curByte)
|
| + {
|
| + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState);
|
| + if (shortRepPrice < p->opt[1].price)
|
| {
|
| - UInt32 slot;
|
| - GetPosSlot2(distance, slot);
|
| - curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
|
| + p->opt[1].price = shortRepPrice;
|
| + MakeAs_ShortRep(&p->opt[1]);
|
| }
|
| - opt = &p->opt[len];
|
| - if (curAndLenPrice < opt->price)
|
| + }
|
| +
|
| + last = (mainLen >= repLens[repMaxIndex] ? mainLen : repLens[repMaxIndex]);
|
| +
|
| + if (last < 2)
|
| + {
|
| + p->backRes = p->opt[1].dist;
|
| + return 1;
|
| + }
|
| +
|
| + p->opt[1].len = 1;
|
| +
|
| + p->opt[0].reps[0] = reps[0];
|
| + p->opt[0].reps[1] = reps[1];
|
| + p->opt[0].reps[2] = reps[2];
|
| + p->opt[0].reps[3] = reps[3];
|
| +
|
| + {
|
| + unsigned len = last;
|
| + do
|
| + p->opt[len--].price = kInfinityPrice;
|
| + while (len >= 2);
|
| + }
|
| +
|
| + // ---------- REP ----------
|
| +
|
| + for (i = 0; i < LZMA_NUM_REPS; i++)
|
| + {
|
| + unsigned repLen = repLens[i];
|
| + UInt32 price;
|
| + if (repLen < 2)
|
| + continue;
|
| + price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState);
|
| + do
|
| {
|
| - opt->price = curAndLenPrice;
|
| - opt->posPrev = 0;
|
| - opt->backPrev = distance + LZMA_NUM_REPS;
|
| - opt->prev1IsChar = False;
|
| + UInt32 price2 = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
|
| + COptimal *opt = &p->opt[repLen];
|
| + if (price2 < opt->price)
|
| + {
|
| + opt->price = price2;
|
| + opt->len = repLen;
|
| + opt->dist = i;
|
| + opt->extra = 0;
|
| + }
|
| }
|
| - if (len == matches[offs])
|
| + while (--repLen >= 2);
|
| + }
|
| +
|
| +
|
| + // ---------- MATCH ----------
|
| + {
|
| + unsigned len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
|
| + if (len <= mainLen)
|
| {
|
| - offs += 2;
|
| - if (offs == numPairs)
|
| - break;
|
| + unsigned offs = 0;
|
| + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
|
| +
|
| + while (len > matches[offs])
|
| + offs += 2;
|
| +
|
| + for (; ; len++)
|
| + {
|
| + COptimal *opt;
|
| + UInt32 dist = matches[(size_t)offs + 1];
|
| + UInt32 price2 = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
|
| + unsigned lenToPosState = GetLenToPosState(len);
|
| +
|
| + if (dist < kNumFullDistances)
|
| + price2 += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
|
| + else
|
| + {
|
| + unsigned slot;
|
| + GetPosSlot2(dist, slot);
|
| + price2 += p->alignPrices[dist & kAlignMask];
|
| + price2 += p->posSlotPrices[lenToPosState][slot];
|
| + }
|
| +
|
| + opt = &p->opt[len];
|
| +
|
| + if (price2 < opt->price)
|
| + {
|
| + opt->price = price2;
|
| + opt->len = len;
|
| + opt->dist = dist + LZMA_NUM_REPS;
|
| + opt->extra = 0;
|
| + }
|
| +
|
| + if (len == matches[offs])
|
| + {
|
| + offs += 2;
|
| + if (offs == numPairs)
|
| + break;
|
| + }
|
| + }
|
| }
|
| }
|
| - }
|
| +
|
|
|
| - cur = 0;
|
| + cur = 0;
|
|
|
| #ifdef SHOW_STAT2
|
| /* if (position >= 0) */
|
| {
|
| unsigned i;
|
| printf("\n pos = %4X", position);
|
| - for (i = cur; i <= lenEnd; i++)
|
| + for (i = cur; i <= last; i++)
|
| printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
|
| }
|
| #endif
|
| + }
|
| +
|
|
|
| - }
|
| +
|
| + // ---------- Optimal Parsing ----------
|
|
|
| for (;;)
|
| {
|
| - UInt32 numAvail;
|
| - UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
|
| - UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
|
| - Bool nextIsChar;
|
| + UInt32 numAvail, numAvailFull;
|
| + unsigned newLen, numPairs, prev, state, posState, startLen;
|
| + UInt32 curPrice, litPrice, matchPrice, repMatchPrice;
|
| + Bool nextIsLit;
|
| Byte curByte, matchByte;
|
| const Byte *data;
|
| - COptimal *curOpt;
|
| - COptimal *nextOpt;
|
| + COptimal *curOpt, *nextOpt;
|
|
|
| - cur++;
|
| - if (cur == lenEnd)
|
| - return Backward(p, backRes, cur);
|
| + if (++cur == last)
|
| + return Backward(p, cur);
|
|
|
| newLen = ReadMatchDistances(p, &numPairs);
|
| +
|
| if (newLen >= p->numFastBytes)
|
| {
|
| p->numPairs = numPairs;
|
| - p->longestMatchLength = newLen;
|
| - return Backward(p, backRes, cur);
|
| + p->longestMatchLen = newLen;
|
| + return Backward(p, cur);
|
| }
|
| - position++;
|
| +
|
| curOpt = &p->opt[cur];
|
| - posPrev = curOpt->posPrev;
|
| - if (curOpt->prev1IsChar)
|
| - {
|
| - posPrev--;
|
| - if (curOpt->prev2)
|
| - {
|
| - state = p->opt[curOpt->posPrev2].state;
|
| - if (curOpt->backPrev2 < LZMA_NUM_REPS)
|
| - state = kRepNextStates[state];
|
| - else
|
| - state = kMatchNextStates[state];
|
| - }
|
| - else
|
| - state = p->opt[posPrev].state;
|
| - state = kLiteralNextStates[state];
|
| - }
|
| - else
|
| - state = p->opt[posPrev].state;
|
| - if (posPrev == cur - 1)
|
| + prev = cur - curOpt->len;
|
| +
|
| + if (curOpt->len == 1)
|
| {
|
| + state = p->opt[prev].state;
|
| if (IsShortRep(curOpt))
|
| state = kShortRepNextStates[state];
|
| else
|
| @@ -1234,92 +1310,136 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
| }
|
| else
|
| {
|
| - UInt32 pos;
|
| const COptimal *prevOpt;
|
| - if (curOpt->prev1IsChar && curOpt->prev2)
|
| + UInt32 b0;
|
| + UInt32 dist = curOpt->dist;
|
| +
|
| + if (curOpt->extra)
|
| {
|
| - posPrev = curOpt->posPrev2;
|
| - pos = curOpt->backPrev2;
|
| - state = kRepNextStates[state];
|
| + prev -= curOpt->extra;
|
| + state = kState_RepAfterLit;
|
| + if (curOpt->extra == 1)
|
| + state = (dist < LZMA_NUM_REPS) ? kState_RepAfterLit : kState_MatchAfterLit;
|
| }
|
| else
|
| {
|
| - pos = curOpt->backPrev;
|
| - if (pos < LZMA_NUM_REPS)
|
| + state = p->opt[prev].state;
|
| + if (dist < LZMA_NUM_REPS)
|
| state = kRepNextStates[state];
|
| else
|
| state = kMatchNextStates[state];
|
| }
|
| - prevOpt = &p->opt[posPrev];
|
| - if (pos < LZMA_NUM_REPS)
|
| +
|
| + prevOpt = &p->opt[prev];
|
| + b0 = prevOpt->reps[0];
|
| +
|
| + if (dist < LZMA_NUM_REPS)
|
| {
|
| - UInt32 i;
|
| - reps[0] = prevOpt->backs[pos];
|
| - for (i = 1; i <= pos; i++)
|
| - reps[i] = prevOpt->backs[i - 1];
|
| - for (; i < LZMA_NUM_REPS; i++)
|
| - reps[i] = prevOpt->backs[i];
|
| + if (dist == 0)
|
| + {
|
| + reps[0] = b0;
|
| + reps[1] = prevOpt->reps[1];
|
| + reps[2] = prevOpt->reps[2];
|
| + reps[3] = prevOpt->reps[3];
|
| + }
|
| + else
|
| + {
|
| + reps[1] = b0;
|
| + b0 = prevOpt->reps[1];
|
| + if (dist == 1)
|
| + {
|
| + reps[0] = b0;
|
| + reps[2] = prevOpt->reps[2];
|
| + reps[3] = prevOpt->reps[3];
|
| + }
|
| + else
|
| + {
|
| + reps[2] = b0;
|
| + reps[0] = prevOpt->reps[dist];
|
| + reps[3] = prevOpt->reps[dist ^ 1];
|
| + }
|
| + }
|
| }
|
| else
|
| {
|
| - UInt32 i;
|
| - reps[0] = (pos - LZMA_NUM_REPS);
|
| - for (i = 1; i < LZMA_NUM_REPS; i++)
|
| - reps[i] = prevOpt->backs[i - 1];
|
| + reps[0] = (dist - LZMA_NUM_REPS + 1);
|
| + reps[1] = b0;
|
| + reps[2] = prevOpt->reps[1];
|
| + reps[3] = prevOpt->reps[2];
|
| }
|
| }
|
| +
|
| curOpt->state = (CState)state;
|
| + curOpt->reps[0] = reps[0];
|
| + curOpt->reps[1] = reps[1];
|
| + curOpt->reps[2] = reps[2];
|
| + curOpt->reps[3] = reps[3];
|
|
|
| - curOpt->backs[0] = reps[0];
|
| - curOpt->backs[1] = reps[1];
|
| - curOpt->backs[2] = reps[2];
|
| - curOpt->backs[3] = reps[3];
|
| -
|
| - curPrice = curOpt->price;
|
| - nextIsChar = False;
|
| data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| curByte = *data;
|
| - matchByte = *(data - (reps[0] + 1));
|
| + matchByte = *(data - reps[0]);
|
|
|
| + position++;
|
| posState = (position & p->pbMask);
|
|
|
| - curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
|
| - {
|
| - const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
|
| - curAnd1Price +=
|
| - (!IsCharState(state) ?
|
| - LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
|
| - LitEnc_GetPrice(probs, curByte, p->ProbPrices));
|
| - }
|
| + /*
|
| + The order of Price checks:
|
| + < LIT
|
| + <= SHORT_REP
|
| + < LIT : REP_0
|
| + < REP [ : LIT : REP_0 ]
|
| + < MATCH [ : LIT : REP_0 ]
|
| + */
|
| +
|
| + curPrice = curOpt->price;
|
| + litPrice = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
|
|
|
| - nextOpt = &p->opt[cur + 1];
|
| + nextOpt = &p->opt[(size_t)cur + 1];
|
| + nextIsLit = False;
|
|
|
| - if (curAnd1Price < nextOpt->price)
|
| + // if (litPrice >= nextOpt->price) litPrice = 0; else // 18.new
|
| {
|
| - nextOpt->price = curAnd1Price;
|
| - nextOpt->posPrev = cur;
|
| - MakeAsChar(nextOpt);
|
| - nextIsChar = True;
|
| + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
|
| + litPrice += (!IsLitState(state) ?
|
| + LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
|
| + LitEnc_GetPrice(probs, curByte, p->ProbPrices));
|
| +
|
| + if (litPrice < nextOpt->price)
|
| + {
|
| + nextOpt->price = litPrice;
|
| + nextOpt->len = 1;
|
| + MakeAs_Lit(nextOpt);
|
| + nextIsLit = True;
|
| + }
|
| }
|
|
|
| matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
|
| repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
|
|
|
| - if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
|
| + // ---------- SHORT_REP ----------
|
| + // if (IsLitState(state)) // 18.new
|
| + if (matchByte == curByte)
|
| + // if (repMatchPrice < nextOpt->price) // 18.new
|
| + if (nextOpt->len < 2
|
| + || (nextOpt->dist != 0
|
| + && nextOpt->extra <= 1 // 17.old
|
| + ))
|
| {
|
| - UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
|
| - if (shortRepPrice <= nextOpt->price)
|
| + UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState);
|
| + if (shortRepPrice <= nextOpt->price) // 17.old
|
| + // if (shortRepPrice < nextOpt->price) // 18.new
|
| {
|
| nextOpt->price = shortRepPrice;
|
| - nextOpt->posPrev = cur;
|
| - MakeAsShortRep(nextOpt);
|
| - nextIsChar = True;
|
| + nextOpt->len = 1;
|
| + MakeAs_ShortRep(nextOpt);
|
| + nextIsLit = False;
|
| }
|
| }
|
| +
|
| numAvailFull = p->numAvail;
|
| {
|
| UInt32 temp = kNumOpts - 1 - cur;
|
| - if (temp < numAvailFull)
|
| + if (numAvailFull > temp)
|
| numAvailFull = temp;
|
| }
|
|
|
| @@ -1327,41 +1447,53 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
| continue;
|
| numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
|
|
|
| - if (!nextIsChar && matchByte != curByte) /* speed optimization */
|
| + // numAvail <= p->numFastBytes
|
| +
|
| + // ---------- LIT : REP_0 ----------
|
| +
|
| + if (
|
| + // litPrice != 0 && // 18.new
|
| + !nextIsLit
|
| + && matchByte != curByte
|
| + && numAvailFull > 2)
|
| {
|
| - /* try Literal + rep0 */
|
| - UInt32 temp;
|
| - UInt32 lenTest2;
|
| - const Byte *data2 = data - reps[0] - 1;
|
| - UInt32 limit = p->numFastBytes + 1;
|
| - if (limit > numAvailFull)
|
| - limit = numAvailFull;
|
| -
|
| - for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
|
| - lenTest2 = temp - 1;
|
| - if (lenTest2 >= 2)
|
| + const Byte *data2 = data - reps[0];
|
| + if (data[1] == data2[1] && data[2] == data2[2])
|
| {
|
| - UInt32 state2 = kLiteralNextStates[state];
|
| - UInt32 posStateNext = (position + 1) & p->pbMask;
|
| - UInt32 nextRepMatchPrice = curAnd1Price +
|
| - GET_PRICE_1(p->isMatch[state2][posStateNext]) +
|
| - GET_PRICE_1(p->isRep[state2]);
|
| - /* for (; lenTest2 >= 2; lenTest2--) */
|
| + unsigned len;
|
| + unsigned limit = p->numFastBytes + 1;
|
| + if (limit > numAvailFull)
|
| + limit = numAvailFull;
|
| + for (len = 3; len < limit && data[len] == data2[len]; len++);
|
| +
|
| {
|
| - UInt32 curAndLenPrice;
|
| - COptimal *opt;
|
| - UInt32 offset = cur + 1 + lenTest2;
|
| - while (lenEnd < offset)
|
| - p->opt[++lenEnd].price = kInfinityPrice;
|
| - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
| - opt = &p->opt[offset];
|
| - if (curAndLenPrice < opt->price)
|
| + unsigned state2 = kLiteralNextStates[state];
|
| + unsigned posState2 = (position + 1) & p->pbMask;
|
| + UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2);
|
| {
|
| - opt->price = curAndLenPrice;
|
| - opt->posPrev = cur + 1;
|
| - opt->backPrev = 0;
|
| - opt->prev1IsChar = True;
|
| - opt->prev2 = False;
|
| + unsigned offset = cur + len;
|
| + while (last < offset)
|
| + p->opt[++last].price = kInfinityPrice;
|
| +
|
| + // do
|
| + {
|
| + UInt32 price2;
|
| + COptimal *opt;
|
| + len--;
|
| + // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2);
|
| + price2 = price + p->repLenEnc.prices[posState2][len - LZMA_MATCH_LEN_MIN];
|
| +
|
| + opt = &p->opt[offset];
|
| + // offset--;
|
| + if (price2 < opt->price)
|
| + {
|
| + opt->price = price2;
|
| + opt->len = len;
|
| + opt->dist = 0;
|
| + opt->extra = 1;
|
| + }
|
| + }
|
| + // while (len >= 3);
|
| }
|
| }
|
| }
|
| @@ -1369,87 +1501,105 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
|
|
| startLen = 2; /* speed optimization */
|
| {
|
| - UInt32 repIndex;
|
| - for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
|
| - {
|
| - UInt32 lenTest;
|
| - UInt32 lenTestTemp;
|
| - UInt32 price;
|
| - const Byte *data2 = data - reps[repIndex] - 1;
|
| - if (data[0] != data2[0] || data[1] != data2[1])
|
| - continue;
|
| - for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
|
| - while (lenEnd < cur + lenTest)
|
| - p->opt[++lenEnd].price = kInfinityPrice;
|
| - lenTestTemp = lenTest;
|
| - price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
|
| - do
|
| + // ---------- REP ----------
|
| + unsigned repIndex = 0; // 17.old
|
| + // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused
|
| + for (; repIndex < LZMA_NUM_REPS; repIndex++)
|
| {
|
| - UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
|
| - COptimal *opt = &p->opt[cur + lenTest];
|
| - if (curAndLenPrice < opt->price)
|
| + unsigned len;
|
| + UInt32 price;
|
| + const Byte *data2 = data - reps[repIndex];
|
| + if (data[0] != data2[0] || data[1] != data2[1])
|
| + continue;
|
| +
|
| + for (len = 2; len < numAvail && data[len] == data2[len]; len++);
|
| +
|
| + // if (len < startLen) continue; // 18.new: speed optimization
|
| +
|
| + while (last < cur + len)
|
| + p->opt[++last].price = kInfinityPrice;
|
| {
|
| - opt->price = curAndLenPrice;
|
| - opt->posPrev = cur;
|
| - opt->backPrev = repIndex;
|
| - opt->prev1IsChar = False;
|
| + unsigned len2 = len;
|
| + price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState);
|
| + do
|
| + {
|
| + UInt32 price2 = price + p->repLenEnc.prices[posState][(size_t)len2 - 2];
|
| + COptimal *opt = &p->opt[cur + len2];
|
| + if (price2 < opt->price)
|
| + {
|
| + opt->price = price2;
|
| + opt->len = len2;
|
| + opt->dist = repIndex;
|
| + opt->extra = 0;
|
| + }
|
| + }
|
| + while (--len2 >= 2);
|
| }
|
| - }
|
| - while (--lenTest >= 2);
|
| - lenTest = lenTestTemp;
|
| -
|
| - if (repIndex == 0)
|
| - startLen = lenTest + 1;
|
|
|
| - /* if (_maxMode) */
|
| + if (repIndex == 0) startLen = len + 1; // 17.old
|
| + // startLen = len + 1; // 18.new
|
| +
|
| + /* if (_maxMode) */
|
| {
|
| - UInt32 lenTest2 = lenTest + 1;
|
| - UInt32 limit = lenTest2 + p->numFastBytes;
|
| + // ---------- REP : LIT : REP_0 ----------
|
| + // numFastBytes + 1 + numFastBytes
|
| +
|
| + unsigned len2 = len + 1;
|
| + unsigned limit = len2 + p->numFastBytes;
|
| if (limit > numAvailFull)
|
| limit = numAvailFull;
|
| - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
|
| - lenTest2 -= lenTest + 1;
|
| - if (lenTest2 >= 2)
|
| +
|
| + for (; len2 < limit && data[len2] == data2[len2]; len2++);
|
| +
|
| + len2 -= len;
|
| + if (len2 >= 3)
|
| {
|
| - UInt32 nextRepMatchPrice;
|
| - UInt32 state2 = kRepNextStates[state];
|
| - UInt32 posStateNext = (position + lenTest) & p->pbMask;
|
| - UInt32 curAndLenCharPrice =
|
| - price + p->repLenEnc.prices[posState][lenTest - 2] +
|
| - GET_PRICE_0(p->isMatch[state2][posStateNext]) +
|
| - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
|
| - data[lenTest], data2[lenTest], p->ProbPrices);
|
| - state2 = kLiteralNextStates[state2];
|
| - posStateNext = (position + lenTest + 1) & p->pbMask;
|
| - nextRepMatchPrice = curAndLenCharPrice +
|
| - GET_PRICE_1(p->isMatch[state2][posStateNext]) +
|
| - GET_PRICE_1(p->isRep[state2]);
|
| + unsigned state2 = kRepNextStates[state];
|
| + unsigned posState2 = (position + len) & p->pbMask;
|
| + price +=
|
| + p->repLenEnc.prices[posState][(size_t)len - 2]
|
| + + GET_PRICE_0(p->isMatch[state2][posState2])
|
| + + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
|
| + data[len], data2[len], p->ProbPrices);
|
|
|
| - /* for (; lenTest2 >= 2; lenTest2--) */
|
| + // state2 = kLiteralNextStates[state2];
|
| + state2 = kState_LitAfterRep;
|
| + posState2 = (posState2 + 1) & p->pbMask;
|
| +
|
| +
|
| + price += GetPrice_Rep_0(p, state2, posState2);
|
| {
|
| - UInt32 curAndLenPrice;
|
| - COptimal *opt;
|
| - UInt32 offset = cur + lenTest + 1 + lenTest2;
|
| - while (lenEnd < offset)
|
| - p->opt[++lenEnd].price = kInfinityPrice;
|
| - curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
| - opt = &p->opt[offset];
|
| - if (curAndLenPrice < opt->price)
|
| + unsigned offset = cur + len + len2;
|
| + while (last < offset)
|
| + p->opt[++last].price = kInfinityPrice;
|
| + // do
|
| {
|
| - opt->price = curAndLenPrice;
|
| - opt->posPrev = cur + lenTest + 1;
|
| - opt->backPrev = 0;
|
| - opt->prev1IsChar = True;
|
| - opt->prev2 = True;
|
| - opt->posPrev2 = cur;
|
| - opt->backPrev2 = repIndex;
|
| + unsigned price2;
|
| + COptimal *opt;
|
| + len2--;
|
| + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
|
| + price2 = price + p->repLenEnc.prices[posState2][len2 - LZMA_MATCH_LEN_MIN];
|
| +
|
| + opt = &p->opt[offset];
|
| + // offset--;
|
| + if (price2 < opt->price)
|
| + {
|
| + opt->price = price2;
|
| + opt->len = len2;
|
| + opt->extra = (CExtra)(len + 1);
|
| + opt->dist = repIndex;
|
| + }
|
| }
|
| + // while (len2 >= 3);
|
| }
|
| }
|
| }
|
| + }
|
| }
|
| - }
|
| - /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
|
| +
|
| +
|
| + // ---------- MATCH ----------
|
| + /* for (unsigned len = 2; len <= newLen; len++) */
|
| if (newLen > numAvail)
|
| {
|
| newLen = numAvail;
|
| @@ -1457,134 +1607,148 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
| matches[numPairs] = newLen;
|
| numPairs += 2;
|
| }
|
| +
|
| if (newLen >= startLen)
|
| {
|
| UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
|
| - UInt32 offs, curBack, posSlot;
|
| - UInt32 lenTest;
|
| - while (lenEnd < cur + newLen)
|
| - p->opt[++lenEnd].price = kInfinityPrice;
|
| + UInt32 dist;
|
| + unsigned offs, posSlot, len;
|
| + while (last < cur + newLen)
|
| + p->opt[++last].price = kInfinityPrice;
|
|
|
| offs = 0;
|
| while (startLen > matches[offs])
|
| offs += 2;
|
| - curBack = matches[offs + 1];
|
| - GetPosSlot2(curBack, posSlot);
|
| - for (lenTest = /*2*/ startLen; ; lenTest++)
|
| + dist = matches[(size_t)offs + 1];
|
| +
|
| + // if (dist >= kNumFullDistances)
|
| + GetPosSlot2(dist, posSlot);
|
| +
|
| + for (len = /*2*/ startLen; ; len++)
|
| {
|
| - UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
|
| - {
|
| - UInt32 lenToPosState = GetLenToPosState(lenTest);
|
| - COptimal *opt;
|
| - if (curBack < kNumFullDistances)
|
| - curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
|
| - else
|
| - curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
|
| -
|
| - opt = &p->opt[cur + lenTest];
|
| - if (curAndLenPrice < opt->price)
|
| + UInt32 price = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
|
| {
|
| - opt->price = curAndLenPrice;
|
| - opt->posPrev = cur;
|
| - opt->backPrev = curBack + LZMA_NUM_REPS;
|
| - opt->prev1IsChar = False;
|
| - }
|
| + COptimal *opt;
|
| + unsigned lenToPosState = len - 2; lenToPosState = GetLenToPosState2(lenToPosState);
|
| + if (dist < kNumFullDistances)
|
| + price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
|
| + else
|
| + price += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[dist & kAlignMask];
|
| +
|
| + opt = &p->opt[cur + len];
|
| + if (price < opt->price)
|
| + {
|
| + opt->price = price;
|
| + opt->len = len;
|
| + opt->dist = dist + LZMA_NUM_REPS;
|
| + opt->extra = 0;
|
| + }
|
| }
|
|
|
| - if (/*_maxMode && */lenTest == matches[offs])
|
| + if (/*_maxMode && */ len == matches[offs])
|
| {
|
| - /* Try Match + Literal + Rep0 */
|
| - const Byte *data2 = data - curBack - 1;
|
| - UInt32 lenTest2 = lenTest + 1;
|
| - UInt32 limit = lenTest2 + p->numFastBytes;
|
| + // MATCH : LIT : REP_0
|
| +
|
| + const Byte *data2 = data - dist - 1;
|
| + unsigned len2 = len + 1;
|
| + unsigned limit = len2 + p->numFastBytes;
|
| if (limit > numAvailFull)
|
| limit = numAvailFull;
|
| - for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
|
| - lenTest2 -= lenTest + 1;
|
| - if (lenTest2 >= 2)
|
| +
|
| + for (; len2 < limit && data[len2] == data2[len2]; len2++);
|
| +
|
| + len2 -= len;
|
| +
|
| + if (len2 >= 3)
|
| {
|
| - UInt32 nextRepMatchPrice;
|
| - UInt32 state2 = kMatchNextStates[state];
|
| - UInt32 posStateNext = (position + lenTest) & p->pbMask;
|
| - UInt32 curAndLenCharPrice = curAndLenPrice +
|
| - GET_PRICE_0(p->isMatch[state2][posStateNext]) +
|
| - LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
|
| - data[lenTest], data2[lenTest], p->ProbPrices);
|
| - state2 = kLiteralNextStates[state2];
|
| - posStateNext = (posStateNext + 1) & p->pbMask;
|
| - nextRepMatchPrice = curAndLenCharPrice +
|
| - GET_PRICE_1(p->isMatch[state2][posStateNext]) +
|
| - GET_PRICE_1(p->isRep[state2]);
|
| -
|
| - /* for (; lenTest2 >= 2; lenTest2--) */
|
| + unsigned state2 = kMatchNextStates[state];
|
| + unsigned posState2 = (position + len) & p->pbMask;
|
| + unsigned offset;
|
| + price += GET_PRICE_0(p->isMatch[state2][posState2]);
|
| + price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
|
| + data[len], data2[len], p->ProbPrices);
|
| +
|
| + // state2 = kLiteralNextStates[state2];
|
| + state2 = kState_LitAfterMatch;
|
| +
|
| + posState2 = (posState2 + 1) & p->pbMask;
|
| + price += GetPrice_Rep_0(p, state2, posState2);
|
| +
|
| + offset = cur + len + len2;
|
| + while (last < offset)
|
| + p->opt[++last].price = kInfinityPrice;
|
| + // do
|
| {
|
| - UInt32 offset = cur + lenTest + 1 + lenTest2;
|
| - UInt32 curAndLenPrice2;
|
| + UInt32 price2;
|
| COptimal *opt;
|
| - while (lenEnd < offset)
|
| - p->opt[++lenEnd].price = kInfinityPrice;
|
| - curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
|
| + len2--;
|
| + // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
|
| + price2 = price + p->repLenEnc.prices[posState2][len2 - LZMA_MATCH_LEN_MIN];
|
| opt = &p->opt[offset];
|
| - if (curAndLenPrice2 < opt->price)
|
| + // offset--;
|
| + if (price2 < opt->price)
|
| {
|
| - opt->price = curAndLenPrice2;
|
| - opt->posPrev = cur + lenTest + 1;
|
| - opt->backPrev = 0;
|
| - opt->prev1IsChar = True;
|
| - opt->prev2 = True;
|
| - opt->posPrev2 = cur;
|
| - opt->backPrev2 = curBack + LZMA_NUM_REPS;
|
| + opt->price = price2;
|
| + opt->len = len2;
|
| + opt->extra = (CExtra)(len + 1);
|
| + opt->dist = dist + LZMA_NUM_REPS;
|
| }
|
| }
|
| + // while (len2 >= 3);
|
| }
|
| +
|
| offs += 2;
|
| if (offs == numPairs)
|
| break;
|
| - curBack = matches[offs + 1];
|
| - if (curBack >= kNumFullDistances)
|
| - GetPosSlot2(curBack, posSlot);
|
| + dist = matches[(size_t)offs + 1];
|
| + // if (dist >= kNumFullDistances)
|
| + GetPosSlot2(dist, posSlot);
|
| }
|
| }
|
| }
|
| }
|
| }
|
|
|
| +
|
| +
|
| #define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
|
|
|
| -static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
|
| +
|
| +
|
| +static unsigned GetOptimumFast(CLzmaEnc *p)
|
| {
|
| - UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
|
| + UInt32 numAvail, mainDist;
|
| + unsigned mainLen, numPairs, repIndex, repLen, i;
|
| const Byte *data;
|
| - const UInt32 *matches;
|
|
|
| if (p->additionalOffset == 0)
|
| mainLen = ReadMatchDistances(p, &numPairs);
|
| else
|
| {
|
| - mainLen = p->longestMatchLength;
|
| + mainLen = p->longestMatchLen;
|
| numPairs = p->numPairs;
|
| }
|
|
|
| numAvail = p->numAvail;
|
| - *backRes = (UInt32)-1;
|
| + p->backRes = MARK_LIT;
|
| if (numAvail < 2)
|
| return 1;
|
| if (numAvail > LZMA_MATCH_LEN_MAX)
|
| numAvail = LZMA_MATCH_LEN_MAX;
|
| data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| -
|
| repLen = repIndex = 0;
|
| +
|
| for (i = 0; i < LZMA_NUM_REPS; i++)
|
| {
|
| - UInt32 len;
|
| - const Byte *data2 = data - p->reps[i] - 1;
|
| + unsigned len;
|
| + const Byte *data2 = data - p->reps[i];
|
| if (data[0] != data2[0] || data[1] != data2[1])
|
| continue;
|
| for (len = 2; len < numAvail && data[len] == data2[len]; len++);
|
| if (len >= p->numFastBytes)
|
| {
|
| - *backRes = i;
|
| - MovePos(p, len - 1);
|
| + p->backRes = i;
|
| + MOVE_POS(p, len - 1)
|
| return len;
|
| }
|
| if (len > repLen)
|
| @@ -1594,84 +1758,152 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) |
| }
|
| }
|
|
|
| - matches = p->matches;
|
| if (mainLen >= p->numFastBytes)
|
| {
|
| - *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
|
| - MovePos(p, mainLen - 1);
|
| + p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
|
| + MOVE_POS(p, mainLen - 1)
|
| return mainLen;
|
| }
|
|
|
| mainDist = 0; /* for GCC */
|
| +
|
| if (mainLen >= 2)
|
| {
|
| - mainDist = matches[numPairs - 1];
|
| - while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
|
| + mainDist = p->matches[(size_t)numPairs - 1];
|
| + while (numPairs > 2)
|
| {
|
| - if (!ChangePair(matches[numPairs - 3], mainDist))
|
| + UInt32 dist2;
|
| + if (mainLen != p->matches[(size_t)numPairs - 4] + 1)
|
| + break;
|
| + dist2 = p->matches[(size_t)numPairs - 3];
|
| + if (!ChangePair(dist2, mainDist))
|
| break;
|
| numPairs -= 2;
|
| - mainLen = matches[numPairs - 2];
|
| - mainDist = matches[numPairs - 1];
|
| + mainLen--;
|
| + mainDist = dist2;
|
| }
|
| if (mainLen == 2 && mainDist >= 0x80)
|
| mainLen = 1;
|
| }
|
|
|
| - if (repLen >= 2 && (
|
| - (repLen + 1 >= mainLen) ||
|
| - (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
|
| - (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
|
| + if (repLen >= 2)
|
| + if ( repLen + 1 >= mainLen
|
| + || (repLen + 2 >= mainLen && mainDist >= (1 << 9))
|
| + || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))
|
| {
|
| - *backRes = repIndex;
|
| - MovePos(p, repLen - 1);
|
| + p->backRes = repIndex;
|
| + MOVE_POS(p, repLen - 1)
|
| return repLen;
|
| }
|
|
|
| if (mainLen < 2 || numAvail <= 2)
|
| return 1;
|
|
|
| - p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
|
| - if (p->longestMatchLength >= 2)
|
| {
|
| - UInt32 newDistance = matches[p->numPairs - 1];
|
| - if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
|
| - (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
|
| - (p->longestMatchLength > mainLen + 1) ||
|
| - (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
|
| - return 1;
|
| + unsigned len1 = ReadMatchDistances(p, &p->numPairs);
|
| + p->longestMatchLen = len1;
|
| +
|
| + if (len1 >= 2)
|
| + {
|
| + UInt32 newDist = p->matches[(size_t)p->numPairs - 1];
|
| + if ( (len1 >= mainLen && newDist < mainDist)
|
| + || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))
|
| + || (len1 > mainLen + 1)
|
| + || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))
|
| + return 1;
|
| + }
|
| }
|
|
|
| data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
| +
|
| for (i = 0; i < LZMA_NUM_REPS; i++)
|
| {
|
| - UInt32 len, limit;
|
| - const Byte *data2 = data - p->reps[i] - 1;
|
| + unsigned len, limit;
|
| + const Byte *data2 = data - p->reps[i];
|
| if (data[0] != data2[0] || data[1] != data2[1])
|
| continue;
|
| limit = mainLen - 1;
|
| - for (len = 2; len < limit && data[len] == data2[len]; len++);
|
| - if (len >= limit)
|
| - return 1;
|
| + for (len = 2;; len++)
|
| + {
|
| + if (len >= limit)
|
| + return 1;
|
| + if (data[len] != data2[len])
|
| + break;
|
| + }
|
| + }
|
| +
|
| + p->backRes = mainDist + LZMA_NUM_REPS;
|
| + if (mainLen != 2)
|
| + {
|
| + MOVE_POS(p, mainLen - 2)
|
| }
|
| - *backRes = mainDist + LZMA_NUM_REPS;
|
| - MovePos(p, mainLen - 2);
|
| return mainLen;
|
| }
|
|
|
| -static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
|
| +
|
| +
|
| +
|
| +static void WriteEndMarker(CLzmaEnc *p, unsigned posState)
|
| {
|
| - UInt32 len;
|
| - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
|
| + UInt32 range;
|
| + range = p->rc.range;
|
| + {
|
| + UInt32 ttt, newBound;
|
| + CLzmaProb *prob = &p->isMatch[p->state][posState];
|
| + RC_BIT_PRE(&p->rc, prob)
|
| + RC_BIT_1(&p->rc, prob)
|
| + prob = &p->isRep[p->state];
|
| + RC_BIT_PRE(&p->rc, prob)
|
| + RC_BIT_0(&p->rc, prob)
|
| + }
|
| p->state = kMatchNextStates[p->state];
|
| - len = LZMA_MATCH_LEN_MIN;
|
| - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
|
| - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
|
| - RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
|
| - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
|
| +
|
| + p->rc.range = range;
|
| + LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState);
|
| + range = p->rc.range;
|
| +
|
| + {
|
| + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1);
|
| + CLzmaProb *probs = p->posSlotEncoder[0];
|
| + unsigned m = 1;
|
| + do
|
| + {
|
| + UInt32 ttt, newBound;
|
| + RC_BIT_PRE(p, probs + m)
|
| + RC_BIT_1(&p->rc, probs + m);
|
| + m = (m << 1) + 1;
|
| + }
|
| + while (m < (1 << kNumPosSlotBits));
|
| + }
|
| + {
|
| + // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range;
|
| + unsigned numBits = 30 - kNumAlignBits;
|
| + do
|
| + {
|
| + range >>= 1;
|
| + p->rc.low += range;
|
| + RC_NORM(&p->rc)
|
| + }
|
| + while (--numBits);
|
| + }
|
| +
|
| + {
|
| + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
|
| + CLzmaProb *probs = p->posAlignEncoder;
|
| + unsigned m = 1;
|
| + do
|
| + {
|
| + UInt32 ttt, newBound;
|
| + RC_BIT_PRE(p, probs + m)
|
| + RC_BIT_1(&p->rc, probs + m);
|
| + m = (m << 1) + 1;
|
| + }
|
| + while (m < kAlignTableSize);
|
| + }
|
| + p->rc.range = range;
|
| }
|
|
|
| +
|
| static SRes CheckErrors(CLzmaEnc *p)
|
| {
|
| if (p->result != SZ_OK)
|
| @@ -1685,7 +1917,8 @@ static SRes CheckErrors(CLzmaEnc *p) |
| return p->result;
|
| }
|
|
|
| -static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
|
| +
|
| +MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
|
| {
|
| /* ReleaseMFStream(); */
|
| p->finished = True;
|
| @@ -1696,47 +1929,108 @@ static SRes Flush(CLzmaEnc *p, UInt32 nowPos) |
| return CheckErrors(p);
|
| }
|
|
|
| +
|
| +
|
| static void FillAlignPrices(CLzmaEnc *p)
|
| {
|
| - UInt32 i;
|
| - for (i = 0; i < kAlignTableSize; i++)
|
| - p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
|
| + unsigned i;
|
| + const CProbPrice *ProbPrices = p->ProbPrices;
|
| + const CLzmaProb *probs = p->posAlignEncoder;
|
| p->alignPriceCount = 0;
|
| + for (i = 0; i < kAlignTableSize / 2; i++)
|
| + {
|
| + UInt32 price = 0;
|
| + unsigned symbol = i;
|
| + unsigned m = 1;
|
| + unsigned bit;
|
| + UInt32 prob;
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
|
| + prob = probs[m];
|
| + p->alignPrices[i ] = price + GET_PRICEa_0(prob);
|
| + p->alignPrices[i + 8] = price + GET_PRICEa_1(prob);
|
| + // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
|
| + }
|
| }
|
|
|
| +
|
| static void FillDistancesPrices(CLzmaEnc *p)
|
| {
|
| UInt32 tempPrices[kNumFullDistances];
|
| - UInt32 i, lenToPosState;
|
| + unsigned i, lenToPosState;
|
| +
|
| + const CProbPrice *ProbPrices = p->ProbPrices;
|
| + p->matchPriceCount = 0;
|
| +
|
| for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
|
| {
|
| - UInt32 posSlot = GetPosSlot1(i);
|
| - UInt32 footerBits = ((posSlot >> 1) - 1);
|
| - UInt32 base = ((2 | (posSlot & 1)) << footerBits);
|
| - tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
|
| + unsigned posSlot = GetPosSlot1(i);
|
| + unsigned footerBits = ((posSlot >> 1) - 1);
|
| + unsigned base = ((2 | (posSlot & 1)) << footerBits);
|
| + // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices);
|
| +
|
| + const CLzmaProb *probs = p->posEncoders + base;
|
| + UInt32 price = 0;
|
| + unsigned m = 1;
|
| + unsigned symbol = i - base;
|
| + do
|
| + {
|
| + unsigned bit = symbol & 1;
|
| + symbol >>= 1;
|
| + price += GET_PRICEa(probs[m], bit);
|
| + m = (m << 1) + bit;
|
| + }
|
| + while (--footerBits);
|
| + tempPrices[i] = price;
|
| }
|
|
|
| for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
|
| {
|
| - UInt32 posSlot;
|
| + unsigned posSlot;
|
| const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
|
| UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
|
| - for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
|
| - posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
|
| - for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
|
| - posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
|
| + unsigned distTableSize = p->distTableSize;
|
| + const CLzmaProb *probs = encoder;
|
| + for (posSlot = 0; posSlot < distTableSize; posSlot += 2)
|
| + {
|
| + // posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
|
| + UInt32 price = 0;
|
| + unsigned bit;
|
| + unsigned symbol = (posSlot >> 1) + (1 << (kNumPosSlotBits - 1));
|
| + UInt32 prob;
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
|
| + bit = symbol & 1; symbol >>= 1; price += GET_PRICEa(probs[symbol], bit);
|
| + prob = probs[(posSlot >> 1) + (1 << (kNumPosSlotBits - 1))];
|
| + posSlotPrices[posSlot ] = price + GET_PRICEa_0(prob);
|
| + posSlotPrices[posSlot + 1] = price + GET_PRICEa_1(prob);
|
| + }
|
| + for (posSlot = kEndPosModelIndex; posSlot < distTableSize; posSlot++)
|
| + posSlotPrices[posSlot] += ((UInt32)(((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
|
|
|
| {
|
| UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
|
| - for (i = 0; i < kStartPosModelIndex; i++)
|
| - distancesPrices[i] = posSlotPrices[i];
|
| - for (; i < kNumFullDistances; i++)
|
| - distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
|
| + {
|
| + distancesPrices[0] = posSlotPrices[0];
|
| + distancesPrices[1] = posSlotPrices[1];
|
| + distancesPrices[2] = posSlotPrices[2];
|
| + distancesPrices[3] = posSlotPrices[3];
|
| + }
|
| + for (i = 4; i < kNumFullDistances; i += 2)
|
| + {
|
| + UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)];
|
| + distancesPrices[i ] = slotPrice + tempPrices[i];
|
| + distancesPrices[i + 1] = slotPrice + tempPrices[i + 1];
|
| + }
|
| }
|
| }
|
| - p->matchPriceCount = 0;
|
| }
|
|
|
| +
|
| +
|
| void LzmaEnc_Construct(CLzmaEnc *p)
|
| {
|
| RangeEnc_Construct(&p->rc);
|
| @@ -1760,26 +2054,27 @@ void LzmaEnc_Construct(CLzmaEnc *p) |
| LzmaEnc_InitPriceTables(p->ProbPrices);
|
| p->litProbs = NULL;
|
| p->saveState.litProbs = NULL;
|
| +
|
| }
|
|
|
| -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
|
| +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
|
| {
|
| void *p;
|
| - p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
|
| + p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
|
| if (p)
|
| LzmaEnc_Construct((CLzmaEnc *)p);
|
| return p;
|
| }
|
|
|
| -void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
| +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
|
| {
|
| - alloc->Free(alloc, p->litProbs);
|
| - alloc->Free(alloc, p->saveState.litProbs);
|
| + ISzAlloc_Free(alloc, p->litProbs);
|
| + ISzAlloc_Free(alloc, p->saveState.litProbs);
|
| p->litProbs = NULL;
|
| p->saveState.litProbs = NULL;
|
| }
|
|
|
| -void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| #ifndef _7ZIP_ST
|
| MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
|
| @@ -1790,13 +2085,14 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) |
| RangeEnc_Free(&p->rc, alloc);
|
| }
|
|
|
| -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
|
| - alloc->Free(alloc, p);
|
| + ISzAlloc_Free(alloc, p);
|
| }
|
|
|
| -static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
|
| +
|
| +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize)
|
| {
|
| UInt32 nowPos32, startPos32;
|
| if (p->needInit)
|
| @@ -1814,13 +2110,13 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
|
|
| if (p->nowPos64 == 0)
|
| {
|
| - UInt32 numPairs;
|
| + unsigned numPairs;
|
| Byte curByte;
|
| if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
|
| return Flush(p, nowPos32);
|
| ReadMatchDistances(p, &numPairs);
|
| - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
|
| - p->state = kLiteralNextStates[p->state];
|
| + RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]);
|
| + // p->state = kLiteralNextStates[p->state];
|
| curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
|
| LitEnc_Encode(&p->rc, p->litProbs, curByte);
|
| p->additionalOffset--;
|
| @@ -1828,109 +2124,225 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
| }
|
|
|
| if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
|
| +
|
| for (;;)
|
| {
|
| - UInt32 pos, len, posState;
|
| -
|
| + UInt32 dist;
|
| + unsigned len, posState;
|
| + UInt32 range, ttt, newBound;
|
| + CLzmaProb *probs;
|
| +
|
| if (p->fastMode)
|
| - len = GetOptimumFast(p, &pos);
|
| + len = GetOptimumFast(p);
|
| else
|
| - len = GetOptimum(p, nowPos32, &pos);
|
| + {
|
| + unsigned oci = p->optCur;
|
| + if (p->optEnd == oci)
|
| + len = GetOptimum(p, nowPos32);
|
| + else
|
| + {
|
| + const COptimal *opt = &p->opt[oci];
|
| + len = opt->len;
|
| + p->backRes = opt->dist;
|
| + p->optCur = oci + 1;
|
| + }
|
| + }
|
| +
|
| + posState = (unsigned)nowPos32 & p->pbMask;
|
| + range = p->rc.range;
|
| + probs = &p->isMatch[p->state][posState];
|
| +
|
| + RC_BIT_PRE(&p->rc, probs)
|
| +
|
| + dist = p->backRes;
|
|
|
| #ifdef SHOW_STAT2
|
| - printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
|
| + printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist);
|
| #endif
|
|
|
| - posState = nowPos32 & p->pbMask;
|
| - if (len == 1 && pos == (UInt32)-1)
|
| + if (dist == MARK_LIT)
|
| {
|
| Byte curByte;
|
| - CLzmaProb *probs;
|
| const Byte *data;
|
| + unsigned state;
|
|
|
| - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
|
| + RC_BIT_0(&p->rc, probs);
|
| + p->rc.range = range;
|
| data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
|
| - curByte = *data;
|
| probs = LIT_PROBS(nowPos32, *(data - 1));
|
| - if (IsCharState(p->state))
|
| + curByte = *data;
|
| + state = p->state;
|
| + p->state = kLiteralNextStates[state];
|
| + if (IsLitState(state))
|
| LitEnc_Encode(&p->rc, probs, curByte);
|
| else
|
| - LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
|
| - p->state = kLiteralNextStates[p->state];
|
| + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0]));
|
| }
|
| else
|
| {
|
| - RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
|
| - if (pos < LZMA_NUM_REPS)
|
| + RC_BIT_1(&p->rc, probs);
|
| + probs = &p->isRep[p->state];
|
| + RC_BIT_PRE(&p->rc, probs)
|
| +
|
| + if (dist < LZMA_NUM_REPS)
|
| {
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
|
| - if (pos == 0)
|
| + RC_BIT_1(&p->rc, probs);
|
| + probs = &p->isRepG0[p->state];
|
| + RC_BIT_PRE(&p->rc, probs)
|
| + if (dist == 0)
|
| {
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
|
| + RC_BIT_0(&p->rc, probs);
|
| + probs = &p->isRep0Long[p->state][posState];
|
| + RC_BIT_PRE(&p->rc, probs)
|
| + if (len != 1)
|
| + {
|
| + RC_BIT_1_BASE(&p->rc, probs);
|
| + }
|
| + else
|
| + {
|
| + RC_BIT_0_BASE(&p->rc, probs);
|
| + p->state = kShortRepNextStates[p->state];
|
| + }
|
| }
|
| else
|
| {
|
| - UInt32 distance = p->reps[pos];
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
|
| - if (pos == 1)
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
|
| + RC_BIT_1(&p->rc, probs);
|
| + probs = &p->isRepG1[p->state];
|
| + RC_BIT_PRE(&p->rc, probs)
|
| + if (dist == 1)
|
| + {
|
| + RC_BIT_0_BASE(&p->rc, probs);
|
| + dist = p->reps[1];
|
| + }
|
| else
|
| {
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
|
| - if (pos == 3)
|
| + RC_BIT_1(&p->rc, probs);
|
| + probs = &p->isRepG2[p->state];
|
| + RC_BIT_PRE(&p->rc, probs)
|
| + if (dist == 2)
|
| + {
|
| + RC_BIT_0_BASE(&p->rc, probs);
|
| + dist = p->reps[2];
|
| + }
|
| + else
|
| + {
|
| + RC_BIT_1_BASE(&p->rc, probs);
|
| + dist = p->reps[3];
|
| p->reps[3] = p->reps[2];
|
| + }
|
| p->reps[2] = p->reps[1];
|
| }
|
| p->reps[1] = p->reps[0];
|
| - p->reps[0] = distance;
|
| + p->reps[0] = dist;
|
| }
|
| - if (len == 1)
|
| - p->state = kShortRepNextStates[p->state];
|
| - else
|
| +
|
| + RC_NORM(&p->rc)
|
| +
|
| + p->rc.range = range;
|
| +
|
| + if (len != 1)
|
| {
|
| - LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
|
| + LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
|
| + if (!p->fastMode)
|
| + if (--p->repLenEnc.counters[posState] == 0)
|
| + LenPriceEnc_UpdateTable(&p->repLenEnc, posState, &p->repLenProbs, p->ProbPrices);
|
| +
|
| p->state = kRepNextStates[p->state];
|
| }
|
| }
|
| else
|
| {
|
| - UInt32 posSlot;
|
| - RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
|
| + unsigned posSlot;
|
| + RC_BIT_0(&p->rc, probs);
|
| + p->rc.range = range;
|
| p->state = kMatchNextStates[p->state];
|
| - LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
|
| - pos -= LZMA_NUM_REPS;
|
| - GetPosSlot(pos, posSlot);
|
| - RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
|
| +
|
| + LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
|
| + if (!p->fastMode)
|
| + if (--p->lenEnc.counters[posState] == 0)
|
| + LenPriceEnc_UpdateTable(&p->lenEnc, posState, &p->lenProbs, p->ProbPrices);
|
| +
|
| + dist -= LZMA_NUM_REPS;
|
| + p->reps[3] = p->reps[2];
|
| + p->reps[2] = p->reps[1];
|
| + p->reps[1] = p->reps[0];
|
| + p->reps[0] = dist + 1;
|
|
|
| - if (posSlot >= kStartPosModelIndex)
|
| + p->matchPriceCount++;
|
| + GetPosSlot(dist, posSlot);
|
| + // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot);
|
| + {
|
| + UInt32 symbol = posSlot + (1 << kNumPosSlotBits);
|
| + range = p->rc.range;
|
| + probs = p->posSlotEncoder[GetLenToPosState(len)];
|
| + do
|
| + {
|
| + CLzmaProb *prob = probs + (symbol >> kNumPosSlotBits);
|
| + UInt32 bit = (symbol >> (kNumPosSlotBits - 1)) & 1;
|
| + symbol <<= 1;
|
| + RC_BIT(&p->rc, prob, bit);
|
| + }
|
| + while (symbol < (1 << kNumPosSlotBits * 2));
|
| + p->rc.range = range;
|
| + }
|
| +
|
| + if (dist >= kStartPosModelIndex)
|
| {
|
| - UInt32 footerBits = ((posSlot >> 1) - 1);
|
| - UInt32 base = ((2 | (posSlot & 1)) << footerBits);
|
| - UInt32 posReduced = pos - base;
|
| + unsigned footerBits = ((posSlot >> 1) - 1);
|
|
|
| - if (posSlot < kEndPosModelIndex)
|
| - RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
|
| + if (dist < kNumFullDistances)
|
| + {
|
| + unsigned base = ((2 | (posSlot & 1)) << footerBits);
|
| + RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, dist - base);
|
| + }
|
| else
|
| {
|
| - RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
|
| - RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
|
| - p->alignPriceCount++;
|
| + UInt32 pos2 = (dist | 0xF) << (32 - footerBits);
|
| + range = p->rc.range;
|
| + // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
|
| + /*
|
| + do
|
| + {
|
| + range >>= 1;
|
| + p->rc.low += range & (0 - ((dist >> --footerBits) & 1));
|
| + RC_NORM(&p->rc)
|
| + }
|
| + while (footerBits > kNumAlignBits);
|
| + */
|
| + do
|
| + {
|
| + range >>= 1;
|
| + p->rc.low += range & (0 - (pos2 >> 31));
|
| + pos2 += pos2;
|
| + RC_NORM(&p->rc)
|
| + }
|
| + while (pos2 != 0xF0000000);
|
| +
|
| +
|
| + // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
|
| +
|
| + {
|
| + unsigned m = 1;
|
| + unsigned bit;
|
| + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
|
| + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
|
| + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit;
|
| + bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit);
|
| + p->rc.range = range;
|
| + p->alignPriceCount++;
|
| + }
|
| }
|
| }
|
| - p->reps[3] = p->reps[2];
|
| - p->reps[2] = p->reps[1];
|
| - p->reps[1] = p->reps[0];
|
| - p->reps[0] = pos;
|
| - p->matchPriceCount++;
|
| }
|
| }
|
| - p->additionalOffset -= len;
|
| +
|
| nowPos32 += len;
|
| + p->additionalOffset -= len;
|
| +
|
| if (p->additionalOffset == 0)
|
| {
|
| UInt32 processed;
|
| +
|
| if (!p->fastMode)
|
| {
|
| if (p->matchPriceCount >= (1 << 7))
|
| @@ -1938,13 +2350,15 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
| if (p->alignPriceCount >= kAlignTableSize)
|
| FillAlignPrices(p);
|
| }
|
| +
|
| if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
|
| break;
|
| processed = nowPos32 - startPos32;
|
| - if (useLimits)
|
| +
|
| + if (maxPackSize)
|
| {
|
| - if (processed + kNumOpts + 300 >= maxUnpackSize ||
|
| - RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
|
| + if (processed + kNumOpts + 300 >= maxUnpackSize
|
| + || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize)
|
| break;
|
| }
|
| else if (processed >= (1 << 17))
|
| @@ -1954,13 +2368,16 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
| }
|
| }
|
| }
|
| +
|
| p->nowPos64 += nowPos32 - startPos32;
|
| return Flush(p, nowPos32);
|
| }
|
|
|
| +
|
| +
|
| #define kBigHashDicLimit ((UInt32)1 << 24)
|
|
|
| -static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| UInt32 beforeSize = kNumOpts;
|
| if (!RangeEnc_Alloc(&p->rc, alloc))
|
| @@ -1975,8 +2392,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I |
| if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
|
| {
|
| LzmaEnc_FreeLits(p, alloc);
|
| - p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
| - p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
| + p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
| + p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
| if (!p->litProbs || !p->saveState.litProbs)
|
| {
|
| LzmaEnc_FreeLits(p, alloc);
|
| @@ -1994,8 +2411,13 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I |
| #ifndef _7ZIP_ST
|
| if (p->mtMode)
|
| {
|
| - RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
|
| + RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes,
|
| + LZMA_MATCH_LEN_MAX
|
| + + 1 /* 18.04 */
|
| + , allocBig));
|
| p->matchFinderObj = &p->matchFinderMt;
|
| + p->matchFinderBase.bigHash = (Byte)(
|
| + (p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
|
| MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
|
| }
|
| else
|
| @@ -2012,17 +2434,21 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I |
|
|
| void LzmaEnc_Init(CLzmaEnc *p)
|
| {
|
| - UInt32 i;
|
| + unsigned i;
|
| p->state = 0;
|
| - for (i = 0 ; i < LZMA_NUM_REPS; i++)
|
| - p->reps[i] = 0;
|
| + p->reps[0] =
|
| + p->reps[1] =
|
| + p->reps[2] =
|
| + p->reps[3] = 1;
|
|
|
| RangeEnc_Init(&p->rc);
|
|
|
| + for (i = 0; i < (1 << kNumAlignBits); i++)
|
| + p->posAlignEncoder[i] = kProbInitValue;
|
|
|
| for (i = 0; i < kNumStates; i++)
|
| {
|
| - UInt32 j;
|
| + unsigned j;
|
| for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
|
| {
|
| p->isMatch[i][j] = kProbInitValue;
|
| @@ -2034,39 +2460,38 @@ void LzmaEnc_Init(CLzmaEnc *p) |
| p->isRepG2[i] = kProbInitValue;
|
| }
|
|
|
| - {
|
| - UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
|
| - CLzmaProb *probs = p->litProbs;
|
| - for (i = 0; i < num; i++)
|
| - probs[i] = kProbInitValue;
|
| - }
|
| -
|
| {
|
| for (i = 0; i < kNumLenToPosStates; i++)
|
| {
|
| CLzmaProb *probs = p->posSlotEncoder[i];
|
| - UInt32 j;
|
| + unsigned j;
|
| for (j = 0; j < (1 << kNumPosSlotBits); j++)
|
| probs[j] = kProbInitValue;
|
| }
|
| }
|
| {
|
| - for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
|
| + for (i = 0; i < kNumFullDistances; i++)
|
| p->posEncoders[i] = kProbInitValue;
|
| }
|
|
|
| - LenEnc_Init(&p->lenEnc.p);
|
| - LenEnc_Init(&p->repLenEnc.p);
|
| + {
|
| + UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
|
| + UInt32 k;
|
| + CLzmaProb *probs = p->litProbs;
|
| + for (k = 0; k < num; k++)
|
| + probs[k] = kProbInitValue;
|
| + }
|
|
|
| - for (i = 0; i < (1 << kNumAlignBits); i++)
|
| - p->posAlignEncoder[i] = kProbInitValue;
|
|
|
| - p->optimumEndIndex = 0;
|
| - p->optimumCurrentIndex = 0;
|
| + LenEnc_Init(&p->lenProbs);
|
| + LenEnc_Init(&p->repLenProbs);
|
| +
|
| + p->optEnd = 0;
|
| + p->optCur = 0;
|
| p->additionalOffset = 0;
|
|
|
| p->pbMask = (1 << p->pb) - 1;
|
| - p->lpMask = (1 << p->lp) - 1;
|
| + p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
|
| }
|
|
|
| void LzmaEnc_InitPrices(CLzmaEnc *p)
|
| @@ -2080,14 +2505,14 @@ void LzmaEnc_InitPrices(CLzmaEnc *p) |
| p->lenEnc.tableSize =
|
| p->repLenEnc.tableSize =
|
| p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
|
| - LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
|
| - LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
|
| + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
|
| + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, &p->repLenProbs, p->ProbPrices);
|
| }
|
|
|
| -static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| - UInt32 i;
|
| - for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
|
| + unsigned i;
|
| + for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++)
|
| if (p->dictSize <= ((UInt32)1 << i))
|
| break;
|
| p->distTableSize = i * 2;
|
| @@ -2102,7 +2527,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a |
| }
|
|
|
| static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
|
| - ISzAlloc *alloc, ISzAlloc *allocBig)
|
| + ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
| p->matchFinderBase.stream = inStream;
|
| @@ -2113,7 +2538,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS |
|
|
| SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
|
| ISeqInStream *inStream, UInt32 keepWindowSize,
|
| - ISzAlloc *alloc, ISzAlloc *allocBig)
|
| + ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
| p->matchFinderBase.stream = inStream;
|
| @@ -2129,12 +2554,13 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) |
| }
|
|
|
| SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
| - UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
| LzmaEnc_SetInputBuf(p, src, srcLen);
|
| p->needInit = 1;
|
|
|
| + LzmaEnc_SetDataSize(pp, srcLen);
|
| return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
|
| }
|
|
|
| @@ -2152,15 +2578,15 @@ void LzmaEnc_Finish(CLzmaEncHandle pp) |
|
|
| typedef struct
|
| {
|
| - ISeqOutStream funcTable;
|
| + ISeqOutStream vt;
|
| Byte *data;
|
| SizeT rem;
|
| Bool overflow;
|
| -} CSeqOutStreamBuf;
|
| +} CLzmaEnc_SeqOutStreamBuf;
|
|
|
| -static size_t MyWrite(void *pp, const void *data, size_t size)
|
| +static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size)
|
| {
|
| - CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
|
| + CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt);
|
| if (p->rem < size)
|
| {
|
| size = p->rem;
|
| @@ -2193,9 +2619,9 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, |
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
| UInt64 nowPos64;
|
| SRes res;
|
| - CSeqOutStreamBuf outStream;
|
| + CLzmaEnc_SeqOutStreamBuf outStream;
|
|
|
| - outStream.funcTable.Write = MyWrite;
|
| + outStream.vt.Write = SeqOutStreamBuf_Write;
|
| outStream.data = dest;
|
| outStream.rem = *destLen;
|
| outStream.overflow = False;
|
| @@ -2207,11 +2633,15 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, |
| if (reInit)
|
| LzmaEnc_Init(p);
|
| LzmaEnc_InitPrices(p);
|
| +
|
| nowPos64 = p->nowPos64;
|
| RangeEnc_Init(&p->rc);
|
| - p->rc.outStream = &outStream.funcTable;
|
| + p->rc.outStream = &outStream.vt;
|
| +
|
| + if (desiredPackSize == 0)
|
| + return SZ_ERROR_OUTPUT_EOF;
|
|
|
| - res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
|
| + res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);
|
|
|
| *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
|
| *destLen -= outStream.rem;
|
| @@ -2234,12 +2664,12 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) |
|
|
| for (;;)
|
| {
|
| - res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
|
| + res = LzmaEnc_CodeOneBlock(p, 0, 0);
|
| if (res != SZ_OK || p->finished)
|
| break;
|
| if (progress)
|
| {
|
| - res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
| + res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
| if (res != SZ_OK)
|
| {
|
| res = SZ_ERROR_PROGRESS;
|
| @@ -2251,7 +2681,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) |
| LzmaEnc_Finish(p);
|
|
|
| /*
|
| - if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
|
| + if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
|
| res = SZ_ERROR_FAIL;
|
| }
|
| */
|
| @@ -2261,7 +2691,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) |
|
|
|
|
| SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
| - ISzAlloc *alloc, ISzAlloc *allocBig)
|
| + ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
|
| return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
| @@ -2296,21 +2726,27 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) |
| }
|
|
|
|
|
| +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)
|
| +{
|
| + return ((CLzmaEnc *)pp)->writeEndMark;
|
| +}
|
| +
|
| +
|
| SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
| - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| + int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| SRes res;
|
| CLzmaEnc *p = (CLzmaEnc *)pp;
|
|
|
| - CSeqOutStreamBuf outStream;
|
| + CLzmaEnc_SeqOutStreamBuf outStream;
|
|
|
| - outStream.funcTable.Write = MyWrite;
|
| + outStream.vt.Write = SeqOutStreamBuf_Write;
|
| outStream.data = dest;
|
| outStream.rem = *destLen;
|
| outStream.overflow = False;
|
|
|
| p->writeEndMark = writeEndMark;
|
| - p->rc.outStream = &outStream.funcTable;
|
| + p->rc.outStream = &outStream.vt;
|
|
|
| res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
|
|
| @@ -2330,7 +2766,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte |
|
|
| SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
| const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
| - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
| + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
|
| {
|
| CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
|
| SRes res;
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h |
| index c2806b45f4..c9938f04bc 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h |
| @@ -1,5 +1,5 @@ |
| /* LzmaEnc.h -- LZMA Encoder
|
| -2013-01-18 : Igor Pavlov : Public domain */
|
| +2017-07-27 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __LZMA_ENC_H
|
| #define __LZMA_ENC_H
|
| @@ -12,12 +12,10 @@ EXTERN_C_BEGIN |
|
|
| typedef struct _CLzmaEncProps
|
| {
|
| - int level; /* 0 <= level <= 9 */
|
| + int level; /* 0 <= level <= 9 */
|
| UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
| - (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
| - default = (1 << 24) */
|
| - UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
|
| - Encoder uses this value to reduce dictionary size */
|
| + (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
|
| + default = (1 << 24) */
|
| int lc; /* 0 <= lc <= 8, default = 3 */
|
| int lp; /* 0 <= lp <= 4, default = 0 */
|
| int pb; /* 0 <= pb <= 4, default = 2 */
|
| @@ -25,9 +23,12 @@ typedef struct _CLzmaEncProps |
| int fb; /* 5 <= fb <= 273, default = 32 */
|
| int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
| int numHashBytes; /* 2, 3 or 4, default = 4 */
|
| - UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
| + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
| unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
| int numThreads; /* 1 or 2, default = 2 */
|
| +
|
| + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
|
| + Encoder uses this value to reduce dictionary size */
|
| } CLzmaEncProps;
|
|
|
| void LzmaEncProps_Init(CLzmaEncProps *p);
|
| @@ -37,41 +38,38 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); |
|
|
| /* ---------- CLzmaEncHandle Interface ---------- */
|
|
|
| -/* LzmaEnc_* functions can return the following exit codes:
|
| -Returns:
|
| +/* LzmaEnc* functions can return the following exit codes:
|
| +SRes:
|
| SZ_OK - OK
|
| SZ_ERROR_MEM - Memory allocation error
|
| SZ_ERROR_PARAM - Incorrect paramater in props
|
| - SZ_ERROR_WRITE - Write callback error.
|
| + SZ_ERROR_WRITE - ISeqOutStream write callback error
|
| + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
|
| SZ_ERROR_PROGRESS - some break from progress callback
|
| - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
| + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
|
| */
|
|
|
| typedef void * CLzmaEncHandle;
|
|
|
| -CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
| -void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
| +CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
|
| +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
| +
|
| SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
| +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
|
| SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
| +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
|
| +
|
| SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
| - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
| + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
| SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
| - int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
| + int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
|
|
| -/* ---------- One Call Interface ---------- */
|
|
|
| -/* LzmaEncode
|
| -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)
|
| -*/
|
| +/* ---------- One Call Interface ---------- */
|
|
|
| SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
| const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
| - ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
| + ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
|
|
|
| EXTERN_C_END
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c |
| index ece07e618a..8fd86f224b 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c |
| @@ -1,5 +1,5 @@ |
| /* Threads.c -- multithreading library
|
| -2014-09-21 : Igor Pavlov : Public domain */
|
| +2017-06-26 : Igor Pavlov : Public domain */
|
|
|
| #include "Precomp.h"
|
|
|
| @@ -12,18 +12,20 @@ |
| static WRes GetError()
|
| {
|
| DWORD res = GetLastError();
|
| - return (res) ? (WRes)(res) : 1;
|
| + return res ? (WRes)res : 1;
|
| }
|
|
|
| -WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
| -WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
| +static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
|
| +static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
|
|
| WRes HandlePtr_Close(HANDLE *p)
|
| {
|
| if (*p != NULL)
|
| + {
|
| if (!CloseHandle(*p))
|
| return GetError();
|
| - *p = NULL;
|
| + *p = NULL;
|
| + }
|
| return 0;
|
| }
|
|
|
| @@ -49,7 +51,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) |
| return HandleToWRes(*p);
|
| }
|
|
|
| -WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
|
| +static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
|
| {
|
| *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
|
| return HandleToWRes(*p);
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h b/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h |
| index e927208d79..f913241aea 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h |
| @@ -1,5 +1,5 @@ |
| /* Threads.h -- multithreading library
|
| -2013-11-12 : Igor Pavlov : Public domain */
|
| +2017-06-18 : Igor Pavlov : Public domain */
|
|
|
| #ifndef __7Z_THREADS_H
|
| #define __7Z_THREADS_H
|
| @@ -49,7 +49,8 @@ WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); |
| WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
|
|
|
| typedef HANDLE CSemaphore;
|
| -#define Semaphore_Construct(p) (*p) = NULL
|
| +#define Semaphore_Construct(p) *(p) = NULL
|
| +#define Semaphore_IsCreated(p) (*(p) != NULL)
|
| #define Semaphore_Close(p) HandlePtr_Close(p)
|
| #define Semaphore_Wait(p) Handle_WaitObject(*(p))
|
| WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt b/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt |
| index 7aaeb07ff4..f4793264a5 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt |
| @@ -1,6 +1,67 @@ |
| HISTORY of the LZMA SDK
|
| -----------------------
|
|
|
| +18.05 2018-04-30
|
| +-------------------------
|
| +- The speed for LZMA/LZMA2 compressing was increased
|
| + by 8% for fastest/fast compression levels and
|
| + by 3% for normal/maximum compression levels.
|
| +- Previous versions of 7-Zip could work incorrectly in "Large memory pages" mode in
|
| + Windows 10 because of some BUG with "Large Pages" in Windows 10.
|
| + Now 7-Zip doesn't use "Large Pages" on Windows 10 up to revision 1709 (16299).
|
| +- The BUG was fixed in Lzma2Enc.c
|
| + Lzma2Enc_Encode2() function worked incorretly,
|
| + if (inStream == NULL) and the number of block threads is more than 1.
|
| +
|
| +
|
| +18.03 beta 2018-03-04
|
| +-------------------------
|
| +- Asm\x86\LzmaDecOpt.asm: new optimized LZMA decoder written in asm
|
| + for x64 with about 30% higher speed than main version of LZMA decoder written in C.
|
| +- The speed for single-thread LZMA/LZMA2 decoder written in C was increased by 3%.
|
| +- 7-Zip now can use multi-threading for 7z/LZMA2 decoding,
|
| + if there are multiple independent data chunks in LZMA2 stream.
|
| +- 7-Zip now can use multi-threading for xz decoding,
|
| + if there are multiple blocks in xz stream.
|
| +
|
| +
|
| +18.01 2019-01-28
|
| +-------------------------
|
| +- The BUG in 17.01 - 18.00 beta was fixed:
|
| + XzDec.c : random block unpacking and XzUnpacker_IsBlockFinished()
|
| + didn't work correctly for xz archives without checksum (CRC).
|
| +
|
| +
|
| +18.00 beta 2019-01-10
|
| +-------------------------
|
| +- The BUG in xz encoder was fixed:
|
| + There was memory leak of 16 KB for each file compressed with
|
| + xz compression method, if additional filter was used.
|
| +
|
| +
|
| +17.01 beta 2017-08-28
|
| +-------------------------
|
| +- Minor speed optimization for LZMA2 (xz and 7z) multi-threading compression.
|
| + 7-Zip now uses additional memory buffers for multi-block LZMA2 compression.
|
| + CPU utilization was slightly improved.
|
| +- 7-zip now creates multi-block xz archives by default. Block size can be
|
| + specified with -ms[Size]{m|g} switch.
|
| +- xz decoder now can unpack random block from multi-block xz archives.
|
| +- 7-Zip command line: @listfile now doesn't work after -- switch.
|
| + Use -i@listfile before -- switch instead.
|
| +- The BUGs were fixed:
|
| + 7-Zip 17.00 beta crashed for commands that write anti-item to 7z archive.
|
| +
|
| +
|
| +17.00 beta 2017-04-29
|
| +-------------------------
|
| +- NewHandler.h / NewHandler.cpp:
|
| + now it redefines operator new() only for old MSVC compilers (_MSC_VER < 1900).
|
| +- C/7zTypes.h : the names of variables in interface structures were changed (vt).
|
| +- Some bugs were fixed. 7-Zip could crash in some cases.
|
| +- Some internal changes in code.
|
| +
|
| +
|
| 16.04 2016-10-04
|
| -------------------------
|
| - The bug was fixed in DllSecur.c.
|
| @@ -168,7 +229,7 @@ HISTORY of the LZMA SDK |
|
|
| 4.57 2007-12-12
|
| -------------------------
|
| -- Speed optimizations in C++ LZMA Decoder.
|
| +- Speed optimizations in ?++ LZMA Decoder.
|
| - Small changes for more compatibility with some C/C++ compilers.
|
|
|
|
|
| diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt b/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt |
| index 86fef248f4..01521e9398 100644 |
| --- a/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt |
| +++ b/BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt |
| @@ -1,4 +1,4 @@ |
| -LZMA SDK 16.04
|
| +LZMA SDK 18.05
|
| --------------
|
|
|
| LZMA SDK provides the documentation, samples, header files,
|
| -- |
| 2.34.1.307.g9b7440fafd-goog |
| |