File 0001-Update-LZMA-SDK-to-version-17.01.patch of Package gzdoom

From 242509244f96dfab216981f76f032be668312724 Mon Sep 17 00:00:00 2001
From: Jan Engelhardt <jengelh@inai.de>
Date: Mon, 8 Jan 2018 13:00:01 +0100
Subject: [PATCH] Update LZMA SDK to version 17.01

---
 lzma/C/7z.h                   |  12 +-
 lzma/C/7zArcIn.c              | 129 +++++++++----------
 lzma/C/7zBuf.c                |  12 +-
 lzma/C/7zBuf.h                |  10 +-
 lzma/C/7zCrc.c                |  16 +--
 lzma/C/7zCrcOpt.c             |  50 ++++----
 lzma/C/7zDec.c                |  54 ++++----
 lzma/C/7zStream.c             | 111 ++++++++--------
 lzma/C/7zTypes.h              | 230 +++++++++++++++++++++++++--------
 lzma/C/7zVersion.h            |  22 +++-
 lzma/C/Bcj2.c                 |   5 +-
 lzma/C/Bra.c                  | 289 ++++++++++++++++++++++++++++--------------
 lzma/C/Bra86.c                |   4 +-
 lzma/C/BraIA64.c              |  82 +++++-------
 lzma/C/Compiler.h             |   3 +-
 lzma/C/CpuArch.c              |  13 +-
 lzma/C/CpuArch.h              | 175 ++++++++++++++++++++-----
 lzma/C/LzFind.c               | 163 ++++++++++++++----------
 lzma/C/LzFind.h               |  12 +-
 lzma/C/LzFindMt.c             |  67 ++++++----
 lzma/C/LzFindMt.h             |   6 +-
 lzma/C/Lzma2Dec.c             | 158 +++++++++++------------
 lzma/C/Lzma2Dec.h             |   8 +-
 lzma/C/LzmaDec.c              |  34 ++---
 lzma/C/LzmaDec.h              |  12 +-
 lzma/C/LzmaEnc.c              | 194 ++++++++++++++++------------
 lzma/C/LzmaEnc.h              |  48 ++++---
 lzma/C/Ppmd.h                 |   6 +-
 lzma/C/Ppmd7.c                |  38 +++---
 lzma/C/Ppmd7.h                |  28 ++--
 lzma/C/Ppmd7Dec.c             |  34 ++---
 lzma/C/Threads.c              |  14 +-
 lzma/C/Threads.h              |   5 +-
 src/files.cpp                 |   4 +-
 src/resourcefiles/file_7z.cpp |  17 ++-
 35 files changed, 1239 insertions(+), 826 deletions(-)

diff --git a/lzma/C/7z.h b/lzma/C/7z.h
index 476815194..6c7886e38 100644
--- a/lzma/C/7z.h
+++ b/lzma/C/7z.h
@@ -1,5 +1,5 @@
 /* 7z.h -- 7z interface
-2015-11-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_H
 #define __7Z_H
@@ -98,7 +98,7 @@ UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
 SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
     ILookInStream *stream, UInt64 startPos,
     Byte *outBuffer, size_t outSize,
-    ISzAlloc *allocMain);
+    ISzAllocPtr allocMain);
 
 typedef struct
 {
@@ -131,7 +131,7 @@ typedef struct
 #define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
 
 void SzArEx_Init(CSzArEx *p);
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
+void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
 UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
 int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
 
@@ -179,8 +179,8 @@ SRes SzArEx_Extract(
     size_t *outBufferSize,    /* buffer size for output buffer */
     size_t *offset,           /* offset of stream for required file in *outBuffer */
     size_t *outSizeProcessed, /* size of file in *outBuffer */
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp);
+    ISzAllocPtr allocMain,
+    ISzAllocPtr allocTemp);
 
 
 /*
@@ -195,7 +195,7 @@ SZ_ERROR_FAIL
 */
 
 SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
-    ISzAlloc *allocMain, ISzAlloc *allocTemp);
+    ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
 
 EXTERN_C_END
 
diff --git a/lzma/C/7zArcIn.c b/lzma/C/7zArcIn.c
index 06e35de0d..e1b03d879 100644
--- a/lzma/C/7zArcIn.c
+++ b/lzma/C/7zArcIn.c
@@ -1,5 +1,5 @@
 /* 7zArcIn.c -- 7z Input functions
-2015-11-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -11,7 +11,7 @@
 #include "CpuArch.h"
 
 #define MY_ALLOC(T, p, size, alloc) { \
-  if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
+  if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
 
 #define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
 
@@ -60,7 +60,7 @@ const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
 
 #define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
 
-static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
+static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc)
 {
   if (num == 0)
   {
@@ -75,18 +75,18 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
   return SZ_OK;
 }
 
-void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
+void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc)
 {
-  IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
-  IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
+  ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+  ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
 }
 
 #define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
 
-void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
+void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc)
 {
-  IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
-  IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
+  ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
+  ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
 }
 
 
@@ -107,18 +107,18 @@ static void SzAr_Init(CSzAr *p)
   p->CodersData = NULL;
 }
 
-static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
+static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc)
 {
-  IAlloc_Free(alloc, p->PackPositions);
+  ISzAlloc_Free(alloc, p->PackPositions);
   SzBitUi32s_Free(&p->FolderCRCs, alloc);
  
-  IAlloc_Free(alloc, p->FoCodersOffsets);
-  IAlloc_Free(alloc, p->FoStartPackStreamIndex);
-  IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
-  IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
-  IAlloc_Free(alloc, p->CoderUnpackSizes);
+  ISzAlloc_Free(alloc, p->FoCodersOffsets);
+  ISzAlloc_Free(alloc, p->FoStartPackStreamIndex);
+  ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes);
+  ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
+  ISzAlloc_Free(alloc, p->CoderUnpackSizes);
   
-  IAlloc_Free(alloc, p->CodersData);
+  ISzAlloc_Free(alloc, p->CodersData);
 
   SzAr_Init(p);
 }
@@ -147,16 +147,16 @@ void SzArEx_Init(CSzArEx *p)
   SzBitUi64s_Init(&p->CTime);
 }
 
-void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
+void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc)
 {
-  IAlloc_Free(alloc, p->UnpackPositions);
-  IAlloc_Free(alloc, p->IsDirs);
+  ISzAlloc_Free(alloc, p->UnpackPositions);
+  ISzAlloc_Free(alloc, p->IsDirs);
 
-  IAlloc_Free(alloc, p->FolderToFile);
-  IAlloc_Free(alloc, p->FileToFolder);
+  ISzAlloc_Free(alloc, p->FolderToFile);
+  ISzAlloc_Free(alloc, p->FileToFolder);
 
-  IAlloc_Free(alloc, p->FileNameOffsets);
-  IAlloc_Free(alloc, p->FileNames);
+  ISzAlloc_Free(alloc, p->FileNameOffsets);
+  ISzAlloc_Free(alloc, p->FileNames);
 
   SzBitUi32s_Free(&p->CRCs, alloc);
   SzBitUi32s_Free(&p->Attribs, alloc);
@@ -305,7 +305,7 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
   return sum;
 }
 
-static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
+static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc)
 {
   Byte allAreDefined;
   Byte *v2;
@@ -328,12 +328,12 @@ static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, I
   {
     unsigned numBits = (unsigned)numItems & 7;
     if (numBits != 0)
-      v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
+      v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
   }
   return SZ_OK;
 }
 
-static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
+static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
 {
   UInt32 i;
   CSzData sd;
@@ -354,7 +354,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
   return SZ_OK;
 }
 
-static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
+static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
 {
   SzBitUi32s_Free(crcs, alloc);
   RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
@@ -380,7 +380,7 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
   return SZ_OK;
 }
 
-static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)
+static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc)
 {
   RINOK(SzReadNumber32(sd, &p->NumPackStreams));
 
@@ -635,7 +635,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
     CSzData *sd2,
     UInt32 numFoldersMax,
     const CBuf *tempBufs, UInt32 numTempBufs,
-    ISzAlloc *alloc)
+    ISzAllocPtr alloc)
 {
   CSzData sd;
   
@@ -788,13 +788,9 @@ static SRes ReadUnpackInfo(CSzAr *p,
       numCodersOutStreams += numCoders;
       if (numCodersOutStreams < numCoders)
         return SZ_ERROR_UNSUPPORTED;
-      
-      packStreamIndex += numPackStreams;
-      if (packStreamIndex < numPackStreams)
-        return SZ_ERROR_UNSUPPORTED;
-      
-      if (packStreamIndex > p->NumPackStreams)
+      if (numPackStreams > p->NumPackStreams - packStreamIndex)
         return SZ_ERROR_ARCHIVE;
+      packStreamIndex += numPackStreams;
     }
   }
 
@@ -938,7 +934,7 @@ static SRes SzReadStreamsInfo(CSzAr *p,
     UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
     UInt64 *dataOffset,
     CSubStreamInfo *ssi,
-    ISzAlloc *alloc)
+    ISzAllocPtr alloc)
 {
   UInt64 type;
 
@@ -980,7 +976,7 @@ static SRes SzReadAndDecodePackedStreams(
     UInt32 numFoldersMax,
     UInt64 baseOffset,
     CSzAr *p,
-    ISzAlloc *allocTemp)
+    ISzAllocPtr allocTemp)
 {
   UInt64 dataStartPos;
   UInt32 fo;
@@ -1047,7 +1043,7 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
 static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
     CSzData *sd2,
     const CBuf *tempBufs, UInt32 numTempBufs,
-    ISzAlloc *alloc)
+    ISzAllocPtr alloc)
 {
   CSzData sd;
   UInt32 i;
@@ -1100,17 +1096,15 @@ static SRes SzReadHeader2(
     CSzData *sd,
     ILookInStream *inStream,
     CBuf *tempBufs, UInt32 *numTempBufs,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp
+    ISzAllocPtr allocMain,
+    ISzAllocPtr allocTemp
     )
 {
-  UInt64 type;
-  UInt32 numFiles = 0;
-  UInt32 numEmptyStreams = 0;
   CSubStreamInfo ssi;
-  const Byte *emptyStreams = NULL;
-  const Byte *emptyFiles = NULL;
 
+{
+  UInt64 type;
+  
   SzData_Clear(&ssi.sdSizes);
   SzData_Clear(&ssi.sdCRCs);
   SzData_Clear(&ssi.sdNumSubStreams);
@@ -1124,9 +1118,9 @@ static SRes SzReadHeader2(
   {
     for (;;)
     {
-      UInt64 type;
-      RINOK(ReadID(sd, &type));
-      if (type == k7zIdEnd)
+      UInt64 type2;
+      RINOK(ReadID(sd, &type2));
+      if (type2 == k7zIdEnd)
         break;
       RINOK(SkipData(sd));
     }
@@ -1164,6 +1158,13 @@ static SRes SzReadHeader2(
 
   if (type != k7zIdFilesInfo)
     return SZ_ERROR_ARCHIVE;
+}
+
+{
+  UInt32 numFiles = 0;
+  UInt32 numEmptyStreams = 0;
+  const Byte *emptyStreams = NULL;
+  const Byte *emptyFiles = NULL;
   
   RINOK(SzReadNumber32(sd, &numFiles));
   p->NumFiles = numFiles;
@@ -1462,7 +1463,7 @@ static SRes SzReadHeader2(
     if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
       return SZ_ERROR_ARCHIVE;
   }
-  
+}
   return SZ_OK;
 }
 
@@ -1471,8 +1472,8 @@ static SRes SzReadHeader(
     CSzArEx *p,
     CSzData *sd,
     ILookInStream *inStream,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
+    ISzAllocPtr allocMain,
+    ISzAllocPtr allocTemp)
 {
   UInt32 i;
   UInt32 numTempBufs = 0;
@@ -1500,8 +1501,8 @@ static SRes SzReadHeader(
 static SRes SzArEx_Open2(
     CSzArEx *p,
     ILookInStream *inStream,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
+    ISzAllocPtr allocMain,
+    ISzAllocPtr allocTemp)
 {
   Byte header[k7zStartHeaderSize];
   Int64 startArcPos;
@@ -1512,7 +1513,7 @@ static SRes SzArEx_Open2(
   SRes res;
 
   startArcPos = 0;
-  RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
+  RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR));
 
   RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
 
@@ -1541,7 +1542,7 @@ static SRes SzArEx_Open2(
 
   {
     Int64 pos = 0;
-    RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
+    RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END));
     if ((UInt64)pos < startArcPos + nextHeaderOffset ||
         (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
         (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
@@ -1622,7 +1623,7 @@ static SRes SzArEx_Open2(
 
 
 SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
-    ISzAlloc *allocMain, ISzAlloc *allocTemp)
+    ISzAllocPtr allocMain, ISzAllocPtr allocTemp)
 {
   SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
   if (res != SZ_OK)
@@ -1640,8 +1641,8 @@ SRes SzArEx_Extract(
     size_t *outBufferSize,
     size_t *offset,
     size_t *outSizeProcessed,
-    ISzAlloc *allocMain,
-    ISzAlloc *allocTemp)
+    ISzAllocPtr allocMain,
+    ISzAllocPtr allocTemp)
 {
   UInt32 folderIndex = p->FileToFolder[fileIndex];
   SRes res = SZ_OK;
@@ -1651,7 +1652,7 @@ SRes SzArEx_Extract(
   
   if (folderIndex == (UInt32)-1)
   {
-    IAlloc_Free(allocMain, *tempBuf);
+    ISzAlloc_Free(allocMain, *tempBuf);
     *blockIndex = folderIndex;
     *tempBuf = NULL;
     *outBufferSize = 0;
@@ -1663,7 +1664,7 @@ SRes SzArEx_Extract(
     UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
     /*
     UInt64 unpackSizeSpec =
-        p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
+        p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] -
         p->UnpackPositions[p->FolderToFile[folderIndex]];
     */
     size_t unpackSize = (size_t)unpackSizeSpec;
@@ -1671,7 +1672,7 @@ SRes SzArEx_Extract(
     if (unpackSize != unpackSizeSpec)
       return SZ_ERROR_MEM;
     *blockIndex = folderIndex;
-    IAlloc_Free(allocMain, *tempBuf);
+    ISzAlloc_Free(allocMain, *tempBuf);
     *tempBuf = NULL;
     
     if (res == SZ_OK)
@@ -1679,7 +1680,7 @@ SRes SzArEx_Extract(
       *outBufferSize = unpackSize;
       if (unpackSize != 0)
       {
-        *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
+        *tempBuf = (Byte *)ISzAlloc_Alloc(allocMain, unpackSize);
         if (*tempBuf == NULL)
           res = SZ_ERROR_MEM;
       }
@@ -1696,7 +1697,7 @@ SRes SzArEx_Extract(
   {
     UInt64 unpackPos = p->UnpackPositions[fileIndex];
     *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
-    *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
+    *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos);
     if (*offset + *outSizeProcessed > *outBufferSize)
       return SZ_ERROR_FAIL;
     if (SzBitWithVals_Check(&p->CRCs, fileIndex))
diff --git a/lzma/C/7zBuf.c b/lzma/C/7zBuf.c
index 089a5c4f2..8865c32a8 100644
--- a/lzma/C/7zBuf.c
+++ b/lzma/C/7zBuf.c
@@ -1,5 +1,5 @@
 /* 7zBuf.c -- Byte Buffer
-2013-01-21 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -11,7 +11,7 @@ void Buf_Init(CBuf *p)
   p->size = 0;
 }
 
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
+int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc)
 {
   p->size = 0;
   if (size == 0)
@@ -19,8 +19,8 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
     p->data = 0;
     return 1;
   }
-  p->data = (Byte *)alloc->Alloc(alloc, size);
-  if (p->data != 0)
+  p->data = (Byte *)ISzAlloc_Alloc(alloc, size);
+  if (p->data)
   {
     p->size = size;
     return 1;
@@ -28,9 +28,9 @@ int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
   return 0;
 }
 
-void Buf_Free(CBuf *p, ISzAlloc *alloc)
+void Buf_Free(CBuf *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->data);
+  ISzAlloc_Free(alloc, p->data);
   p->data = 0;
   p->size = 0;
 }
diff --git a/lzma/C/7zBuf.h b/lzma/C/7zBuf.h
index 65f1d7a71..81d1b5b64 100644
--- a/lzma/C/7zBuf.h
+++ b/lzma/C/7zBuf.h
@@ -1,5 +1,5 @@
 /* 7zBuf.h -- Byte Buffer
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_BUF_H
 #define __7Z_BUF_H
@@ -15,8 +15,8 @@ typedef struct
 } CBuf;
 
 void Buf_Init(CBuf *p);
-int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
-void Buf_Free(CBuf *p, ISzAlloc *alloc);
+int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
+void Buf_Free(CBuf *p, ISzAllocPtr alloc);
 
 typedef struct
 {
@@ -27,8 +27,8 @@ typedef struct
 
 void DynBuf_Construct(CDynBuf *p);
 void DynBuf_SeekToBeg(CDynBuf *p);
-int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
-void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
+int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
+void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
 
 EXTERN_C_END
 
diff --git a/lzma/C/7zCrc.c b/lzma/C/7zCrc.c
index dc6d6abdc..b4d84f023 100644
--- a/lzma/C/7zCrc.c
+++ b/lzma/C/7zCrc.c
@@ -1,5 +1,5 @@
 /* 7zCrc.c -- CRC32 init
-2015-03-10 : Igor Pavlov : Public domain */
+2017-06-06 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -61,12 +61,12 @@ void MY_FAST_CALL CrcGenerateTable()
     UInt32 r = i;
     unsigned j;
     for (j = 0; j < 8; j++)
-      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+      r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
     g_CrcTable[i] = r;
   }
-  for (; i < 256 * CRC_NUM_TABLES; i++)
+  for (i = 256; i < 256 * CRC_NUM_TABLES; i++)
   {
-    UInt32 r = g_CrcTable[i - 256];
+    UInt32 r = g_CrcTable[(size_t)i - 256];
     g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
   }
 
@@ -86,8 +86,8 @@ void MY_FAST_CALL CrcGenerateTable()
   
       #ifdef MY_CPU_X86_OR_AMD64
       if (!CPU_Is_InOrder())
-        g_CrcUpdate = CrcUpdateT8;
       #endif
+        g_CrcUpdate = CrcUpdateT8;
     #endif
 
   #else
@@ -101,7 +101,7 @@ void MY_FAST_CALL CrcGenerateTable()
       g_CrcUpdate = CrcUpdateT4;
       #if CRC_NUM_TABLES >= 8
       g_CrcUpdateT8 = CrcUpdateT8;
-      // g_CrcUpdate = CrcUpdateT8;
+      g_CrcUpdate = CrcUpdateT8;
       #endif
     }
     else if (p[0] != 1 || p[1] != 2)
@@ -111,14 +111,14 @@ void MY_FAST_CALL CrcGenerateTable()
     {
       for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
       {
-        UInt32 x = g_CrcTable[i - 256];
+        UInt32 x = g_CrcTable[(size_t)i - 256];
         g_CrcTable[i] = CRC_UINT32_SWAP(x);
       }
       g_CrcUpdateT4 = CrcUpdateT1_BeT4;
       g_CrcUpdate = CrcUpdateT1_BeT4;
       #if CRC_NUM_TABLES >= 8
       g_CrcUpdateT8 = CrcUpdateT1_BeT8;
-      // g_CrcUpdate = CrcUpdateT1_BeT8;
+      g_CrcUpdate = CrcUpdateT1_BeT8;
       #endif
     }
   }
