]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools Lzma: Update LZMA SDK version to 18.05
authorLiming Gao <liming.gao@intel.com>
Wed, 29 Aug 2018 00:51:28 +0000 (08:51 +0800)
committerLiming Gao <liming.gao@intel.com>
Tue, 9 Oct 2018 01:31:09 +0000 (09:31 +0800)
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>
24 files changed:
BaseTools/Source/C/LzmaCompress/LZMA-SDK-README.txt
BaseTools/Source/C/LzmaCompress/LzmaCompress.c
BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h
BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c
BaseTools/Source/C/LzmaCompress/Sdk/C/7zTypes.h
BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h
BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c
BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h
BaseTools/Source/C/LzmaCompress/Sdk/C/Bra86.c
BaseTools/Source/C/LzmaCompress/Sdk/C/Compiler.h
BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h
BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c
BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h
BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-history.txt
BaseTools/Source/C/LzmaCompress/Sdk/DOC/lzma-sdk.txt

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