diff --git a/lzma/C/7zCrcOpt.c b/lzma/C/7zCrcOpt.c
index d1e1cd7ba..73beba298 100644
--- a/lzma/C/7zCrcOpt.c
+++ b/lzma/C/7zCrcOpt.c
@@ -1,5 +1,5 @@
 /* 7zCrcOpt.c -- CRC32 calculation
-2015-03-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -18,10 +18,10 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U
   {
     v ^= *(const UInt32 *)p;
     v =
-          table[0x300 + ((v      ) & 0xFF)]
-        ^ table[0x200 + ((v >>  8) & 0xFF)]
-        ^ table[0x100 + ((v >> 16) & 0xFF)]
-        ^ table[0x000 + ((v >> 24))];
+          (table + 0x300)[((v      ) & 0xFF)]
+        ^ (table + 0x200)[((v >>  8) & 0xFF)]
+        ^ (table + 0x100)[((v >> 16) & 0xFF)]
+        ^ (table + 0x000)[((v >> 24))];
   }
   for (; size > 0; size--, p++)
     v = CRC_UPDATE_BYTE_2(v, *p);
@@ -38,16 +38,16 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
     UInt32 d;
     v ^= *(const UInt32 *)p;
     v =
-          table[0x700 + ((v      ) & 0xFF)]
-        ^ table[0x600 + ((v >>  8) & 0xFF)]
-        ^ table[0x500 + ((v >> 16) & 0xFF)]
-        ^ table[0x400 + ((v >> 24))];
+          (table + 0x700)[((v      ) & 0xFF)]
+        ^ (table + 0x600)[((v >>  8) & 0xFF)]
+        ^ (table + 0x500)[((v >> 16) & 0xFF)]
+        ^ (table + 0x400)[((v >> 24))];
     d = *((const UInt32 *)p + 1);
     v ^=
-          table[0x300 + ((d      ) & 0xFF)]
-        ^ table[0x200 + ((d >>  8) & 0xFF)]
-        ^ table[0x100 + ((d >> 16) & 0xFF)]
-        ^ table[0x000 + ((d >> 24))];
+          (table + 0x300)[((d      ) & 0xFF)]
+        ^ (table + 0x200)[((d >>  8) & 0xFF)]
+        ^ (table + 0x100)[((d >> 16) & 0xFF)]
+        ^ (table + 0x000)[((d >> 24))];
   }
   for (; size > 0; size--, p++)
     v = CRC_UPDATE_BYTE_2(v, *p);
@@ -74,10 +74,10 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, co
   {
     v ^= *(const UInt32 *)p;
     v =
-          table[0x000 + ((v      ) & 0xFF)]
-        ^ table[0x100 + ((v >>  8) & 0xFF)]
-        ^ table[0x200 + ((v >> 16) & 0xFF)]
-        ^ table[0x300 + ((v >> 24))];
+          (table + 0x000)[((v      ) & 0xFF)]
+        ^ (table + 0x100)[((v >>  8) & 0xFF)]
+        ^ (table + 0x200)[((v >> 16) & 0xFF)]
+        ^ (table + 0x300)[((v >> 24))];
   }
   for (; size > 0; size--, p++)
     v = CRC_UPDATE_BYTE_2_BE(v, *p);
@@ -96,16 +96,16 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, co
     UInt32 d;
     v ^= *(const UInt32 *)p;
     v =
-          table[0x400 + ((v      ) & 0xFF)]
-        ^ table[0x500 + ((v >>  8) & 0xFF)]
-        ^ table[0x600 + ((v >> 16) & 0xFF)]
-        ^ table[0x700 + ((v >> 24))];
+          (table + 0x400)[((v      ) & 0xFF)]
+        ^ (table + 0x500)[((v >>  8) & 0xFF)]
+        ^ (table + 0x600)[((v >> 16) & 0xFF)]
+        ^ (table + 0x700)[((v >> 24))];
     d = *((const UInt32 *)p + 1);
     v ^=
-          table[0x000 + ((d      ) & 0xFF)]
-        ^ table[0x100 + ((d >>  8) & 0xFF)]
-        ^ table[0x200 + ((d >> 16) & 0xFF)]
-        ^ table[0x300 + ((d >> 24))];
+          (table + 0x000)[((d      ) & 0xFF)]
+        ^ (table + 0x100)[((d >>  8) & 0xFF)]
+        ^ (table + 0x200)[((d >> 16) & 0xFF)]
+        ^ (table + 0x300)[((d >> 24))];
   }
   for (; size > 0; size--, p++)
     v = CRC_UPDATE_BYTE_2_BE(v, *p);
diff --git a/lzma/C/7zDec.c b/lzma/C/7zDec.c
index c45d6bf8d..1ae87dfaf 100644
--- a/lzma/C/7zDec.c
+++ b/lzma/C/7zDec.c
@@ -1,5 +1,5 @@
 /* 7zDec.c -- Decoding from 7z folder
-2015-11-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -39,28 +39,28 @@
 
 typedef struct
 {
-  IByteIn p;
+  IByteIn vt;
   const Byte *cur;
   const Byte *end;
   const Byte *begin;
   UInt64 processed;
   Bool extra;
   SRes res;
-  ILookInStream *inStream;
+  const ILookInStream *inStream;
 } CByteInToLook;
 
-static Byte ReadByte(void *pp)
+static Byte ReadByte(const IByteIn *pp)
 {
-  CByteInToLook *p = (CByteInToLook *)pp;
+  CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
   if (p->cur != p->end)
     return *p->cur++;
   if (p->res == SZ_OK)
   {
     size_t size = p->cur - p->begin;
     p->processed += size;
-    p->res = p->inStream->Skip(p->inStream, size);
+    p->res = ILookInStream_Skip(p->inStream, size);
     size = (1 << 25);
-    p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
+    p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
     p->cur = p->begin;
     p->end = p->begin + size;
     if (size != 0)
@@ -70,14 +70,14 @@ static Byte ReadByte(void *pp)
   return 0;
 }
 
-static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
-    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
+    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
 {
   CPpmd7 ppmd;
   CByteInToLook s;
   SRes res = SZ_OK;
 
-  s.p.Read = ReadByte;
+  s.vt.Read = ReadByte;
   s.inStream = inStream;
   s.begin = s.end = s.cur = NULL;
   s.extra = False;
@@ -103,7 +103,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
   {
     CPpmd7z_RangeDec rc;
     Ppmd7z_RangeDec_CreateVTable(&rc);
-    rc.Stream = &s.p;
+    rc.Stream = &s.vt;
     if (!Ppmd7z_RangeDec_Init(&rc))
       res = SZ_ERROR_DATA;
     else if (s.extra)
@@ -113,7 +113,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
       SizeT i;
       for (i = 0; i < outSize; i++)
       {
-        int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
+        int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
         if (s.extra || sym < 0)
           break;
         outBuffer[i] = (Byte)sym;
@@ -132,7 +132,7 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, I
 
 
 static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
-    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
 {
   CLzmaDec state;
   SRes res = SZ_OK;
@@ -149,7 +149,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
     size_t lookahead = (1 << 18);
     if (lookahead > inSize)
       lookahead = (size_t)inSize;
-    res = inStream->Look(inStream, &inBuf, &lookahead);
+    res = ILookInStream_Look(inStream, &inBuf, &lookahead);
     if (res != SZ_OK)
       break;
 
@@ -178,7 +178,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
         break;
       }
 
-      res = inStream->Skip((void *)inStream, inProcessed);
+      res = ILookInStream_Skip(inStream, inProcessed);
       if (res != SZ_OK)
         break;
     }
@@ -192,7 +192,7 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
 #ifndef _7Z_NO_METHOD_LZMA2
 
 static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
-    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
+    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
 {
   CLzma2Dec state;
   SRes res = SZ_OK;
@@ -211,7 +211,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
     size_t lookahead = (1 << 18);
     if (lookahead > inSize)
       lookahead = (size_t)inSize;
-    res = inStream->Look(inStream, &inBuf, &lookahead);
+    res = ILookInStream_Look(inStream, &inBuf, &lookahead);
     if (res != SZ_OK)
       break;
 
@@ -237,7 +237,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
         break;
       }
 
-      res = inStream->Skip((void *)inStream, inProcessed);
+      res = ILookInStream_Skip(inStream, inProcessed);
       if (res != SZ_OK)
         break;
     }
@@ -258,13 +258,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
     size_t curSize = (1 << 18);
     if (curSize > inSize)
       curSize = (size_t)inSize;
-    RINOK(inStream->Look(inStream, &inBuf, &curSize));
+    RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
     if (curSize == 0)
       return SZ_ERROR_INPUT_EOF;
     memcpy(outBuffer, inBuf, curSize);
     outBuffer += curSize;
     inSize -= curSize;
-    RINOK(inStream->Skip((void *)inStream, curSize));
+    RINOK(ILookInStream_Skip(inStream, curSize));
   }
   return SZ_OK;
 }
@@ -372,7 +372,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
     const UInt64 *unpackSizes,
     const UInt64 *packPositions,
     ILookInStream *inStream, UInt64 startPos,
-    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
+    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
     Byte *tempBuf[])
 {
   UInt32 ci;
@@ -404,7 +404,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
           outSizeCur = (SizeT)unpackSize;
           if (outSizeCur != unpackSize)
             return SZ_ERROR_MEM;
-          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
+          temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
           if (!temp && outSizeCur != 0)
             return SZ_ERROR_MEM;
           outBufCur = tempBuf[1 - ci] = temp;
@@ -421,7 +421,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
           return SZ_ERROR_UNSUPPORTED;
       }
       offset = packPositions[si];
-      inSize = packPositions[si + 1] - offset;
+      inSize = packPositions[(size_t)si + 1] - offset;
       RINOK(LookInStream_SeekTo(inStream, startPos + offset));
 
       if (coder->MethodID == k_Copy)
@@ -460,7 +460,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
       tempSizes[2] = (SizeT)s3Size;
       if (tempSizes[2] != s3Size)
         return SZ_ERROR_MEM;
-      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
+      tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
       if (!tempBuf[2] && tempSizes[2] != 0)
         return SZ_ERROR_MEM;
       
@@ -549,7 +549,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
 SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
     ILookInStream *inStream, UInt64 startPos,
     Byte *outBuffer, size_t outSize,
-    ISzAlloc *allocMain)
+    ISzAllocPtr allocMain)
 {
   SRes res;
   CSzFolder folder;
@@ -557,7 +557,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
   
   const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
   sd.Data = data;
-  sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
+  sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
   
   res = SzGetNextFolderItem(&folder, &sd);
   
@@ -579,7 +579,7 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
         outBuffer, (SizeT)outSize, allocMain, tempBuf);
     
     for (i = 0; i < 3; i++)
-      IAlloc_Free(allocMain, tempBuf[i]);
+      ISzAlloc_Free(allocMain, tempBuf[i]);
 
     if (res == SZ_OK)
       if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
diff --git a/lzma/C/7zStream.c b/lzma/C/7zStream.c
index 88f9c42b1..6b5aa1621 100644
--- a/lzma/C/7zStream.c
+++ b/lzma/C/7zStream.c
@@ -1,5 +1,5 @@
 /* 7zStream.c -- 7z Stream functions
-2013-11-12 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -7,12 +7,12 @@
 
 #include "7zTypes.h"
 
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType)
 {
   while (size != 0)
   {
     size_t processed = size;
-    RINOK(stream->Read(stream, buf, &processed));
+    RINOK(ISeqInStream_Read(stream, buf, &processed));
     if (processed == 0)
       return errorType;
     buf = (void *)((Byte *)buf + processed);
@@ -21,40 +21,42 @@ SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorT
   return SZ_OK;
 }
 
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size)
 {
   return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
 }
 
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf)
 {
   size_t processed = 1;
-  RINOK(stream->Read(stream, buf, &processed));
+  RINOK(ISeqInStream_Read(stream, buf, &processed));
   return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
 }
 
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
+
+
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset)
 {
   Int64 t = offset;
-  return stream->Seek(stream, &t, SZ_SEEK_SET);
+  return ILookInStream_Seek(stream, &t, SZ_SEEK_SET);
 }
 
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size)
 {
   const void *lookBuf;
   if (*size == 0)
     return SZ_OK;
-  RINOK(stream->Look(stream, &lookBuf, size));
+  RINOK(ILookInStream_Look(stream, &lookBuf, size));
   memcpy(buf, lookBuf, *size);
-  return stream->Skip(stream, *size);
+  return ILookInStream_Skip(stream, *size);
 }
 
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType)
 {
   while (size != 0)
   {
     size_t processed = size;
-    RINOK(stream->Read(stream, buf, &processed));
+    RINOK(ILookInStream_Read(stream, buf, &processed));
     if (processed == 0)
       return errorType;
     buf = (void *)((Byte *)buf + processed);
@@ -63,61 +65,67 @@ SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes erro
   return SZ_OK;
 }
 
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size)
 {
   return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
 }
 
-static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
+
+
+#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt);
+
+static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size)
 {
   SRes res = SZ_OK;
-  CLookToRead *p = (CLookToRead *)pp;
+  GET_LookToRead2
   size_t size2 = p->size - p->pos;
-  if (size2 == 0 && *size > 0)
+  if (size2 == 0 && *size != 0)
   {
     p->pos = 0;
-    size2 = LookToRead_BUF_SIZE;
-    res = p->realStream->Read(p->realStream, p->buf, &size2);
+    p->size = 0;
+    size2 = p->bufSize;
+    res = ISeekInStream_Read(p->realStream, p->buf, &size2);
     p->size = size2;
   }
-  if (size2 < *size)
+  if (*size > size2)
     *size = size2;
   *buf = p->buf + p->pos;
   return res;
 }
 
-static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
+static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size)
 {
   SRes res = SZ_OK;
-  CLookToRead *p = (CLookToRead *)pp;
+  GET_LookToRead2
   size_t size2 = p->size - p->pos;
-  if (size2 == 0 && *size > 0)
+  if (size2 == 0 && *size != 0)
   {
     p->pos = 0;
-    if (*size > LookToRead_BUF_SIZE)
-      *size = LookToRead_BUF_SIZE;
-    res = p->realStream->Read(p->realStream, p->buf, size);
+    p->size = 0;
+    if (*size > p->bufSize)
+      *size = p->bufSize;
+    res = ISeekInStream_Read(p->realStream, p->buf, size);
     size2 = p->size = *size;
   }
-  if (size2 < *size)
+  if (*size > size2)
     *size = size2;
   *buf = p->buf + p->pos;
   return res;
 }
 
-static SRes LookToRead_Skip(void *pp, size_t offset)
+static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset)
 {
-  CLookToRead *p = (CLookToRead *)pp;
+  GET_LookToRead2
   p->pos += offset;
   return SZ_OK;
 }
 
-static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
+static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size)
 {
-  CLookToRead *p = (CLookToRead *)pp;
+  GET_LookToRead2
   size_t rem = p->size - p->pos;
   if (rem == 0)
-    return p->realStream->Read(p->realStream, buf, size);
+    return ISeekInStream_Read(p->realStream, buf, size);
   if (rem > *size)
     rem = *size;
   memcpy(buf, p->buf + p->pos, rem);
@@ -126,46 +134,43 @@ static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
   return SZ_OK;
 }
 
-static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
+static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin)
 {
-  CLookToRead *p = (CLookToRead *)pp;
+  GET_LookToRead2
   p->pos = p->size = 0;
-  return p->realStream->Seek(p->realStream, pos, origin);
+  return ISeekInStream_Seek(p->realStream, pos, origin);
 }
 
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead)
 {
-  p->s.Look = lookahead ?
-      LookToRead_Look_Lookahead :
-      LookToRead_Look_Exact;
-  p->s.Skip = LookToRead_Skip;
-  p->s.Read = LookToRead_Read;
-  p->s.Seek = LookToRead_Seek;
+  p->vt.Look = lookahead ?
+      LookToRead2_Look_Lookahead :
+      LookToRead2_Look_Exact;
+  p->vt.Skip = LookToRead2_Skip;
+  p->vt.Read = LookToRead2_Read;
+  p->vt.Seek = LookToRead2_Seek;
 }
 
-void LookToRead_Init(CLookToRead *p)
-{
-  p->pos = p->size = 0;
-}
 
-static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
+
+static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size)
 {
-  CSecToLook *p = (CSecToLook *)pp;
+  CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt);
   return LookInStream_LookRead(p->realStream, buf, size);
 }
 
 void SecToLook_CreateVTable(CSecToLook *p)
 {
-  p->s.Read = SecToLook_Read;
+  p->vt.Read = SecToLook_Read;
 }
 
-static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
+static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size)
 {
-  CSecToRead *p = (CSecToRead *)pp;
-  return p->realStream->Read(p->realStream, buf, size);
+  CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt);
+  return ILookInStream_Read(p->realStream, buf, size);
 }
 
 void SecToRead_CreateVTable(CSecToRead *p)
 {
-  p->s.Read = SecToRead_Read;
+  p->vt.Read = SecToRead_Read;
 }
diff --git a/lzma/C/7zTypes.h b/lzma/C/7zTypes.h
index adde88e75..29244b23e 100644
--- a/lzma/C/7zTypes.h
+++ b/lzma/C/7zTypes.h
@@ -1,11 +1,11 @@
 /* 7zTypes.h -- Basic types
-2013-11-12 : Igor Pavlov : Public domain */
+2017-07-17 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_TYPES_H
 #define __7Z_TYPES_H
 
 #ifdef _WIN32
-#include <windows.h>
+/* #include <windows.h> */
 #endif
 
 #include <stddef.h>
@@ -42,13 +42,23 @@ EXTERN_C_BEGIN
 
 typedef int SRes;
 
+
 #ifdef _WIN32
-typedef DWORD WRes;
-/* typedef unsigned WRes; */
+
+/* typedef DWORD WRes; */
+typedef unsigned WRes;
+#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
+
 #else
+
 typedef int WRes;
+#define MY__FACILITY_WIN32 7
+#define MY__FACILITY__WRes MY__FACILITY_WIN32
+#define MY_SRes_HRESULT_FROM_WRes(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (MY__FACILITY__WRes << 16) | 0x80000000)))
+
 #endif
 
+
 #ifndef RINOK
 #define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
 #endif
@@ -112,48 +122,72 @@ typedef int Bool;
 #define MY_NO_INLINE
 #endif
 
+#define MY_FORCE_INLINE __forceinline
+
 #define MY_CDECL __cdecl
 #define MY_FAST_CALL __fastcall
 
 #else
 
 #define MY_NO_INLINE
+#define MY_FORCE_INLINE
 #define MY_CDECL
 #define MY_FAST_CALL
 
+/* inline keyword : for C++ / C99 */
+
+/* GCC, clang: */
+/*
+#if defined (__GNUC__) && (__GNUC__ >= 4)
+#define MY_FORCE_INLINE __attribute__((always_inline))
+#define MY_NO_INLINE __attribute__((noinline))
+#endif
+*/
+
 #endif
 
 
 /* The following interfaces use first parameter as pointer to structure */
 
-typedef struct
+typedef struct IByteIn IByteIn;
+struct IByteIn
 {
-  Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
-} IByteIn;
+  Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */
+};
+#define IByteIn_Read(p) (p)->Read(p)
 
-typedef struct
-{
-  void (*Write)(void *p, Byte b);
-} IByteOut;
 
-typedef struct
+typedef struct IByteOut IByteOut;
+struct IByteOut
 {
-  SRes (*Read)(void *p, void *buf, size_t *size);
+  void (*Write)(const IByteOut *p, Byte b);
+};
+#define IByteOut_Write(p, b) (p)->Write(p, b)
+
+
+typedef struct ISeqInStream ISeqInStream;
+struct ISeqInStream
+{
+  SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size);
     /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
        (output(*size) < input(*size)) is allowed */
-} ISeqInStream;
+};
+#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
 
 /* it can return SZ_ERROR_INPUT_EOF */
-SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf);
 
-typedef struct
+
+typedef struct ISeqOutStream ISeqOutStream;
+struct ISeqOutStream
 {
-  size_t (*Write)(void *p, const void *buf, size_t size);
+  size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size);
     /* Returns: result - the number of actually written bytes.
        (result < size) means error */
-} ISeqOutStream;
+};
+#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
 
 typedef enum
 {
@@ -162,78 +196,162 @@ typedef enum
   SZ_SEEK_END = 2
 } ESzSeek;
 
-typedef struct
-{
-  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
-  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ISeekInStream;
 
-typedef struct
+typedef struct ISeekInStream ISeekInStream;
+struct ISeekInStream
 {
-  SRes (*Look)(void *p, const void **buf, size_t *size);
+  SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
+  SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin);
+};
+#define ISeekInStream_Read(p, buf, size)   (p)->Read(p, buf, size)
+#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
+
+
+typedef struct ILookInStream ILookInStream;
+struct ILookInStream
+{
+  SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size);
     /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
        (output(*size) > input(*size)) is not allowed
        (output(*size) < input(*size)) is allowed */
-  SRes (*Skip)(void *p, size_t offset);
+  SRes (*Skip)(const ILookInStream *p, size_t offset);
     /* offset must be <= output(*size) of Look */
 
-  SRes (*Read)(void *p, void *buf, size_t *size);
+  SRes (*Read)(const ILookInStream *p, void *buf, size_t *size);
     /* reads directly (without buffer). It's same as ISeqInStream::Read */
-  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-} ILookInStream;
+  SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin);
+};
 
-SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+#define ILookInStream_Look(p, buf, size)   (p)->Look(p, buf, size)
+#define ILookInStream_Skip(p, offset)      (p)->Skip(p, offset)
+#define ILookInStream_Read(p, buf, size)   (p)->Read(p, buf, size)
+#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
+
+
+SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset);
 
 /* reads via ILookInStream::Read */
-SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size);
+
 
-#define LookToRead_BUF_SIZE (1 << 14)
 
 typedef struct
 {
-  ILookInStream s;
-  ISeekInStream *realStream;
+  ILookInStream vt;
+  const ISeekInStream *realStream;
+ 
   size_t pos;
-  size_t size;
-  Byte buf[LookToRead_BUF_SIZE];
-} CLookToRead;
+  size_t size; /* it's data size */
+  
+  /* the following variables must be set outside */
+  Byte *buf;
+  size_t bufSize;
+} CLookToRead2;
+
+void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
+
+#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; }
 
-void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-void LookToRead_Init(CLookToRead *p);
 
 typedef struct
 {
-  ISeqInStream s;
-  ILookInStream *realStream;
+  ISeqInStream vt;
+  const ILookInStream *realStream;
 } CSecToLook;
 
 void SecToLook_CreateVTable(CSecToLook *p);
 
+
+
 typedef struct
 {
-  ISeqInStream s;
-  ILookInStream *realStream;
+  ISeqInStream vt;
+  const ILookInStream *realStream;
 } CSecToRead;
 
 void SecToRead_CreateVTable(CSecToRead *p);
 
-typedef struct
+
+typedef struct ICompressProgress ICompressProgress;
+
+struct ICompressProgress
 {
-  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+  SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize);
     /* Returns: result. (result != SZ_OK) means break.
        Value (UInt64)(Int64)-1 for size means unknown value. */
-} ICompressProgress;
+};
+#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
 
-typedef struct
+
+
+typedef struct ISzAlloc ISzAlloc;
+typedef const ISzAlloc * ISzAllocPtr;
+
+struct ISzAlloc
 {
-  void *(*Alloc)(void *p, size_t size);
-  void (*Free)(void *p, void *address); /* address can be 0 */
-} ISzAlloc;
+  void *(*Alloc)(ISzAllocPtr p, size_t size);
+  void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
+};
+
+#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
+#define ISzAlloc_Free(p, a) (p)->Free(p, a)
+
+/* deprecated */
+#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
+#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
+
+
+
+
+
+#ifndef MY_offsetof
+  #ifdef offsetof
+    #define MY_offsetof(type, m) offsetof(type, m)
+    /*
+    #define MY_offsetof(type, m) FIELD_OFFSET(type, m)
+    */
+  #else
+    #define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
+  #endif
+#endif
+
+
+
+#ifndef MY_container_of
+
+/*
+#define MY_container_of(ptr, type, m) container_of(ptr, type, m)
+#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
+#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
+#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
+*/
+
+/*
+  GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
+    GCC 3.4.4 : classes with constructor
+    GCC 4.8.1 : classes with non-public variable members"
+*/
+
+#define MY_container_of(ptr, type, m) ((type *)((char *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m)))
+
+
+#endif
+
+#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(ptr))
+
+/*
+#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+*/
+#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m)
+
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
+/*
+#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m)
+*/
+
 
-#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-#define IAlloc_Free(p, a) (p)->Free((p), a)
 
 #ifdef _WIN32
 
diff --git a/lzma/C/7zVersion.h b/lzma/C/7zVersion.h
index c4f5c8e94..a0f562791 100644
--- a/lzma/C/7zVersion.h
+++ b/lzma/C/7zVersion.h
@@ -1,14 +1,21 @@
-#define MY_VER_MAJOR 15
-#define MY_VER_MINOR 14
+#define MY_VER_MAJOR 17
+#define MY_VER_MINOR 01
 #define MY_VER_BUILD 0
-#define MY_VERSION_NUMBERS "15.14"
-#define MY_VERSION "15.14"
-#define MY_DATE "2015-12-31"
+#define MY_VERSION_NUMBERS "17.01 beta"
+#define MY_VERSION MY_VERSION_NUMBERS
+
+#ifdef MY_CPU_NAME
+  #define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
+#else
+  #define MY_VERSION_CPU MY_VERSION
+#endif
+
+#define MY_DATE "2017-08-28"
 #undef MY_COPYRIGHT
 #undef MY_VERSION_COPYRIGHT_DATE
 #define MY_AUTHOR_NAME "Igor Pavlov"
 #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
-#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov"
+#define MY_COPYRIGHT_CR "Copyright (c) 1999-2017 Igor Pavlov"
 
 #ifdef USE_COPYRIGHT_CR
   #define MY_COPYRIGHT MY_COPYRIGHT_CR
@@ -16,4 +23,5 @@
   #define MY_COPYRIGHT MY_COPYRIGHT_PD
 #endif
 
-#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE
+#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
+#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE
diff --git a/lzma/C/Bcj2.c b/lzma/C/Bcj2.c
index 3c88e44fc..0efff4e5d 100644
--- a/lzma/C/Bcj2.c
+++ b/lzma/C/Bcj2.c
@@ -1,5 +1,5 @@
 /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
-2015-08-01 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -61,7 +61,8 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p)
       Byte *dest = p->dest;
       if (dest == p->destLim)
         return SZ_OK;
-      *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
+      *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
+      p->state++;
       p->dest = dest + 1;
     }
   }
diff --git a/lzma/C/Bra.c b/lzma/C/Bra.c
index cdb945692..aed17e330 100644
--- a/lzma/C/Bra.c
+++ b/lzma/C/Bra.c
@@ -1,135 +1,230 @@
 /* Bra.c -- Converters for RISC code
-2010-04-16 : Igor Pavlov : Public domain */
+2017-04-04 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
+#include "CpuArch.h"
 #include "Bra.h"
 
 SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
 {
-  SizeT i;
-  if (size < 4)
-    return 0;
-  size -= 4;
-  ip += 8;
-  for (i = 0; i <= size; i += 4)
+  Byte *p;
+  const Byte *lim;
+  size &= ~(size_t)3;
+  ip += 4;
+  p = data;
+  lim = data + size;
+
+  if (encoding)
+
+  for (;;)
   {
-    if (data[i + 3] == 0xEB)
+    for (;;)
     {
-      UInt32 dest;
-      UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
-      src <<= 2;
-      if (encoding)
-        dest = ip + (UInt32)i + src;
-      else
-        dest = src - (ip + (UInt32)i);
-      dest >>= 2;
-      data[i + 2] = (Byte)(dest >> 16);
-      data[i + 1] = (Byte)(dest >> 8);
-      data[i + 0] = (Byte)dest;
+      if (p >= lim)
+        return p - data;
+      p += 4;
+      if (p[-1] == 0xEB)
+        break;
+    }
+    {
+      UInt32 v = GetUi32(p - 4);
+      v <<= 2;
+        v += ip + (UInt32)(p - data);
+      v >>= 2;
+      v &= 0x00FFFFFF;
+      v |= 0xEB000000;
+      SetUi32(p - 4, v);
+    }
+  }
+
+  for (;;)
+  {
+    for (;;)
+    {
+      if (p >= lim)
+        return p - data;
+      p += 4;
+      if (p[-1] == 0xEB)
+        break;
+    }
+    {
+      UInt32 v = GetUi32(p - 4);
+      v <<= 2;
+        v -= ip + (UInt32)(p - data);
+      v >>= 2;
+      v &= 0x00FFFFFF;
+      v |= 0xEB000000;
+      SetUi32(p - 4, v);
     }
   }
-  return i;
 }
 
+
 SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
 {
-  SizeT i;
-  if (size < 4)
-    return 0;
-  size -= 4;
-  ip += 4;
-  for (i = 0; i <= size; i += 2)
+  Byte *p;
+  const Byte *lim;
+  size &= ~(size_t)1;
+  p = data;
+  lim = data + size - 4;
+
+  if (encoding)
+  
+  for (;;)
   {
-    if ((data[i + 1] & 0xF8) == 0xF0 &&
-        (data[i + 3] & 0xF8) == 0xF8)
+    UInt32 b1;
+    for (;;)
     {
-      UInt32 dest;
-      UInt32 src =
-        (((UInt32)data[i + 1] & 0x7) << 19) |
-        ((UInt32)data[i + 0] << 11) |
-        (((UInt32)data[i + 3] & 0x7) << 8) |
-        (data[i + 2]);
-      
-      src <<= 1;
-      if (encoding)
-        dest = ip + (UInt32)i + src;
-      else
-        dest = src - (ip + (UInt32)i);
-      dest >>= 1;
-      
-      data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
-      data[i + 0] = (Byte)(dest >> 11);
-      data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
-      data[i + 2] = (Byte)dest;
-      i += 2;
+      UInt32 b3;
+      if (p > lim)
+        return p - data;
+      b1 = p[1];
+      b3 = p[3];
+      p += 2;
+      b1 ^= 8;
+      if ((b3 & b1) >= 0xF8)
+        break;
+    }
+    {
+      UInt32 v =
+             ((UInt32)b1 << 19)
+          + (((UInt32)p[1] & 0x7) << 8)
+          + (((UInt32)p[-2] << 11))
+          + (p[0]);
+
+      p += 2;
+      {
+        UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
+          v += cur;
+      }
+
+      p[-4] = (Byte)(v >> 11);
+      p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
+      p[-2] = (Byte)v;
+      p[-1] = (Byte)(0xF8 | (v >> 8));
+    }
+  }
+  
+  for (;;)
+  {
+    UInt32 b1;
+    for (;;)
+    {
+      UInt32 b3;
+      if (p > lim)
+        return p - data;
+      b1 = p[1];
+      b3 = p[3];
+      p += 2;
+      b1 ^= 8;
+      if ((b3 & b1) >= 0xF8)
+        break;
+    }
+    {
+      UInt32 v =
+             ((UInt32)b1 << 19)
+          + (((UInt32)p[1] & 0x7) << 8)
+          + (((UInt32)p[-2] << 11))
+          + (p[0]);
+
+      p += 2;
+      {
+        UInt32 cur = (ip + (UInt32)(p - data)) >> 1;
+          v -= cur;
+      }
+
+      /*
+      SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000));
+      SetUi16(p - 2, (UInt16)(v | 0xF800));
+      */
+      
+      p[-4] = (Byte)(v >> 11);
+      p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7));
+      p[-2] = (Byte)v;
+      p[-1] = (Byte)(0xF8 | (v >> 8));
     }
   }
-  return i;
 }
 
+
 SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
 {
-  SizeT i;
-  if (size < 4)
-    return 0;
-  size -= 4;
-  for (i = 0; i <= size; i += 4)
+  Byte *p;
+  const Byte *lim;
+  size &= ~(size_t)3;
+  ip -= 4;
+  p = data;
+  lim = data + size;
+
+  for (;;)
   {
-    if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
+    for (;;)
     {
-      UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
-        ((UInt32)data[i + 1] << 16) |
-        ((UInt32)data[i + 2] << 8) |
-        ((UInt32)data[i + 3] & (~3));
-      
-      UInt32 dest;
+      if (p >= lim)
+        return p - data;
+      p += 4;
+      /* if ((v & 0xFC000003) == 0x48000001) */
+      if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1)
+        break;
+    }
+    {
+      UInt32 v = GetBe32(p - 4);
       if (encoding)
-        dest = ip + (UInt32)i + src;
+        v += ip + (UInt32)(p - data);
       else
-        dest = src - (ip + (UInt32)i);
-      data[i + 0] = (Byte)(0x48 | ((dest >> 24) &  0x3));
-      data[i + 1] = (Byte)(dest >> 16);
-      data[i + 2] = (Byte)(dest >> 8);
-      data[i + 3] &= 0x3;
-      data[i + 3] |= dest;
+        v -= ip + (UInt32)(p - data);
+      v &= 0x03FFFFFF;
+      v |= 0x48000000;
+      SetBe32(p - 4, v);
     }
   }
-  return i;
 }
 
+
 SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
 {
-  UInt32 i;
-  if (size < 4)
-    return 0;
-  size -= 4;
-  for (i = 0; i <= size; i += 4)
-  {
-    if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
-        (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
-    {
-      UInt32 src =
-        ((UInt32)data[i + 0] << 24) |
-        ((UInt32)data[i + 1] << 16) |
-        ((UInt32)data[i + 2] << 8) |
-        ((UInt32)data[i + 3]);
-      UInt32 dest;
-      
-      src <<= 2;
-      if (encoding)
-        dest = ip + i + src;
-      else
-        dest = src - (ip + i);
-      dest >>= 2;
-      
-      dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
+  Byte *p;
+  const Byte *lim;
+  size &= ~(size_t)3;
+  ip -= 4;
+  p = data;
+  lim = data + size;
 
-      data[i + 0] = (Byte)(dest >> 24);
-      data[i + 1] = (Byte)(dest >> 16);
-      data[i + 2] = (Byte)(dest >> 8);
-      data[i + 3] = (Byte)dest;
+  for (;;)
+  {
+    for (;;)
+    {
+      if (p >= lim)
+        return p - data;
+      /*
+      v = GetBe32(p);
+      p += 4;
+      m = v + ((UInt32)5 << 29);
+      m ^= (UInt32)7 << 29;
+      m += (UInt32)1 << 22;
+      if ((m & ((UInt32)0x1FF << 23)) == 0)
+        break;
+      */
+      p += 4;
+      if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) ||
+          (p[-4] == 0x7F && (p[-3] >= 0xC0)))
+        break;
+    }
+    {
+      UInt32 v = GetBe32(p - 4);
+      v <<= 2;
+      if (encoding)
+        v += ip + (UInt32)(p - data);
+      else
+        v -= ip + (UInt32)(p - data);
+      
+      v &= 0x01FFFFFF;
+      v -= (UInt32)1 << 24;
+      v ^= 0xFF000000;
+      v >>= 2;
+      v |= 0x40000000;
+      SetBe32(p - 4, v);
     }
   }
-  return i;
 }
diff --git a/lzma/C/Bra86.c b/lzma/C/Bra86.c
index 6db15e7ec..93ed4d762 100644
--- a/lzma/C/Bra86.c
+++ b/lzma/C/Bra86.c
@@ -1,5 +1,5 @@
 /* Bra86.c -- Converter for x86 code (BCJ)
-2013-11-12 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -37,7 +37,7 @@ SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding
       else
       {
         mask >>= (unsigned)d;
-        if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
+        if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1])))
         {
           mask = (mask >> 1) | 4;
           pos++;
diff --git a/lzma/C/BraIA64.c b/lzma/C/BraIA64.c
index fa60356b2..d1dbc62c5 100644
--- a/lzma/C/BraIA64.c
+++ b/lzma/C/BraIA64.c
@@ -1,69 +1,53 @@
 /* BraIA64.c -- Converter for IA-64 code
-2013-11-12 : Igor Pavlov : Public domain */
+2017-01-26 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
+#include "CpuArch.h"
 #include "Bra.h"
 
-static const Byte kBranchTable[32] =
-{
-  0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0,
-  4, 4, 6, 6, 0, 0, 7, 7,
-  4, 4, 0, 0, 4, 4, 0, 0
-};
-
 SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
 {
   SizeT i;
   if (size < 16)
     return 0;
   size -= 16;
-  for (i = 0; i <= size; i += 16)
+  i = 0;
+  do
   {
-    UInt32 instrTemplate = data[i] & 0x1F;
-    UInt32 mask = kBranchTable[instrTemplate];
-    UInt32 bitPos = 5;
-    int slot;
-    for (slot = 0; slot < 3; slot++, bitPos += 41)
+    unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3;
+    if (m)
     {
-      UInt32 bytePos, bitRes;
-      UInt64 instruction, instNorm;
-      int j;
-      if (((mask >> slot) & 1) == 0)
-        continue;
-      bytePos = (bitPos >> 3);
-      bitRes = bitPos & 0x7;
-      instruction = 0;
-      for (j = 0; j < 6; j++)
-        instruction += (UInt64)data[i + j + bytePos] << (8 * j);
-
-      instNorm = instruction >> bitRes;
-      if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
+      m++;
+      do
       {
-        UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
-        UInt32 dest;
-        src |= ((UInt32)(instNorm >> 36) & 1) << 20;
-        
-        src <<= 4;
-        
-        if (encoding)
-          dest = ip + (UInt32)i + src;
-        else
-          dest = src - (ip + (UInt32)i);
-        
-        dest >>= 4;
-        
-        instNorm &= ~((UInt64)(0x8FFFFF) << 13);
-        instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
-        instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
-        
-        instruction &= (1 << bitRes) - 1;
-        instruction |= (instNorm << bitRes);
-        for (j = 0; j < 6; j++)
-          data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
+        Byte *p = data + (i + (size_t)m * 5 - 8);
+        if (((p[3] >> m) & 15) == 5
+            && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0)
+        {
+          unsigned raw = GetUi32(p);
+          unsigned v = raw >> m;
+          v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3);
+          
+          v <<= 4;
+          if (encoding)
+            v += ip + (UInt32)i;
+          else
+            v -= ip + (UInt32)i;
+          v >>= 4;
+          
+          v &= 0x1FFFFF;
+          v += 0x700000;
+          v &= 0x8FFFFF;
+          raw &= ~((UInt32)0x8FFFFF << m);
+          raw |= (v << m);
+          SetUi32(p, raw);
+        }
       }
+      while (++m <= 4);
     }
+    i += 16;
   }
+  while (i <= size);
   return i;
 }
diff --git a/lzma/C/Compiler.h b/lzma/C/Compiler.h
index 5bba7ee56..0cc409d8a 100644
--- a/lzma/C/Compiler.h
+++ b/lzma/C/Compiler.h
@@ -1,5 +1,5 @@
 /* Compiler.h
-2015-08-02 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_COMPILER_H
 #define __7Z_COMPILER_H
@@ -21,6 +21,7 @@
     #pragma warning(disable : 4514) // unreferenced inline function has been removed
     #pragma warning(disable : 4702) // unreachable code
     #pragma warning(disable : 4710) // not inlined
+    #pragma warning(disable : 4714) // function marked as __forceinline not inlined
     #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
   #endif
 
diff --git a/lzma/C/CpuArch.c b/lzma/C/CpuArch.c
index 36fc5bb49..554ffa4fc 100644
--- a/lzma/C/CpuArch.c
+++ b/lzma/C/CpuArch.c
@@ -1,5 +1,5 @@
 /* CpuArch.c -- CPU specific code
-2015-03-25: Igor Pavlov : Public domain */
+2016-02-25: Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
     "push %%EDX\n\t"
     "popf\n\t"
     "andl %%EAX, %0\n\t":
-    "=c" (flag) : "c" (flag));
+    "=c" (flag) : "c" (flag) :
+    "%eax", "%edx");
   #endif
   return flag;
 }
@@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
   #else
 
   __asm__ __volatile__ (
-  #if defined(MY_CPU_X86) && defined(__PIC__)
+  #if defined(MY_CPU_AMD64) && defined(__PIC__)
+    "mov %%rbx, %%rdi;"
+    "cpuid;"
+    "xchg %%rbx, %%rdi;"
+    : "=a" (*a) ,
+      "=D" (*b) ,
+  #elif defined(MY_CPU_X86) && defined(__PIC__)
     "mov %%ebx, %%edi;"
     "cpuid;"
     "xchgl %%ebx, %%edi;"
diff --git a/lzma/C/CpuArch.h b/lzma/C/CpuArch.h
index f6a28ba7e..51dd607b0 100644
--- a/lzma/C/CpuArch.h
+++ b/lzma/C/CpuArch.h
@@ -1,5 +1,5 @@
 /* CpuArch.h -- CPU specific code
-2015-12-01: Igor Pavlov : Public domain */
+2017-06-30 : Igor Pavlov : Public domain */
 
 #ifndef __CPU_ARCH_H
 #define __CPU_ARCH_H
@@ -16,48 +16,122 @@ If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of pl
 MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
 */
 
-#if defined(_M_X64) \
-   || defined(_M_AMD64) \
-   || defined(__x86_64__) \
-   || defined(__AMD64__) \
-   || defined(__amd64__)
+#if  defined(_M_X64) \
+  || defined(_M_AMD64) \
+  || defined(__x86_64__) \
+  || defined(__AMD64__) \
+  || defined(__amd64__)
   #define MY_CPU_AMD64
-#endif
-
-#if defined(MY_CPU_AMD64) \
-    || defined(_M_IA64) \
-    || defined(__AARCH64EL__) \
-    || defined(__AARCH64EB__)
+  #ifdef __ILP32__
+    #define MY_CPU_NAME "x32"
+  #else
+    #define MY_CPU_NAME "x64"
+  #endif
   #define MY_CPU_64BIT
 #endif
 
-#if defined(_M_IX86) || defined(__i386__)
-#define MY_CPU_X86
+
+#if  defined(_M_IX86) \
+  || defined(__i386__)
+  #define MY_CPU_X86
+  #define MY_CPU_NAME "x86"
+  #define MY_CPU_32BIT
 #endif
 
+
+#if  defined(_M_ARM64) \
+  || defined(__AARCH64EL__) \
+  || defined(__AARCH64EB__) \
+  || defined(__aarch64__)
+  #define MY_CPU_ARM64
+  #define MY_CPU_NAME "arm64"
+  #define MY_CPU_64BIT
+#endif
+
+
+#if  defined(_M_ARM) \
+  || defined(_M_ARM_NT) \
+  || defined(_M_ARMT) \
+  || defined(__arm__) \
+  || defined(__thumb__) \
+  || defined(__ARMEL__) \
+  || defined(__ARMEB__) \
+  || defined(__THUMBEL__) \
+  || defined(__THUMBEB__)
+  #define MY_CPU_ARM
+  #define MY_CPU_NAME "arm"
+  #define MY_CPU_32BIT
+#endif
+
+
+#if  defined(_M_IA64) \
+  || defined(__ia64__)
+  #define MY_CPU_IA64
+  #define MY_CPU_NAME "ia64"
+  #define MY_CPU_64BIT
+#endif
+
+
+#if  defined(__mips64) \
+  || defined(__mips64__) \
+  || (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
+  #define MY_CPU_NAME "mips64"
+  #define MY_CPU_64BIT
+#elif defined(__mips__)
+  #define MY_CPU_NAME "mips"
+  /* #define MY_CPU_32BIT */
+#endif
+
+
+#if  defined(__ppc64__) \
+  || defined(__powerpc64__)
+  #ifdef __ILP32__
+    #define MY_CPU_NAME "ppc64-32"
+  #else
+    #define MY_CPU_NAME "ppc64"
+  #endif
+  #define MY_CPU_64BIT
+#elif defined(__ppc__) \
+  || defined(__powerpc__)
+  #define MY_CPU_NAME "ppc"
+  #define MY_CPU_32BIT
+#endif
+
+
+#if  defined(__sparc64__)
+  #define MY_CPU_NAME "sparc64"
+  #define MY_CPU_64BIT
+#elif defined(__sparc__)
+  #define MY_CPU_NAME "sparc"
+  /* #define MY_CPU_32BIT */
+#endif
+
+
 #if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
 #define MY_CPU_X86_OR_AMD64
 #endif
 
-#if defined(MY_CPU_X86) \
-    || defined(_M_ARM) \
-    || defined(__ARMEL__) \
-    || defined(__THUMBEL__) \
-    || defined(__ARMEB__) \
-    || defined(__THUMBEB__)
-  #define MY_CPU_32BIT
+
+#ifdef _WIN32
+
+  #ifdef MY_CPU_ARM
+  #define MY_CPU_ARM_LE
+  #endif
+
+  #ifdef MY_CPU_ARM64
+  #define MY_CPU_ARM64_LE
+  #endif
+
+  #ifdef _M_IA64
+  #define MY_CPU_IA64_LE
+  #endif
+
 #endif
 
-#if defined(_WIN32) && defined(_M_ARM)
-#define MY_CPU_ARM_LE
-#endif
-
-#if defined(_WIN32) && defined(_M_IA64)
-#define MY_CPU_IA64_LE
-#endif
 
 #if defined(MY_CPU_X86_OR_AMD64) \
     || defined(MY_CPU_ARM_LE) \
+    || defined(MY_CPU_ARM64_LE) \
     || defined(MY_CPU_IA64_LE) \
     || defined(__LITTLE_ENDIAN__) \
     || defined(__ARMEL__) \
@@ -66,6 +140,7 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
     || defined(__MIPSEL__) \
     || defined(__MIPSEL) \
     || defined(_MIPSEL) \
+    || defined(__BFIN__) \
     || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
   #define MY_CPU_LE
 #endif
@@ -85,14 +160,37 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
   #define MY_CPU_BE
 #endif
 
+
 #if defined(MY_CPU_LE) && defined(MY_CPU_BE)
-Stop_Compiling_Bad_Endian
+  #error Stop_Compiling_Bad_Endian
 #endif
 
 
+#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
+  #error Stop_Compiling_Bad_32_64_BIT
+#endif
+
+
+#ifndef MY_CPU_NAME
+  #ifdef MY_CPU_LE
+    #define MY_CPU_NAME "LE"
+  #elif MY_CPU_BE
+    #define MY_CPU_NAME "BE"
+  #else
+    /*
+    #define MY_CPU_NAME ""
+    */
+  #endif
+#endif
+
+
+
+
+
 #ifdef MY_CPU_LE
   #if defined(MY_CPU_X86_OR_AMD64) \
-      /* || defined(__AARCH64EL__) */
+      || defined(MY_CPU_ARM64) \
+      || defined(__ARM_FEATURE_UNALIGNED)
     #define MY_CPU_LE_UNALIGN
   #endif
 #endif
@@ -138,6 +236,11 @@ Stop_Compiling_Bad_Endian
 
 #endif
 
+#ifdef __has_builtin
+  #define MY__has_builtin(x) __has_builtin(x)
+#else
+  #define MY__has_builtin(x) 0
+#endif
 
 #if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
 
@@ -145,15 +248,21 @@ Stop_Compiling_Bad_Endian
 
 #include <stdlib.h>
 
+#pragma intrinsic(_byteswap_ushort)
 #pragma intrinsic(_byteswap_ulong)
 #pragma intrinsic(_byteswap_uint64)
+
+/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */
 #define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
 #define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
 
 #define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
 
-#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#elif defined(MY_CPU_LE_UNALIGN) && ( \
+       (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
+    || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) )
 
+/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const Byte *)(p)) */
 #define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
 #define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
 
@@ -178,10 +287,14 @@ Stop_Compiling_Bad_Endian
 #endif
 
 
+#ifndef GetBe16
+
 #define GetBe16(p) ( (UInt16) ( \
     ((UInt16)((const Byte *)(p))[0] << 8) | \
              ((const Byte *)(p))[1] ))
 
+#endif
+
 
 
 #ifdef MY_CPU_X86_OR_AMD64
diff --git a/lzma/C/LzFind.c b/lzma/C/LzFind.c
index 2d05fa395..18ef49dca 100644
--- a/lzma/C/LzFind.c
+++ b/lzma/C/LzFind.c
@@ -1,5 +1,5 @@
 /* LzFind.c -- Match finder for LZ algorithms
-2015-10-15 : Igor Pavlov : Public domain */
+2017-06-10 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -16,18 +16,18 @@
 
 #define kStartMaxLen 3
 
-static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)
 {
   if (!p->directInput)
   {
-    alloc->Free(alloc, p->bufferBase);
+    ISzAlloc_Free(alloc, p->bufferBase);
     p->bufferBase = NULL;
   }
 }
 
 /* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
 
-static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)
 {
   UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
   if (p->directInput)
@@ -39,7 +39,7 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
   {
     LzInWindow_Free(p, alloc);
     p->blockSize = blockSize;
-    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+    p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);
   }
   return (p->bufferBase != NULL);
 }
@@ -81,7 +81,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
     if (size == 0)
       return;
 
-    p->result = p->stream->Read(p->stream, dest, &size);
+    p->result = ISeqInStream_Read(p->stream, dest, &size);
     if (p->result != SZ_OK)
       return;
     if (size == 0)
@@ -142,6 +142,7 @@ void MatchFinder_Construct(CMatchFinder *p)
   p->bufferBase = NULL;
   p->directInput = 0;
   p->hash = NULL;
+  p->expectedDataSize = (UInt64)(Int64)-1;
   MatchFinder_SetDefaultSettings(p);
 
   for (i = 0; i < 256; i++)
@@ -149,34 +150,34 @@ void MatchFinder_Construct(CMatchFinder *p)
     UInt32 r = i;
     unsigned j;
     for (j = 0; j < 8; j++)
-      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+      r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
     p->crc[i] = r;
   }
 }
 
-static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->hash);
+  ISzAlloc_Free(alloc, p->hash);
   p->hash = NULL;
 }
 
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)
 {
   MatchFinder_FreeThisClassMemory(p, alloc);
   LzInWindow_Free(p, alloc);
 }
 
-static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
+static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)
 {
   size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
   if (sizeInBytes / sizeof(CLzRef) != num)
     return NULL;
-  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+  return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);
 }
 
 int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
     UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-    ISzAlloc *alloc)
+    ISzAllocPtr alloc)
 {
   UInt32 sizeReserv;
   
@@ -208,7 +209,11 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
         hs = (1 << 16) - 1;
       else
       {
-        hs = historySize - 1;
+        hs = historySize;
+        if (hs > p->expectedDataSize)
+          hs = (UInt32)p->expectedDataSize;
+        if (hs != 0)
+          hs--;
         hs |= (hs >> 1);
         hs |= (hs >> 2);
         hs |= (hs >> 4);
@@ -292,17 +297,33 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
   p->posLimit = p->pos + limit;
 }
 
-void MatchFinder_Init_2(CMatchFinder *p, int readData)
+
+void MatchFinder_Init_LowHash(CMatchFinder *p)
+{
+  size_t i;
+  CLzRef *items = p->hash;
+  size_t numItems = p->fixedHashSize;
+  for (i = 0; i < numItems; i++)
+    items[i] = kEmptyHashValue;
+}
+
+
+void MatchFinder_Init_HighHash(CMatchFinder *p)
+{
+  size_t i;
+  CLzRef *items = p->hash + p->fixedHashSize;
+  size_t numItems = (size_t)p->hashMask + 1;
+  for (i = 0; i < numItems; i++)
+    items[i] = kEmptyHashValue;
+}
+
+
+void MatchFinder_Init_3(CMatchFinder *p, int readData)
 {
-  UInt32 i;
-  UInt32 *hash = p->hash;
-  UInt32 num = p->hashSizeSum;
-  for (i = 0; i < num; i++)
-    hash[i] = kEmptyHashValue;
-  
   p->cyclicBufferPos = 0;
   p->buffer = p->bufferBase;
-  p->pos = p->streamPos = p->cyclicBufferSize;
+  p->pos =
+  p->streamPos = p->cyclicBufferSize;
   p->result = SZ_OK;
   p->streamEndWasReached = 0;
   
@@ -312,10 +333,14 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData)
   MatchFinder_SetLimits(p);
 }
 
+
 void MatchFinder_Init(CMatchFinder *p)
 {
-  MatchFinder_Init_2(p, True);
+  MatchFinder_Init_HighHash(p);
+  MatchFinder_Init_LowHash(p);
+  MatchFinder_Init_3(p, True);
 }
+
   
 static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
 {
@@ -558,10 +583,10 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 
   d2 = pos - hash[h2];
 
-  curMatch = hash[kFix3HashSize + hv];
+  curMatch = (hash + kFix3HashSize)[hv];
   
   hash[h2] = pos;
-  hash[kFix3HashSize + hv] = pos;
+  (hash + kFix3HashSize)[hv] = pos;
 
   maxLen = 2;
   offset = 0;
@@ -594,13 +619,13 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   pos = p->pos;
 
   d2 = pos - hash[                h2];
-  d3 = pos - hash[kFix3HashSize + h3];
+  d3 = pos - (hash + kFix3HashSize)[h3];
 
-  curMatch = hash[kFix4HashSize + hv];
+  curMatch = (hash + kFix4HashSize)[hv];
 
   hash[                h2] = pos;
-  hash[kFix3HashSize + h3] = pos;
-  hash[kFix4HashSize + hv] = pos;
+  (hash + kFix3HashSize)[h3] = pos;
+  (hash + kFix4HashSize)[hv] = pos;
 
   maxLen = 0;
   offset = 0;
@@ -615,7 +640,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
   {
     maxLen = 3;
-    distances[offset + 1] = d3 - 1;
+    distances[(size_t)offset + 1] = d3 - 1;
     offset += 2;
     d2 = d3;
   }
@@ -623,7 +648,7 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   if (offset != 0)
   {
     UPDATE_maxLen
-    distances[offset - 2] = maxLen;
+    distances[(size_t)offset - 2] = maxLen;
     if (maxLen == lenLimit)
     {
       SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@@ -650,15 +675,15 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   pos = p->pos;
 
   d2 = pos - hash[                h2];
-  d3 = pos - hash[kFix3HashSize + h3];
-  d4 = pos - hash[kFix4HashSize + h4];
+  d3 = pos - (hash + kFix3HashSize)[h3];
+  d4 = pos - (hash + kFix4HashSize)[h4];
 
-  curMatch = hash[kFix5HashSize + hv];
+  curMatch = (hash + kFix5HashSize)[hv];
 
   hash[                h2] = pos;
-  hash[kFix3HashSize + h3] = pos;
-  hash[kFix4HashSize + h4] = pos;
-  hash[kFix5HashSize + hv] = pos;
+  (hash + kFix3HashSize)[h3] = pos;
+  (hash + kFix4HashSize)[h4] = pos;
+  (hash + kFix5HashSize)[hv] = pos;
 
   maxLen = 0;
   offset = 0;
@@ -691,7 +716,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
       && *(cur - d4 + 3) == *(cur + 3))
   {
     maxLen = 4;
-    distances[offset + 1] = d4 - 1;
+    distances[(size_t)offset + 1] = d4 - 1;
     offset += 2;
     d2 = d4;
   }
@@ -699,7 +724,7 @@ static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   if (offset != 0)
   {
     UPDATE_maxLen
-    distances[offset - 2] = maxLen;
+    distances[(size_t)offset - 2] = maxLen;
     if (maxLen == lenLimit)
     {
       SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
@@ -726,13 +751,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   pos = p->pos;
   
   d2 = pos - hash[                h2];
-  d3 = pos - hash[kFix3HashSize + h3];
+  d3 = pos - (hash + kFix3HashSize)[h3];
   
-  curMatch = hash[kFix4HashSize + hv];
+  curMatch = (hash + kFix4HashSize)[hv];
 
   hash[                h2] = pos;
-  hash[kFix3HashSize + h3] = pos;
-  hash[kFix4HashSize + hv] = pos;
+  (hash + kFix3HashSize)[h3] = pos;
+  (hash + kFix4HashSize)[hv] = pos;
 
   maxLen = 0;
   offset = 0;
@@ -747,7 +772,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
   {
     maxLen = 3;
-    distances[offset + 1] = d3 - 1;
+    distances[(size_t)offset + 1] = d3 - 1;
     offset += 2;
     d2 = d3;
   }
@@ -755,7 +780,7 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   if (offset != 0)
   {
     UPDATE_maxLen
-    distances[offset - 2] = maxLen;
+    distances[(size_t)offset - 2] = maxLen;
     if (maxLen == lenLimit)
     {
       p->son[p->cyclicBufferPos] = curMatch;
@@ -784,15 +809,15 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   pos = p->pos;
   
   d2 = pos - hash[                h2];
-  d3 = pos - hash[kFix3HashSize + h3];
-  d4 = pos - hash[kFix4HashSize + h4];
+  d3 = pos - (hash + kFix3HashSize)[h3];
+  d4 = pos - (hash + kFix4HashSize)[h4];
 
-  curMatch = hash[kFix5HashSize + hv];
+  curMatch = (hash + kFix5HashSize)[hv];
 
   hash[                h2] = pos;
-  hash[kFix3HashSize + h3] = pos;
-  hash[kFix4HashSize + h4] = pos;
-  hash[kFix5HashSize + hv] = pos;
+  (hash + kFix3HashSize)[h3] = pos;
+  (hash + kFix4HashSize)[h4] = pos;
+  (hash + kFix5HashSize)[hv] = pos;
 
   maxLen = 0;
   offset = 0;
@@ -825,7 +850,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
       && *(cur - d4 + 3) == *(cur + 3))
   {
     maxLen = 4;
-    distances[offset + 1] = d4 - 1;
+    distances[(size_t)offset + 1] = d4 - 1;
     offset += 2;
     d2 = d4;
   }
@@ -833,7 +858,7 @@ static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
   if (offset != 0)
   {
     UPDATE_maxLen
-    distances[offset - 2] = maxLen;
+    distances[(size_t)offset - 2] = maxLen;
     if (maxLen == lenLimit)
     {
       p->son[p->cyclicBufferPos] = curMatch;
@@ -897,9 +922,9 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
     SKIP_HEADER(3)
     HASH3_CALC;
     hash = p->hash;
-    curMatch = hash[kFix3HashSize + hv];
+    curMatch = (hash + kFix3HashSize)[hv];
     hash[h2] =
-    hash[kFix3HashSize + hv] = p->pos;
+    (hash + kFix3HashSize)[hv] = p->pos;
     SKIP_FOOTER
   }
   while (--num != 0);
@@ -914,10 +939,10 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
     SKIP_HEADER(4)
     HASH4_CALC;
     hash = p->hash;
-    curMatch = hash[kFix4HashSize + hv];
+    curMatch = (hash + kFix4HashSize)[hv];
     hash[                h2] =
-    hash[kFix3HashSize + h3] =
-    hash[kFix4HashSize + hv] = p->pos;
+    (hash + kFix3HashSize)[h3] =
+    (hash + kFix4HashSize)[hv] = p->pos;
     SKIP_FOOTER
   }
   while (--num != 0);
@@ -933,11 +958,11 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
     SKIP_HEADER(5)
     HASH5_CALC;
     hash = p->hash;
-    curMatch = hash[kFix5HashSize + hv];
+    curMatch = (hash + kFix5HashSize)[hv];
     hash[                h2] =
-    hash[kFix3HashSize + h3] =
-    hash[kFix4HashSize + h4] =
-    hash[kFix5HashSize + hv] = p->pos;
+    (hash + kFix3HashSize)[h3] =
+    (hash + kFix4HashSize)[h4] =
+    (hash + kFix5HashSize)[hv] = p->pos;
     SKIP_FOOTER
   }
   while (--num != 0);
@@ -953,10 +978,10 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
     SKIP_HEADER(4)
     HASH4_CALC;
     hash = p->hash;
-    curMatch = hash[kFix4HashSize + hv];
+    curMatch = (hash + kFix4HashSize)[hv];
     hash[                h2] =
-    hash[kFix3HashSize + h3] =
-    hash[kFix4HashSize + hv] = p->pos;
+    (hash + kFix3HashSize)[h3] =
+    (hash + kFix4HashSize)[hv] = p->pos;
     p->son[p->cyclicBufferPos] = curMatch;
     MOVE_POS
   }
@@ -973,11 +998,11 @@ static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
     SKIP_HEADER(5)
     HASH5_CALC;
     hash = p->hash;
-    curMatch = p->hash[kFix5HashSize + hv];
+    curMatch = hash + kFix5HashSize)[hv];
     hash[                h2] =
-    hash[kFix3HashSize + h3] =
-    hash[kFix4HashSize + h4] =
-    hash[kFix5HashSize + hv] = p->pos;
+    (hash + kFix3HashSize)[h3] =
+    (hash + kFix4HashSize)[h4] =
+    (hash + kFix5HashSize)[hv] = p->pos;
     p->son[p->cyclicBufferPos] = curMatch;
     MOVE_POS
   }
diff --git a/lzma/C/LzFind.h b/lzma/C/LzFind.h
index d119944f4..42c13be15 100644
--- a/lzma/C/LzFind.h
+++ b/lzma/C/LzFind.h
@@ -1,5 +1,5 @@
 /* LzFind.h -- Match finder for LZ algorithms
-2015-10-15 : Igor Pavlov : Public domain */
+2017-06-10 : Igor Pavlov : Public domain */
 
 #ifndef __LZ_FIND_H
 #define __LZ_FIND_H
@@ -47,6 +47,8 @@ typedef struct _CMatchFinder
   SRes result;
   UInt32 crc[256];
   size_t numRefs;
+
+  UInt64 expectedDataSize;
 } CMatchFinder;
 
 #define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
@@ -71,8 +73,8 @@ void MatchFinder_Construct(CMatchFinder *p);
 */
 int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
     UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-    ISzAlloc *alloc);
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+    ISzAllocPtr alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
 void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
 void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
 
@@ -103,7 +105,9 @@ typedef struct _IMatchFinder
 
 void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
 
-void MatchFinder_Init_2(CMatchFinder *p, int readData);
+void MatchFinder_Init_LowHash(CMatchFinder *p);
+void MatchFinder_Init_HighHash(CMatchFinder *p);
+void MatchFinder_Init_3(CMatchFinder *p, int readData);
 void MatchFinder_Init(CMatchFinder *p);
 
 UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
diff --git a/lzma/C/LzFindMt.c b/lzma/C/LzFindMt.c
index a4ffa5ef9..65c9ffd73 100644
--- a/lzma/C/LzFindMt.c
+++ b/lzma/C/LzFindMt.c
@@ -1,5 +1,5 @@
 /* LzFindMt.c -- multithreaded Match finder for LZ algorithms
-2015-10-15 : Igor Pavlov : Public domain */
+2017-06-10 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -33,6 +33,8 @@ static void MtSync_GetNextBlock(CMtSync *p)
 
     Event_Set(&p->canStart);
     Event_Wait(&p->wasStarted);
+
+    // if (mt) MatchFinder_Init_LowHash(mt->MatchFinder);
   }
   else
   {
@@ -155,6 +157,9 @@ static void HashThreadFunc(CMatchFinderMt *mt)
     UInt32 numProcessedBlocks = 0;
     Event_Wait(&p->canStart);
     Event_Set(&p->wasStarted);
+
+    MatchFinder_Init_HighHash(mt->MatchFinder);
+
     for (;;)
     {
       if (p->exit)
@@ -205,7 +210,7 @@ static void HashThreadFunc(CMatchFinderMt *mt)
             if (num > kMtHashBlockSize - 2)
               num = kMtHashBlockSize - 2;
             mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
-            heads[0] += num;
+            heads[0] = 2 + num;
           }
           mf->pos += num;
           mf->buffer += num;
@@ -443,13 +448,13 @@ void MatchFinderMt_Construct(CMatchFinderMt *p)
   MtSync_Construct(&p->btSync);
 }
 
-static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
+static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->hashBuf);
+  ISzAlloc_Free(alloc, p->hashBuf);
   p->hashBuf = NULL;
 }
 
-void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc)
 {
   MtSync_Destruct(&p->hashSync);
   MtSync_Destruct(&p->btSync);
@@ -472,7 +477,7 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
 }
 
 SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
-    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
+    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc)
 {
   CMatchFinder *mf = p->MatchFinder;
   p->historySize = historySize;
@@ -480,7 +485,7 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
     return SZ_ERROR_PARAM;
   if (!p->hashBuf)
   {
-    p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
+    p->hashBuf = (UInt32 *)ISzAlloc_Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
     if (!p->hashBuf)
       return SZ_ERROR_MEM;
     p->btBuf = p->hashBuf + kHashBufferSize;
@@ -496,14 +501,18 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
 }
 
 /* Call it after ReleaseStream / SetStream */
-void MatchFinderMt_Init(CMatchFinderMt *p)
+static void MatchFinderMt_Init(CMatchFinderMt *p)
 {
   CMatchFinder *mf = p->MatchFinder;
-  p->btBufPos = p->btBufPosLimit = 0;
-  p->hashBufPos = p->hashBufPosLimit = 0;
+  
+  p->btBufPos =
+  p->btBufPosLimit = 0;
+  p->hashBufPos =
+  p->hashBufPosLimit = 0;
 
   /* Init without data reading. We don't want to read data in this thread */
-  MatchFinder_Init_2(mf, False);
+  MatchFinder_Init_3(mf, False);
+  MatchFinder_Init_LowHash(mf);
   
   p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
   p->btNumAvailBytes = 0;
@@ -591,10 +600,10 @@ static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *dista
   MT_HASH3_CALC
 
   curMatch2 = hash[                h2];
-  curMatch3 = hash[kFix3HashSize + h3];
+  curMatch3 = (hash + kFix3HashSize)[h3];
   
   hash[                h2] = lzPos;
-  hash[kFix3HashSize + h3] = lzPos;
+  (hash + kFix3HashSize)[h3] = lzPos;
 
   if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
   {
@@ -627,12 +636,12 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distan
   MT_HASH4_CALC
       
   curMatch2 = hash[                h2];
-  curMatch3 = hash[kFix3HashSize + h3];
-  curMatch4 = hash[kFix4HashSize + h4];
+  curMatch3 = (hash + kFix3HashSize)[h3];
+  curMatch4 = (hash + kFix4HashSize)[h4];
   
   hash[                h2] = lzPos;
-  hash[kFix3HashSize + h3] = lzPos;
-  hash[kFix4HashSize + h4] = lzPos;
+  (hash + kFix3HashSize)[h3] = lzPos;
+  (hash + kFix4HashSize)[h4] = lzPos;
 
   if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
   {
@@ -684,8 +693,12 @@ static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
     UInt32 i;
     for (i = 0; i < len; i += 2)
     {
-      *distances++ = *btBuf++;
-      *distances++ = *btBuf++;
+      UInt32 v0 = btBuf[0];
+      UInt32 v1 = btBuf[1];
+      btBuf += 2;
+      distances[0] = v0;
+      distances[1] = v1;
+      distances += 2;
     }
   }
   INCREASE_LZ_POS
@@ -712,8 +725,12 @@ static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
     distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
     do
     {
-      *distances2++ = *btBuf++;
-      *distances2++ = *btBuf++;
+      UInt32 v0 = btBuf[0];
+      UInt32 v1 = btBuf[1];
+      btBuf += 2;
+      distances2[0] = v0;
+      distances2[1] = v1;
+      distances2 += 2;
     }
     while ((len -= 2) != 0);
     len = (UInt32)(distances2 - (distances));
@@ -746,7 +763,7 @@ static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
   SKIP_HEADER_MT(3)
       UInt32 h2, h3;
       MT_HASH3_CALC
-      hash[kFix3HashSize + h3] =
+      (hash + kFix3HashSize)[h3] =
       hash[                h2] =
         p->lzPos;
   SKIP_FOOTER_MT
@@ -758,8 +775,8 @@ static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
   SKIP_HEADER_MT(4)
       UInt32 h2, h3, h4;
       MT_HASH4_CALC
-      hash[kFix4HashSize + h4] =
-      hash[kFix3HashSize + h3] =
+      (hash + kFix4HashSize)[h4] =
+      (hash + kFix3HashSize)[h3] =
       hash[                h2] =
         p->lzPos;
   SKIP_FOOTER_MT
@@ -777,7 +794,7 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
   {
     case 2:
       p->GetHeadsFunc = GetHeads2;
-      p->MixMatchesFunc = (Mf_Mix_Matches)0;
+      p->MixMatchesFunc = (Mf_Mix_Matches)NULL;
       vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
       vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
       break;
diff --git a/lzma/C/LzFindMt.h b/lzma/C/LzFindMt.h
index 89b91fefd..a6645f53c 100644
--- a/lzma/C/LzFindMt.h
+++ b/lzma/C/LzFindMt.h
@@ -1,5 +1,5 @@
 /* LzFindMt.h -- multithreaded Match finder for LZ algorithms
-2015-05-03 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __LZ_FIND_MT_H
 #define __LZ_FIND_MT_H
@@ -90,9 +90,9 @@ typedef struct _CMatchFinderMt
 } CMatchFinderMt;
 
 void MatchFinderMt_Construct(CMatchFinderMt *p);
-void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
 SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
-    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
+    UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
 void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
 void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
 
diff --git a/lzma/C/Lzma2Dec.c b/lzma/C/Lzma2Dec.c
index b84f88a48..63853c6df 100644
--- a/lzma/C/Lzma2Dec.c
+++ b/lzma/C/Lzma2Dec.c
@@ -1,5 +1,5 @@
 /* Lzma2Dec.c -- LZMA2 Decoder
-2015-11-09 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 /* #define SHOW_DEBUG_INFO */
 
@@ -74,14 +74,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
   return SZ_OK;
 }
 
-SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
 {
   Byte props[LZMA_PROPS_SIZE];
   RINOK(Lzma2Dec_GetOldProps(prop, props));
   return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
 }
 
-SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
 {
   Byte props[LZMA_PROPS_SIZE];
   RINOK(Lzma2Dec_GetOldProps(prop, props));
@@ -105,16 +105,16 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
       p->control = b;
       PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
       PRF(printf(" %2X", (unsigned)b));
-      if (p->control == 0)
+      if (b == 0)
         return LZMA2_STATE_FINISHED;
       if (LZMA2_IS_UNCOMPRESSED_STATE(p))
       {
-        if ((p->control & 0x7F) > 2)
+        if (b > 2)
           return LZMA2_STATE_ERROR;
         p->unpackSize = 0;
       }
       else
-        p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
+        p->unpackSize = (UInt32)(b & 0x1F) << 16;
       return LZMA2_STATE_UNPACK0;
     
     case LZMA2_STATE_UNPACK0:
@@ -169,6 +169,7 @@ static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT s
 
 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
 
+
 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
     const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
 {
@@ -176,12 +177,17 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
   *srcLen = 0;
   *status = LZMA_STATUS_NOT_SPECIFIED;
 
-  while (p->state != LZMA2_STATE_FINISHED)
+  while (p->state != LZMA2_STATE_ERROR)
   {
-    SizeT dicPos = p->decoder.dicPos;
+    SizeT dicPos;
+
+    if (p->state == LZMA2_STATE_FINISHED)
+    {
+      *status = LZMA_STATUS_FINISHED_WITH_MARK;
+      return SZ_OK;
+    }
     
-    if (p->state == LZMA2_STATE_ERROR)
-      return SZ_ERROR_DATA;
+    dicPos = p->decoder.dicPos;
     
     if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
     {
@@ -198,29 +204,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
       }
       (*srcLen)++;
       p->state = Lzma2Dec_UpdateState(p, *src++);
-
       if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
-      {
-        p->state = LZMA2_STATE_ERROR;
-        return SZ_ERROR_DATA;
-      }
+        break;
       continue;
     }
     
     {
-      SizeT destSizeCur = dicLimit - dicPos;
-      SizeT srcSizeCur = inSize - *srcLen;
+      SizeT inCur = inSize - *srcLen;
+      SizeT outCur = dicLimit - dicPos;
       ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
       
-      if (p->unpackSize <= destSizeCur)
+      if (outCur >= p->unpackSize)
       {
-        destSizeCur = (SizeT)p->unpackSize;
+        outCur = (SizeT)p->unpackSize;
         curFinishMode = LZMA_FINISH_END;
       }
 
       if (LZMA2_IS_UNCOMPRESSED_STATE(p))
       {
-        if (*srcLen == inSize)
+        if (inCur == 0)
         {
           *status = LZMA_STATUS_NEEDS_MORE_INPUT;
           return SZ_OK;
@@ -232,33 +234,25 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
           if (initDic)
             p->needInitProp = p->needInitState = True;
           else if (p->needInitDic)
-          {
-            p->state = LZMA2_STATE_ERROR;
-            return SZ_ERROR_DATA;
-          }
+            break;
           p->needInitDic = False;
           LzmaDec_InitDicAndState(&p->decoder, initDic, False);
         }
 
-        if (srcSizeCur > destSizeCur)
-          srcSizeCur = destSizeCur;
+        if (inCur > outCur)
+          inCur = outCur;
+        if (inCur == 0)
+          break;
 
-        if (srcSizeCur == 0)
-        {
-          p->state = LZMA2_STATE_ERROR;
-          return SZ_ERROR_DATA;
-        }
+        LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
 
-        LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
-
-        src += srcSizeCur;
-        *srcLen += srcSizeCur;
-        p->unpackSize -= (UInt32)srcSizeCur;
+        src += inCur;
+        *srcLen += inCur;
+        p->unpackSize -= (UInt32)inCur;
         p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
       }
       else
       {
-        SizeT outSizeProcessed;
         SRes res;
 
         if (p->state == LZMA2_STATE_DATA)
@@ -267,96 +261,98 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
           Bool initDic = (mode == 3);
           Bool initState = (mode != 0);
           if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
-          {
-            p->state = LZMA2_STATE_ERROR;
-            return SZ_ERROR_DATA;
-          }
-          
+            break;
+
           LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
           p->needInitDic = False;
           p->needInitState = False;
           p->state = LZMA2_STATE_DATA_CONT;
         }
   
-        if (srcSizeCur > p->packSize)
-          srcSizeCur = (SizeT)p->packSize;
+        if (inCur > p->packSize)
+          inCur = (SizeT)p->packSize;
           
-        res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
+        res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
         
-        src += srcSizeCur;
-        *srcLen += srcSizeCur;
-        p->packSize -= (UInt32)srcSizeCur;
+        src += inCur;
+        *srcLen += inCur;
+        p->packSize -= (UInt32)inCur;
+        outCur = p->decoder.dicPos - dicPos;
+        p->unpackSize -= (UInt32)outCur;
 
-        outSizeProcessed = p->decoder.dicPos - dicPos;
-        p->unpackSize -= (UInt32)outSizeProcessed;
-
-        RINOK(res);
+        if (res != 0)
+          break;
+        
         if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
-          return res;
+        {
+          if (p->packSize == 0)
+            break;
+          return SZ_OK;
+        }
 
-        if (srcSizeCur == 0 && outSizeProcessed == 0)
+        if (inCur == 0 && outCur == 0)
         {
           if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
               || p->unpackSize != 0
               || p->packSize != 0)
-          {
-            p->state = LZMA2_STATE_ERROR;
-            return SZ_ERROR_DATA;
-          }
+            break;
           p->state = LZMA2_STATE_CONTROL;
         }
         
-        if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
-          *status = LZMA_STATUS_NOT_FINISHED;
+        *status = LZMA_STATUS_NOT_SPECIFIED;
       }
     }
   }
   
-  *status = LZMA_STATUS_FINISHED_WITH_MARK;
-  return SZ_OK;
+  *status = LZMA_STATUS_NOT_SPECIFIED;
+  p->state = LZMA2_STATE_ERROR;
+  return SZ_ERROR_DATA;
 }
 
+
 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
 {
   SizeT outSize = *destLen, inSize = *srcLen;
   *srcLen = *destLen = 0;
+  
   for (;;)
   {
-    SizeT srcSizeCur = inSize, outSizeCur, dicPos;
+    SizeT inCur = inSize, outCur, dicPos;
     ELzmaFinishMode curFinishMode;
     SRes res;
+    
     if (p->decoder.dicPos == p->decoder.dicBufSize)
       p->decoder.dicPos = 0;
     dicPos = p->decoder.dicPos;
-    if (outSize > p->decoder.dicBufSize - dicPos)
+    curFinishMode = LZMA_FINISH_ANY;
+    outCur = p->decoder.dicBufSize - dicPos;
+    
+    if (outCur >= outSize)
     {
-      outSizeCur = p->decoder.dicBufSize;
-      curFinishMode = LZMA_FINISH_ANY;
-    }
-    else
-    {
-      outSizeCur = dicPos + outSize;
+      outCur = outSize;
       curFinishMode = finishMode;
     }
 
-    res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
-    src += srcSizeCur;
-    inSize -= srcSizeCur;
-    *srcLen += srcSizeCur;
-    outSizeCur = p->decoder.dicPos - dicPos;
-    memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
-    dest += outSizeCur;
-    outSize -= outSizeCur;
-    *destLen += outSizeCur;
+    res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
+    
+    src += inCur;
+    inSize -= inCur;
+    *srcLen += inCur;
+    outCur = p->decoder.dicPos - dicPos;
+    memcpy(dest, p->decoder.dic + dicPos, outCur);
+    dest += outCur;
+    outSize -= outCur;
+    *destLen += outCur;
     if (res != 0)
       return res;
-    if (outSizeCur == 0 || outSize == 0)
+    if (outCur == 0 || outSize == 0)
       return SZ_OK;
   }
 }
 
+
 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
+    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
 {
   CLzma2Dec p;
   SRes res;
diff --git a/lzma/C/Lzma2Dec.h b/lzma/C/Lzma2Dec.h
index e6a0f6ed6..917af990d 100644
--- a/lzma/C/Lzma2Dec.h
+++ b/lzma/C/Lzma2Dec.h
@@ -1,5 +1,5 @@
 /* Lzma2Dec.h -- LZMA2 Decoder
-2015-05-13 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __LZMA2_DEC_H
 #define __LZMA2_DEC_H
@@ -26,8 +26,8 @@ typedef struct
 #define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
 #define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
 
-SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
-SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
+SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
+SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
 void Lzma2Dec_Init(CLzma2Dec *p);
 
 
@@ -73,7 +73,7 @@ Returns:
 */
 
 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
+    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
 
 EXTERN_C_END
 
diff --git a/lzma/C/LzmaDec.c b/lzma/C/LzmaDec.c
index 27efbaba9..e96fa975b 100644
--- a/lzma/C/LzmaDec.c
+++ b/lzma/C/LzmaDec.c
@@ -1,5 +1,5 @@
 /* LzmaDec.c -- LZMA Decoder
-2015-06-23 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -294,14 +294,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
       
       #ifdef _LZMA_SIZE_OPT
       {
-        unsigned limit, offset;
+        unsigned lim, offset;
         CLzmaProb *probLen = prob + LenChoice;
         IF_BIT_0(probLen)
         {
           UPDATE_0(probLen);
           probLen = prob + LenLow + (posState << kLenNumLowBits);
           offset = 0;
-          limit = (1 << kLenNumLowBits);
+          lim = (1 << kLenNumLowBits);
         }
         else
         {
@@ -312,17 +312,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
             UPDATE_0(probLen);
             probLen = prob + LenMid + (posState << kLenNumMidBits);
             offset = kLenNumLowSymbols;
-            limit = (1 << kLenNumMidBits);
+            lim = (1 << kLenNumMidBits);
           }
           else
           {
             UPDATE_1(probLen);
             probLen = prob + LenHigh;
             offset = kLenNumLowSymbols + kLenNumMidSymbols;
-            limit = (1 << kLenNumHighBits);
+            lim = (1 << kLenNumHighBits);
           }
         }
-        TREE_DECODE(probLen, limit, len);
+        TREE_DECODE(probLen, lim, len);
         len += offset;
       }
       #else
@@ -975,19 +975,19 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
   }
 }
 
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->probs);
+  ISzAlloc_Free(alloc, p->probs);
   p->probs = NULL;
 }
 
-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->dic);
+  ISzAlloc_Free(alloc, p->dic);
   p->dic = NULL;
 }
 
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc)
 {
   LzmaDec_FreeProbs(p, alloc);
   LzmaDec_FreeDict(p, alloc);
@@ -1019,13 +1019,13 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
   return SZ_OK;
 }
 
-static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAllocPtr alloc)
 {
   UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
   if (!p->probs || numProbs != p->numProbs)
   {
     LzmaDec_FreeProbs(p, alloc);
-    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+    p->probs = (CLzmaProb *)ISzAlloc_Alloc(alloc, numProbs * sizeof(CLzmaProb));
     p->numProbs = numProbs;
     if (!p->probs)
       return SZ_ERROR_MEM;
@@ -1033,7 +1033,7 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl
   return SZ_OK;
 }
 
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
 {
   CLzmaProps propNew;
   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
@@ -1042,7 +1042,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, I
   return SZ_OK;
 }
 
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc)
 {
   CLzmaProps propNew;
   SizeT dicBufSize;
@@ -1062,7 +1062,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
   if (!p->dic || dicBufSize != p->dicBufSize)
   {
     LzmaDec_FreeDict(p, alloc);
-    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+    p->dic = (Byte *)ISzAlloc_Alloc(alloc, dicBufSize);
     if (!p->dic)
     {
       LzmaDec_FreeProbs(p, alloc);
@@ -1076,7 +1076,7 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
 
 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-    ELzmaStatus *status, ISzAlloc *alloc)
+    ELzmaStatus *status, ISzAllocPtr alloc)
 {
   CLzmaDec p;
   SRes res;
diff --git a/lzma/C/LzmaDec.h b/lzma/C/LzmaDec.h
index cc44daef2..d6af92203 100644
--- a/lzma/C/LzmaDec.h
+++ b/lzma/C/LzmaDec.h
@@ -1,5 +1,5 @@
 /* LzmaDec.h -- LZMA Decoder
-2013-01-18 : Igor Pavlov : Public domain */
+2017-04-03 : Igor Pavlov : Public domain */
 
 #ifndef __LZMA_DEC_H
 #define __LZMA_DEC_H
@@ -129,11 +129,11 @@ LzmaDec_Allocate* can return:
   SZ_ERROR_UNSUPPORTED - Unsupported properties
 */
    
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
 
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAllocPtr alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAllocPtr alloc);
 
 /* ---------- Dictionary Interface ---------- */
 
@@ -220,7 +220,7 @@ Returns:
 
 SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-    ELzmaStatus *status, ISzAlloc *alloc);
+    ELzmaStatus *status, ISzAllocPtr alloc);
 
 EXTERN_C_END
 
diff --git a/lzma/C/LzmaEnc.c b/lzma/C/LzmaEnc.c
index 9c164e6f0..9b7e69104 100644
--- a/lzma/C/LzmaEnc.c
+++ b/lzma/C/LzmaEnc.c
@@ -1,5 +1,5 @@
 /* LzmaEnc.c -- LZMA Encoder
-2015-11-08 : Igor Pavlov : Public domain */
+2017-06-22 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -23,8 +23,8 @@
 static unsigned g_STAT_OFFSET = 0;
 #endif
 
-#define kMaxHistorySize ((UInt32)3 << 29)
-/* #define kMaxHistorySize ((UInt32)7 << 29) */
+#define kLzmaMaxHistorySize ((UInt32)3 << 29)
+/* #define kLzmaMaxHistorySize ((UInt32)7 << 29) */
 
 #define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
 
@@ -62,14 +62,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
   if (level < 0) level = 5;
   p->level = level;
   
-  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level <= 7 ? (1 << 25) : (1 << 26)));
   if (p->dictSize > p->reduceSize)
   {
     unsigned i;
+    UInt32 reduceSize = (UInt32)p->reduceSize;
     for (i = 11; i <= 30; i++)
     {
-      if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
-      if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
+      if (reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
+      if (reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
     }
   }
 
@@ -108,7 +109,7 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
 
 #define kDicLogSizeMaxCompress 32
 
-#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
+#define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); }
 
 static UInt32 GetPosSlot1(UInt32 pos)
 {
@@ -145,19 +146,19 @@ static void LzmaEnc_FastPosInit(Byte *g_FastPos)
 
 /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
 /*
-#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
   (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
-  res = p->g_FastPos[pos >> i] + (i * 2); }
+  res = p->g_FastPos[pos >> zz] + (zz * 2); }
 */
 
 /*
-#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
+#define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \
   (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
-  res = p->g_FastPos[pos >> i] + (i * 2); }
+  res = p->g_FastPos[pos >> zz] + (zz * 2); }
 */
 
-#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
-  res = p->g_FastPos[pos >> i] + (i * 2); }
+#define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
+  res = p->g_FastPos[pos >> zz] + (zz * 2); }
 
 /*
 #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
@@ -445,7 +446,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
       || props.lp > LZMA_LP_MAX
       || props.pb > LZMA_PB_MAX
       || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
-      || props.dictSize > kMaxHistorySize)
+      || props.dictSize > kLzmaMaxHistorySize)
     return SZ_ERROR_PARAM;
 
   p->dictSize = props.dictSize;
@@ -492,6 +493,15 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
   return SZ_OK;
 }
 
+
+void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize)
+{
+  CLzmaEnc *p = (CLzmaEnc *)pp;
+  p->matchFinderBase.expectedDataSize = expectedDataSiize;
+}
+
+
+
 static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
 static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
 static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
@@ -512,11 +522,11 @@ static void RangeEnc_Construct(CRangeEnc *p)
 #define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
 
 #define RC_BUF_SIZE (1 << 16)
-static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
 {
   if (!p->bufBase)
   {
-    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+    p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
     if (!p->bufBase)
       return 0;
     p->bufLim = p->bufBase + RC_BUF_SIZE;
@@ -524,9 +534,9 @@ static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
   return 1;
 }
 
-static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->bufBase);
+  ISzAlloc_Free(alloc, p->bufBase);
   p->bufBase = 0;
 }
 
@@ -550,7 +560,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
   if (p->res != SZ_OK)
     return;
   num = p->buf - p->bufBase;
-  if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+  if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
     p->res = SZ_ERROR_WRITE;
   p->processed += num;
   p->buf = p->bufBase;
@@ -882,7 +892,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
   
   if (numPairs > 0)
   {
-    lenRes = p->matches[numPairs - 2];
+    lenRes = p->matches[(size_t)numPairs - 2];
     if (lenRes == p->numFastBytes)
     {
       UInt32 numAvail = p->numAvail;
@@ -891,7 +901,7 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
       {
         const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
         const Byte *pby = pbyCur + lenRes;
-        ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
+        ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[(size_t)numPairs - 1];
         const Byte *pbyLim = pbyCur + numAvail;
         for (; pby != pbyLim && *pby == pby[dif]; pby++);
         lenRes = (UInt32)(pby - pbyCur);
@@ -939,7 +949,7 @@ static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32
 
 static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
 {
-  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+  return p->repLenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN] +
     GetPureRepPrice(p, repIndex, state, posState);
 }
 
@@ -956,9 +966,9 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
       p->opt[posMem].posPrev = posMem - 1;
       if (p->opt[cur].prev2)
       {
-        p->opt[posMem - 1].prev1IsChar = False;
-        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
-        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+        p->opt[(size_t)posMem - 1].prev1IsChar = False;
+        p->opt[(size_t)posMem - 1].posPrev = p->opt[cur].posPrev2;
+        p->opt[(size_t)posMem - 1].backPrev = p->opt[cur].backPrev2;
       }
     }
     {
@@ -983,12 +993,17 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
 
 static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
 {
-  UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
-  UInt32 matchPrice, repMatchPrice, normalMatchPrice;
+  UInt32 lenEnd, cur;
   UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
   UInt32 *matches;
+
+  {
+
+  UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len;
+  UInt32 matchPrice, repMatchPrice, normalMatchPrice;
   const Byte *data;
   Byte curByte, matchByte;
+
   if (p->optimumEndIndex != p->optimumCurrentIndex)
   {
     const COptimal *opt = &p->opt[p->optimumCurrentIndex];
@@ -1046,7 +1061,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
   matches = p->matches;
   if (mainLen >= p->numFastBytes)
   {
-    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+    *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
     MovePos(p, mainLen - 1);
     return mainLen;
   }
@@ -1111,7 +1126,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
     price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
     do
     {
-      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
+      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)repLen - 2];
       COptimal *opt = &p->opt[repLen];
       if (curAndLenPrice < opt->price)
       {
@@ -1135,9 +1150,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
     for (; ; len++)
     {
       COptimal *opt;
-      UInt32 distance = matches[offs + 1];
+      UInt32 distance = matches[(size_t)offs + 1];
 
-      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
+      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)len - LZMA_MATCH_LEN_MIN];
       UInt32 lenToPosState = GetLenToPosState(len);
       if (distance < kNumFullDistances)
         curAndLenPrice += p->distancesPrices[lenToPosState][distance];
@@ -1176,8 +1191,11 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
     }
     #endif
 
+  }
+
   for (;;)
   {
+    UInt32 numAvail;
     UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
     UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
     Bool nextIsChar;
@@ -1248,7 +1266,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
         UInt32 i;
         reps[0] = prevOpt->backs[pos];
         for (i = 1; i <= pos; i++)
-          reps[i] = prevOpt->backs[i - 1];
+          reps[i] = prevOpt->backs[(size_t)i - 1];
         for (; i < LZMA_NUM_REPS; i++)
           reps[i] = prevOpt->backs[i];
       }
@@ -1257,7 +1275,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
         UInt32 i;
         reps[0] = (pos - LZMA_NUM_REPS);
         for (i = 1; i < LZMA_NUM_REPS; i++)
-          reps[i] = prevOpt->backs[i - 1];
+          reps[i] = prevOpt->backs[(size_t)i - 1];
       }
     }
     curOpt->state = (CState)state;
@@ -1284,7 +1302,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
           LitEnc_GetPrice(probs, curByte, p->ProbPrices));
     }
 
-    nextOpt = &p->opt[cur + 1];
+    nextOpt = &p->opt[(size_t)cur + 1];
 
     if (curAnd1Price < nextOpt->price)
     {
@@ -1377,7 +1395,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
       price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
       do
       {
-        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][(size_t)lenTest - 2];
         COptimal *opt = &p->opt[cur + lenTest];
         if (curAndLenPrice < opt->price)
         {
@@ -1407,9 +1425,9 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
             UInt32 state2 = kRepNextStates[state];
             UInt32 posStateNext = (position + lenTest) & p->pbMask;
             UInt32 curAndLenCharPrice =
-                price + p->repLenEnc.prices[posState][lenTest - 2] +
+                price + p->repLenEnc.prices[posState][(size_t)lenTest - 2] +
                 GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
                     data[lenTest], data2[lenTest], p->ProbPrices);
             state2 = kLiteralNextStates[state2];
             posStateNext = (position + lenTest + 1) & p->pbMask;
@@ -1460,11 +1478,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
       offs = 0;
       while (startLen > matches[offs])
         offs += 2;
-      curBack = matches[offs + 1];
+      curBack = matches[(size_t)offs + 1];
       GetPosSlot2(curBack, posSlot);
       for (lenTest = /*2*/ startLen; ; lenTest++)
       {
-        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][(size_t)lenTest - LZMA_MATCH_LEN_MIN];
+        {
         UInt32 lenToPosState = GetLenToPosState(lenTest);
         COptimal *opt;
         if (curBack < kNumFullDistances)
@@ -1480,6 +1499,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
           opt->backPrev = curBack + LZMA_NUM_REPS;
           opt->prev1IsChar = False;
         }
+        }
 
         if (/*_maxMode && */lenTest == matches[offs])
         {
@@ -1498,7 +1518,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
             UInt32 posStateNext = (position + lenTest) & p->pbMask;
             UInt32 curAndLenCharPrice = curAndLenPrice +
                 GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[(size_t)lenTest - 1]),
                     data[lenTest], data2[lenTest], p->ProbPrices);
             state2 = kLiteralNextStates[state2];
             posStateNext = (posStateNext + 1) & p->pbMask;
@@ -1509,15 +1529,15 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
             /* for (; lenTest2 >= 2; lenTest2--) */
             {
               UInt32 offset = cur + lenTest + 1 + lenTest2;
-              UInt32 curAndLenPrice;
+              UInt32 curAndLenPrice2;
               COptimal *opt;
               while (lenEnd < offset)
                 p->opt[++lenEnd].price = kInfinityPrice;
-              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+              curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
               opt = &p->opt[offset];
-              if (curAndLenPrice < opt->price)
+              if (curAndLenPrice2 < opt->price)
               {
-                opt->price = curAndLenPrice;
+                opt->price = curAndLenPrice2;
                 opt->posPrev = cur + lenTest + 1;
                 opt->backPrev = 0;
                 opt->prev1IsChar = True;
@@ -1530,7 +1550,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
           offs += 2;
           if (offs == numPairs)
             break;
-          curBack = matches[offs + 1];
+          curBack = matches[(size_t)offs + 1];
           if (curBack >= kNumFullDistances)
             GetPosSlot2(curBack, posSlot);
         }
@@ -1587,7 +1607,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
   matches = p->matches;
   if (mainLen >= p->numFastBytes)
   {
-    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+    *backRes = matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
     MovePos(p, mainLen - 1);
     return mainLen;
   }
@@ -1595,14 +1615,14 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
   mainDist = 0; /* for GCC */
   if (mainLen >= 2)
   {
-    mainDist = matches[numPairs - 1];
-    while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
+    mainDist = matches[(size_t)numPairs - 1];
+    while (numPairs > 2 && mainLen == matches[(size_t)numPairs - 4] + 1)
     {
-      if (!ChangePair(matches[numPairs - 3], mainDist))
+      if (!ChangePair(matches[(size_t)numPairs - 3], mainDist))
         break;
       numPairs -= 2;
-      mainLen = matches[numPairs - 2];
-      mainDist = matches[numPairs - 1];
+      mainLen = matches[(size_t)numPairs - 2];
+      mainDist = matches[(size_t)numPairs - 1];
     }
     if (mainLen == 2 && mainDist >= 0x80)
       mainLen = 1;
@@ -1624,7 +1644,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
   p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
   if (p->longestMatchLength >= 2)
   {
-    UInt32 newDistance = matches[p->numPairs - 1];
+    UInt32 newDistance = matches[(size_t)p->numPairs - 1];
     if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
         (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
         (p->longestMatchLength > mainLen + 1) ||
@@ -1718,7 +1738,6 @@ static void FillDistancesPrices(CLzmaEnc *p)
 
     {
       UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
-      UInt32 i;
       for (i = 0; i < kStartPosModelIndex; i++)
         distancesPrices[i] = posSlotPrices[i];
       for (; i < kNumFullDistances; i++)
@@ -1753,24 +1772,24 @@ void LzmaEnc_Construct(CLzmaEnc *p)
   p->saveState.litProbs = NULL;
 }
 
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
 {
   void *p;
-  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+  p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
   if (p)
     LzmaEnc_Construct((CLzmaEnc *)p);
   return p;
 }
 
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->litProbs);
-  alloc->Free(alloc, p->saveState.litProbs);
+  ISzAlloc_Free(alloc, p->litProbs);
+  ISzAlloc_Free(alloc, p->saveState.litProbs);
   p->litProbs = NULL;
   p->saveState.litProbs = NULL;
 }
 
-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   #ifndef _7ZIP_ST
   MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
@@ -1781,10 +1800,10 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
   RangeEnc_Free(&p->rc, alloc);
 }
 
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
-  alloc->Free(alloc, p);
+  ISzAlloc_Free(alloc, p);
 }
 
 static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
@@ -1951,7 +1970,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
 
 #define kBigHashDicLimit ((UInt32)1 << 24)
 
-static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   UInt32 beforeSize = kNumOpts;
   if (!RangeEnc_Alloc(&p->rc, alloc))
@@ -1966,8 +1985,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
     if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
     {
       LzmaEnc_FreeLits(p, alloc);
-      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
-      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+      p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
+      p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
       if (!p->litProbs || !p->saveState.litProbs)
       {
         LzmaEnc_FreeLits(p, alloc);
@@ -1987,6 +2006,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
   {
     RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
     p->matchFinderObj = &p->matchFinderMt;
+    p->matchFinderBase.bigHash = (Byte)(
+        (p->dictSize > kBigHashDicLimit && p->matchFinderBase.hashMask >= 0xFFFFFF) ? 1 : 0);
     MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
   }
   else
@@ -2075,7 +2096,7 @@ void LzmaEnc_InitPrices(CLzmaEnc *p)
   LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
 }
 
-static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   UInt32 i;
   for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
@@ -2093,7 +2114,7 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a
 }
 
 static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
-    ISzAlloc *alloc, ISzAlloc *allocBig)
+    ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   CLzmaEnc *p = (CLzmaEnc *)pp;
   p->matchFinderBase.stream = inStream;
@@ -2104,7 +2125,7 @@ static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInS
 
 SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
     ISeqInStream *inStream, UInt32 keepWindowSize,
-    ISzAlloc *alloc, ISzAlloc *allocBig)
+    ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   CLzmaEnc *p = (CLzmaEnc *)pp;
   p->matchFinderBase.stream = inStream;
@@ -2120,12 +2141,13 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
 }
 
 SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
-    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+    UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   CLzmaEnc *p = (CLzmaEnc *)pp;
   LzmaEnc_SetInputBuf(p, src, srcLen);
   p->needInit = 1;
 
+  LzmaEnc_SetDataSize(pp, srcLen);
   return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
 }
 
@@ -2143,15 +2165,15 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
 
 typedef struct
 {
-  ISeqOutStream funcTable;
+  ISeqOutStream vt;
   Byte *data;
   SizeT rem;
   Bool overflow;
-} CSeqOutStreamBuf;
+} CLzmaEnc_SeqOutStreamBuf;
 
-static size_t MyWrite(void *pp, const void *data, size_t size)
+static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size)
 {
-  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+  CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt);
   if (p->rem < size)
   {
     size = p->rem;
@@ -2184,9 +2206,9 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
   CLzmaEnc *p = (CLzmaEnc *)pp;
   UInt64 nowPos64;
   SRes res;
-  CSeqOutStreamBuf outStream;
+  CLzmaEnc_SeqOutStreamBuf outStream;
 
-  outStream.funcTable.Write = MyWrite;
+  outStream.vt.Write = SeqOutStreamBuf_Write;
   outStream.data = dest;
   outStream.rem = *destLen;
   outStream.overflow = False;
@@ -2200,7 +2222,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
   LzmaEnc_InitPrices(p);
   nowPos64 = p->nowPos64;
   RangeEnc_Init(&p->rc);
-  p->rc.outStream = &outStream.funcTable;
+  p->rc.outStream = &outStream.vt;
 
   res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
   
@@ -2230,7 +2252,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
       break;
     if (progress)
     {
-      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
+      res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
       if (res != SZ_OK)
       {
         res = SZ_ERROR_PROGRESS;
@@ -2242,7 +2264,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
   LzmaEnc_Finish(p);
 
   /*
-  if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
+  if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
     res = SZ_ERROR_FAIL;
   }
   */
@@ -2252,7 +2274,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
 
 
 SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
-    ISzAlloc *alloc, ISzAlloc *allocBig)
+    ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
   return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
@@ -2287,21 +2309,27 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
 }
 
 
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp)
+{
+  return ((CLzmaEnc *)pp)->writeEndMark;
+}
+
+
 SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+    int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   SRes res;
   CLzmaEnc *p = (CLzmaEnc *)pp;
 
-  CSeqOutStreamBuf outStream;
+  CLzmaEnc_SeqOutStreamBuf outStream;
 
-  outStream.funcTable.Write = MyWrite;
+  outStream.vt.Write = SeqOutStreamBuf_Write;
   outStream.data = dest;
   outStream.rem = *destLen;
   outStream.overflow = False;
 
   p->writeEndMark = writeEndMark;
-  p->rc.outStream = &outStream.funcTable;
+  p->rc.outStream = &outStream.vt;
 
   res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
   
@@ -2321,7 +2349,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
 
 SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
     const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+    ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
 {
   CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
   SRes res;
diff --git a/lzma/C/LzmaEnc.h b/lzma/C/LzmaEnc.h
index cffe220bb..9194ee576 100644
--- a/lzma/C/LzmaEnc.h
+++ b/lzma/C/LzmaEnc.h
@@ -1,5 +1,5 @@
 /*  LzmaEnc.h -- LZMA Encoder
-2013-01-18 : Igor Pavlov : Public domain */
+2017-07-27 : Igor Pavlov : Public domain */
 
 #ifndef __LZMA_ENC_H
 #define __LZMA_ENC_H
@@ -12,12 +12,10 @@ EXTERN_C_BEGIN
 
 typedef struct _CLzmaEncProps
 {
-  int level;       /*  0 <= level <= 9 */
+  int level;       /* 0 <= level <= 9 */
   UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
-                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
-                       default = (1 << 24) */
-  UInt64 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
-                        Encoder uses this value to reduce dictionary size */
+                      (1 << 12) <= dictSize <= (3 << 29) for 64-bit version
+                      default = (1 << 24) */
   int lc;          /* 0 <= lc <= 8, default = 3 */
   int lp;          /* 0 <= lp <= 4, default = 0 */
   int pb;          /* 0 <= pb <= 4, default = 2 */
@@ -25,9 +23,12 @@ typedef struct _CLzmaEncProps
   int fb;          /* 5 <= fb <= 273, default = 32 */
   int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
   int numHashBytes; /* 2, 3 or 4, default = 4 */
-  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */
+  UInt32 mc;       /* 1 <= mc <= (1 << 30), default = 32 */
   unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
   int numThreads;  /* 1 or 2, default = 2 */
+
+  UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
+                        Encoder uses this value to reduce dictionary size */
 } CLzmaEncProps;
 
 void LzmaEncProps_Init(CLzmaEncProps *p);
@@ -37,41 +38,38 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
 
 /* ---------- CLzmaEncHandle Interface ---------- */
 
-/* LzmaEnc_* functions can return the following exit codes:
-Returns:
+/* LzmaEnc* functions can return the following exit codes:
+SRes:
   SZ_OK           - OK
   SZ_ERROR_MEM    - Memory allocation error
   SZ_ERROR_PARAM  - Incorrect paramater in props
-  SZ_ERROR_WRITE  - Write callback error.
+  SZ_ERROR_WRITE  - ISeqOutStream write callback error
+  SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
   SZ_ERROR_PROGRESS - some break from progress callback
-  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+  SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
 */
 
 typedef void * CLzmaEncHandle;
 
-CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
+CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+
 SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
+void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
 SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
+
 SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+    ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
 SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+    int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
+
 
 /* ---------- One Call Interface ---------- */
 
-/* LzmaEncode
-Return code:
-  SZ_OK               - OK
-  SZ_ERROR_MEM        - Memory allocation error
-  SZ_ERROR_PARAM      - Incorrect paramater
-  SZ_ERROR_OUTPUT_EOF - output buffer overflow
-  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
-*/
-
 SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
     const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+    ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
 
 EXTERN_C_END
 
diff --git a/lzma/C/Ppmd.h b/lzma/C/Ppmd.h
index 4356dd1d8..a5c1e3ef2 100644
--- a/lzma/C/Ppmd.h
+++ b/lzma/C/Ppmd.h
@@ -1,5 +1,5 @@
 /* Ppmd.h -- PPMD codec common code
-2013-01-18 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 #ifndef __PPMD_H
@@ -77,8 +77,8 @@ typedef
   CPpmd_Byte_Ref;
 
 #define PPMD_SetAllBitsIn256Bytes(p) \
-  { unsigned i; for (i = 0; i < 256 / sizeof(p[0]); i += 8) { \
-  p[i+7] = p[i+6] = p[i+5] = p[i+4] = p[i+3] = p[i+2] = p[i+1] = p[i+0] = ~(size_t)0; }}
+  { size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
+  p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
 
 EXTERN_C_END
  
diff --git a/lzma/C/Ppmd7.c b/lzma/C/Ppmd7.c
index abd7e6309..0951a7c74 100644
--- a/lzma/C/Ppmd7.c
+++ b/lzma/C/Ppmd7.c
@@ -1,5 +1,5 @@
 /* Ppmd7.c -- PPMdH codec
-2015-09-28 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 #include "Precomp.h"
@@ -15,7 +15,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x
 #define UNIT_SIZE 12
 
 #define U2B(nu) ((UInt32)(nu) * UNIT_SIZE)
-#define U2I(nu) (p->Units2Indx[(nu) - 1])
+#define U2I(nu) (p->Units2Indx[(size_t)(nu) - 1])
 #define I2U(indx) (p->Indx2Units[indx])
 
 #ifdef PPMD_32BIT
@@ -88,29 +88,31 @@ void Ppmd7_Construct(CPpmd7 *p)
   memset(p->HB2Flag + 0x40, 8, 0x100 - 0x40);
 }
 
-void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc)
+void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc)
 {
-  alloc->Free(alloc, p->Base);
+  ISzAlloc_Free(alloc, p->Base);
   p->Size = 0;
   p->Base = 0;
 }
 
-Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc)
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc)
 {
-  if (p->Base == 0 || p->Size != size)
+  if (!p->Base || p->Size != size)
   {
+    size_t size2;
     Ppmd7_Free(p, alloc);
+    size2 = 0
+      #ifndef PPMD_32BIT
+      + UNIT_SIZE
+      #endif
+      ;
     p->AlignOffset =
       #ifdef PPMD_32BIT
         (4 - size) & 3;
       #else
         4 - (size & 3);
       #endif
-    if ((p->Base = (Byte *)alloc->Alloc(alloc, p->AlignOffset + size
-        #ifndef PPMD_32BIT
-        + UNIT_SIZE
-        #endif
-        )) == 0)
+    if ((p->Base = (Byte *)ISzAlloc_Alloc(alloc, p->AlignOffset + size + size2)) == 0)
       return False;
     p->Size = size;
   }
@@ -276,12 +278,12 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU
   return oldPtr;
 }
 
-#define SUCCESSOR(p) ((CPpmd_Void_Ref)(size_t)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
+#define SUCCESSOR(p) ((CPpmd_Void_Ref)((p)->SuccessorLow | ((UInt32)(p)->SuccessorHigh << 16)))
 
 static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v)
 {
-  (p)->SuccessorLow = (UInt16)((UInt32)((size_t)v) & 0xFFFF);
-  (p)->SuccessorHigh = (UInt16)(((UInt32)((size_t)v) >> 16) & 0xFFFF);
+  (p)->SuccessorLow = (UInt16)((UInt32)(v) & 0xFFFF);
+  (p)->SuccessorHigh = (UInt16)(((UInt32)(v) >> 16) & 0xFFFF);
 }
 
 static void RestartModel(CPpmd7 *p)
@@ -513,7 +515,7 @@ static void UpdateModel(CPpmd7 *p)
         /* Expand for one UNIT */
         unsigned oldNU = ns1 >> 1;
         unsigned i = U2I(oldNU);
-        if (i != U2I(oldNU + 1))
+        if (i != U2I((size_t)oldNU + 1))
         {
           void *ptr = AllocUnits(p, i + 1);
           void *oldPtr;
@@ -639,10 +641,10 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq)
   unsigned nonMasked = p->MinContext->NumStats - numMasked;
   if (p->MinContext->NumStats != 256)
   {
-    see = p->See[p->NS2Indx[nonMasked - 1]] +
+    see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] +
         (nonMasked < (unsigned)SUFFIX(p->MinContext)->NumStats - p->MinContext->NumStats) +
-        2 * (p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
-        4 * (numMasked > nonMasked) +
+        2 * (unsigned)(p->MinContext->SummFreq < 11 * p->MinContext->NumStats) +
+        4 * (unsigned)(numMasked > nonMasked) +
         p->HiBitsFlag;
     {
       unsigned r = (see->Summ >> see->Shift);
diff --git a/lzma/C/Ppmd7.h b/lzma/C/Ppmd7.h
index 96521c31f..45002d95b 100644
--- a/lzma/C/Ppmd7.h
+++ b/lzma/C/Ppmd7.h
@@ -1,5 +1,5 @@
 /* Ppmd7.h -- PPMdH compression codec
-2010-03-12 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 /* This code supports virtual RangeDecoder and includes the implementation
@@ -60,8 +60,8 @@ typedef struct
 } CPpmd7;
 
 void Ppmd7_Construct(CPpmd7 *p);
-Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAlloc *alloc);
-void Ppmd7_Free(CPpmd7 *p, ISzAlloc *alloc);
+Bool Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
+void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
 void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
 #define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
 
@@ -86,10 +86,10 @@ void Ppmd7_Update2(CPpmd7 *p);
 void Ppmd7_UpdateBin(CPpmd7 *p);
 
 #define Ppmd7_GetBinSumm(p) \
-    &p->BinSumm[Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
-    p->NS2BSIndx[Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
+    &p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1][p->PrevSuccess + \
+    p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] + \
     (p->HiBitsFlag = p->HB2Flag[p->FoundState->Symbol]) + \
-    2 * p->HB2Flag[Ppmd7Context_OneState(p->MinContext)->Symbol] + \
+    2 * p->HB2Flag[(unsigned)Ppmd7Context_OneState(p->MinContext)->Symbol] + \
     ((p->RunLength >> 26) & 0x20)]
 
 CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
@@ -97,16 +97,18 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
 
 /* ---------- Decode ---------- */
 
-typedef struct
+typedef struct IPpmd7_RangeDec IPpmd7_RangeDec;
+
+struct IPpmd7_RangeDec
 {
-  UInt32 (*GetThreshold)(void *p, UInt32 total);
-  void (*Decode)(void *p, UInt32 start, UInt32 size);
-  UInt32 (*DecodeBit)(void *p, UInt32 size0);
-} IPpmd7_RangeDec;
+  UInt32 (*GetThreshold)(const IPpmd7_RangeDec *p, UInt32 total);
+  void (*Decode)(const IPpmd7_RangeDec *p, UInt32 start, UInt32 size);
+  UInt32 (*DecodeBit)(const IPpmd7_RangeDec *p, UInt32 size0);
+};
 
 typedef struct
 {
-  IPpmd7_RangeDec p;
+  IPpmd7_RangeDec vt;
   UInt32 Range;
   UInt32 Code;
   IByteIn *Stream;
@@ -116,7 +118,7 @@ void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p);
 Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p);
 #define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
 
-int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc);
+int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc);
 
 
 /* ---------- Encode ---------- */
diff --git a/lzma/C/Ppmd7Dec.c b/lzma/C/Ppmd7Dec.c
index 04b4b09e3..7953bb07c 100644
--- a/lzma/C/Ppmd7Dec.c
+++ b/lzma/C/Ppmd7Dec.c
@@ -1,5 +1,5 @@
 /* Ppmd7Dec.c -- PPMdH Decoder
-2010-03-12 : Igor Pavlov : Public domain
+2017-04-03 : Igor Pavlov : Public domain
 This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
 
 #include "Precomp.h"
@@ -13,44 +13,46 @@ Bool Ppmd7z_RangeDec_Init(CPpmd7z_RangeDec *p)
   unsigned i;
   p->Code = 0;
   p->Range = 0xFFFFFFFF;
-  if (p->Stream->Read((void *)p->Stream) != 0)
+  if (IByteIn_Read(p->Stream) != 0)
     return False;
   for (i = 0; i < 4; i++)
-    p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+    p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
   return (p->Code < 0xFFFFFFFF);
 }
 
-static UInt32 Range_GetThreshold(void *pp, UInt32 total)
+#define GET_Ppmd7z_RangeDec CPpmd7z_RangeDec *p = CONTAINER_FROM_VTBL(pp, CPpmd7z_RangeDec, vt);
+ 
+static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
 {
-  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
-  return (p->Code) / (p->Range /= total);
+  GET_Ppmd7z_RangeDec
+  return p->Code / (p->Range /= total);
 }
 
 static void Range_Normalize(CPpmd7z_RangeDec *p)
 {
   if (p->Range < kTopValue)
   {
-    p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+    p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
     p->Range <<= 8;
     if (p->Range < kTopValue)
     {
-      p->Code = (p->Code << 8) | p->Stream->Read((void *)p->Stream);
+      p->Code = (p->Code << 8) | IByteIn_Read(p->Stream);
       p->Range <<= 8;
     }
   }
 }
 
-static void Range_Decode(void *pp, UInt32 start, UInt32 size)
+static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
 {
-  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+  GET_Ppmd7z_RangeDec
   p->Code -= start * p->Range;
   p->Range *= size;
   Range_Normalize(p);
 }
 
-static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
+static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
 {
-  CPpmd7z_RangeDec *p = (CPpmd7z_RangeDec *)pp;
+  GET_Ppmd7z_RangeDec
   UInt32 newBound = (p->Range >> 14) * size0;
   UInt32 symbol;
   if (p->Code < newBound)
@@ -70,15 +72,15 @@ static UInt32 Range_DecodeBit(void *pp, UInt32 size0)
 
 void Ppmd7z_RangeDec_CreateVTable(CPpmd7z_RangeDec *p)
 {
-  p->p.GetThreshold = Range_GetThreshold;
-  p->p.Decode = Range_Decode;
-  p->p.DecodeBit = Range_DecodeBit;
+  p->vt.GetThreshold = Range_GetThreshold;
+  p->vt.Decode = Range_Decode;
+  p->vt.DecodeBit = Range_DecodeBit;
 }
 
 
 #define MASK(sym) ((signed char *)charMask)[sym]
 
-int Ppmd7_DecodeSymbol(CPpmd7 *p, IPpmd7_RangeDec *rc)
+int Ppmd7_DecodeSymbol(CPpmd7 *p, const IPpmd7_RangeDec *rc)
 {
   size_t charMask[256 / sizeof(size_t)];
   if (p->MinContext->NumStats != 1)
diff --git a/lzma/C/Threads.c b/lzma/C/Threads.c
index d3d0912da..930ad271b 100644
--- a/lzma/C/Threads.c
+++ b/lzma/C/Threads.c
@@ -1,5 +1,5 @@
 /* Threads.c -- multithreading library
-2014-09-21 : Igor Pavlov : Public domain */
+2017-06-26 : Igor Pavlov : Public domain */
 
 #include "Precomp.h"
 
@@ -12,18 +12,20 @@
 static WRes GetError()
 {
   DWORD res = GetLastError();
-  return (res) ? (WRes)(res) : 1;
+  return res ? (WRes)res : 1;
 }
 
-WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
-WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
+static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
+static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
 
 WRes HandlePtr_Close(HANDLE *p)
 {
   if (*p != NULL)
+  {
     if (!CloseHandle(*p))
       return GetError();
-  *p = NULL;
+    *p = NULL;
+  }
   return 0;
 }
 
@@ -49,7 +51,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
   return HandleToWRes(*p);
 }
 
-WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
+static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
 {
   *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
   return HandleToWRes(*p);
diff --git a/lzma/C/Threads.h b/lzma/C/Threads.h
index 9b3e1c556..e53ace435 100644
--- a/lzma/C/Threads.h
+++ b/lzma/C/Threads.h
@@ -1,5 +1,5 @@
 /* Threads.h -- multithreading library
-2013-11-12 : Igor Pavlov : Public domain */
+2017-06-18 : Igor Pavlov : Public domain */
 
 #ifndef __7Z_THREADS_H
 #define __7Z_THREADS_H
@@ -49,7 +49,8 @@ WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
 WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
 
 typedef HANDLE CSemaphore;
-#define Semaphore_Construct(p) (*p) = NULL
+#define Semaphore_Construct(p) *(p) = NULL
+#define Semaphore_IsCreated(p) (*(p) != NULL)
 #define Semaphore_Close(p) HandlePtr_Close(p)
 #define Semaphore_Wait(p) Handle_WaitObject(*(p))
 WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
diff --git a/src/files.cpp b/src/files.cpp
index 8ad4d6329..1b0e5db1f 100644
--- a/src/files.cpp
+++ b/src/files.cpp
@@ -393,8 +393,8 @@ struct FileReaderLZMA::StreamPointer
 	CLzmaDec Stream;
 };
 
-static void *SzAlloc(void *, size_t size) { return malloc(size); }
-static void SzFree(void *, void *address) { free(address); }
+static void *SzAlloc(ISzAllocPtr, size_t size) { return malloc(size); }
+static void SzFree(ISzAllocPtr, void *address) { free(address); }
 ISzAlloc g_Alloc = { SzAlloc, SzFree };
 
 FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip)
diff --git a/src/resourcefiles/file_7z.cpp b/src/resourcefiles/file_7z.cpp
index d6bfa68f6..aa5018eb3 100644
--- a/src/resourcefiles/file_7z.cpp
+++ b/src/resourcefiles/file_7z.cpp
@@ -67,7 +67,7 @@ struct CZDFileInStream
 		File = _file;
 	}
 
-	static SRes Read(void *pp, void *buf, size_t *size)
+	static SRes Read(const ISeekInStream *pp, void *buf, size_t *size)
 	{
 		CZDFileInStream *p = (CZDFileInStream *)pp;
 		long numread = p->File->Read(buf, (long)*size);
@@ -80,7 +80,7 @@ struct CZDFileInStream
 		return SZ_OK;
 	}
 
-	static SRes Seek(void *pp, Int64 *pos, ESzSeek origin)
+	static SRes Seek(const ISeekInStream *pp, Int64 *pos, ESzSeek origin)
 	{
 		CZDFileInStream *p = (CZDFileInStream *)pp;
 		int move_method;
@@ -111,7 +111,8 @@ struct C7zArchive
 {
 	CSzArEx DB;
 	CZDFileInStream ArchiveStream;
-	CLookToRead LookStream;
+	CLookToRead2 LookStream;
+	Byte StreamBuffer[1<<14];
 	UInt32 BlockIndex;
 	Byte *OutBuffer;
 	size_t OutBufferSize;
@@ -123,9 +124,11 @@ struct C7zArchive
 			CrcGenerateTable();
 		}
 		file->Seek(0, SEEK_SET);
-		LookToRead_CreateVTable(&LookStream, false);
+		LookToRead2_CreateVTable(&LookStream, false);
 		LookStream.realStream = &ArchiveStream.s;
-		LookToRead_Init(&LookStream);
+		LookToRead2_Init(&LookStream);
+		LookStream.bufSize = sizeof(StreamBuffer);
+		LookStream.buf = StreamBuffer;
 		SzArEx_Init(&DB);
 		BlockIndex = 0xFFFFFFFF;
 		OutBuffer = NULL;
@@ -143,13 +146,13 @@ struct C7zArchive
 
 	SRes Open()
 	{
-		return SzArEx_Open(&DB, &LookStream.s, &g_Alloc, &g_Alloc);
+		return SzArEx_Open(&DB, &LookStream.vt, &g_Alloc, &g_Alloc);
 	}
 
 	SRes Extract(UInt32 file_index, char *buffer)
 	{
 		size_t offset, out_size_processed;
-		SRes res = SzArEx_Extract(&DB, &LookStream.s, file_index,
+		SRes res = SzArEx_Extract(&DB, &LookStream.vt, file_index,
 			&BlockIndex, &OutBuffer, &OutBufferSize,
 			&offset, &out_size_processed,
 			&g_Alloc, &g_Alloc);
-- 
2.15.1

openSUSE Build Service is sponsored by