This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions

20
C/7z.h
View File

@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface
2013-01-18 : Igor Pavlov : Public domain */
2014-02-08 : Igor Pavlov : Public domain */
#ifndef __7Z_H
#define __7Z_H
@@ -11,7 +11,7 @@ EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
extern Byte k7zSignature[k7zSignatureSize];
extern const Byte k7zSignature[k7zSignatureSize];
typedef struct
{
@@ -25,8 +25,7 @@ typedef struct
{
size_t PropsOffset;
UInt32 MethodID;
Byte NumInStreams;
Byte NumOutStreams;
Byte NumStreams;
Byte PropsSize;
} CSzCoderInfo;
@@ -34,23 +33,22 @@ typedef struct
{
UInt32 InIndex;
UInt32 OutIndex;
} CSzBindPair;
} CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BINDS_IN_FOLDER_MAX 3
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
#define SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX 4
typedef struct
{
UInt32 NumCoders;
UInt32 NumBindPairs;
UInt32 NumBonds;
UInt32 NumPackStreams;
UInt32 MainOutStream;
UInt32 UnpackStream;
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBindPair BindPairs[SZ_NUM_BINDS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;
/*

View File

@@ -1,5 +1,5 @@
/* 7zAlloc.c -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */
2015-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -22,7 +22,7 @@ int g_allocCountTemp = 0;
void *SzAlloc(void *p, size_t size)
{
p = p;
UNUSED_VAR(p);
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
@@ -34,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
void SzFree(void *p, void *address)
{
p = p;
UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{
@@ -47,7 +47,7 @@ void SzFree(void *p, void *address)
void *SzAllocTemp(void *p, size_t size)
{
p = p;
UNUSED_VAR(p);
if (size == 0)
return 0;
#ifdef _SZ_ALLOC_DEBUG
@@ -62,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
void SzFreeTemp(void *p, void *address)
{
p = p;
UNUSED_VAR(p);
#ifdef _SZ_ALLOC_DEBUG
if (address != 0)
{

View File

@@ -1,15 +1,23 @@
/* 7zAlloc.h -- Allocation functions
2010-10-29 : Igor Pavlov : Public domain */
2013-03-25 : Igor Pavlov : Public domain */
#ifndef __7Z_ALLOC_H
#define __7Z_ALLOC_H
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
void *SzAlloc(void *p, size_t size);
void SzFree(void *p, void *address);
void *SzAllocTemp(void *p, size_t size);
void SzFreeTemp(void *p, void *address);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,5 +1,5 @@
/* 7zArcIn.c -- 7z Input functions
2014-06-16 : Igor Pavlov : Public domain */
2015-05-16 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -10,9 +10,17 @@
#include "7zCrc.h"
#include "CpuArch.h"
#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
#define MY_ALLOC(T, p, size, alloc) { \
if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = 0; else MY_ALLOC(T, p, size, alloc) }
#define MY_ALLOC_AND_CPY(to, size, from, alloc) \
{ MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }
#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
{ if ((size) == 0) p = 0; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
#define k7zMajorVersion 0
enum EIdEnum
@@ -48,17 +56,15 @@ enum EIdEnum
// k7zIsReal
};
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
#define NUM_FOLDER_CODERS_MAX 32
#define NUM_CODER_STREAMS_MAX 32
/*
static int SzFolder_FindBindPairForInStream(const CSzFolder *p, UInt32 inStreamIndex)
static int SzFolder_FindBondForInStream(const CSzFolder *p, UInt32 inStreamIndex)
{
UInt32 i;
for (i = 0; i < p->NumBindPairs; i++)
if (p->BindPairs[i].InIndex == inStreamIndex)
for (i = 0; i < p->NumBonds; i++)
if (p->Bonds[i].InIndex == inStreamIndex)
return i;
return -1;
}
@@ -68,8 +74,16 @@ static int SzFolder_FindBindPairForInStream(const CSzFolder *p, UInt32 inStreamI
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
{
MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
MY_ALLOC(UInt32, p->Vals, num, alloc);
if (num == 0)
{
p->Defs = 0;
p->Vals = 0;
}
else
{
MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
MY_ALLOC(UInt32, p->Vals, num, alloc);
}
return SZ_OK;
}
@@ -170,7 +184,7 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
static int TestSignatureCandidate(Byte *testBytes)
{
size_t i;
unsigned i;
for (i = 0; i < k7zSignatureSize; i++)
if (testBytes[i] != k7zSignature[i])
return 0;
@@ -224,7 +238,7 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
Byte b;
if ((firstByte & mask) == 0)
{
UInt64 highPart = firstByte & (mask - 1);
UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);
*value |= (highPart << (8 * i));
return SZ_OK;
}
@@ -367,23 +381,23 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
{
Byte allAreDefined;
UInt32 i;
Byte *v2;
UInt32 numBytes = (numItems + 7) >> 3;
*v = NULL;
RINOK(SzReadByte(sd, &allAreDefined));
if (numBytes == 0)
return SZ_OK;
if (allAreDefined == 0)
{
if (numBytes > sd->Size)
return SZ_ERROR_ARCHIVE;
MY_ALLOC(Byte, *v, numBytes, alloc);
memcpy(*v, sd->Data, numBytes);
MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc);
SKIP_DATA(sd, numBytes);
return SZ_OK;
}
MY_ALLOC(Byte, *v, numBytes, alloc);
v2 = *v;
for (i = 0; i < numBytes; i++)
v2[i] = 0xFF;
memset(v2, 0xFF, (size_t)numBytes);
{
unsigned numBits = (unsigned)numItems & 7;
if (numBits != 0)
@@ -398,7 +412,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
CSzData sd;
UInt32 *vals;
const Byte *defs;
MY_ALLOC(UInt32, crcs->Vals, numItems, alloc);
MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc);
sd = *sd2;
defs = crcs->Defs;
vals = crcs->Vals;
@@ -486,19 +500,22 @@ static SRes SzReadSwitch(CSzData *sd)
}
*/
#define SZ_NUM_IN_STREAMS_IN_FOLDER_MAX 16
#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
{
UInt32 numCoders, numBindPairs, numPackStreams, i;
UInt32 numInStreams = 0, numOutStreams = 0;
UInt32 numCoders, i;
UInt32 numInStreams = 0;
const Byte *dataStart = sd->Data;
Byte inStreamUsed[SZ_NUM_IN_STREAMS_IN_FOLDER_MAX];
f->NumCoders = 0;
f->NumBonds = 0;
f->NumPackStreams = 0;
f->UnpackStream = 0;
RINOK(SzReadNumber32(sd, &numCoders));
if (numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
f->NumCoders = numCoders;
for (i = 0; i < numCoders; i++)
{
@@ -506,9 +523,11 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
CSzCoderInfo *coder = f->Coders + i;
unsigned idSize, j;
UInt64 id;
RINOK(SzReadByte(sd, &mainByte));
if ((mainByte & 0xC0) != 0)
return SZ_ERROR_UNSUPPORTED;
idSize = (unsigned)(mainByte & 0xF);
if (idSize > sizeof(id))
return SZ_ERROR_UNSUPPORTED;
@@ -525,106 +544,132 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
return SZ_ERROR_UNSUPPORTED;
coder->MethodID = (UInt32)id;
coder->NumInStreams = 1;
coder->NumOutStreams = 1;
coder->NumStreams = 1;
coder->PropsOffset = 0;
coder->PropsSize = 0;
if ((mainByte & 0x10) != 0)
{
UInt32 numStreams;
RINOK(SzReadNumber32(sd, &numStreams));
if (numStreams > NUM_CODER_STREAMS_MAX)
if (numStreams > k_NumCodersStreams_in_Folder_MAX)
return SZ_ERROR_UNSUPPORTED;
coder->NumInStreams = (Byte)numStreams;
coder->NumStreams = (Byte)numStreams;
RINOK(SzReadNumber32(sd, &numStreams));
if (numStreams > NUM_CODER_STREAMS_MAX)
if (numStreams != 1)
return SZ_ERROR_UNSUPPORTED;
coder->NumOutStreams = (Byte)numStreams;
}
numInStreams += coder->NumStreams;
if (numInStreams > k_NumCodersStreams_in_Folder_MAX)
return SZ_ERROR_UNSUPPORTED;
if ((mainByte & 0x20) != 0)
{
UInt32 propsSize = 0;
RINOK(SzReadNumber32(sd, &propsSize));
if (propsSize >= 0x40)
return SZ_ERROR_UNSUPPORTED;
if (propsSize > sd->Size)
return SZ_ERROR_ARCHIVE;
if (propsSize >= 0x80)
return SZ_ERROR_UNSUPPORTED;
coder->PropsOffset = sd->Data - dataStart;
coder->PropsSize = (Byte)propsSize;
sd->Data += (size_t)propsSize;
sd->Size -= (size_t)propsSize;
}
numInStreams += coder->NumInStreams;
numOutStreams += coder->NumOutStreams;
}
if (numOutStreams == 0)
return SZ_ERROR_UNSUPPORTED;
f->NumBindPairs = numBindPairs = numOutStreams - 1;
if (numInStreams < numBindPairs)
return SZ_ERROR_ARCHIVE;
if (numInStreams > SZ_NUM_IN_STREAMS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
f->MainOutStream = 0;
f->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
for (i = 0; i < numInStreams; i++)
inStreamUsed[i] = False;
if (numBindPairs != 0)
/*
if (numInStreams == 1 && numCoders == 1)
{
Byte outStreamUsed[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
if (numBindPairs > SZ_NUM_BINDS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
for (i = 0; i < numOutStreams; i++)
outStreamUsed[i] = False;
for (i = 0; i < numBindPairs; i++)
{
CSzBindPair *bp = f->BindPairs + i;
RINOK(SzReadNumber32(sd, &bp->InIndex));
if (bp->InIndex >= numInStreams)
return SZ_ERROR_ARCHIVE;
inStreamUsed[bp->InIndex] = True;
RINOK(SzReadNumber32(sd, &bp->OutIndex));
if (bp->OutIndex >= numInStreams)
return SZ_ERROR_ARCHIVE;
outStreamUsed[bp->OutIndex] = True;
}
for (i = 0; i < numOutStreams; i++)
if (!outStreamUsed[i])
{
f->MainOutStream = i;
break;
}
if (i == numOutStreams)
return SZ_ERROR_ARCHIVE;
}
if (numPackStreams == 1)
{
for (i = 0; i < numInStreams; i++)
if (!inStreamUsed[i])
break;
if (i == numInStreams)
return SZ_ERROR_ARCHIVE;
f->PackStreams[0] = i;
f->NumPackStreams = 1;
f->PackStreams[0] = 0;
}
else
for (i = 0; i < numPackStreams; i++)
*/
{
Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];
UInt32 numBonds, numPackStreams;
numBonds = numCoders - 1;
if (numInStreams < numBonds)
return SZ_ERROR_ARCHIVE;
if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
f->NumBonds = numBonds;
numPackStreams = numInStreams - numBonds;
if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
return SZ_ERROR_UNSUPPORTED;
f->NumPackStreams = numPackStreams;
for (i = 0; i < numInStreams; i++)
streamUsed[i] = False;
if (numBonds != 0)
{
RINOK(SzReadNumber32(sd, f->PackStreams + i));
}
Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];
for (i = 0; i < numOutStreams; i++)
for (i = 0; i < numCoders; i++)
coderUsed[i] = False;
for (i = 0; i < numBonds; i++)
{
CSzBond *bp = f->Bonds + i;
RINOK(SzReadNumber32(sd, &bp->InIndex));
if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex])
return SZ_ERROR_ARCHIVE;
streamUsed[bp->InIndex] = True;
RINOK(SzReadNumber32(sd, &bp->OutIndex));
if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex])
return SZ_ERROR_ARCHIVE;
coderUsed[bp->OutIndex] = True;
}
for (i = 0; i < numCoders; i++)
if (!coderUsed[i])
{
f->UnpackStream = i;
break;
}
if (i == numCoders)
return SZ_ERROR_ARCHIVE;
}
if (numPackStreams == 1)
{
for (i = 0; i < numInStreams; i++)
if (!streamUsed[i])
break;
if (i == numInStreams)
return SZ_ERROR_ARCHIVE;
f->PackStreams[0] = i;
}
else
for (i = 0; i < numPackStreams; i++)
{
UInt32 index;
RINOK(SzReadNumber32(sd, &index));
if (index >= numInStreams || streamUsed[index])
return SZ_ERROR_ARCHIVE;
streamUsed[index] = True;
f->PackStreams[i] = index;
}
}
for (i = 0; i < numCoders; i++)
{
RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
}
f->NumCoders = numCoders;
return SZ_OK;
}
@@ -658,24 +703,25 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
return SZ_OK;
}
#define k_InStreamUsed_MAX 64
#define k_OutStreamUsed_MAX 64
#define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
static SRes ReadUnpackInfo(CSzAr *p,
CSzData *sd2,
UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
UInt32 numFoldersMax,
const CBuf *tempBufs, UInt32 numTempBufs,
ISzAlloc *alloc)
{
CSzData sd;
Byte inStreamUsed[k_InStreamUsed_MAX];
Byte outStreamUsed[k_OutStreamUsed_MAX];
UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
const Byte *startBufPtr;
Byte external;
RINOK(WaitId(sd2, k7zIdFolder));
RINOK(SzReadNumber32(sd2, &numFolders));
if (p->NumFolders > numFoldersMax)
if (numFolders > numFoldersMax)
return SZ_ERROR_UNSUPPORTED;
p->NumFolders = numFolders;
@@ -685,7 +731,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
else
{
UInt32 index;
SzReadNumber32(sd2, &index);
RINOK(SzReadNumber32(sd2, &index));
if (index >= numTempBufs)
return SZ_ERROR_ARCHIVE;
sd.Data = tempBufs[index].data;
@@ -703,18 +749,19 @@ static SRes ReadUnpackInfo(CSzAr *p,
for (fo = 0; fo < numFolders; fo++)
{
UInt32 numCoders, ci, numInStreams = 0, numOutStreams = 0;
UInt32 numCoders, ci, numInStreams = 0;
p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
RINOK(SzReadNumber32(&sd, &numCoders));
if (numCoders > NUM_FOLDER_CODERS_MAX)
if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
return SZ_ERROR_UNSUPPORTED;
for (ci = 0; ci < numCoders; ci++)
{
Byte mainByte;
unsigned idSize;
UInt32 coderInStreams, coderOutStreams;
UInt32 coderInStreams;
SZ_READ_BYTE_2(mainByte);
if ((mainByte & 0xC0) != 0)
@@ -727,17 +774,18 @@ static SRes ReadUnpackInfo(CSzAr *p,
SKIP_DATA2(sd, idSize);
coderInStreams = 1;
coderOutStreams = 1;
if ((mainByte & 0x10) != 0)
{
UInt32 coderOutStreams;
RINOK(SzReadNumber32(&sd, &coderInStreams));
RINOK(SzReadNumber32(&sd, &coderOutStreams));
if (coderInStreams > NUM_CODER_STREAMS_MAX ||
coderOutStreams > NUM_CODER_STREAMS_MAX)
if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1)
return SZ_ERROR_UNSUPPORTED;
}
numInStreams += coderInStreams;
numOutStreams += coderOutStreams;
if ((mainByte & 0x20) != 0)
{
UInt32 propsSize;
@@ -751,64 +799,73 @@ static SRes ReadUnpackInfo(CSzAr *p,
{
UInt32 indexOfMainStream = 0;
UInt32 numPackStreams = 1;
if (numOutStreams != 1 || numInStreams != 1)
if (numCoders != 1 || numInStreams != 1)
{
Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX];
Byte coderUsed[k_Scan_NumCoders_MAX];
UInt32 i;
UInt32 numBindPairs = numOutStreams - 1;
if (numOutStreams == 0 || numInStreams < numBindPairs)
UInt32 numBonds = numCoders - 1;
if (numInStreams < numBonds)
return SZ_ERROR_ARCHIVE;
if (numInStreams > k_InStreamUsed_MAX ||
numOutStreams > k_OutStreamUsed_MAX)
if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
return SZ_ERROR_UNSUPPORTED;
for (i = 0; i < numInStreams; i++)
inStreamUsed[i] = False;
for (i = 0; i < numOutStreams; i++)
outStreamUsed[i] = False;
streamUsed[i] = False;
for (i = 0; i < numCoders; i++)
coderUsed[i] = False;
for (i = 0; i < numBindPairs; i++)
for (i = 0; i < numBonds; i++)
{
UInt32 index;
RINOK(SzReadNumber32(&sd, &index));
if (index >= numInStreams || inStreamUsed[index])
if (index >= numInStreams || streamUsed[index])
return SZ_ERROR_ARCHIVE;
inStreamUsed[index] = True;
streamUsed[index] = True;
RINOK(SzReadNumber32(&sd, &index));
if (index >= numInStreams || outStreamUsed[index])
if (index >= numCoders || coderUsed[index])
return SZ_ERROR_ARCHIVE;
outStreamUsed[index] = True;
coderUsed[index] = True;
}
numPackStreams = numInStreams - numBindPairs;
numPackStreams = numInStreams - numBonds;
if (numPackStreams != 1)
for (i = 0; i < numPackStreams; i++)
{
UInt32 temp;
RINOK(SzReadNumber32(&sd, &temp));
if (temp >= numInStreams)
UInt32 index;
RINOK(SzReadNumber32(&sd, &index));
if (index >= numInStreams || streamUsed[index])
return SZ_ERROR_ARCHIVE;
streamUsed[index] = True;
}
for (i = 0; i < numOutStreams; i++)
if (!outStreamUsed[i])
for (i = 0; i < numCoders; i++)
if (!coderUsed[i])
{
indexOfMainStream = i;
break;
}
if (i == numOutStreams)
if (i == numCoders)
return SZ_ERROR_ARCHIVE;
}
p->FoStartPackStreamIndex[fo] = packStreamIndex;
p->FoSizesOffsets[fo] = (numOutStreams << 8) | indexOfMainStream;
numCodersOutStreams += numOutStreams;
if (numCodersOutStreams < numOutStreams)
p->FoSizesOffsets[fo] = (numCoders << 8) | indexOfMainStream;
numCodersOutStreams += numCoders;
if (numCodersOutStreams < numCoders)
return SZ_ERROR_UNSUPPORTED;
packStreamIndex += numPackStreams;
if (packStreamIndex < numPackStreams)
return SZ_ERROR_UNSUPPORTED;
if (packStreamIndex > p->NumPackStreams)
return SZ_ERROR_ARCHIVE;
}
@@ -818,8 +875,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
size_t dataSize = sd.Data - startBufPtr;
p->FoStartPackStreamIndex[fo] = packStreamIndex;
p->FoCodersOffsets[fo] = dataSize;
MY_ALLOC(Byte, p->CodersData, dataSize, alloc);
memcpy(p->CodersData, startBufPtr, dataSize);
MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc);
}
if (external != 0)
@@ -831,7 +887,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
// MY_ALLOC(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
// MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
{
size_t dataSize = sd.Size;
/*
@@ -843,8 +899,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
*/
RINOK(SkipNumbers(&sd, numCodersOutStreams));
dataSize -= sd.Size;
MY_ALLOC(Byte, p->UnpackSizesData, dataSize, alloc);
memcpy(p->UnpackSizesData, sd.Data - dataSize, dataSize);
MY_ALLOC_ZE_AND_CPY(p->UnpackSizesData, dataSize, sd.Data - dataSize, alloc);
p->UnpackSizesDataSize = dataSize;
/*
const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams);
@@ -1019,8 +1074,10 @@ static SRes SzReadAndDecodePackedStreams(
sdCodersUnpSizes.Data = p->UnpackSizesData;
sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
for (fo = 0; fo < p->NumFolders; fo++)
Buf_Init(tempBufs + fo);
for (fo = 0; fo < p->NumFolders; fo++)
{
CBuf *tempBuf = tempBufs + fo;
@@ -1049,6 +1106,7 @@ static SRes SzReadAndDecodePackedStreams(
if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM;
}
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
for (fo = 0; fo < p->NumFolders; fo++)
@@ -1060,6 +1118,7 @@ static SRes SzReadAndDecodePackedStreams(
if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
return SZ_ERROR_CRC;
}
return SZ_OK;
}
@@ -1069,6 +1128,8 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
*offsets++ = 0;
if (numFiles == 0)
return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
if (size < 2)
return SZ_ERROR_ARCHIVE;
if (data[size - 2] != 0 || data[size - 1] != 0)
return SZ_ERROR_ARCHIVE;
do
@@ -1100,20 +1161,23 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
CNtfsFileTime *vals;
Byte *defs;
Byte external;
RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
RINOK(SzReadByte(sd2, &external));
if (external == 0)
sd = *sd2;
else
{
UInt32 index;
SzReadNumber32(sd2, &index);
RINOK(SzReadNumber32(sd2, &index));
if (index >= numTempBufs)
return SZ_ERROR_ARCHIVE;
sd.Data = tempBufs[index].data;
sd.Size = tempBufs[index].size;
}
MY_ALLOC(CNtfsFileTime, p->Vals, num, alloc);
MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc);
vals = p->Vals;
defs = p->Defs;
for (i = 0; i < num; i++)
@@ -1127,8 +1191,10 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
}
else
vals[i].High = vals[i].Low = 0;
if (external == 0)
*sd2 = sd;
return SZ_OK;
}
@@ -1141,8 +1207,7 @@ static SRes SzReadHeader2(
// Byte **emptyFileVector, /* allocTemp */
// Byte **lwtVector, /* allocTemp */
ILookInStream *inStream,
CBuf *tempBufs,
UInt32 *numTempBufs,
CBuf *tempBufs, UInt32 *numTempBufs,
ISzAlloc *allocMain,
ISzAlloc *allocTemp
)
@@ -1225,11 +1290,12 @@ static SRes SzReadHeader2(
RINOK(ReadNumber(sd, &size));
if (size > sd->Size)
return SZ_ERROR_ARCHIVE;
if ((UInt64)(int)type != type)
if (type >= ((UInt32)1 << 8))
{
SKIP_DATA(sd, size);
}
else switch((int)type)
else switch((unsigned)type)
{
case k7zIdName:
{
@@ -1246,7 +1312,7 @@ static SRes SzReadHeader2(
else
{
UInt32 index;
SzReadNumber32(sd, &index);
RINOK(SzReadNumber32(sd, &index));
if (index >= *numTempBufs)
return SZ_ERROR_ARCHIVE;
namesData = (tempBufs)[index].data;
@@ -1255,9 +1321,8 @@ static SRes SzReadHeader2(
if ((namesSize & 1) != 0)
return SZ_ERROR_ARCHIVE;
MY_ALLOC(Byte, p->FileNames, namesSize, allocMain);
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
memcpy(p->FileNames, namesData, namesSize);
MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain);
RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
if (external == 0)
{
@@ -1290,7 +1355,7 @@ static SRes SzReadHeader2(
else
{
UInt32 index;
SzReadNumber32(sd, &index);
RINOK(SzReadNumber32(sd, &index));
if (index >= *numTempBufs)
return SZ_ERROR_ARCHIVE;
sdSwitch.Data = (tempBufs)[index].data;
@@ -1352,9 +1417,9 @@ static SRes SzReadHeader2(
sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain);
MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain);
MY_ALLOC_ZE(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain);
MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
MY_ALLOC(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));
@@ -1660,20 +1725,19 @@ static SRes SzArEx_Open2(
{
if (type == k7zIdHeader)
{
/*
CSzData sd2;
int ttt;
for (ttt = 0; ttt < 1; ttt++)
// for (ttt = 0; ttt < 40000; ttt++)
unsigned ttt;
for (ttt = 0; ttt < 40000; ttt++)
{
SzArEx_Free(p, allocMain);
sd2 = sd;
res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp
);
res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp);
if (res != SZ_OK)
break;
}
// res = SzReadHeader(p, &sd, allocMain, allocTemp);
*/
res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp);
}
else
res = SZ_ERROR_UNSUPPORTED;

View File

@@ -1,5 +1,5 @@
/* 7zBuf2.c -- Byte Buffer
2013-11-12 : Igor Pavlov : Public domain */
2014-08-22 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -34,8 +34,11 @@ int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc)
alloc->Free(alloc, p->data);
p->data = data;
}
memcpy(p->data + p->pos, buf, size);
p->pos += size;
if (size != 0)
{
memcpy(p->data + p->pos, buf, size);
p->pos += size;
}
return 1;
}

View File

@@ -1,5 +1,5 @@
/* 7zCrc.c -- CRC32 init
2013-11-12 : Igor Pavlov : Public domain */
2015-03-10 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -8,24 +8,28 @@
#define kCrcPoly 0xEDB88320
#ifdef MY_CPU_X86_OR_AMD64
#ifdef MY_CPU_LE
#define CRC_NUM_TABLES 8
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#elif defined(MY_CPU_LE)
#define CRC_NUM_TABLES 4
#else
#define CRC_NUM_TABLES 5
#define CRC_NUM_TABLES 9
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
#ifndef MY_CPU_BE
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
CRC_FUNC g_CrcUpdateT4;
CRC_FUNC g_CrcUpdateT8;
CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
@@ -38,6 +42,17 @@ UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
}
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
const Byte *pEnd = p + size;
for (; p != pEnd; p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
}
void MY_FAST_CALL CrcGenerateTable()
{
UInt32 i;
@@ -54,22 +69,43 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
#if CRC_NUM_TABLES < 4
g_CrcUpdate = CrcUpdateT1;
#else
#ifdef MY_CPU_LE
g_CrcUpdate = CrcUpdateT4;
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
#if CRC_NUM_TABLES == 8
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
#ifdef MY_CPU_X86_OR_AMD64
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
#endif
#else
{
#ifndef MY_CPU_BE
UInt32 k = 1;
if (*(const Byte *)&k == 1)
UInt32 k = 0x01020304;
const Byte *p = (const Byte *)&k;
if (p[0] == 4 && p[1] == 3)
{
g_CrcUpdateT4 = CrcUpdateT4;
g_CrcUpdate = CrcUpdateT4;
#if CRC_NUM_TABLES >= 8
g_CrcUpdateT8 = CrcUpdateT8;
// g_CrcUpdate = CrcUpdateT8;
#endif
}
else if (p[0] != 1 || p[1] != 2)
g_CrcUpdate = CrcUpdateT1;
else
#endif
{
@@ -78,8 +114,15 @@ void MY_FAST_CALL CrcGenerateTable()
UInt32 x = g_CrcTable[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;
#endif
}
}
#endif
#endif
}

View File

@@ -1,14 +1,14 @@
/* 7zCrcOpt.c -- CRC32 calculation
2013-11-12 : Igor Pavlov : Public domain */
2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
#ifndef MY_CPU_BE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
@@ -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);
@@ -30,7 +30,28 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
return CrcUpdateT4(v, data, size, table);
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
for (; size >= 8; size -= 8, p += 8)
{
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))];
d = *((const UInt32 *)p + 1);
v ^=
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);
return v;
}
#endif
@@ -40,27 +61,55 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
v = CRC_UINT32_SWAP(v);
table += 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
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))];
}
table -= 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT32_SWAP(v);
}
UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
table += 0x100;
v = CRC_UINT32_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 8; size -= 8, p += 8)
{
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))];
d = *((const UInt32 *)p + 1);
v ^=
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);
return CRC_UINT32_SWAP(v);
}
#endif

208
C/7zDec.c
View File

@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder
2014-06-16 : Igor Pavlov : Public domain */
2015-06-13 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -12,6 +12,7 @@
#include "Bcj2.h"
#include "Bra.h"
#include "CpuArch.h"
#include "Delta.h"
#include "LzmaDec.h"
#include "Lzma2Dec.h"
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -19,14 +20,17 @@
#endif
#define k_Copy 0
#define k_Delta 3
#define k_LZMA2 0x21
#define k_LZMA 0x30101
#define k_BCJ 0x03030103
#define k_PPC 0x03030205
#define k_ARM 0x03030501
#define k_ARMT 0x03030701
#define k_SPARC 0x03030805
#define k_BCJ2 0x0303011B
#define k_BCJ 0x3030103
#define k_BCJ2 0x303011B
#define k_PPC 0x3030205
#define k_IA64 0x3030401
#define k_ARM 0x3030501
#define k_ARMT 0x3030701
#define k_SPARC 0x3030805
#ifdef _7ZIP_PPMD_SUPPPORT
@@ -174,6 +178,9 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
return res;
}
#ifndef _7Z_NO_METHOD_LZMA2
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
{
@@ -223,6 +230,9 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
return res;
}
#endif
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
{
while (inSize > 0)
@@ -248,7 +258,9 @@ static Bool IS_MAIN_METHOD(UInt32 m)
{
case k_Copy:
case k_LZMA:
#ifndef _7Z_NO_METHOD_LZMA2
case k_LZMA2:
#endif
#ifdef _7ZIP_PPMD_SUPPPORT
case k_PPMD:
#endif
@@ -260,13 +272,12 @@ static Bool IS_MAIN_METHOD(UInt32 m)
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
{
return
c->NumInStreams == 1 &&
c->NumOutStreams == 1 &&
/* c->MethodID <= (UInt32)0xFFFFFFFF && */
IS_MAIN_METHOD((UInt32)c->MethodID);
c->NumStreams == 1
/* && c->MethodID <= (UInt32)0xFFFFFFFF */
&& IS_MAIN_METHOD((UInt32)c->MethodID);
}
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
static SRes CheckSupportedFolder(const CSzFolder *f)
{
@@ -276,51 +287,64 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
return SZ_ERROR_UNSUPPORTED;
if (f->NumCoders == 1)
{
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
#ifndef _7Z_NO_METHODS_FILTERS
if (f->NumCoders == 2)
{
const CSzCoderInfo *c = &f->Coders[1];
if (
/* c->MethodID > (UInt32)0xFFFFFFFF || */
c->NumInStreams != 1 ||
c->NumOutStreams != 1 ||
f->NumPackStreams != 1 ||
f->PackStreams[0] != 0 ||
f->NumBindPairs != 1 ||
f->BindPairs[0].InIndex != 1 ||
f->BindPairs[0].OutIndex != 0)
c->NumStreams != 1
|| f->NumPackStreams != 1
|| f->PackStreams[0] != 0
|| f->NumBonds != 1
|| f->Bonds[0].InIndex != 1
|| f->Bonds[0].OutIndex != 0)
return SZ_ERROR_UNSUPPORTED;
switch ((UInt32)c->MethodID)
{
case k_Delta:
case k_BCJ:
case k_PPC:
case k_IA64:
case k_SPARC:
case k_ARM:
case k_ARMT:
break;
default:
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
#endif
if (f->NumCoders == 4)
{
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
!IS_BCJ2(&f->Coders[3]))
if (!IS_SUPPORTED_CODER(&f->Coders[1])
|| !IS_SUPPORTED_CODER(&f->Coders[2])
|| !IS_BCJ2(&f->Coders[3]))
return SZ_ERROR_UNSUPPORTED;
if (f->NumPackStreams != 4 ||
f->PackStreams[0] != 2 ||
f->PackStreams[1] != 6 ||
f->PackStreams[2] != 1 ||
f->PackStreams[3] != 0 ||
f->NumBindPairs != 3 ||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
if (f->NumPackStreams != 4
|| f->PackStreams[0] != 2
|| f->PackStreams[1] != 6
|| f->PackStreams[2] != 1
|| f->PackStreams[3] != 0
|| f->NumBonds != 3
|| f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
|| f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
|| f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
return SZ_ERROR_UNSUPPORTED;
return SZ_OK;
}
return SZ_ERROR_UNSUPPORTED;
}
@@ -364,7 +388,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
if (outSizeCur != unpackSize)
return SZ_ERROR_MEM;
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
if (temp == 0 && outSizeCur != 0)
if (!temp && outSizeCur != 0)
return SZ_ERROR_MEM;
outBufCur = tempBuf[1 - ci] = temp;
tempSizes[1 - ci] = outSizeCur;
@@ -393,66 +417,118 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
{
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
#ifndef _7Z_NO_METHOD_LZMA2
else if (coder->MethodID == k_LZMA2)
{
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
}
else
#endif
#ifdef _7ZIP_PPMD_SUPPPORT
else if (coder->MethodID == k_PPMD)
{
#ifdef _7ZIP_PPMD_SUPPPORT
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
#else
return SZ_ERROR_UNSUPPORTED;
#endif
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
}
else if (coder->MethodID == k_BCJ2)
{
UInt64 offset = packPositions[1];
UInt64 s3Size = packPositions[2] - offset;
SRes res;
if (ci != 3)
return SZ_ERROR_UNSUPPORTED;
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
tempSizes[2] = (SizeT)s3Size;
if (tempSizes[2] != s3Size)
return SZ_ERROR_MEM;
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
if (tempBuf[2] == 0 && tempSizes[2] != 0)
if (!tempBuf[2] && tempSizes[2] != 0)
return SZ_ERROR_MEM;
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
RINOK(res)
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
if ((tempSizes[0] & 3) != 0 ||
(tempSizes[1] & 3) != 0 ||
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
return SZ_ERROR_DATA;
res = Bcj2_Decode(
tempBuf3, tempSize3,
tempBuf[0], tempSizes[0],
tempBuf[1], tempSizes[1],
tempBuf[2], tempSizes[2],
outBuffer, outSize);
RINOK(res)
}
else
{
if (ci != 1)
return SZ_ERROR_UNSUPPORTED;
switch (coder->MethodID)
{
case k_BCJ:
CBcj2Dec p;
p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
p.dest = outBuffer;
p.destLim = outBuffer + outSize;
Bcj2Dec_Init(&p);
RINOK(Bcj2Dec_Decode(&p));
{
UInt32 state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
unsigned i;
for (i = 0; i < 4; i++)
if (p.bufs[i] != p.lims[i])
return SZ_ERROR_DATA;
if (!Bcj2Dec_IsFinished(&p))
return SZ_ERROR_DATA;
if (p.dest != p.destLim
|| p.state != BCJ2_STREAM_MAIN)
return SZ_ERROR_DATA;
}
CASE_BRA_CONV(ARM)
default:
return SZ_ERROR_UNSUPPORTED;
}
}
#ifndef _7Z_NO_METHODS_FILTERS
else if (ci == 1)
{
if (coder->MethodID == k_Delta)
{
if (coder->PropsSize != 1)
return SZ_ERROR_UNSUPPORTED;
{
Byte state[DELTA_STATE_SIZE];
Delta_Init(state);
Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
}
}
else
{
if (coder->PropsSize != 0)
return SZ_ERROR_UNSUPPORTED;
switch (coder->MethodID)
{
case k_BCJ:
{
UInt32 state;
x86_Convert_Init(state);
x86_Convert(outBuffer, outSize, 0, &state, 0);
break;
}
CASE_BRA_CONV(PPC)
CASE_BRA_CONV(IA64)
CASE_BRA_CONV(SPARC)
CASE_BRA_CONV(ARM)
CASE_BRA_CONV(ARMT)
default:
return SZ_ERROR_UNSUPPORTED;
}
}
}
#endif
else
return SZ_ERROR_UNSUPPORTED;
}
return SZ_OK;
}
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *inStream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
@@ -477,10 +553,10 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
if (res != SZ_OK)
return res;
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.MainOutStream])
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.UnpackStream])
return SZ_ERROR_FAIL;
{
int i;
unsigned i;
Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],

View File

@@ -1,10 +1,17 @@
#define MY_VER_MAJOR 9
#define MY_VER_MINOR 38
#define MY_VER_MAJOR 15
#define MY_VER_MINOR 05
#define MY_VER_BUILD 00
#define MY_VERSION "9.38 beta"
// #define MY_7ZIP_VERSION "9.38"
#define MY_DATE "2015-01-03"
#define MY_VERSION "15.05 beta"
#define MY_DATE "2015-06-14"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
#else
#define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " : " MY_COPYRIGHT " : " MY_DATE

29
C/Aes.c
View File

@@ -1,5 +1,5 @@
/* Aes.c -- AES encryption / decryption
2013-11-12 : Igor Pavlov : Public domain */
2015-02-23 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -7,7 +7,7 @@
#include "CpuArch.h"
static UInt32 T[256 * 4];
static Byte Sbox[256] = {
static const Byte Sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
@@ -40,7 +40,7 @@ AES_CODE_FUNC g_AesCtr_Code;
static UInt32 D[256 * 4];
static Byte InvS[256];
static Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
static const Byte Rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
@@ -56,6 +56,7 @@ void AesGenTables(void)
unsigned i;
for (i = 0; i < 256; i++)
InvS[Sbox[i]] = (Byte)i;
for (i = 0; i < 256; i++)
{
{
@@ -82,9 +83,11 @@ void AesGenTables(void)
D[0x300 + i] = Ui32(a9, aD, aB, aE);
}
}
g_AesCbc_Encode = AesCbc_Encode;
g_AesCbc_Decode = AesCbc_Decode;
g_AesCtr_Code = AesCtr_Code;
#ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported())
{
@@ -95,34 +98,38 @@ void AesGenTables(void)
#endif
}
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
#define HT4(m, i, s, p) m[i] = \
HT(i, 0, s) ^ \
HT(i, 1, s) ^ \
HT(i, 2, s) ^ \
HT(i, 3, s) ^ w[p + i]
/* such order (2031) in HT16 is for VC6/K8 speed optimization) */
#define HT16(m, s, p) \
HT4(m, 2, s, p); \
HT4(m, 0, s, p); \
HT4(m, 3, s, p); \
HT4(m, 1, s, p); \
HT4(m, 2, s, p); \
HT4(m, 3, s, p); \
#define FT(i, x) Sbox[gb ## x(m[(i + x) & 3])]
#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i];
#define HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
#define HD4(m, i, s, p) m[i] = \
HD(i, 0, s) ^ \
HD(i, 1, s) ^ \
HD(i, 2, s) ^ \
HD(i, 3, s) ^ w[p + i];
/* such order (0231) in HD16 is for VC6/K8 speed optimization) */
#define HD16(m, s, p) \
HD4(m, 0, s, p); \
HD4(m, 1, s, p); \
HD4(m, 2, s, p); \
HD4(m, 3, s, p); \
HD4(m, 1, s, p); \
#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i];
@@ -169,7 +176,7 @@ void MY_FAST_CALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize)
/* Aes_Encode and Aes_Decode functions work with little-endian words.
src and dest are pointers to 4 UInt32 words.
arc and dest can point to same block */
src and dest can point to same block */
static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src)
{
@@ -271,13 +278,17 @@ void MY_FAST_CALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks)
UInt32 temp[4];
Byte buf[16];
int i;
if (++p[0] == 0)
p[1]++;
Aes_Encode(p + 4, temp, p);
SetUi32(buf, temp[0]);
SetUi32(buf + 4, temp[1]);
SetUi32(buf + 8, temp[2]);
SetUi32(buf + 12, temp[3]);
for (i = 0; i < 16; i++)
*data++ ^= buf[i];
}

View File

@@ -1,5 +1,5 @@
/* Alloc.c -- Memory allocation functions
2013-11-12 : Igor Pavlov : Public domain */
2015-02-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -125,3 +125,12 @@ void BigFree(void *address)
}
#endif
static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void *SzBigAlloc(void *p, size_t size) { UNUSED_VAR(p); return BigAlloc(size); }
static void SzBigFree(void *p, void *address) { UNUSED_VAR(p); BigFree(address); }
ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };

View File

@@ -1,14 +1,12 @@
/* Alloc.h -- Memory allocation functions
2009-02-07 : Igor Pavlov : Public domain */
2015-02-21 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
#include <stddef.h>
#include "7zTypes.h"
#ifdef __cplusplus
extern "C" {
#endif
EXTERN_C_BEGIN
void *MyAlloc(size_t size);
void MyFree(void *address);
@@ -31,8 +29,9 @@ void BigFree(void *address);
#endif
#ifdef __cplusplus
}
#endif
extern ISzAlloc g_Alloc;
extern ISzAlloc g_BigAlloc;
EXTERN_C_END
#endif

332
C/Bcj2.c
View File

@@ -1,134 +1,256 @@
/* Bcj2.c -- Converter for x86 code (BCJ2)
2008-10-04 : Igor Pavlov : Public domain */
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2014-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Bcj2.h"
#include "CpuArch.h"
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb UInt16
#endif
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
#define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kTopValue ((UInt32)1 << 24)
#define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5
#define RC_READ_BYTE (*buffer++)
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
#define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
#define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE;
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE;
int Bcj2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize)
void Bcj2Dec_Init(CBcj2Dec *p)
{
CProb p[256 + 2];
SizeT inPos = 0, outPos = 0;
unsigned i;
const Byte *buffer, *bufferLim;
UInt32 range, code;
Byte prevByte = 0;
p->state = BCJ2_DEC_STATE_OK;
p->ip = 0;
p->temp[3] = 0;
p->range = 0;
p->code = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1;
}
unsigned int i;
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
p[i] = kBitModelTotal >> 1;
SRes Bcj2Dec_Decode(CBcj2Dec *p)
{
if (p->range <= 5)
{
p->state = BCJ2_DEC_STATE_OK;
for (; p->range != 5; p->range++)
{
if (p->range == 1 && p->code != 0)
return SZ_ERROR_DATA;
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
buffer = buf3;
bufferLim = buffer + size3;
RC_INIT2
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
if (p->code == 0xFFFFFFFF)
return SZ_ERROR_DATA;
p->range = 0xFFFFFFFF;
}
else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
{
while (p->state <= BCJ2_DEC_STATE_ORIG_3)
{
Byte *dest = p->dest;
if (dest == p->destLim)
return SZ_OK;
*dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
p->dest = dest + 1;
}
}
if (outSize == 0)
return SZ_OK;
/*
if (BCJ2_IS_32BIT_STREAM(p->state))
{
const Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state])
return SZ_OK;
p->bufs[p->state] = cur + 4;
{
UInt32 val;
Byte *dest;
SizeT rem;
p->ip += 4;
val = GetBe32(cur) - p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
return SZ_OK;
}
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
p->state = BCJ2_DEC_STATE_OK;
}
}
*/
for (;;)
{
Byte b;
CProb *prob;
UInt32 bound;
UInt32 ttt;
SizeT limit = size0 - inPos;
if (outSize - outPos < limit)
limit = outSize - outPos;
while (limit != 0)
{
Byte b = buf0[inPos];
outBuf[outPos++] = b;
if (IsJ(prevByte, b))
break;
inPos++;
prevByte = b;
limit--;
}
if (limit == 0 || outPos == outSize)
break;
b = buf0[inPos++];
if (b == 0xE8)
prob = p + prevByte;
else if (b == 0xE9)
prob = p + 256;
else
prob = p + 257;
IF_BIT_0(prob)
{
UPDATE_0(prob)
prevByte = b;
}
if (BCJ2_IS_32BIT_STREAM(p->state))
p->state = BCJ2_DEC_STATE_OK;
else
{
UInt32 dest;
const Byte *v;
UPDATE_1(prob)
if (b == 0xE8)
if (p->range < kTopValue)
{
v = buf1;
if (size1 < 4)
return SZ_ERROR_DATA;
buf1 += 4;
size1 -= 4;
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
return SZ_OK;
}
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
else
{
v = buf2;
if (size2 < 4)
return SZ_ERROR_DATA;
buf2 += 4;
size2 -= 4;
const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
const Byte *srcLim;
Byte *dest;
SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
if (num == 0)
{
p->state = BCJ2_STREAM_MAIN;
return SZ_OK;
}
dest = p->dest;
if (num > (SizeT)(p->destLim - dest))
{
num = p->destLim - dest;
if (num == 0)
{
p->state = BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
}
srcLim = src + num;
if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0];
else for (;;)
{
Byte b = *src;
*dest = b;
if (b != 0x0F)
{
if ((b & 0xFE) == 0xE8)
break;
dest++;
if (++src != srcLim)
continue;
break;
}
dest++;
if (++src == srcLim)
break;
if ((*src & 0xF0) != 0x80)
continue;
*dest = *src;
break;
}
num = src - p->bufs[BCJ2_STREAM_MAIN];
if (src == srcLim)
{
p->temp[3] = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = src;
p->ip += (UInt32)num;
p->dest += num;
p->state =
p->bufs[BCJ2_STREAM_MAIN] ==
p->lims[BCJ2_STREAM_MAIN] ?
BCJ2_STREAM_MAIN :
BCJ2_DEC_STATE_ORIG;
return SZ_OK;
}
{
UInt32 bound, ttt;
CProb *prob;
Byte b = src[0];
Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
p->temp[3] = b;
p->bufs[BCJ2_STREAM_MAIN] = src + 1;
num++;
p->ip += (UInt32)num;
p->dest += num;
prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
_IF_BIT_0
{
_UPDATE_0
continue;
}
_UPDATE_1
}
}
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
outBuf[outPos++] = (Byte)dest;
if (outPos == outSize)
}
{
UInt32 val;
unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
const Byte *cur = p->bufs[cj];
Byte *dest;
SizeT rem;
if (cur == p->lims[cj])
{
p->state = cj;
break;
outBuf[outPos++] = (Byte)(dest >> 8);
if (outPos == outSize)
}
val = GetBe32(cur);
p->bufs[cj] = cur + 4;
p->ip += 4;
val -= p->ip;
dest = p->dest;
rem = p->destLim - dest;
if (rem < 4)
{
SizeT i;
SetUi32(p->temp, val);
for (i = 0; i < rem; i++)
dest[i] = p->temp[i];
p->dest = dest + rem;
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
break;
outBuf[outPos++] = (Byte)(dest >> 16);
if (outPos == outSize)
break;
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
}
SetUi32(dest, val);
p->temp[3] = (Byte)(val >> 24);
p->dest = dest + 4;
}
}
return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA;
if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
{
p->range <<= 8;
p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
}
return SZ_OK;
}

150
C/Bcj2.h
View File

@@ -1,5 +1,5 @@
/* Bcj2.h -- Converter for x86 code (BCJ2)
2013-01-18 : Igor Pavlov : Public domain */
/* Bcj2.h -- BCJ2 Converter for x86 code
2014-11-10 : Igor Pavlov : Public domain */
#ifndef __BCJ2_H
#define __BCJ2_H
@@ -8,26 +8,138 @@
EXTERN_C_BEGIN
#define BCJ2_NUM_STREAMS 4
enum
{
BCJ2_STREAM_MAIN,
BCJ2_STREAM_CALL,
BCJ2_STREAM_JUMP,
BCJ2_STREAM_RC
};
enum
{
BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
BCJ2_DEC_STATE_ORIG_1,
BCJ2_DEC_STATE_ORIG_2,
BCJ2_DEC_STATE_ORIG_3,
BCJ2_DEC_STATE_ORIG,
BCJ2_DEC_STATE_OK
};
enum
{
BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
BCJ2_ENC_STATE_OK
};
#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
/*
Conditions:
outSize <= FullOutputSize,
where FullOutputSize is full size of output stream of x86_2 filter.
If buf0 overlaps outBuf, there are two required conditions:
1) (buf0 >= outBuf)
2) (buf0 + size0 >= outBuf + FullOutputSize).
Returns:
SZ_OK
SZ_ERROR_DATA - Data error
CBcj2Dec / CBcj2Enc
bufs sizes:
BUF_SIZE(n) = lims[n] - bufs[n]
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
*/
int Bcj2_Decode(
const Byte *buf0, SizeT size0,
const Byte *buf1, SizeT size1,
const Byte *buf2, SizeT size2,
const Byte *buf3, SizeT size3,
Byte *outBuf, SizeT outSize);
/*
CBcj2Dec:
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
bufs[BCJ2_STREAM_MAIN] >= dest &&
bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
BUF_SIZE(BCJ2_STREAM_CALL) +
BUF_SIZE(BCJ2_STREAM_JUMP)
tempReserv = 0 : for first call of Bcj2Dec_Decode
tempReserv = 4 : for any other calls of Bcj2Dec_Decode
overlap with offset = 1 is not allowed
*/
typedef struct
{
const Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
Byte *dest;
const Byte *destLim;
unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
UInt32 ip;
Byte temp[4];
UInt32 range;
UInt32 code;
UInt16 probs[2 + 256];
} CBcj2Dec;
void Bcj2Dec_Init(CBcj2Dec *p);
/* Returns: SZ_OK or SZ_ERROR_DATA */
SRes Bcj2Dec_Decode(CBcj2Dec *p);
#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
typedef enum
{
BCJ2_ENC_FINISH_MODE_CONTINUE,
BCJ2_ENC_FINISH_MODE_END_BLOCK,
BCJ2_ENC_FINISH_MODE_END_STREAM
} EBcj2Enc_FinishMode;
typedef struct
{
Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
const Byte *src;
const Byte *srcLim;
unsigned state;
EBcj2Enc_FinishMode finishMode;
Byte prevByte;
Byte cache;
UInt32 range;
UInt64 low;
UInt64 cacheSize;
UInt32 ip;
/* 32-bit ralative offset in JUMP/CALL commands is
- (mod 4 GB) in 32-bit mode
- signed Int32 in 64-bit mode
We use (mod 4 GB) check for fileSize.
Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
UInt32 fileIp;
UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
UInt32 tempTarget;
unsigned tempPos;
Byte temp[4 * 2];
unsigned flushPos;
UInt16 probs[2 + 256];
} CBcj2Enc;
void Bcj2Enc_Init(CBcj2Enc *p);
void Bcj2Enc_Encode(CBcj2Enc *p);
#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
#define BCJ2_RELAT_LIMIT_NUM_BITS 26
#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
/* limit for CBcj2Enc::fileSize variable */
#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
EXTERN_C_END

312
C/Bcj2Enc.c Normal file
View File

@@ -0,0 +1,312 @@
/* Bcj2Enc.c -- BCJ2 Encoder (Converter for x86 code)
2014-11-10 : Igor Pavlov : Public domain */
#include "Precomp.h"
/* #define SHOW_STAT */
#ifdef SHOW_STAT
#include <stdio.h>
#define PRF(x) x
#else
#define PRF(x)
#endif
#include <windows.h>
#include <string.h>
#include "Bcj2.h"
#include "CpuArch.h"
#define CProb UInt16
#define kTopValue ((UInt32)1 << 24)
#define kNumModelBits 11
#define kBitModelTotal (1 << kNumModelBits)
#define kNumMoveBits 5
void Bcj2Enc_Init(CBcj2Enc *p)
{
unsigned i;
p->state = BCJ2_ENC_STATE_OK;
p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
p->prevByte = 0;
p->cache = 0;
p->range = 0xFFFFFFFF;
p->low = 0;
p->cacheSize = 1;
p->ip = 0;
p->fileIp = 0;
p->fileSize = 0;
p->relatLimit = BCJ2_RELAT_LIMIT;
p->tempPos = 0;
p->flushPos = 0;
for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
p->probs[i] = kBitModelTotal >> 1;
}
static Bool MY_FAST_CALL RangeEnc_ShiftLow(CBcj2Enc *p)
{
if ((UInt32)p->low < (UInt32)0xFF000000 || (UInt32)(p->low >> 32) != 0)
{
Byte *buf = p->bufs[BCJ2_STREAM_RC];
do
{
if (buf == p->lims[BCJ2_STREAM_RC])
{
p->state = BCJ2_STREAM_RC;
p->bufs[BCJ2_STREAM_RC] = buf;
return True;
}
*buf++ = (Byte)(p->cache + (Byte)(p->low >> 32));
p->cache = 0xFF;
}
while (--p->cacheSize);
p->bufs[BCJ2_STREAM_RC] = buf;
p->cache = (Byte)((UInt32)p->low >> 24);
}
p->cacheSize++;
p->low = (UInt32)p->low << 8;
return False;
}
static void Bcj2Enc_Encode_2(CBcj2Enc *p)
{
if (BCJ2_IS_32BIT_STREAM(p->state))
{
Byte *cur = p->bufs[p->state];
if (cur == p->lims[p->state])
return;
SetBe32(cur, p->tempTarget);
p->bufs[p->state] = cur + 4;
}
p->state = BCJ2_ENC_STATE_ORIG;
for (;;)
{
if (p->range < kTopValue)
{
if (RangeEnc_ShiftLow(p))
return;
p->range <<= 8;
}
{
{
const Byte *src = p->src;
const Byte *srcLim;
Byte *dest;
SizeT num = p->srcLim - src;
if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE)
{
if (num <= 4)
return;
num -= 4;
}
else if (num == 0)
break;
dest = p->bufs[BCJ2_STREAM_MAIN];
if (num > (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest))
{
num = p->lims[BCJ2_STREAM_MAIN] - dest;
if (num == 0)
{
p->state = BCJ2_STREAM_MAIN;
return;
}
}
srcLim = src + num;
if (p->prevByte == 0x0F && (src[0] & 0xF0) == 0x80)
*dest = src[0];
else for (;;)
{
Byte b = *src;
*dest = b;
if (b != 0x0F)
{
if ((b & 0xFE) == 0xE8)
break;
dest++;
if (++src != srcLim)
continue;
break;
}
dest++;
if (++src == srcLim)
break;
if ((*src & 0xF0) != 0x80)
continue;
*dest = *src;
break;
}
num = src - p->src;
if (src == srcLim)
{
p->prevByte = src[-1];
p->bufs[BCJ2_STREAM_MAIN] = dest;
p->src = src;
p->ip += (UInt32)num;
continue;
}
{
Byte context = (Byte)(num == 0 ? p->prevByte : src[-1]);
Bool needConvert;
p->bufs[BCJ2_STREAM_MAIN] = dest + 1;
p->ip += (UInt32)num + 1;
src++;
needConvert = False;
if ((SizeT)(p->srcLim - src) >= 4)
{
UInt32 relatVal = GetUi32(src);
if ((p->fileSize == 0 || (UInt32)(p->ip + 4 + relatVal - p->fileIp) < p->fileSize)
&& ((relatVal + p->relatLimit) >> 1) < p->relatLimit)
needConvert = True;
}
{
UInt32 bound;
unsigned ttt;
Byte b = src[-1];
CProb *prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)context : (b == 0xE9 ? 1 : 0));
ttt = *prob;
bound = (p->range >> kNumModelBits) * ttt;
if (!needConvert)
{
p->range = bound;
*prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
p->src = src;
p->prevByte = b;
continue;
}
p->low += bound;
p->range -= bound;
*prob = (CProb)(ttt - (ttt >> kNumMoveBits));
{
UInt32 relatVal = GetUi32(src);
UInt32 absVal;
p->ip += 4;
absVal = p->ip + relatVal;
p->prevByte = src[3];
src += 4;
p->src = src;
{
unsigned cj = (b == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
Byte *cur = p->bufs[cj];
if (cur == p->lims[cj])
{
p->state = cj;
p->tempTarget = absVal;
return;
}
SetBe32(cur, absVal);
p->bufs[cj] = cur + 4;
}
}
}
}
}
}
}
if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM)
return;
for (; p->flushPos < 5; p->flushPos++)
if (RangeEnc_ShiftLow(p))
return;
p->state = BCJ2_ENC_STATE_OK;
}
void Bcj2Enc_Encode(CBcj2Enc *p)
{
PRF(printf("\n"));
PRF(printf("---- ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
if (p->tempPos != 0)
{
unsigned extra = 0;
for (;;)
{
const Byte *src = p->src;
const Byte *srcLim = p->srcLim;
unsigned finishMode = p->finishMode;
p->src = p->temp;
p->srcLim = p->temp + p->tempPos;
if (src != srcLim)
p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE;
PRF(printf(" ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
Bcj2Enc_Encode_2(p);
{
unsigned num = (unsigned)(p->src - p->temp);
unsigned tempPos = p->tempPos - num;
unsigned i;
p->tempPos = tempPos;
for (i = 0; i < tempPos; i++)
p->temp[i] = p->temp[i + num];
p->src = src;
p->srcLim = srcLim;
p->finishMode = finishMode;
if (p->state != BCJ2_ENC_STATE_ORIG || src == srcLim)
return;
if (extra >= tempPos)
{
p->src = src - tempPos;
p->tempPos = 0;
break;
}
p->temp[tempPos] = src[0];
p->tempPos = tempPos + 1;
p->src = src + 1;
extra++;
}
}
}
PRF(printf("++++ ip = %8d tempPos = %8d src = %8d\n", p->ip, p->tempPos, p->srcLim - p->src));
Bcj2Enc_Encode_2(p);
if (p->state == BCJ2_ENC_STATE_ORIG)
{
const Byte *src = p->src;
unsigned rem = (unsigned)(p->srcLim - src);
unsigned i;
for (i = 0; i < rem; i++)
p->temp[i] = src[i];
p->tempPos = rem;
p->src = src + rem;
}
}

View File

@@ -1,5 +1,5 @@
/* Compiler.h -- Compiler ypes
2013-11-12 : Igor Pavlov : Public domain */
/* Compiler.h
2015-03-25 : Igor Pavlov : Public domain */
#ifndef __7Z_COMPILER_H
#define __7Z_COMPILER_H
@@ -25,4 +25,7 @@
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code
2012-05-29: Igor Pavlov : Public domain */
2015-03-25: Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -54,7 +54,7 @@ static UInt32 CheckFlag(UInt32 flag)
#define CHECK_CPUID_IS_SUPPORTED
#endif
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
{
#ifdef USE_ASM
@@ -116,7 +116,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
return True;
}
static UInt32 kVendors[][3] =
static const UInt32 kVendors[][3] =
{
{ 0x756E6547, 0x49656E69, 0x6C65746E},
{ 0x68747541, 0x69746E65, 0x444D4163},
@@ -144,18 +144,21 @@ Bool CPU_Is_InOrder()
UInt32 family, model;
if (!x86cpuid_CheckAndRead(&p))
return True;
family = x86cpuid_GetFamily(&p);
model = x86cpuid_GetModel(&p);
family = x86cpuid_GetFamily(p.ver);
model = x86cpuid_GetModel(p.ver);
firm = x86cpuid_GetFirm(&p);
switch (firm)
{
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
/* Atom CPU */
model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x2006 /* 45 nm, Z6xx */
|| model == 0x2007 /* 32 nm, Z2460 */
|| model == 0x3005 /* 32 nm, Z2760 */
|| model == 0x3006 /* 32 nm, N2xxx, D2xxx */
/* In-Order Atom CPU */
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|| model == 0x26 /* 45 nm, Z6xx */
|| model == 0x27 /* 32 nm, Z2460 */
|| model == 0x35 /* 32 nm, Z2760 */
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
)));
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2013-11-12: Igor Pavlov : Public domain */
2015-03-25: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -20,8 +20,11 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_AMD64
#endif
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
#define MY_CPU_64BIT
#if defined(MY_CPU_AMD64) \
|| defined(_M_IA64) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__)
#define MY_CPU_64BIT
#endif
#if defined(_M_IX86) || defined(__i386__)
@@ -32,8 +35,13 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_X86_OR_AMD64
#endif
#if defined(MY_CPU_X86) || defined(_M_ARM)
#define MY_CPU_32BIT
#if defined(MY_CPU_X86) \
|| defined(_M_ARM) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__)
#define MY_CPU_32BIT
#endif
#if defined(_WIN32) && defined(_M_ARM)
@@ -48,30 +56,49 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_LE_UNALIGN
#endif
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
#define MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL)
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE
#if defined(__BIG_ENDIAN__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__)
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
Stop_Compiling_Bad_Endian
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
#define SetUi16(p, v) *(UInt16 *)(p) = (v);
#define SetUi32(p, v) *(UInt32 *)(p) = (v);
#define SetUi64(p, v) *(UInt64 *)(p) = (v);
#else
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
#define GetUi16(p) ( (UInt16) ( \
((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \
((const Byte *)(p))[0] | \
@@ -81,23 +108,24 @@ Stop_Compiling_Bad_Endian
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#define SetUi16(p, d) { UInt32 _x_ = (d); \
((Byte *)(p))[0] = (Byte)_x_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, d) { UInt32 _x_ = (d); \
((Byte *)(p))[0] = (Byte)_x_; \
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); \
_ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); }
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
SetUi32(p, (UInt32)_x64_); \
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
#endif
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
#include <stdlib.h>
@@ -106,6 +134,8 @@ Stop_Compiling_Bad_Endian
#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)
#else
#define GetBe32(p) ( \
@@ -116,9 +146,19 @@ Stop_Compiling_Bad_Endian
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; }
#endif
#define GetBe16(p) ((UInt16)(((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1]))
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#ifdef MY_CPU_X86_OR_AMD64
@@ -140,12 +180,14 @@ enum
CPU_FIRM_VIA
};
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
int x86cpuid_GetFirm(const Cx86cpuid *p);
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
#define x86cpuid_GetStepping(ver) (ver & 0xF)
Bool CPU_Is_InOrder();
Bool CPU_Is_Aes_Supported();

View File

@@ -1,5 +1,5 @@
/* LzFind.c -- Match finder for LZ algorithms
2009-04-22 : Igor Pavlov : Public domain */
2015-05-15 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -12,7 +12,7 @@
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
#define kNormalizeMask (~(kNormalizeStepMin - 1))
#define kMaxHistorySize ((UInt32)3 << 30)
#define kMaxHistorySize ((UInt32)7 << 29)
#define kStartMaxLen 3
@@ -21,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
if (!p->directInput)
{
alloc->Free(alloc, p->bufferBase);
p->bufferBase = 0;
p->bufferBase = NULL;
}
}
@@ -35,17 +35,16 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a
p->blockSize = blockSize;
return 1;
}
if (p->bufferBase == 0 || p->blockSize != blockSize)
if (!p->bufferBase || p->blockSize != blockSize)
{
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
}
return (p->bufferBase != 0);
return (p->bufferBase != NULL);
}
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
@@ -60,6 +59,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
if (p->directInput)
{
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
@@ -71,12 +71,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
p->streamEndWasReached = 1;
return;
}
for (;;)
{
Byte *dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest);
if (size == 0)
return;
p->result = p->stream->Read(p->stream, dest, &size);
if (p->result != SZ_OK)
return;
@@ -94,8 +96,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
void MatchFinder_MoveBlock(CMatchFinder *p)
{
memmove(p->bufferBase,
p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
p->buffer = p->bufferBase + p->keepSizeBefore;
}
@@ -135,15 +137,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
void MatchFinder_Construct(CMatchFinder *p)
{
UInt32 i;
p->bufferBase = 0;
p->bufferBase = NULL;
p->directInput = 0;
p->hash = 0;
p->hash = NULL;
MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++)
{
UInt32 r = i;
int j;
unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r;
@@ -153,7 +155,7 @@ void MatchFinder_Construct(CMatchFinder *p)
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hash);
p->hash = 0;
p->hash = NULL;
}
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
@@ -162,11 +164,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
LzInWindow_Free(p, alloc);
}
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
return 0;
return NULL;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
}
@@ -175,19 +177,24 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
ISzAlloc *alloc)
{
UInt32 sizeReserv;
if (historySize > kMaxHistorySize)
{
MatchFinder_Free(p, alloc);
return 0;
}
sizeReserv = historySize >> 1;
if (historySize > ((UInt32)2 << 30))
sizeReserv = historySize >> 2;
if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
if (LzInWindow_Create(p, sizeReserv, alloc))
{
UInt32 newCyclicBufferSize = historySize + 1;
@@ -212,6 +219,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
hs = (1 << 24) - 1;
else
hs >>= 1;
/* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
}
}
p->hashMask = hs;
@@ -223,24 +231,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
}
{
UInt32 prevSize = p->hashSizeSum + p->numSons;
UInt32 newSize;
size_t newSize;
size_t numSons;
p->historySize = historySize;
p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize;
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
newSize = p->hashSizeSum + p->numSons;
if (p->hash != 0 && prevSize == newSize)
numSons = newCyclicBufferSize;
if (p->btMode)
numSons <<= 1;
newSize = hs + numSons;
if (p->hash && p->numRefs == newSize)
return 1;
MatchFinder_FreeThisClassMemory(p, alloc);
p->numRefs = newSize;
p->hash = AllocRefs(newSize, alloc);
if (p->hash != 0)
if (p->hash)
{
p->son = p->hash + p->hashSizeSum;
return 1;
}
}
}
MatchFinder_Free(p, alloc);
return 0;
}
@@ -249,9 +265,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
{
UInt32 limit = kMaxValForNormalize - p->pos;
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
if (limit2 < limit)
limit = limit2;
limit2 = p->streamPos - p->pos;
if (limit2 <= p->keepSizeAfter)
{
if (limit2 > 0)
@@ -259,8 +277,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
}
else
limit2 -= p->keepSizeAfter;
if (limit2 < limit)
limit = limit2;
{
UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
@@ -273,8 +293,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
void MatchFinder_Init(CMatchFinder *p)
{
UInt32 i;
for (i = 0; i < p->hashSizeSum; i++)
p->hash[i] = kEmptyHashValue;
UInt32 *hash = p->hash;
UInt32 num = p->hashSizeSum;
for (i = 0; i < num; i++)
hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize;
@@ -289,9 +312,9 @@ static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
return (p->pos - p->historySize - 1) & kNormalizeMask;
}
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems)
{
UInt32 i;
size_t i;
for (i = 0; i < numItems; i++)
{
UInt32 value = items[i];
@@ -306,7 +329,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
static void MatchFinder_Normalize(CMatchFinder *p)
{
UInt32 subValue = MatchFinder_GetSubValue(p);
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
MatchFinder_Normalize3(subValue, p->hash, p->numRefs);
MatchFinder_ReduceOffsets(p, subValue);
}
@@ -467,7 +490,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
cur = p->buffer;
@@ -483,13 +506,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
#define UPDATE_maxLen { \
ptrdiff_t diff = (ptrdiff_t)0 - d2; \
const Byte *c = cur + maxLen; \
const Byte *lim = cur + lenLimit; \
for (; c != lim; c++) if (*(c + diff) != *c) break; \
maxLen = (UInt32)(c - cur); }
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
curMatch = p->hash[hv];
p->hash[hv] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 1)
}
@@ -499,35 +529,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
curMatch = p->hash[hv];
p->hash[hv] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 2)
}
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 hash2Value, delta2, maxLen, offset;
UInt32 h2, d2, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(3)
HASH3_CALC;
delta2 = p->pos - p->hash[hash2Value];
curMatch = p->hash[kFix3HashSize + hashValue];
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
hash = p->hash;
pos = p->pos;
d2 = pos - hash[h2];
curMatch = hash[kFix3HashSize + hv];
hash[h2] = pos;
hash[kFix3HashSize + hv] = pos;
maxLen = 2;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
UPDATE_maxLen
distances[0] = maxLen;
distances[1] = delta2 - 1;
distances[1] = d2 - 1;
offset = 2;
if (maxLen == lenLimit)
{
@@ -535,44 +568,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
GET_MATCHES_FOOTER(offset, maxLen)
}
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
UInt32 h2, h3, d2, d3, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(4)
HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
hash = p->hash;
pos = p->pos;
maxLen = 1;
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
curMatch = hash[kFix4HashSize + hv];
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + hv] = pos;
maxLen = 0;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
distances[1] = d2 - 1;
offset = 2;
}
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
distances[offset + 1] = delta3 - 1;
distances[offset + 1] = d3 - 1;
offset += 2;
delta2 = delta3;
d2 = d3;
}
if (offset != 0)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
@@ -580,46 +620,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
if (maxLen < 3)
maxLen = 3;
GET_MATCHES_FOOTER(offset, maxLen)
}
/*
static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(5)
HASH5_CALC;
hash = p->hash;
pos = p->pos;
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
d4 = pos - hash[kFix4HashSize + h4];
curMatch = hash[kFix5HashSize + hv];
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + h4] = pos;
hash[kFix5HashSize + hv] = pos;
maxLen = 0;
offset = 0;
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = d2 - 1;
offset = 2;
if (*(cur - d2 + 2) == cur[2])
distances[0] = maxLen = 3;
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[2] = maxLen = 3;
distances[3] = d3 - 1;
offset = 4;
d2 = d3;
}
}
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[0] = maxLen = 3;
distances[1] = d3 - 1;
offset = 2;
d2 = d3;
}
if (d2 != d4 && d4 < p->cyclicBufferSize
&& *(cur - d4) == *cur
&& *(cur - d4 + 3) == *(cur + 3))
{
maxLen = 4;
distances[offset + 1] = d4 - 1;
offset += 2;
d2 = d4;
}
if (offset != 0)
{
UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
MOVE_POS_RET;
}
}
if (maxLen < 4)
maxLen = 4;
GET_MATCHES_FOOTER(offset, maxLen)
}
*/
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
UInt32 h2, h3, d2, d3, maxLen, offset, pos;
UInt32 *hash;
GET_MATCHES_HEADER(4)
HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
hash = p->hash;
pos = p->pos;
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
curMatch = hash[kFix4HashSize + hv];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + hv] = pos;
maxLen = 1;
maxLen = 0;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
distances[1] = d2 - 1;
offset = 2;
}
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
maxLen = 3;
distances[offset + 1] = delta3 - 1;
distances[offset + 1] = d3 - 1;
offset += 2;
delta2 = delta3;
d2 = d3;
}
if (offset != 0)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
@@ -627,22 +752,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
MOVE_POS_RET;
}
}
if (maxLen < 3)
maxLen = 3;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances));
distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
/*
static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos
UInt32 *hash;
GET_MATCHES_HEADER(5)
HASH5_CALC;
hash = p->hash;
pos = p->pos;
d2 = pos - hash[ h2];
d3 = pos - hash[kFix3HashSize + h3];
d4 = pos - hash[kFix4HashSize + h4];
curMatch = hash[kFix5HashSize + hv];
hash[ h2] = pos;
hash[kFix3HashSize + h3] = pos;
hash[kFix4HashSize + h4] = pos;
hash[kFix5HashSize + hv] = pos;
maxLen = 0;
offset = 0;
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = d2 - 1;
offset = 2;
if (*(cur - d2 + 2) == cur[2])
distances[0] = maxLen = 3;
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[2] = maxLen = 3;
distances[3] = d3 - 1;
offset = 4;
d2 = d3;
}
}
else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
{
distances[0] = maxLen = 3;
distances[1] = d3 - 1;
offset = 2;
d2 = d3;
}
if (d2 != d4 && d4 < p->cyclicBufferSize
&& *(cur - d4) == *cur
&& *(cur - d4 + 3) == *(cur + 3))
{
maxLen = 4;
distances[offset + 1] = d4 - 1;
offset += 2;
d2 = d4;
}
if (offset != 0)
{
UPDATE_maxLen
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS_RET;
}
}
if (maxLen < 4)
maxLen = 4;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
*/
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
curMatch = p->hash[hv];
p->hash[hv] = p->pos;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances, 2) - (distances));
distances, 2) - (distances));
MOVE_POS_RET
}
@@ -652,8 +858,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
SKIP_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
curMatch = p->hash[hv];
p->hash[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -665,8 +871,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
curMatch = p->hash[hv];
p->hash[hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -676,12 +882,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 hash2Value;
UInt32 h2;
UInt32 *hash;
SKIP_HEADER(3)
HASH3_CALC;
curMatch = p->hash[kFix3HashSize + hashValue];
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
hash = p->hash;
curMatch = hash[kFix3HashSize + hv];
hash[h2] =
hash[kFix3HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
@@ -691,43 +899,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 hash2Value, hash3Value;
UInt32 h2, h3;
UInt32 *hash;
SKIP_HEADER(4)
HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] = p->pos;
p->hash[kFix4HashSize + hashValue] = p->pos;
hash = p->hash;
curMatch = hash[kFix4HashSize + hv];
hash[ h2] =
hash[kFix3HashSize + h3] =
hash[kFix4HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
/*
static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 h2, h3, h4;
UInt32 *hash;
SKIP_HEADER(5)
HASH5_CALC;
hash = p->hash;
curMatch = hash[kFix5HashSize + hv];
hash[ h2] =
hash[kFix3HashSize + h3] =
hash[kFix4HashSize + h4] =
hash[kFix5HashSize + hv] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
*/
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 hash2Value, hash3Value;
UInt32 h2, h3;
UInt32 *hash;
SKIP_HEADER(4)
HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
hash = p->hash;
curMatch = hash[kFix4HashSize + hv];
hash[ h2] =
hash[kFix3HashSize + h3] =
hash[kFix4HashSize + hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
/*
static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 h2, h3, h4;
UInt32 *hash;
SKIP_HEADER(5)
HASH5_CALC;
hash = p->hash;
curMatch = p->hash[kFix5HashSize + hv];
hash[ h2] =
hash[kFix3HashSize + h3] =
hash[kFix4HashSize + h4] =
hash[kFix5HashSize + hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
*/
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
curMatch = p->hash[hv];
p->hash[hv] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
@@ -737,13 +992,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
if (!p->btMode)
{
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
/* if (p->numHashBytes <= 4) */
{
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
}
/*
else
{
vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip;
}
*/
}
else if (p->numHashBytes == 2)
{
@@ -755,9 +1019,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
}
else
else /* if (p->numHashBytes == 4) */
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
}
/*
else
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip;
}
*/
}

View File

@@ -1,5 +1,5 @@
/* LzFind.h -- Match finder for LZ algorithms
2013-01-18 : Igor Pavlov : Public domain */
2015-05-01 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H
#define __LZ_FIND_H
@@ -21,6 +21,11 @@ typedef struct _CMatchFinder
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
Byte streamEndWasReached;
Byte btMode;
Byte bigHash;
Byte directInput;
UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
@@ -29,27 +34,22 @@ typedef struct _CMatchFinder
Byte *bufferBase;
ISeqInStream *stream;
int streamEndWasReached;
UInt32 blockSize;
UInt32 keepSizeBefore;
UInt32 keepSizeAfter;
UInt32 numHashBytes;
int directInput;
size_t directInputRem;
int btMode;
int bigHash;
UInt32 historySize;
UInt32 fixedHashSize;
UInt32 hashSizeSum;
UInt32 numSons;
SRes result;
UInt32 crc[256];
size_t numRefs;
} CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
@@ -68,7 +68,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
@@ -82,7 +82,6 @@ Conditions:
*/
typedef void (*Mf_Init_Func)(void *object);
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
@@ -91,7 +90,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder
{
Mf_Init_Func Init;
Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;

View File

@@ -1,5 +1,5 @@
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
2014-12-29 : Igor Pavlov : Public domain */
2015-05-03 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -7,7 +7,7 @@
#include "LzFindMt.h"
void MtSync_Construct(CMtSync *p)
static void MtSync_Construct(CMtSync *p)
{
p->wasCreated = False;
p->csWasInitialized = False;
@@ -20,7 +20,7 @@ void MtSync_Construct(CMtSync *p)
Semaphore_Construct(&p->filledSemaphore);
}
void MtSync_GetNextBlock(CMtSync *p)
static void MtSync_GetNextBlock(CMtSync *p)
{
if (p->needStart)
{
@@ -48,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p)
/* MtSync_StopWriting must be called if Writing was started */
void MtSync_StopWriting(CMtSync *p)
static void MtSync_StopWriting(CMtSync *p)
{
UInt32 myNumBlocks = p->numProcessedBlocks;
if (!Thread_WasCreated(&p->thread) || p->needStart)
@@ -71,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p)
p->needStart = True;
}
void MtSync_Destruct(CMtSync *p)
static void MtSync_Destruct(CMtSync *p)
{
if (Thread_WasCreated(&p->thread))
{
@@ -134,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; }
#define kMtMaxValForNormalize 0xFFFFFFFF
#define DEF_GetHeads2(name, v, action) \
static void GetHeads ## name(const Byte *p, UInt32 pos, \
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
{ action; for (; numHeads != 0; numHeads--) { \
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
static void GetHeads ## name(const Byte *p, UInt32 pos, \
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
{ action; for (; numHeads != 0; numHeads--) { \
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), UNUSED_VAR(hashMask); UNUSED_VAR(crc); )
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
/* DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask) */
void HashThreadFunc(CMatchFinderMt *mt)
static void HashThreadFunc(CMatchFinderMt *mt)
{
CMtSync *p = &mt->hashSync;
for (;;)
@@ -192,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
{
UInt32 subValue = (mf->pos - mf->historySize - 1);
MatchFinder_ReduceOffsets(mf, subValue);
MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1);
}
{
UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -217,7 +217,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
}
}
void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
static void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
{
MtSync_GetNextBlock(&p->hashSync);
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
@@ -233,7 +233,7 @@ void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
#define NO_INLINE MY_FAST_CALL
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
static Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
{
@@ -310,12 +310,14 @@ Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CL
#endif
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{
UInt32 numProcessed = 0;
UInt32 curPos = 2;
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
distances[1] = p->hashNumAvail;
while (curPos < limit)
{
if (p->hashBufPos == p->hashBufPosLimit)
@@ -324,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
distances[1] = numProcessed + p->hashNumAvail;
if (p->hashNumAvail >= p->numHashBytes)
continue;
distances[0] = curPos + p->hashNumAvail;
distances += curPos;
for (; p->hashNumAvail != 0; p->hashNumAvail--)
distances[curPos++] = 0;
break;
*distances++ = 0;
return;
}
{
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
@@ -343,13 +347,14 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
if (size2 < size)
size = size2;
}
#ifndef MFMT_GM_INLINE
while (curPos < limit && size-- != 0)
{
UInt32 *startDistances = distances + curPos;
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
startDistances + 1, p->numHashBytes - 1) - startDistances);
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
startDistances + 1, p->numHashBytes - 1) - startDistances);
*startDistances = num - 1;
curPos += num;
cyclicBufferPos++;
@@ -360,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
{
UInt32 posRes;
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos), size, &posRes);
p->hashBufPos += posRes - pos;
cyclicBufferPos += posRes - pos;
p->buffer += posRes - pos;
@@ -376,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
p->cyclicBufferPos = cyclicBufferPos;
}
}
distances[0] = curPos;
}
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
{
CMtSync *sync = &p->hashSync;
if (!sync->needStart)
@@ -393,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
{
UInt32 subValue = p->pos - p->cyclicBufferSize;
MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
MatchFinder_Normalize3(subValue, p->son, (size_t)p->cyclicBufferSize * 2);
p->pos -= subValue;
}
@@ -432,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt)
void MatchFinderMt_Construct(CMatchFinderMt *p)
{
p->hashBuf = 0;
p->hashBuf = NULL;
MtSync_Construct(&p->hashSync);
MtSync_Construct(&p->btSync);
}
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hashBuf);
p->hashBuf = 0;
p->hashBuf = NULL;
}
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
@@ -457,9 +463,11 @@ static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { Has
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
{
Byte allocaDummy[0x180];
allocaDummy[0] = 0;
allocaDummy[1] = allocaDummy[0];
BtThreadFunc((CMatchFinderMt *)p);
unsigned i = 0;
for (i = 0; i < 16; i++)
allocaDummy[i] = (Byte)0;
if (allocaDummy[0] == 0)
BtThreadFunc((CMatchFinderMt *)p);
return 0;
}
@@ -470,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
p->historySize = historySize;
if (kMtBtBlockSize <= matchMaxLen * 4)
return SZ_ERROR_PARAM;
if (p->hashBuf == 0)
if (!p->hashBuf)
{
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
if (p->hashBuf == 0)
if (!p->hashBuf)
return SZ_ERROR_MEM;
p->btBuf = p->hashBuf + kHashBufferSize;
}
@@ -519,13 +527,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
/* p->MatchFinder->ReleaseStream(); */
}
void MatchFinderMt_Normalize(CMatchFinderMt *p)
static void MatchFinderMt_Normalize(CMatchFinderMt *p)
{
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
p->lzPos = p->historySize + 1;
}
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
{
UInt32 blockIndex;
MtSync_GetNextBlock(&p->btSync);
@@ -537,34 +545,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
MatchFinderMt_Normalize(p);
}
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
{
return p->pointerToCurPos;
}
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
static UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
{
GET_NEXT_BLOCK_IF_REQUIRED;
return p->btNumAvailBytes;
}
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
return p->pointerToCurPos[index];
}
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
UInt32 hash2Value, curMatch2;
UInt32 h2, curMatch2;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH2_CALC
curMatch2 = hash[hash2Value];
hash[hash2Value] = lzPos;
curMatch2 = hash[h2];
hash[h2] = lzPos;
if (curMatch2 >= matchMinPos)
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
@@ -572,23 +575,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 2;
*distances++ = lzPos - curMatch2 - 1;
}
return distances;
}
UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
static UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
UInt32 h2, h3, curMatch2, curMatch3;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH3_CALC
curMatch2 = hash[ hash2Value];
curMatch3 = hash[kFix3HashSize + hash3Value];
curMatch2 = hash[ h2];
curMatch3 = hash[kFix3HashSize + h3];
hash[ hash2Value] =
hash[kFix3HashSize + hash3Value] =
lzPos;
hash[ h2] = lzPos;
hash[kFix3HashSize + h3] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
@@ -601,43 +604,45 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
distances[0] = 2;
distances += 2;
}
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{
*distances++ = 3;
*distances++ = lzPos - curMatch3 - 1;
}
return distances;
}
/*
UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
{
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
UInt32 h2, h3, h4, curMatch2, curMatch3, curMatch4;
UInt32 *hash = p->hash;
const Byte *cur = p->pointerToCurPos;
UInt32 lzPos = p->lzPos;
MT_HASH4_CALC
curMatch2 = hash[ hash2Value];
curMatch3 = hash[kFix3HashSize + hash3Value];
curMatch4 = hash[kFix4HashSize + hash4Value];
curMatch2 = hash[ h2];
curMatch3 = hash[kFix3HashSize + h3];
curMatch4 = hash[kFix4HashSize + h4];
hash[ hash2Value] =
hash[kFix3HashSize + hash3Value] =
hash[kFix4HashSize + hash4Value] =
lzPos;
hash[ h2] = lzPos;
hash[kFix3HashSize + h3] = lzPos;
hash[kFix4HashSize + h4] = lzPos;
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
{
distances[1] = lzPos - curMatch2 - 1;
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
{
distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
return distances + 2;
}
distances[0] = 2;
distances += 2;
}
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
{
distances[1] = lzPos - curMatch3 - 1;
@@ -659,13 +664,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
*distances++ = 4;
*distances++ = lzPos - curMatch4 - 1;
}
return distances;
}
*/
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
static UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{
const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++;
@@ -683,7 +689,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
return len;
}
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
{
const UInt32 *btBuf = p->btBuf + p->btBufPos;
UInt32 len = *btBuf++;
@@ -691,6 +697,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
if (len == 0)
{
/* change for bt5 ! */
if (p->btNumAvailBytes-- >= 4)
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
}
@@ -706,7 +713,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
*distances2++ = *btBuf++;
}
while ((len -= 2) != 0);
len = (UInt32)(distances2 - (distances));
len = (UInt32)(distances2 - (distances));
}
INCREASE_LZ_POS
return len;
@@ -716,41 +723,41 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
static void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER2_MT { p->btNumAvailBytes--;
SKIP_FOOTER_MT
}
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(2)
UInt32 hash2Value;
UInt32 h2;
MT_HASH2_CALC
hash[hash2Value] = p->lzPos;
hash[h2] = p->lzPos;
SKIP_FOOTER_MT
}
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(3)
UInt32 hash2Value, hash3Value;
UInt32 h2, h3;
MT_HASH3_CALC
hash[kFix3HashSize + hash3Value] =
hash[ hash2Value] =
hash[kFix3HashSize + h3] =
hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
}
/*
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
{
SKIP_HEADER_MT(4)
UInt32 hash2Value, hash3Value, hash4Value;
UInt32 h2, h3, h4;
MT_HASH4_CALC
hash[kFix4HashSize + hash4Value] =
hash[kFix3HashSize + hash3Value] =
hash[ hash2Value] =
hash[kFix4HashSize + h4] =
hash[kFix3HashSize + h3] =
hash[ h2] =
p->lzPos;
SKIP_FOOTER_MT
}
@@ -759,11 +766,11 @@ void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
switch(p->MatchFinder->numHashBytes)
switch (p->MatchFinder->numHashBytes)
{
case 2:
p->GetHeadsFunc = GetHeads2;
@@ -779,7 +786,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
default:
/* case 4: */
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
/* p->GetHeadsFunc = GetHeads4; */
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
break;

View File

@@ -1,5 +1,5 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2013-01-18 : Igor Pavlov : Public domain */
2015-05-03 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_MT_H
#define __LZ_FIND_MT_H
@@ -75,7 +75,7 @@ typedef struct _CMatchFinderMt
UInt32 matchMaxLen;
UInt32 numHashBytes;
UInt32 pos;
Byte *buffer;
const Byte *buffer;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
UInt32 cutValue;

View File

@@ -1,5 +1,5 @@
/* LzHash.h -- HASH functions for LZ algorithms
2009-02-07 : Igor Pavlov : Public domain */
2015-04-12 : Igor Pavlov : Public domain */
#ifndef __LZ_HASH_H
#define __LZ_HASH_H
@@ -12,43 +12,46 @@
#define kFix4HashSize (kHash2Size + kHash3Size)
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
#define HASH2_CALC hv = cur[0] | ((UInt32)cur[1] << 8);
#define HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
h2 = temp & (kHash2Size - 1); \
hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
h2 = temp & (kHash2Size - 1); \
temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \
hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
hash4Value &= (kHash4Size - 1); }
h2 = temp & (kHash2Size - 1); \
temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \
temp ^= (p->crc[cur[3]] << 5); \
h4 = temp & (kHash4Size - 1); \
hv = (temp ^ (p->crc[cur[4]] << 3)) & p->hashMask; }
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
/* #define HASH_ZIP_CALC hv = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hv = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
h2 = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
h2 = temp & (kHash2Size - 1); \
h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
h2 = temp & (kHash2Size - 1); \
temp ^= ((UInt32)cur[2] << 8); \
h3 = temp & (kHash3Size - 1); \
h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
#endif

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder
2010-12-15 : Igor Pavlov : Public domain */
2014-10-29 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
@@ -99,7 +99,7 @@ void Lzma2Dec_Init(CLzma2Dec *p)
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{
switch(p->state)
switch (p->state)
{
case LZMA2_STATE_CONTROL:
p->control = b;
@@ -140,7 +140,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PROP:
{
int lc, lp;
unsigned lc, lp;
if (b >= (9 * 5 * 5))
return LZMA2_STATE_ERROR;
lc = b % 9;
@@ -179,13 +179,16 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
while (p->state != LZMA2_STATE_FINISHED)
{
SizeT dicPos = p->decoder.dicPos;
if (p->state == LZMA2_STATE_ERROR)
return SZ_ERROR_DATA;
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
{
*status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK;
}
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
{
if (*srcLen == inSize)
@@ -195,8 +198,15 @@ 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;
}
continue;
}
{
SizeT destSizeCur = dicLimit - dicPos;
SizeT srcSizeCur = inSize - *srcLen;
@@ -222,7 +232,10 @@ 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;
}
p->needInitDic = False;
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
}
@@ -231,7 +244,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
srcSizeCur = destSizeCur;
if (srcSizeCur == 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
@@ -247,17 +263,21 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (p->state == LZMA2_STATE_DATA)
{
int mode = LZMA2_GET_LZMA_MODE(p);
unsigned mode = LZMA2_GET_LZMA_MODE(p);
Bool initDic = (mode == 3);
Bool initState = (mode > 0);
Bool initState = (mode != 0);
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
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;
@@ -276,16 +296,22 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
if (srcSizeCur == 0 && outSizeProcessed == 0)
{
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
p->unpackSize != 0 || p->packSize != 0)
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|| p->unpackSize != 0
|| p->packSize != 0)
{
p->state = LZMA2_STATE_ERROR;
return SZ_ERROR_DATA;
}
p->state = LZMA2_STATE_CONTROL;
}
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
*status = LZMA_STATUS_NOT_FINISHED;
}
}
}
*status = LZMA_STATUS_FINISHED_WITH_MARK;
return SZ_OK;
}

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2013-01-18 : Igor Pavlov : Public domain */
2015-05-13 : Igor Pavlov : Public domain */
#ifndef __LZMA2_DEC_H
#define __LZMA2_DEC_H
@@ -15,7 +15,7 @@ typedef struct
CLzmaDec decoder;
UInt32 packSize;
UInt32 unpackSize;
int state;
unsigned state;
Byte control;
Bool needInitDic;
Bool needInitState;

View File

@@ -238,9 +238,9 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
if (temp > p->lzmaProps.reduceSize)
{
UInt64 numBlocks = temp / p->blockSize;
if (numBlocks < t2)
if (numBlocks < (unsigned)t2)
{
t2 = (UInt32)numBlocks;
t2 = (unsigned)numBlocks;
t3 = t1 * t2;
}
}

View File

@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder
2015-01-01 : Igor Pavlov : Public domain */
2015-05-14 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -114,14 +114,14 @@
#define Literal (RepLenCoder + kNumLenProbs)
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define LZMA_LIT_SIZE 0x300
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded.
@@ -133,8 +133,8 @@ Out:
p->remainLen:
< kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished
= kMatchSpecLenStart + 1 : Flush marker
= kMatchSpecLenStart + 2 : State Init Marker
= kMatchSpecLenStart + 1 : Flush marker (unused now)
= kMatchSpecLenStart + 2 : State Init Marker (unused now)
*/
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
@@ -172,9 +172,10 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
unsigned symbol;
UPDATE_0(prob);
prob = probs + Literal;
if (checkDicSize != 0 || processedPos != 0)
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
if (processedPos != 0 || checkDicSize != 0)
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
processedPos++;
if (state < kNumLitStates)
{
@@ -195,7 +196,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
else
{
unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
unsigned offs = 0x100;
state -= (state < 10) ? 3 : 6;
symbol = 1;
@@ -222,11 +223,11 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
#endif
}
dic[dicPos++] = (Byte)symbol;
processedPos++;
continue;
}
else
{
UPDATE_1(prob);
prob = probs + IsRep + state;
@@ -249,7 +250,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
IF_BIT_0(prob)
{
UPDATE_0(prob);
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
processedPos++;
state = state < kNumLitStates ? 9 : 11;
@@ -290,6 +291,8 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
state = state < kNumLitStates ? 8 : 11;
prob = probs + RepLenCoder;
}
#ifdef _LZMA_SIZE_OPT
{
unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice;
@@ -322,6 +325,42 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
TREE_DECODE(probLen, limit, len);
len += offset;
}
#else
{
CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
len -= 8;
}
else
{
UPDATE_1(probLen);
probLen = prob + LenChoice2;
IF_BIT_0(probLen)
{
UPDATE_0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
len = 1;
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
TREE_GET_BIT(probLen, len);
}
else
{
UPDATE_1(probLen);
probLen = prob + LenHigh;
TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
len += kLenNumLowSymbols + kLenNumMidSymbols;
}
}
}
#endif
if (state >= kNumStates)
{
@@ -332,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (distance >= kStartPosModelIndex)
{
unsigned posSlot = (unsigned)distance;
int numDirectBits = (int)(((distance >> 1) - 1));
unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
distance = (2 | (distance & 1));
if (posSlot < kEndPosModelIndex)
{
@@ -391,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
}
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
@@ -407,17 +447,21 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
len += kMatchMinLen;
if (limit == dicPos)
return SZ_ERROR_DATA;
{
SizeT rem = limit - dicPos;
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
SizeT rem;
unsigned curLen;
SizeT pos;
if ((rem = limit - dicPos) == 0)
return SZ_ERROR_DATA;
curLen = ((rem < len) ? (unsigned)rem : len);
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
processedPos += curLen;
len -= curLen;
if (pos + curLen <= dicBufSize)
if (curLen <= dicBufSize - pos)
{
Byte *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
@@ -441,7 +485,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
}
}
while (dicPos < limit && buf < bufLimit);
NORMALIZE;
p->buf = buf;
p->range = range;
p->code = code;
@@ -465,9 +511,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
SizeT dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize;
unsigned len = p->remainLen;
UInt32 rep0 = p->reps[0];
if (limit - dicPos < len)
len = (unsigned)(limit - dicPos);
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
SizeT rem = limit - dicPos;
if (rem < len)
len = (unsigned)(rem);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize;
@@ -477,7 +524,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
while (len != 0)
{
len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
dicPos++;
}
p->dicPos = dicPos;
@@ -495,17 +542,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem;
}
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
if (p->processedPos >= p->prop.dicSize)
if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
p->checkDicSize = p->prop.dicSize;
LzmaDec_WriteRem(p, limit);
}
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
if (p->remainLen > kMatchSpecLenStart)
{
p->remainLen = kMatchSpecLenStart;
}
return 0;
}
@@ -522,12 +571,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
UInt32 range = p->range;
UInt32 code = p->code;
const Byte *bufLimit = buf + inSize;
CLzmaProb *probs = p->probs;
const CLzmaProb *probs = p->probs;
unsigned state = p->state;
ELzmaDummy res;
{
CLzmaProb *prob;
const CLzmaProb *prob;
UInt32 bound;
unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
@@ -541,9 +590,9 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
prob += ((UInt32)LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
if (state < kNumLitStates)
{
@@ -553,13 +602,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
else
{
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
(p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
unsigned offs = 0x100;
unsigned symbol = 1;
do
{
unsigned bit;
CLzmaProb *probLit;
const CLzmaProb *probLit;
matchByte <<= 1;
bit = (matchByte & offs);
probLit = prob + offs + bit + symbol;
@@ -629,7 +678,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
{
unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice;
const CLzmaProb *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen)
{
UPDATE_0_CHECK;
@@ -669,7 +718,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
unsigned numDirectBits = ((posSlot >> 1) - 1);
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
@@ -708,13 +757,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
}
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
{
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
}
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
@@ -739,8 +781,8 @@ void LzmaDec_Init(CLzmaDec *p)
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
UInt32 i;
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
SizeT i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
@@ -762,7 +804,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{
int checkEndMarkNow;
if (p->needFlush != 0)
if (p->needFlush)
{
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++;
@@ -773,8 +815,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
}
if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA;
LzmaDec_InitRc(p, p->tempBuf);
p->code =
((UInt32)p->tempBuf[1] << 24)
| ((UInt32)p->tempBuf[2] << 16)
| ((UInt32)p->tempBuf[3] << 8)
| ((UInt32)p->tempBuf[4]);
p->range = 0xFFFFFFFF;
p->needFlush = 0;
p->tempBufSize = 0;
}
@@ -858,7 +905,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
return SZ_ERROR_DATA;
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
{
unsigned kkk = (unsigned)(p->buf - p->tempBuf);
if (rem < kkk)
return SZ_ERROR_FAIL; /* some internal error */
rem -= kkk;
if (lookAhead < rem)
return SZ_ERROR_FAIL; /* some internal error */
lookAhead -= rem;
}
(*srcLen) += lookAhead;
src += lookAhead;
inSize -= lookAhead;
@@ -913,13 +969,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->probs);
p->probs = 0;
p->probs = NULL;
}
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->dic);
p->dic = 0;
p->dic = NULL;
}
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
@@ -957,12 +1013,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
{
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
if (p->probs == 0 || numProbs != p->numProbs)
if (!p->probs || numProbs != p->numProbs)
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (p->probs == 0)
if (!p->probs)
return SZ_ERROR_MEM;
}
return SZ_OK;
@@ -983,12 +1039,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize)
{
UInt32 dictSize = propNew.dicSize;
SizeT mask = ((UInt32)1 << 12) - 1;
if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1;
else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;;
dicBufSize = ((SizeT)dictSize + mask) & ~mask;
if (dicBufSize < dictSize)
dicBufSize = dictSize;
}
if (!p->dic || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
if (p->dic == 0)
if (!p->dic)
{
LzmaDec_FreeProbs(p, alloc);
return SZ_ERROR_MEM;

View File

@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
2014-12-29 : Igor Pavlov : Public domain */
2015-05-15 Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -23,6 +23,9 @@
static unsigned g_STAT_OFFSET = 0;
#endif
#define kMaxHistorySize ((UInt32)3 << 29)
/* #define kMaxHistorySize ((UInt32)7 << 29) */
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
#define kBlockSize (9 << 10)
@@ -58,6 +61,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
int level = p->level;
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 > p->reduceSize)
{
@@ -68,14 +72,17 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
}
}
if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
if (p->numHashBytes < 0) p->numHashBytes = 4;
if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
if (p->numThreads < 0)
p->numThreads =
#ifndef _7ZIP_ST
@@ -92,17 +99,18 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
return props.dictSize;
}
#if (_MSC_VER >= 1400)
/* BSR code is fast for some new CPUs */
/* #define LZMA_LOG_BSR */
/* Define it for Intel's CPU */
#endif
#ifdef LZMA_LOG_BSR
#define kDicLogSizeMaxCompress 30
#define kDicLogSizeMaxCompress 32
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
UInt32 GetPosSlot1(UInt32 pos)
static UInt32 GetPosSlot1(UInt32 pos)
{
UInt32 res;
BSR2_RET(pos, res);
@@ -113,27 +121,44 @@ UInt32 GetPosSlot1(UInt32 pos)
#else
#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
#define kNumLogBits (9 + sizeof(size_t) / 2)
/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
void LzmaEnc_FastPosInit(Byte *g_FastPos)
static void LzmaEnc_FastPosInit(Byte *g_FastPos)
{
int c = 2, slotFast;
unsigned slot;
g_FastPos[0] = 0;
g_FastPos[1] = 1;
g_FastPos += 2;
for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
for (slot = 2; slot < kNumLogBits * 2; slot++)
{
UInt32 k = (1 << ((slotFast >> 1) - 1));
UInt32 j;
for (j = 0; j < k; j++, c++)
g_FastPos[c] = (Byte)slotFast;
size_t k = ((size_t)1 << ((slot >> 1) - 1));
size_t j;
for (j = 0; j < k; j++)
g_FastPos[j] = (Byte)slot;
g_FastPos += k;
}
}
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
/*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 2); }
*/
/*
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
res = p->g_FastPos[pos >> i] + (i * 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) { res = (pos < (1 << (kNumLogBits + 6))) ? \
p->g_FastPos[pos >> 6] + 12 : \
@@ -213,6 +238,7 @@ typedef struct
#define kNumStates 12
typedef struct
{
CLzmaProb choice;
@@ -222,14 +248,16 @@ typedef struct
CLzmaProb high[kLenNumHighSymbols];
} CLenEnc;
typedef struct
{
CLenEnc p;
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 tableSize;
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
UInt32 counters[LZMA_NUM_PB_STATES_MAX];
} CLenPriceEnc;
typedef struct
{
UInt32 range;
@@ -244,10 +272,14 @@ typedef struct
SRes res;
} CRangeEnc;
typedef struct
{
CLzmaProb *litProbs;
UInt32 state;
UInt32 reps[LZMA_NUM_REPS];
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates];
CLzmaProb isRepG0[kNumStates];
@@ -261,15 +293,49 @@ typedef struct
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
UInt32 reps[LZMA_NUM_REPS];
UInt32 state;
} CSaveState;
typedef struct
{
IMatchFinder matchFinder;
void *matchFinderObj;
IMatchFinder matchFinder;
UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex;
UInt32 longestMatchLength;
UInt32 numPairs;
UInt32 numAvail;
UInt32 numFastBytes;
UInt32 additionalOffset;
UInt32 reps[LZMA_NUM_REPS];
UInt32 state;
unsigned lc, lp, pb;
unsigned lpMask, pbMask;
unsigned lclp;
CLzmaProb *litProbs;
Bool fastMode;
Bool writeEndMark;
Bool finished;
Bool multiThread;
Bool needInit;
UInt64 nowPos64;
UInt32 matchPriceCount;
UInt32 alignPriceCount;
UInt32 distTableSize;
UInt32 dictSize;
SRes result;
CRangeEnc rc;
#ifndef _7ZIP_ST
Bool mtMode;
@@ -282,12 +348,6 @@ typedef struct
Byte pad[128];
#endif
UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex;
UInt32 longestMatchLength;
UInt32 numPairs;
UInt32 numAvail;
COptimal opt[kNumOpts];
#ifndef LZMA_LOG_BSR
@@ -296,22 +356,10 @@ typedef struct
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
UInt32 numFastBytes;
UInt32 additionalOffset;
UInt32 reps[LZMA_NUM_REPS];
UInt32 state;
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
UInt32 alignPrices[kAlignTableSize];
UInt32 alignPriceCount;
UInt32 distTableSize;
unsigned lc, lp, pb;
unsigned lpMask, pbMask;
CLzmaProb *litProbs;
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
CLzmaProb isRep[kNumStates];
@@ -327,26 +375,14 @@ typedef struct
CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc;
unsigned lclp;
Bool fastMode;
CRangeEnc rc;
Bool writeEndMark;
UInt64 nowPos64;
UInt32 matchPriceCount;
Bool finished;
Bool multiThread;
SRes result;
UInt32 dictSize;
int needInit;
CSaveState saveState;
#ifndef _7ZIP_ST
Byte pad2[128];
#endif
} CLzmaEnc;
void LzmaEnc_SaveState(CLzmaEncHandle pp)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
@@ -370,7 +406,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps));
memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb));
}
void LzmaEnc_RestoreState(CLzmaEncHandle pp)
@@ -396,7 +432,7 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp)
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
memcpy(dest->reps, p->reps, sizeof(p->reps));
memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb));
}
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
@@ -405,9 +441,13 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
CLzmaEncProps props = *props2;
LzmaEncProps_Normalize(&props);
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
if (props.lc > LZMA_LC_MAX
|| props.lp > LZMA_LP_MAX
|| props.pb > LZMA_PB_MAX
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|| props.dictSize > kMaxHistorySize)
return SZ_ERROR_PARAM;
p->dictSize = props.dictSize;
{
unsigned fb = props.fb;
@@ -421,7 +461,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
p->lp = props.lp;
p->pb = props.pb;
p->fastMode = (props.algo == 0);
p->matchFinderBase.btMode = props.btMode;
p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
{
UInt32 numHashBytes = 4;
if (props.btMode)
@@ -607,7 +647,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol,
while (symbol < 0x10000);
}
void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
{
UInt32 i;
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
@@ -643,7 +683,7 @@ void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= 0x100;
@@ -656,7 +696,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro
return price;
}
static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 offs = 0x100;
@@ -700,7 +740,7 @@ static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLeve
}
}
static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= (1 << numBitLevels);
@@ -712,7 +752,7 @@ static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 s
return price;
}
static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 m = 1;
@@ -763,7 +803,7 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posSt
}
}
static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices)
{
UInt32 a0 = GET_PRICE_0a(p->choice);
UInt32 a1 = GET_PRICE_1a(p->choice);
@@ -786,20 +826,20 @@ static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UIn
prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
}
static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices)
{
LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
p->counters[posState] = p->tableSize;
}
static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices)
{
UInt32 posState;
for (posState = 0; posState < numPosStates; posState++)
LenPriceEnc_UpdateTable(p, posState, ProbPrices);
}
static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices)
{
LenEnc_Encode(&p->p, rc, symbol, posState);
if (updatePrice)
@@ -845,14 +885,16 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
lenRes = p->matches[numPairs - 2];
if (lenRes == p->numFastBytes)
{
const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
UInt32 distance = p->matches[numPairs - 1] + 1;
UInt32 numAvail = p->numAvail;
if (numAvail > LZMA_MATCH_LEN_MAX)
numAvail = LZMA_MATCH_LEN_MAX;
{
const Byte *pby2 = pby - distance;
for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
const Byte *pby = pbyCur + lenRes;
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
const Byte *pbyLim = pbyCur + numAvail;
for (; pby != pbyLim && *pby == pby[dif]; pby++);
lenRes = (UInt32)(pby - pbyCur);
}
}
}
@@ -937,7 +979,7 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
return p->optimumCurrentIndex;
}
#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300)
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{
@@ -981,7 +1023,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest;
const Byte *data2;
reps[i] = p->reps[i];
data2 = data - (reps[i] + 1);
data2 = data - reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
{
repLens[i] = 0;
@@ -1282,7 +1324,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
/* try Literal + rep0 */
UInt32 temp;
UInt32 lenTest2;
const Byte *data2 = data - (reps[0] + 1);
const Byte *data2 = data - reps[0] - 1;
UInt32 limit = p->numFastBytes + 1;
if (limit > numAvailFull)
limit = numAvailFull;
@@ -1325,7 +1367,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
UInt32 lenTest;
UInt32 lenTestTemp;
UInt32 price;
const Byte *data2 = data - (reps[repIndex] + 1);
const Byte *data2 = data - reps[repIndex] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
@@ -1442,7 +1484,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
if (/*_maxMode && */lenTest == matches[offs])
{
/* Try Match + Literal + Rep0 */
const Byte *data2 = data - (curBack + 1);
const Byte *data2 = data - curBack - 1;
UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
@@ -1525,7 +1567,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++)
{
UInt32 len;
const Byte *data2 = data - (p->reps[i] + 1);
const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
for (len = 2; len < numAvail && data[len] == data2[len]; len++);
@@ -1594,7 +1636,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
for (i = 0; i < LZMA_NUM_REPS; i++)
{
UInt32 len, limit;
const Byte *data2 = data - (p->reps[i] + 1);
const Byte *data2 = data - p->reps[i] - 1;
if (data[0] != data2[0] || data[1] != data2[1])
continue;
limit = mainLen - 1;
@@ -1690,6 +1732,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
{
RangeEnc_Construct(&p->rc);
MatchFinder_Construct(&p->matchFinderBase);
#ifndef _7ZIP_ST
MatchFinderMt_Construct(&p->matchFinderMt);
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
@@ -1732,6 +1775,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
#ifndef _7ZIP_ST
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
#endif
MatchFinder_Free(&p->matchFinderBase, allocBig);
LzmaEnc_FreeLits(p, alloc);
RangeEnc_Free(&p->rc, alloc);
@@ -1768,7 +1812,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
ReadMatchDistances(p, &numPairs);
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
p->state = kLiteralNextStates[p->state];
curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
LitEnc_Encode(&p->rc, p->litProbs, curByte);
p->additionalOffset--;
nowPos32++;
@@ -1894,7 +1938,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
break;
}
else if (processed >= (1 << 15))
else if (processed >= (1 << 17))
{
p->nowPos64 += nowPos32 - startPos32;
return CheckErrors(p);
@@ -1912,6 +1956,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
UInt32 beforeSize = kNumOpts;
if (!RangeEnc_Alloc(&p->rc, alloc))
return SZ_ERROR_MEM;
#ifndef _7ZIP_ST
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
#endif
@@ -1921,8 +1966,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
{
LzmaEnc_FreeLits(p, alloc);
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
if (p->litProbs == 0 || p->saveState.litProbs == 0)
{
LzmaEnc_FreeLits(p, alloc);
@@ -1932,7 +1977,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
}
}
p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
if (beforeSize + p->dictSize < keepWindowSize)
beforeSize = keepWindowSize - p->dictSize;
@@ -1952,6 +1997,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
p->matchFinderObj = &p->matchFinderBase;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
}
return SZ_OK;
}
@@ -1980,9 +2026,10 @@ void LzmaEnc_Init(CLzmaEnc *p)
}
{
UInt32 num = 0x300 << (p->lp + p->lc);
UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
CLzmaProb *probs = p->litProbs;
for (i = 0; i < num; i++)
p->litProbs[i] = kProbInitValue;
probs[i] = kProbInitValue;
}
{
@@ -2089,7 +2136,7 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
if (p->mtMode)
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
#else
pp = pp;
UNUSED_VAR(pp);
#endif
}
@@ -2201,25 +2248,23 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
int i;
unsigned i;
UInt32 dictSize = p->dictSize;
if (*size < LZMA_PROPS_SIZE)
return SZ_ERROR_PARAM;
*size = LZMA_PROPS_SIZE;
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
for (i = 11; i <= 30; i++)
if (dictSize >= ((UInt32)1 << 22))
{
if (dictSize <= ((UInt32)2 << i))
{
dictSize = (2 << i);
break;
}
if (dictSize <= ((UInt32)3 << i))
{
dictSize = (3 << i);
break;
}
UInt32 kDictMask = ((UInt32)1 << 20) - 1;
if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
dictSize = (dictSize + kDictMask) & ~kDictMask;
}
else for (i = 11; i <= 30; i++)
{
if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; }
if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; }
}
for (i = 0; i < 4; i++)

View File

@@ -1,18 +1,12 @@
/* LzmaLib.c -- LZMA library wrapper
2008-08-05
Igor Pavlov
Public domain */
2015-06-13 : Igor Pavlov : Public domain */
#include "LzmaEnc.h"
#include "LzmaDec.h"
#include "Alloc.h"
#include "LzmaDec.h"
#include "LzmaEnc.h"
#include "LzmaLib.h"
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize,
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
@@ -38,7 +32,7 @@ MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned cha
}
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize)
{
ELzmaStatus status;

View File

@@ -1,5 +1,5 @@
/* RotateDefs.h -- Rotate functions
2013-11-12 : Igor Pavlov : Public domain */
2015-03-25 : Igor Pavlov : Public domain */
#ifndef __ROTATE_DEFS_H
#define __ROTATE_DEFS_H
@@ -8,16 +8,20 @@
#include <stdlib.h>
// #if (_MSC_VER >= 1200)
/* don't use _rotl with MINGW. It can insert slow call to function. */
/* #if (_MSC_VER >= 1200) */
#pragma intrinsic(_rotl)
#pragma intrinsic(_rotr)
// #endif
/* #endif */
#define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n))
#else
/* new compilers can translate these macros to fast commands. */
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))

334
C/Sha1.c Normal file
View File

@@ -0,0 +1,334 @@
/* Sha1.c -- SHA-1 Hash
2015-05-10 : Igor Pavlov : Public domain
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
#include "Precomp.h"
#include <string.h>
#include "CpuArch.h"
#include "RotateDefs.h"
#include "Sha1.h"
// define it for speed optimization
// #define _SHA1_UNROLL
#ifdef _SHA1_UNROLL
#define kNumW 16
#define WW(i) W[(i)&15]
#else
#define kNumW 80
#define WW(i) W[i]
#endif
#define w0(i) (W[i] = data[i])
#define w1(i) (WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1))
#define f1(x,y,z) (z^(x&(y^z)))
#define f2(x,y,z) (x^y^z)
#define f3(x,y,z) ((x&y)|(z&(x|y)))
#define f4(x,y,z) (x^y^z)
#define RK(a,b,c,d,e, fx, w, k) e += fx(b,c,d) + w + k + rotlFixed(a,5); b = rotlFixed(b,30);
#define R0(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w0(i), 0x5A827999)
#define R1(a,b,c,d,e, i) RK(a,b,c,d,e, f1, w1(i), 0x5A827999)
#define R2(a,b,c,d,e, i) RK(a,b,c,d,e, f2, w1(i), 0x6ED9EBA1)
#define R3(a,b,c,d,e, i) RK(a,b,c,d,e, f3, w1(i), 0x8F1BBCDC)
#define R4(a,b,c,d,e, i) RK(a,b,c,d,e, f4, w1(i), 0xCA62C1D6)
#define RX_1_4(rx1, rx4, i) \
rx1(a,b,c,d,e, i); \
rx4(e,a,b,c,d, i+1); \
rx4(d,e,a,b,c, i+2); \
rx4(c,d,e,a,b, i+3); \
rx4(b,c,d,e,a, i+4); \
#define RX_5(rx, i) RX_1_4(rx, rx, i);
#ifdef _SHA1_UNROLL
#define RX_15 \
RX_5(R0, 0); \
RX_5(R0, 5); \
RX_5(R0, 10);
#define RX_20(rx, i) \
RX_5(rx, i); \
RX_5(rx, i + 5); \
RX_5(rx, i + 10); \
RX_5(rx, i + 15);
#else
#define RX_15 { unsigned i; for (i = 0; i < 15; i += 5) { RX_5(R0, i); } }
#define RX_20(rx, ii) { unsigned i; i = ii; for (; i < ii + 20; i += 5) { RX_5(rx, i); } }
#endif
void Sha1_Init(CSha1 *p)
{
p->state[0] = 0x67452301;
p->state[1] = 0xEFCDAB89;
p->state[2] = 0x98BADCFE;
p->state[3] = 0x10325476;
p->state[4] = 0xC3D2E1F0;
p->count = 0;
}
void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest)
{
UInt32 a, b, c, d, e;
UInt32 W[kNumW];
a = p->state[0];
b = p->state[1];
c = p->state[2];
d = p->state[3];
e = p->state[4];
RX_15
RX_1_4(R0, R1, 15);
RX_20(R2, 20);
RX_20(R3, 40);
RX_20(R4, 60);
destDigest[0] = p->state[0] + a;
destDigest[1] = p->state[1] + b;
destDigest[2] = p->state[2] + c;
destDigest[3] = p->state[3] + d;
destDigest[4] = p->state[4] + e;
}
void Sha1_UpdateBlock_Rar(CSha1 *p, UInt32 *data, int returnRes)
{
UInt32 a, b, c, d, e;
UInt32 W[kNumW];
a = p->state[0];
b = p->state[1];
c = p->state[2];
d = p->state[3];
e = p->state[4];
RX_15
RX_1_4(R0, R1, 15);
RX_20(R2, 20);
RX_20(R3, 40);
RX_20(R4, 60);
p->state[0] += a;
p->state[1] += b;
p->state[2] += c;
p->state[3] += d;
p->state[4] += e;
if (returnRes)
{
unsigned i;
for (i = 0 ; i < SHA1_NUM_BLOCK_WORDS; i++)
data[i] = W[kNumW - SHA1_NUM_BLOCK_WORDS + i];
}
}
#define Sha1_UpdateBlock(p) Sha1_GetBlockDigest(p, p->buffer, p->state)
void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
{
unsigned pos, pos2;
if (size == 0)
return;
pos = (unsigned)p->count & 0x3F;
p->count += size;
pos2 = pos & 3;
pos >>= 2;
if (pos2 != 0)
{
UInt32 w = ((UInt32)data[0]) << 24;
if (--size && pos2 < 3)
{
w |= ((UInt32)data[1]) << 16;
if (--size && pos2 < 2)
{
w |= ((UInt32)data[2]) << 8;
--size;
}
}
data += 4 - pos2;
p->buffer[pos++] |= (w >> (8 * pos2));
}
for (;;)
{
if (pos == SHA1_NUM_BLOCK_WORDS)
{
for (;;)
{
unsigned i;
Sha1_UpdateBlock(p);
if (size < SHA1_BLOCK_SIZE)
break;
size -= SHA1_BLOCK_SIZE;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i += 2)
{
p->buffer[i ] = GetBe32(data);
p->buffer[i + 1] = GetBe32(data + 4);
data += 8;
}
}
pos = 0;
}
if (size < 4)
break;
p->buffer[pos] = GetBe32(data);
data += 4;
size -= 4;
pos++;
}
if (size != 0)
{
UInt32 w = ((UInt32)data[0]) << 24;
if (size > 1)
{
w |= ((UInt32)data[1]) << 16;
if (size > 2)
w |= ((UInt32)data[2]) << 8;
}
p->buffer[pos] = w;
}
}
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode)
{
int returnRes = False;
unsigned pos = (unsigned)p->count & 0x3F;
p->count += size;
while (size--)
{
unsigned pos2 = (pos & 3);
UInt32 v = ((UInt32)*data++) << (8 * (3 - pos2));
UInt32 *ref = &(p->buffer[pos >> 2]);
pos++;
if (pos2 == 0)
{
*ref = v;
continue;
}
*ref |= v;
if (pos == SHA1_BLOCK_SIZE)
{
pos = 0;
Sha1_UpdateBlock_Rar(p, p->buffer, returnRes);
if (returnRes)
{
unsigned i;
for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
{
UInt32 d = p->buffer[i];
Byte *prev = data + i * 4 - SHA1_BLOCK_SIZE;
SetUi32(prev, d);
}
}
returnRes = rar350Mode;
}
}
}
void Sha1_Final(CSha1 *p, Byte *digest)
{
unsigned pos = (unsigned)p->count & 0x3F;
unsigned pos2 = (pos & 3);
UInt64 numBits;
UInt32 w;
unsigned i;
pos >>= 2;
w = 0;
if (pos2 != 0)
w = p->buffer[pos];
p->buffer[pos++] = w | (((UInt32)0x80000000) >> (8 * pos2));
while (pos != (SHA1_NUM_BLOCK_WORDS - 2))
{
pos &= 0xF;
if (pos == 0)
Sha1_UpdateBlock(p);
p->buffer[pos++] = 0;
}
numBits = (p->count << 3);
p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
Sha1_UpdateBlock(p);
for (i = 0; i < SHA1_NUM_DIGEST_WORDS; i++)
{
UInt32 v = p->state[i];
SetBe32(digest, v);
digest += 4;
}
Sha1_Init(p);
}
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size)
{
const UInt64 numBits = (p->count + size) << 5;
block[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
block[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
block[size++] = 0x80000000;
while (size != (SHA1_NUM_BLOCK_WORDS - 2))
block[size++] = 0;
}
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size)
{
unsigned pos = (unsigned)p->count & 0xF;
p->count += size;
while (size--)
{
p->buffer[pos++] = *data++;
if (pos == SHA1_NUM_BLOCK_WORDS)
{
pos = 0;
Sha1_UpdateBlock(p);
}
}
}
void Sha1_32_Final(CSha1 *p, UInt32 *digest)
{
UInt64 numBits;
unsigned pos = (unsigned)p->count & 0xF;
p->buffer[pos++] = 0x80000000;
while (pos != (SHA1_NUM_BLOCK_WORDS - 2))
{
pos &= 0xF;
if (pos == 0)
Sha1_UpdateBlock(p);
p->buffer[pos++] = 0;
}
numBits = (p->count << 5);
p->buffer[SHA1_NUM_BLOCK_WORDS - 2] = (UInt32)(numBits >> 32);
p->buffer[SHA1_NUM_BLOCK_WORDS - 1] = (UInt32)(numBits);
Sha1_GetBlockDigest(p, p->buffer, digest);
Sha1_Init(p);
}

38
C/Sha1.h Normal file
View File

@@ -0,0 +1,38 @@
/* Sha1.h -- SHA-1 Hash
2015-03-04 : Igor Pavlov : Public domain */
#ifndef __7Z_SHA1_H
#define __7Z_SHA1_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define SHA1_NUM_BLOCK_WORDS 16
#define SHA1_NUM_DIGEST_WORDS 5
#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4)
#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4)
typedef struct
{
UInt32 state[SHA1_NUM_DIGEST_WORDS];
UInt64 count;
UInt32 buffer[SHA1_NUM_BLOCK_WORDS];
} CSha1;
void Sha1_Init(CSha1 *p);
void Sha1_GetBlockDigest(CSha1 *p, const UInt32 *data, UInt32 *destDigest);
void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
void Sha1_Final(CSha1 *p, Byte *digest);
void Sha1_Update_Rar(CSha1 *p, Byte *data, size_t size, int rar350Mode);
void Sha1_32_PrepareBlock(const CSha1 *p, UInt32 *block, unsigned size);
void Sha1_32_Update(CSha1 *p, const UInt32 *data, size_t size);
void Sha1_32_Final(CSha1 *p, UInt32 *digest);
EXTERN_C_END
#endif

View File

@@ -1,14 +1,21 @@
/* Crypto/Sha256.c -- SHA-256 Hash
2010-06-11 : Igor Pavlov : Public domain
2015-03-02 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h"
#include <string.h>
#include "CpuArch.h"
#include "RotateDefs.h"
#include "Sha256.h"
/* define it for speed optimization */
/* #define _SHA256_UNROLL */
#ifndef _SFX
#define _SHA256_UNROLL
#define _SHA256_UNROLL2
#endif
/* #define _SHA256_UNROLL2 */
void Sha256_Init(CSha256 *p)
@@ -29,26 +36,18 @@ void Sha256_Init(CSha256 *p)
#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
#define blk0(i) (W[i] = data[i])
#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
#define blk0(i) (W[i])
#define blk2(i) (W[i] += s1(W[((i)-2)&15]) + W[((i)-7)&15] + s0(W[((i)-15)&15]))
#define Ch(x,y,z) (z^(x&(y^z)))
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
#define a(i) T[(0-(i))&7]
#define b(i) T[(1-(i))&7]
#define c(i) T[(2-(i))&7]
#define d(i) T[(3-(i))&7]
#define e(i) T[(4-(i))&7]
#define f(i) T[(5-(i))&7]
#define g(i) T[(6-(i))&7]
#define h(i) T[(7-(i))&7]
#ifdef _SHA256_UNROLL2
#define R(a,b,c,d,e,f,g,h, i) h += S1(e) + Ch(e,f,g) + K[i+j] + (j?blk2(i):blk0(i));\
d += h; h += S0(a) + Maj(a, b, c)
#define R(a,b,c,d,e,f,g,h, i) \
h += S1(e) + Ch(e,f,g) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
d += h; \
h += S0(a) + Maj(a, b, c)
#define RX_8(i) \
R(a,b,c,d,e,f,g,h, i); \
@@ -60,14 +59,32 @@ void Sha256_Init(CSha256 *p)
R(c,d,e,f,g,h,a,b, i+6); \
R(b,c,d,e,f,g,h,a, i+7)
#define RX_16 RX_8(0); RX_8(8);
#else
#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
#define a(i) T[(0-(i))&7]
#define b(i) T[(1-(i))&7]
#define c(i) T[(2-(i))&7]
#define d(i) T[(3-(i))&7]
#define e(i) T[(4-(i))&7]
#define f(i) T[(5-(i))&7]
#define g(i) T[(6-(i))&7]
#define h(i) T[(7-(i))&7]
#define R(i) \
h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+(j)] + (j ? blk2(i) : blk0(i)); \
d(i) += h(i); \
h(i) += S0(a(i)) + Maj(a(i), b(i), c(i)) \
#ifdef _SHA256_UNROLL
#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
#define RX_8(i) R(i+0); R(i+1); R(i+2); R(i+3); R(i+4); R(i+5); R(i+6); R(i+7);
#define RX_16 RX_8(0); RX_8(8);
#else
#define RX_16 unsigned i; for (i = 0; i < 16; i++) { R(i); }
#endif
@@ -92,10 +109,12 @@ static const UInt32 K[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
static void Sha256_Transform(UInt32 *state, const UInt32 *data)
static void Sha256_WriteByteBlock(CSha256 *p)
{
UInt32 W[16];
unsigned j;
UInt32 *state = p->state;
#ifdef _SHA256_UNROLL2
UInt32 a,b,c,d,e,f,g,h;
a = state[0];
@@ -112,14 +131,15 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
T[j] = state[j];
#endif
for (j = 0; j < 16; j += 2)
{
W[j ] = GetBe32(p->buffer + j * 4);
W[j + 1] = GetBe32(p->buffer + j * 4 + 4);
}
for (j = 0; j < 64; j += 16)
{
#if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
RX_8(0); RX_8(8);
#else
unsigned i;
for (i = 0; i < 16; i++) { R(i); }
#endif
RX_16
}
#ifdef _SHA256_UNROLL2
@@ -146,61 +166,72 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
#undef s0
#undef s1
static void Sha256_WriteByteBlock(CSha256 *p)
{
UInt32 data32[16];
unsigned i;
for (i = 0; i < 16; i++)
data32[i] =
((UInt32)(p->buffer[i * 4 ]) << 24) +
((UInt32)(p->buffer[i * 4 + 1]) << 16) +
((UInt32)(p->buffer[i * 4 + 2]) << 8) +
((UInt32)(p->buffer[i * 4 + 3]));
Sha256_Transform(p->state, data32);
}
void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
{
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
while (size > 0)
if (size == 0)
return;
{
p->buffer[curBufferPos++] = *data++;
p->count++;
size--;
if (curBufferPos == 64)
unsigned pos = (unsigned)p->count & 0x3F;
unsigned num;
p->count += size;
num = 64 - pos;
if (num > size)
{
curBufferPos = 0;
Sha256_WriteByteBlock(p);
memcpy(p->buffer + pos, data, size);
return;
}
size -= num;
memcpy(p->buffer + pos, data, num);
data += num;
}
for (;;)
{
Sha256_WriteByteBlock(p);
if (size < 64)
break;
size -= 64;
memcpy(p->buffer, data, 64);
data += 64;
}
if (size != 0)
memcpy(p->buffer, data, size);
}
void Sha256_Final(CSha256 *p, Byte *digest)
{
UInt64 lenInBits = (p->count << 3);
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
unsigned pos = (unsigned)p->count & 0x3F;
unsigned i;
p->buffer[curBufferPos++] = 0x80;
while (curBufferPos != (64 - 8))
p->buffer[pos++] = 0x80;
while (pos != (64 - 8))
{
curBufferPos &= 0x3F;
if (curBufferPos == 0)
pos &= 0x3F;
if (pos == 0)
Sha256_WriteByteBlock(p);
p->buffer[curBufferPos++] = 0;
p->buffer[pos++] = 0;
}
for (i = 0; i < 8; i++)
{
p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
lenInBits <<= 8;
UInt64 numBits = (p->count << 3);
SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
}
Sha256_WriteByteBlock(p);
for (i = 0; i < 8; i++)
{
*digest++ = (Byte)(p->state[i] >> 24);
*digest++ = (Byte)(p->state[i] >> 16);
*digest++ = (Byte)(p->state[i] >> 8);
*digest++ = (Byte)(p->state[i]);
UInt32 v = p->state[i];
SetBe32(digest, v);
digest += 4;
}
Sha256_Init(p);
}

View File

@@ -1,9 +1,9 @@
/* Threads.c -- multithreading library
2013-11-12 : Igor Pavlov : Public domain */
2014-09-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
#ifndef _WIN32_WCE
#ifndef UNDER_CE
#include <process.h>
#endif

View File

@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAs /Yu"Precomp.h" /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /FAcs /Yu"Precomp.h" /FD /c
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
@@ -165,6 +165,10 @@ SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
SOURCE=..\..\BraIA64.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
@@ -173,6 +177,14 @@ SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\Delta.c
# End Source File
# Begin Source File
SOURCE=..\..\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File

View File

@@ -1,5 +1,5 @@
/* 7zMain.c - Test application for 7z Decoder
2015-01-02 : Igor Pavlov : Public domain */
2015-05-11 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -34,75 +34,117 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
}
#ifndef _WIN32
#define _USE_UTF8
#endif
static Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
/* #define _USE_UTF8 */
static Bool Utf16_To_Utf8(Byte *dest, size_t *destLen, const UInt16 *src, size_t srcLen)
#ifdef _USE_UTF8
#define _UTF8_START(n) (0x100 - (1 << (7 - (n))))
#define _UTF8_RANGE(n) (((UInt32)1) << ((n) * 5 + 6))
#define _UTF8_HEAD(n, val) ((Byte)(_UTF8_START(n) + (val >> (6 * (n)))))
#define _UTF8_CHAR(n, val) ((Byte)(0x80 + (((val) >> (6 * (n))) & 0x3F)))
static size_t Utf16_To_Utf8_Calc(const UInt16 *src, const UInt16 *srcLim)
{
size_t destPos = 0, srcPos = 0;
size_t size = 0;
for (;;)
{
unsigned numAdds;
UInt32 value;
if (srcPos == srcLen)
UInt32 val;
if (src == srcLim)
return size;
size++;
val = *src++;
if (val < 0x80)
continue;
if (val < _UTF8_RANGE(1))
{
*destLen = destPos;
return True;
}
value = src[srcPos++];
if (value < 0x80)
{
if (dest)
dest[destPos] = (char)value;
destPos++;
size++;
continue;
}
if (value >= 0xD800 && value < 0xE000)
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
UInt32 c2;
if (value >= 0xDC00 || srcPos == srcLen)
break;
c2 = src[srcPos++];
if (c2 < 0xDC00 || c2 >= 0xE000)
break;
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
UInt32 c2 = *src;
if (c2 >= 0xDC00 && c2 < 0xE000)
{
src++;
size += 3;
continue;
}
}
for (numAdds = 1; numAdds < 5; numAdds++)
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
break;
if (dest)
dest[destPos] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
destPos++;
do
{
numAdds--;
if (dest)
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
destPos++;
}
while (numAdds != 0);
size += 2;
}
}
static Byte *Utf16_To_Utf8(Byte *dest, const UInt16 *src, const UInt16 *srcLim)
{
for (;;)
{
UInt32 val;
if (src == srcLim)
return dest;
val = *src++;
if (val < 0x80)
{
*dest++ = (char)val;
continue;
}
if (val < _UTF8_RANGE(1))
{
dest[0] = _UTF8_HEAD(1, val);
dest[1] = _UTF8_CHAR(0, val);
dest += 2;
continue;
}
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
{
UInt32 c2 = *src;
if (c2 >= 0xDC00 && c2 < 0xE000)
{
src++;
val = (((val - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
dest[0] = _UTF8_HEAD(3, val);
dest[1] = _UTF8_CHAR(2, val);
dest[2] = _UTF8_CHAR(1, val);
dest[3] = _UTF8_CHAR(0, val);
dest += 4;
continue;
}
}
dest[0] = _UTF8_HEAD(2, val);
dest[1] = _UTF8_CHAR(1, val);
dest[2] = _UTF8_CHAR(0, val);
dest += 3;
}
*destLen = destPos;
return False;
}
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
{
size_t destLen = 0;
Bool res;
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
destLen += 1;
if (!Buf_EnsureSize(dest, destLen))
return SZ_ERROR_MEM;
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
dest->data[destLen] = 0;
return res ? SZ_OK : SZ_ERROR_FAIL;
*Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
return SZ_OK;
}
#endif
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
#ifdef _WIN32
#ifndef _USE_UTF8
, UINT codePage
#endif
)
@@ -110,7 +152,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
unsigned len = 0;
for (len = 0; s[len] != 0; len++);
#ifdef _WIN32
#ifndef _USE_UTF8
{
unsigned size = len * 3 + 100;
if (!Buf_EnsureSize(buf, size))
@@ -191,7 +233,7 @@ static SRes PrintString(const UInt16 *s)
SRes res;
Buf_Init(&buf);
res = Utf16_To_Char(&buf, s
#ifdef _WIN32
#ifndef _USE_UTF8
, CP_OEMCP
#endif
);
@@ -281,7 +323,7 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
UIntToStr_2(s, sec); s[2] = 0;
}
void PrintError(const char *sz)
void PrintError(char *sz)
{
printf("\nERROR: %s\n", sz);
}
@@ -318,6 +360,7 @@ int MY_CDECL main(int numargs, char *args[])
// UInt32 parents[NUM_PARENTS_MAX];
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
if (numargs == 1)
{
printf(
@@ -329,6 +372,7 @@ int MY_CDECL main(int numargs, char *args[])
" x: eXtract files with full paths\n");
return 0;
}
if (numargs < 3)
{
PrintError("incorrect command");
@@ -364,11 +408,14 @@ int MY_CDECL main(int numargs, char *args[])
CrcGenerateTable();
SzArEx_Init(&db);
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
if (res == SZ_OK)
{
char *command = args[1];
int listCommand = 0, testCommand = 0, fullPaths = 0;
if (strcmp(command, "l") == 0) listCommand = 1;
else if (strcmp(command, "t") == 0) testCommand = 1;
else if (strcmp(command, "e") == 0) { }
@@ -397,7 +444,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t outSizeProcessed = 0;
// const CSzFileItem *f = db.Files + i;
size_t len;
int isDir = SzArEx_IsDir(&db, i);
unsigned isDir = SzArEx_IsDir(&db, i);
if (listCommand == 0 && isDir && !fullPaths)
continue;
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
@@ -433,6 +480,7 @@ int MY_CDECL main(int numargs, char *args[])
fileSize = SzArEx_GetFileSize(&db, i);
UInt64ToStr(fileSize, s);
if (SzBitWithVals_Check(&db.MTime, i))
ConvertFileTimeToString(&db.MTime.Vals[i], t);
else
@@ -452,6 +500,7 @@ int MY_CDECL main(int numargs, char *args[])
printf("\n");
continue;
}
fputs(testCommand ?
"Testing ":
"Extracting ",
@@ -459,6 +508,7 @@ int MY_CDECL main(int numargs, char *args[])
res = PrintString(temp);
if (res != SZ_OK)
break;
if (isDir)
printf("/");
else
@@ -470,6 +520,7 @@ int MY_CDECL main(int numargs, char *args[])
if (res != SZ_OK)
break;
}
if (!testCommand)
{
CSzFile outFile;
@@ -477,6 +528,7 @@ int MY_CDECL main(int numargs, char *args[])
size_t j;
UInt16 *name = (UInt16 *)temp;
const UInt16 *destPath = (const UInt16 *)name;
for (j = 0; name[j] != 0; j++)
if (name[j] == '/')
{
@@ -502,19 +554,23 @@ int MY_CDECL main(int numargs, char *args[])
res = SZ_ERROR_FAIL;
break;
}
processedSize = outSizeProcessed;
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
{
PrintError("can not write output file");
res = SZ_ERROR_FAIL;
break;
}
if (File_Close(&outFile))
{
PrintError("can not close output file");
res = SZ_ERROR_FAIL;
break;
}
#ifdef USE_WINDOWS_FILE
if (SzBitWithVals_Check(&db.Attribs, i))
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
@@ -525,15 +581,18 @@ int MY_CDECL main(int numargs, char *args[])
IAlloc_Free(&allocImp, outBuffer);
}
}
SzArEx_Free(&db, &allocImp);
SzFree(NULL, temp);
File_Close(&archiveStream.file);
if (res == SZ_OK)
{
printf("\nEverything is Ok\n");
return 0;
}
if (res == SZ_ERROR_UNSUPPORTED)
PrintError("decoder doesn't support this archive");
else if (res == SZ_ERROR_MEM)
@@ -542,5 +601,6 @@ int MY_CDECL main(int numargs, char *args[])
PrintError("CRC error");
else
printf("\nERROR #%d\n", res);
return 1;
}

View File

@@ -1,4 +1,3 @@
# MY_STATIC_LINK=1
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
PROG = 7zDec.exe
@@ -15,7 +14,9 @@ C_OBJS = \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
$O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \
$O\Ppmd7.obj \

BIN
C/Util/7zipInstall/7zip.ico Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,231 @@
# Microsoft Developer Studio Project File - Name="7zipInstall" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=7zipInstall - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "7zipInstall.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "7zipInstall.mak" CFG="7zipInstall - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "7zipInstall - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "7zipInstall - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "7zipInstall - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "7zipInstall - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "7zipInstall - Win32 Release"
# Name "7zipInstall - Win32 Debug"
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\7z.h
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zAlloc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zArcIn.c
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.c
# End Source File
# Begin Source File
SOURCE=..\..\7zBuf.h
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.c
# End Source File
# Begin Source File
SOURCE=..\..\7zCrc.h
# End Source File
# Begin Source File
SOURCE=..\..\7zCrcOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\7zDec.c
# End Source File
# Begin Source File
SOURCE=..\..\7zFile.c
# End Source File
# Begin Source File
SOURCE=..\..\7zFile.h
# End Source File
# Begin Source File
SOURCE=..\..\7zStream.c
# End Source File
# Begin Source File
SOURCE=..\..\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\7zVersion.h
# End Source File
# Begin Source File
SOURCE=..\..\Bcj2.c
# End Source File
# Begin Source File
SOURCE=..\..\Bcj2.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra.c
# End Source File
# Begin Source File
SOURCE=..\..\Bra.h
# End Source File
# Begin Source File
SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
SOURCE=..\..\BraIA64.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\Delta.c
# End Source File
# Begin Source File
SOURCE=..\..\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.h
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.c
# End Source File
# Begin Source File
SOURCE=..\..\LzmaDec.h
# End Source File
# End Group
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Precomp.c
# ADD CPP /Yc"Precomp.h"
# End Source File
# Begin Source File
SOURCE=.\Precomp.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\7zipInstall.c
# End Source File
# Begin Source File
SOURCE=.\resource.rc
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7zipInstall"=.\7zipInstall.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.7zipInstall" type="win32"/>
<description>7-Zip Installer</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges></security></trustInfo>
<dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
<asmv3:application><asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware></asmv3:windowsSettings></asmv3:application>
</assembly>

View File

@@ -0,0 +1,4 @@
/* Precomp.c -- StdAfx
2013-01-21 : Igor Pavlov : Public domain */
#include "Precomp.h"

View File

@@ -0,0 +1,11 @@
/* Precomp.h -- StdAfx
2015-05-24 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "../../Compiler.h"
#include "../../7zTypes.h"
#endif

View File

@@ -0,0 +1,40 @@
PROG = 7zipInstall.exe
!IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
!ENDIF
CFLAGS = $(CFLAGS) -D_LZMA_SIZE_OPT
CFLAGS = $(CFLAGS) \
-D_7Z_NO_METHOD_LZMA2 \
-D_7Z_NO_METHODS_FILTERS
MAIN_OBJS = \
$O\7zipInstall.obj \
C_OBJS = \
$O\7zAlloc.obj \
$O\7zArcIn.obj \
$O\7zBuf.obj \
$O\7zBuf2.obj \
$O\7zCrc.obj \
$O\7zCrcOpt.obj \
$O\7zFile.obj \
$O\7zDec.obj \
$O\7zStream.obj \
$O\Bcj2.obj \
$O\CpuArch.obj \
$O\LzmaDec.obj \
OBJS = \
$(MAIN_OBJS) \
$(C_OBJS) \
$O\resource.res
!include "../../../CPP/Build.mak"
$(MAIN_OBJS): $(*B).c
$(COMPL_O1)
$(C_OBJS): ../../$(*B).c
$(COMPL_O1)

View File

@@ -0,0 +1,9 @@
#define IDD_INSTALL 100
#define IDT_EXTRACT_EXTRACT_TO 110
#define IDE_EXTRACT_PATH 111
#define IDB_EXTRACT_SET_PATH 112
#define IDT_CUR_FILE 113
#define IDC_PROGRESS 114
#define IDI_ICON 1

View File

@@ -0,0 +1,47 @@
#include <winnt.h>
#include <WinUser.h>
#include <CommCtrl.h>
#define USE_COPYRIGHT_CR
#include "../../7zVersion.rc"
#include "resource.h"
MY_VERSION_INFO(MY_VFT_APP, "7-Zip Installer", "7zipInstall", "7zipInstall.exe")
1 ICON "7zip.ico"
#define xc 184
#define yc 96
#define m 8
#define bxs 64
#define bys 16
#define bxsDots 20
#define xs (xc + m + m)
#define ys (yc + m + m)
#define bx1 (xs - m - bxs)
#define bx2 (bx1 - m - bxs)
#define by (ys - m - bys)
IDD_INSTALL DIALOG 0, 0, xs, ys
STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Install 7-Zip"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Destination folder:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8
EDITTEXT IDE_EXTRACT_PATH, m, 21, xc - bxsDots - 12, 14, ES_AUTOHSCROLL
PUSHBUTTON "...", IDB_EXTRACT_SET_PATH, xs - m - bxsDots, 20, bxsDots, bys, WS_GROUP
LTEXT "", IDT_CUR_FILE, m, 50, xc, 8
CONTROL "", IDC_PROGRESS, "msctls_progress32", WS_BORDER, m, 64, xc, 10
DEFPUSHBUTTON "&Install", IDOK, bx2, by, bxs, bys, WS_GROUP
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
END
#ifndef UNDER_CE
1 24 MOVEABLE PURE "7zipInstall.manifest"
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
# Microsoft Developer Studio Project File - Name="7zipUninstall" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=7zipUninstall - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "7zipUninstall.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "7zipUninstall.mak" CFG="7zipUninstall - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "7zipUninstall - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "7zipUninstall - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "7zipUninstall - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W4 /WX /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/Uninstall.exe"
!ELSEIF "$(CFG)" == "7zipUninstall - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W4 /WX /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_UNICODE2" /D "UNICODE2" /Yu"Precomp.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "_DEBUG"
# ADD RSC /l 0x419 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/Uninstall.exe" /pdbtype:sept
!ENDIF
# Begin Target
# Name "7zipUninstall - Win32 Release"
# Name "7zipUninstall - Win32 Debug"
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\7zVersion.h
# End Source File
# End Group
# Begin Group "Spec"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Precomp.c
# ADD CPP /Yc"Precomp.h"
# End Source File
# Begin Source File
SOURCE=.\Precomp.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\7zipUninstall.c
# End Source File
# Begin Source File
SOURCE=.\resource.rc
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7zipUninstall"=.\7zipUninstall.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="7-Zip.7-Zip.Uninstall" type="win32"/>
<description>7-Zip Uninstaller</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"><security><requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges></security></trustInfo>
<dependency><dependentAssembly><assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/></dependentAssembly></dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"><application>
<!-- Vista --> <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Win 7 --> <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Win 8 --> <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Win 8.1 --> <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Win 10 --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application></compatibility>
<asmv3:application><asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware></asmv3:windowsSettings></asmv3:application>
</assembly>

View File

@@ -0,0 +1,4 @@
/* Precomp.c -- StdAfx
2013-01-21 : Igor Pavlov : Public domain */
#include "Precomp.h"

View File

@@ -0,0 +1,11 @@
/* Precomp.h -- StdAfx
2015-05-24 : Igor Pavlov : Public domain */
#ifndef __7Z_PRECOMP_H
#define __7Z_PRECOMP_H
#include "../../Compiler.h"
#include "../../7zTypes.h"
#endif

View File

@@ -0,0 +1,17 @@
PROG = 7zipUninstall.exe
!IFDEF _64BIT_INSTALLER
CFLAGS = $(CFLAGS) -D_64BIT_INSTALLER
!ENDIF
MAIN_OBJS = \
$O\7zipUninstall.obj \
OBJS = \
$(MAIN_OBJS) \
$O\resource.res
!include "../../../CPP/Build.mak"
$(MAIN_OBJS): $(*B).c
$(COMPL_O1)

View File

@@ -0,0 +1,9 @@
#define IDD_INSTALL 100
#define IDT_EXTRACT_EXTRACT_TO 110
#define IDE_EXTRACT_PATH 111
#define IDT_CUR_FILE 113
#define IDC_PROGRESS 114
#define IDI_ICON 1

View File

@@ -0,0 +1,47 @@
#include <winnt.h>
#include <WinUser.h>
#include <CommCtrl.h>
#define USE_COPYRIGHT_CR
#include "../../7zVersion.rc"
#include "resource.h"
MY_VERSION_INFO(MY_VFT_APP, "7-Zip Uninstaller", "Uninstall", "Uninstall.exe")
1 ICON "7zipUninstall.ico"
#define xc 184
#define yc 96
#define m 8
#define bxs 64
#define bys 16
#define xs (xc + m + m)
#define ys (yc + m + m)
#define bx1 (xs - m - bxs)
#define bx2 (bx1 - m - bxs)
#define by (ys - m - bys)
IDD_INSTALL DIALOG 0, 0, xs, ys
STYLE DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
CAPTION "Uninstall 7-Zip"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "Uninstall from:", IDT_EXTRACT_EXTRACT_TO, m, m, xc, 8
EDITTEXT IDE_EXTRACT_PATH, m, 21, xc, 14, ES_AUTOHSCROLL | WS_DISABLED
LTEXT "", IDT_CUR_FILE, m, 50, xc, 8
CONTROL "", IDC_PROGRESS, "msctls_progress32", WS_BORDER, m, 64, xc, 10
DEFPUSHBUTTON "&Uninstall", IDOK, bx2, by, bxs, bys, WS_GROUP
PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
END
#ifndef UNDER_CE
1 24 MOVEABLE PURE "7zipUninstall.manifest"
#endif

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression
2014-12-31 : Igor Pavlov : Public domain */
2015-06-13 : Igor Pavlov : Public domain */
#include "../../Precomp.h"
@@ -18,10 +18,6 @@ const char *kCantWriteMessage = "Can not write output file";
const char *kCantAllocateMessage = "Can not allocate memory";
const char *kDataErrorMessage = "Data error";
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
void PrintHelp(char *buffer)
{
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"

View File

@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup
2014-12-07 : Igor Pavlov : Public domain */
2015-03-25 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -23,7 +23,7 @@
#define k_EXE_ExtIndex 2
static const char *kExts[] =
static const char * const kExts[] =
{
"bat"
, "cmd"
@@ -37,7 +37,7 @@ static const char *kExts[] =
, "htm"
};
static const char *kNames[] =
static const char * const kNames[] =
{
"setup"
, "install"
@@ -63,7 +63,7 @@ static unsigned FindExt(const wchar_t *s, unsigned *extLen)
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, unsigned len)
static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len)
{
unsigned i;
for (i = 0; i < num; i++)
@@ -75,7 +75,7 @@ static unsigned FindItem(const char **items, unsigned num, const wchar_t *s, uns
continue;
for (j = 0; j < len; j++)
{
unsigned c = item[j];
unsigned c = (Byte)item[j];
if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
break;
}
@@ -182,6 +182,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
path[len] = L'\0';
if (handle == INVALID_HANDLE_VALUE)
return GetLastError();
for (;;)
{
if (wcscmp(fd.cFileName, L".") != 0 &&
@@ -199,9 +200,11 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
if (DeleteFileW(path) == 0)
res = GetLastError();
}
if (res != 0)
break;
}
if (!FindNextFileW(handle, &fd))
{
res = GetLastError();
@@ -210,6 +213,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
break;
}
}
path[len] = L'\0';
FindClose(handle);
if (res == 0)
@@ -248,6 +252,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
const wchar_t *cmdLineParams;
const char *errorMessage = NULL;
Bool useShellExecute = True;
DWORD exitCode = 0;
#ifdef _CONSOLE
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
@@ -315,7 +320,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
{
unsigned t = value & 0xF;
value >>= 4;
s[7 - k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = '\0';
}
@@ -584,6 +589,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (hProcess != 0)
{
WaitForSingleObject(hProcess, INFINITE);
if (!GetExitCodeProcess(hProcess, &exitCode))
exitCode = 1;
CloseHandle(hProcess);
}
@@ -596,7 +603,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
RemoveDirWithSubItems(path);
if (res == SZ_OK)
return 0;
return (int)exitCode;
{
if (res == SZ_ERROR_UNSUPPORTED)
@@ -610,6 +617,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
if (!errorMessage)
errorMessage = "ERROR";
}
if (errorMessage)
PrintErrorMessage(errorMessage);
}

View File

@@ -167,6 +167,10 @@ SOURCE=..\..\Bra86.c
# End Source File
# Begin Source File
SOURCE=..\..\BraIA64.c
# End Source File
# Begin Source File
SOURCE=..\..\CpuArch.c
# End Source File
# Begin Source File
@@ -175,6 +179,14 @@ SOURCE=..\..\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\Delta.c
# End Source File
# Begin Source File
SOURCE=..\..\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\Lzma2Dec.c
# End Source File
# Begin Source File

View File

@@ -13,7 +13,9 @@ C_OBJS = \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
$O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \

View File

@@ -14,7 +14,9 @@ C_OBJS = \
$O\Bcj2.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
$O\CpuArch.obj \
$O\Delta.obj \
$O\Lzma2Dec.obj \
$O\LzmaDec.obj \

10
C/Xz.c
View File

@@ -1,5 +1,5 @@
/* Xz.c - Xz
2009-04-15 : Igor Pavlov : Public domain */
2015-05-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -8,8 +8,8 @@
#include "Xz.h"
#include "XzCrc64.h"
Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
{
@@ -40,11 +40,11 @@ void Xz_Free(CXzStream *p, ISzAlloc *alloc)
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
{
int t = XzFlags_GetCheckType(f);
unsigned t = XzFlags_GetCheckType(f);
return (t == 0) ? 0 : (4 << ((t - 1) / 3));
}
void XzCheck_Init(CXzCheck *p, int mode)
void XzCheck_Init(CXzCheck *p, unsigned mode)
{
p->mode = mode;
switch (mode)

14
C/Xz.h
View File

@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
2014-12-30 : Igor Pavlov : Public domain */
2015-05-01 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -59,8 +59,8 @@ SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStream *inStream, Bool *isIndex, UInt
#define XZ_SIG_SIZE 6
#define XZ_FOOTER_SIG_SIZE 2
extern Byte XZ_SIG[XZ_SIG_SIZE];
extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
extern const Byte XZ_SIG[XZ_SIG_SIZE];
extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
#define XZ_STREAM_FLAGS_SIZE 2
#define XZ_STREAM_CRC_SIZE 4
@@ -76,13 +76,13 @@ extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
typedef struct
{
int mode;
unsigned mode;
UInt32 crc;
UInt64 crc64;
CSha256 sha;
} CXzCheck;
void XzCheck_Init(CXzCheck *p, int mode);
void XzCheck_Init(CXzCheck *p, unsigned mode);
void XzCheck_Update(CXzCheck *p, const void *data, size_t size);
int XzCheck_Final(CXzCheck *p, Byte *digest);
@@ -163,7 +163,7 @@ typedef struct
{
ISzAlloc *alloc;
Byte *buf;
int numCoders;
unsigned numCoders;
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
size_t size[MIXCODER_NUM_FILTERS_MAX - 1];
@@ -174,7 +174,7 @@ typedef struct
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc);
void MixCoder_Free(CMixCoder *p);
void MixCoder_Init(CMixCoder *p);
SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId);
SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId);
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, int srcWasFinished,
ECoderFinishMode finishMode, ECoderStatus *status);

View File

@@ -1,5 +1,5 @@
/* XzCrc64.c -- CRC64 calculation
2011-06-28 : Igor Pavlov : Public domain */
2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -13,14 +13,15 @@
#else
#define CRC_NUM_TABLES 5
#define CRC_UINT64_SWAP(v) \
((v >> 56) | \
((v >> 40) & ((UInt64)0xFF << 8)) | \
((v >> 24) & ((UInt64)0xFF << 16)) | \
((v >> 8) & ((UInt64)0xFF << 24)) | \
((v << 8) & ((UInt64)0xFF << 32)) | \
((v << 24) & ((UInt64)0xFF << 40)) | \
((v << 40) & ((UInt64)0xFF << 48)) | \
(v << 56))
((v >> 56) \
| ((v >> 40) & ((UInt64)0xFF << 8)) \
| ((v >> 24) & ((UInt64)0xFF << 16)) \
| ((v >> 8) & ((UInt64)0xFF << 24)) \
| ((v << 8) & ((UInt64)0xFF << 32)) \
| ((v << 24) & ((UInt64)0xFF << 40)) \
| ((v << 40) & ((UInt64)0xFF << 48)) \
| ((v << 56)))
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
#endif
@@ -64,11 +65,6 @@ void MY_FAST_CALL Crc64GenerateTable()
g_Crc64Update = XzCrc64UpdateT4;
#else
{
#ifndef MY_CPU_BE

View File

@@ -1,14 +1,14 @@
/* XzCrc64Opt.c -- CRC64 calculation
2011-06-28 : Igor Pavlov : Public domain */
2015-03-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "CpuArch.h"
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
#ifndef MY_CPU_BE
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
{
const Byte *p = (const Byte *)data;
@@ -17,11 +17,11 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, con
for (; size >= 4; size -= 4, p += 4)
{
UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
v = (v >> 32) ^
table[0x300 + ((d ) & 0xFF)] ^
table[0x200 + ((d >> 8) & 0xFF)] ^
table[0x100 + ((d >> 16) & 0xFF)] ^
table[0x000 + ((d >> 24))];
v = (v >> 32)
^ 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);
@@ -34,36 +34,36 @@ UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, con
#ifndef MY_CPU_LE
#define CRC_UINT64_SWAP(v) \
((v >> 56) | \
((v >> 40) & ((UInt64)0xFF << 8)) | \
((v >> 24) & ((UInt64)0xFF << 16)) | \
((v >> 8) & ((UInt64)0xFF << 24)) | \
((v << 8) & ((UInt64)0xFF << 32)) | \
((v << 24) & ((UInt64)0xFF << 40)) | \
((v << 40) & ((UInt64)0xFF << 48)) | \
(v << 56))
((v >> 56) \
| ((v >> 40) & ((UInt64)0xFF << 8)) \
| ((v >> 24) & ((UInt64)0xFF << 16)) \
| ((v >> 8) & ((UInt64)0xFF << 24)) \
| ((v << 8) & ((UInt64)0xFF << 32)) \
| ((v << 24) & ((UInt64)0xFF << 40)) \
| ((v << 40) & ((UInt64)0xFF << 48)) \
| ((v << 56)))
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8))
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
{
const Byte *p = (const Byte *)data;
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
v = CRC_UINT64_SWAP(v);
table += 0x100;
v = CRC_UINT64_SWAP(v);
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
v = CRC_UPDATE_BYTE_2_BE(v, *p);
for (; size >= 4; size -= 4, p += 4)
{
UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
v = (v << 32) ^
table[0x000 + ((d ) & 0xFF)] ^
table[0x100 + ((d >> 8) & 0xFF)] ^
table[0x200 + ((d >> 16) & 0xFF)] ^
table[0x300 + ((d >> 24))];
v = (v << 32)
^ table[0x000 + ((d ) & 0xFF)]
^ table[0x100 + ((d >> 8) & 0xFF)]
^ table[0x200 + ((d >> 16) & 0xFF)]
^ table[0x300 + ((d >> 24))];
}
table -= 0x100;
v = CRC_UINT64_SWAP(v);
for (; size > 0; size--, p++)
v = CRC_UPDATE_BYTE_2(v, *p);
return v;
v = CRC_UPDATE_BYTE_2_BE(v, *p);
return CRC_UINT64_SWAP(v);
}
#endif

View File

@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode
2014-12-30 : Igor Pavlov : Public domain */
2015-05-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -32,9 +32,9 @@
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
{
int i, limit;
unsigned i, limit;
*value = 0;
limit = (maxSize > 9) ? 9 : (int)maxSize;
limit = (maxSize > 9) ? 9 : (unsigned)maxSize;
for (i = 0; i < limit;)
{
@@ -66,12 +66,12 @@ typedef struct
Byte buf[BRA_BUF_SIZE];
} CBraState;
void BraState_Free(void *pp, ISzAlloc *alloc)
static void BraState_Free(void *pp, ISzAlloc *alloc)
{
alloc->Free(alloc, pp);
}
SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{
CBraState *p = ((CBraState *)pp);
alloc = alloc;
@@ -87,7 +87,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
if (propSize == 4)
{
UInt32 v = GetUi32(props);
switch(p->methodId)
switch (p->methodId)
{
case XZ_ID_PPC:
case XZ_ID_ARM:
@@ -112,7 +112,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
return SZ_OK;
}
void BraState_Init(void *pp)
static void BraState_Init(void *pp)
{
CBraState *p = ((CBraState *)pp);
p->bufPos = p->bufConv = p->bufTotal = 0;
@@ -163,7 +163,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
}
if (p->bufTotal == 0)
break;
switch(p->methodId)
switch (p->methodId)
{
case XZ_ID_Delta:
if (p->encodeMode)
@@ -235,7 +235,7 @@ static void SbState_Free(void *pp, ISzAlloc *alloc)
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{
pp = pp;
UNUSED_VAR(pp);
props = props;
alloc = alloc;
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
@@ -330,9 +330,9 @@ static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
{
int i;
unsigned i;
p->alloc = alloc;
p->buf = 0;
p->buf = NULL;
p->numCoders = 0;
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
p->coders[i].p = NULL;
@@ -340,7 +340,7 @@ void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
void MixCoder_Free(CMixCoder *p)
{
int i;
unsigned i;
for (i = 0; i < p->numCoders; i++)
{
IStateCoder *sc = &p->coders[i];
@@ -351,14 +351,14 @@ void MixCoder_Free(CMixCoder *p)
if (p->buf)
{
p->alloc->Free(p->alloc, p->buf);
p->buf = 0; /* 9.31: the BUG was fixed */
p->buf = NULL; /* 9.31: the BUG was fixed */
}
}
void MixCoder_Init(CMixCoder *p)
{
int i;
for (i = 0; i < p->numCoders - 1; i++)
unsigned i;
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++)
{
p->size[i] = 0;
p->pos[i] = 0;
@@ -371,11 +371,11 @@ void MixCoder_Init(CMixCoder *p)
}
}
SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId)
{
IStateCoder *sc = &p->coders[coderIndex];
p->ids[coderIndex] = methodId;
switch(methodId)
switch (methodId)
{
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
#ifdef USE_SUBBLOCK
@@ -398,10 +398,10 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
*srcLen = 0;
*status = CODER_STATUS_NOT_FINISHED;
if (p->buf == 0)
if (!p->buf)
{
p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
if (p->buf == 0)
if (!p->buf)
return SZ_ERROR_MEM;
}
@@ -411,7 +411,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
for (;;)
{
Bool processed = False;
int i;
unsigned i;
/*
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
break;
@@ -520,8 +520,8 @@ static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *b
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
{
unsigned pos;
int numFilters, i;
UInt32 headerSize = (UInt32)header[0] << 2;
unsigned numFilters, i;
unsigned headerSize = (unsigned)header[0] << 2;
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
return SZ_ERROR_ARCHIVE;
@@ -557,7 +557,7 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
#ifdef XZ_DUMP
printf("\nf[%d] = %2X: ", i, filter->id);
{
int i;
unsigned i;
for (i = 0; i < size; i++)
printf(" %2X", filter->props[i]);
}
@@ -572,9 +572,10 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
{
int i;
unsigned i;
Bool needReInit = True;
int numFilters = XzBlock_GetNumFilters(block);
unsigned numFilters = XzBlock_GetNumFilters(block);
if (numFilters == p->numCoders)
{
for (i = 0; i < numFilters; i++)
@@ -582,6 +583,7 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
break;
needReInit = (i != numFilters);
}
if (needReInit)
{
MixCoder_Free(p);
@@ -592,12 +594,14 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
RINOK(MixCoder_SetFromMethod(p, i, f->id));
}
}
for (i = 0; i < numFilters; i++)
{
const CXzFilter *f = &block->filters[numFilters - 1 - i];
IStateCoder *sc = &p->coders[i];
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
}
MixCoder_Init(p);
return SZ_OK;
}

View File

@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode
2014-12-30 : Igor Pavlov : Public domain */
2015-05-01 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -18,14 +18,6 @@
#include "XzEnc.h"
static void *SzBigAlloc(void *p, size_t size) { p = p; return BigAlloc(size); }
static void SzBigFree(void *p, void *address) { p = p; BigFree(address); }
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
#define XzBlock_ClearFlags(p) (p)->flags = 0;
#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);
#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE;
@@ -59,12 +51,13 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
unsigned pos = 1;
int numFilters, i;
unsigned numFilters, i;
header[pos++] = p->flags;
if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
numFilters = XzBlock_GetNumFilters(p);
for (i = 0; i < numFilters; i++)
{
const CXzFilter *f = &p->filters[i];
@@ -73,8 +66,10 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
memcpy(header + pos, f->props, f->propsSize);
pos += f->propsSize;
}
while((pos & 3) != 0)
while ((pos & 3) != 0)
header[pos++] = 0;
header[0] = (Byte)(pos >> 2);
SetUi32(header + pos, CrcCalc(header, pos));
return WriteBytes(s, header, pos + 4);
@@ -163,13 +158,13 @@ typedef struct
CXzCheck check;
} CSeqCheckInStream;
void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode)
static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned mode)
{
p->processed = 0;
XzCheck_Init(&p->check, mode);
}
void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest)
{
XzCheck_Final(&p->check, digest);
}
@@ -408,7 +403,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
CSeqCheckInStream checkInStream;
CSeqSizeOutStream seqSizeOutStream;
CXzBlock block;
int filterIndex = 0;
unsigned filterIndex = 0;
CXzFilter *filter = NULL;
const CXzFilterProps *fp = props->filterProps;

View File

@@ -1,5 +1,5 @@
/* XzIn.c - Xz input
2014-12-30 : Igor Pavlov : Public domain */
2015-04-21 : Igor Pavlov : Public domain */
#include "Precomp.h"
@@ -134,55 +134,58 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
return res;
}
static SRes SeekFromCur(ILookInStream *inStream, Int64 *res)
static SRes LookInStream_SeekRead_ForArc(ILookInStream *stream, UInt64 offset, void *buf, size_t size)
{
return inStream->Seek(inStream, res, SZ_SEEK_CUR);
RINOK(LookInStream_SeekTo(stream, offset));
return LookInStream_Read(stream, buf, size);
/* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */
}
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
{
UInt64 indexSize;
Byte buf[XZ_STREAM_FOOTER_SIZE];
UInt64 pos = *startOffset;
if ((*startOffset & 3) != 0 || *startOffset < XZ_STREAM_FOOTER_SIZE)
if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
*startOffset = -XZ_STREAM_FOOTER_SIZE;
RINOK(SeekFromCur(stream, startOffset));
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
pos -= XZ_STREAM_FOOTER_SIZE;
RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
UInt32 total = 0;
*startOffset += XZ_STREAM_FOOTER_SIZE;
pos += XZ_STREAM_FOOTER_SIZE;
for (;;)
{
size_t i;
#define TEMP_BUF_SIZE (1 << 10)
Byte tempBuf[TEMP_BUF_SIZE];
if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
return SZ_ERROR_NO_ARCHIVE;
i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
Byte temp[TEMP_BUF_SIZE];
i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos;
pos -= i;
RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i));
total += (UInt32)i;
*startOffset = -(Int64)i;
RINOK(SeekFromCur(stream, startOffset));
RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
for (; i != 0; i--)
if (tempBuf[i - 1] != 0)
if (temp[i - 1] != 0)
break;
if (i != 0)
{
if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
*startOffset += i;
pos += i;
break;
}
if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
return SZ_ERROR_NO_ARCHIVE;
}
if (*startOffset < XZ_STREAM_FOOTER_SIZE)
if (pos < XZ_STREAM_FOOTER_SIZE)
return SZ_ERROR_NO_ARCHIVE;
*startOffset -= XZ_STREAM_FOOTER_SIZE;
RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
pos -= XZ_STREAM_FOOTER_SIZE;
RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE));
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
return SZ_ERROR_NO_ARCHIVE;
}
@@ -197,20 +200,22 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
*startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
RINOK(SeekFromCur(stream, startOffset));
if (pos < indexSize)
return SZ_ERROR_ARCHIVE;
pos -= indexSize;
RINOK(LookInStream_SeekTo(stream, pos));
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
{
UInt64 totalSize = Xz_GetPackSize(p);
UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
if (totalSize == XZ_SIZE_OVERFLOW ||
sum >= ((UInt64)1 << 63) ||
totalSize >= ((UInt64)1 << 63))
if (totalSize == XZ_SIZE_OVERFLOW
|| totalSize >= ((UInt64)1 << 63)
|| pos < totalSize + XZ_STREAM_HEADER_SIZE)
return SZ_ERROR_ARCHIVE;
*startOffset = -(Int64)sum;
RINOK(SeekFromCur(stream, startOffset));
pos -= (totalSize + XZ_STREAM_HEADER_SIZE);
RINOK(LookInStream_SeekTo(stream, pos));
*startOffset = pos;
}
{
CXzStreamFlags headerFlags;
@@ -299,7 +304,7 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
p->streams[p->num++] = st;
if (*startOffset == 0)
break;
RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
RINOK(LookInStream_SeekTo(stream, *startOffset));
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
return SZ_ERROR_PROGRESS;
}

View File

@@ -350,14 +350,6 @@ SOURCE=..\Common\CoderMixer2.h
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2MT.cpp
# End Source File
# Begin Source File
SOURCE=..\Common\CoderMixer2MT.h
# End Source File
# Begin Source File
SOURCE=..\Common\CrossThreadProgress.cpp
# End Source File
# Begin Source File

View File

@@ -9,37 +9,62 @@
namespace NArchive {
namespace N7z {
struct CMethodFull: public CProps
struct CMethodFull: public CMethodProps
{
CMethodId Id;
UInt32 NumInStreams;
UInt32 NumOutStreams;
UInt32 NumStreams;
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
bool IsSimpleCoder() const { return NumStreams == 1; }
};
struct CBind
struct CBond2
{
UInt32 InCoder;
UInt32 InStream;
UInt32 OutCoder;
UInt32 OutStream;
UInt32 InCoder;
};
struct CCompressionMethodMode
{
/*
if (Bonds.Empty()), then default bonds must be created
if (Filter_was_Inserted)
{
Methods[0] is filter method
Bonds don't contain bonds for filter (these bonds must be created)
}
*/
CObjectVector<CMethodFull> Methods;
CRecordVector<CBind> Binds;
CRecordVector<CBond2> Bonds;
bool IsThereBond_to_Coder(unsigned coderIndex) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].InCoder == coderIndex)
return true;
return false;
}
bool DefaultMethod_was_Inserted;
bool Filter_was_Inserted;
#ifndef _7ZIP_ST
UInt32 NumThreads;
bool MultiThreadMixer;
#endif
bool PasswordIsDefined;
UString Password;
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode(): PasswordIsDefined(false)
CCompressionMethodMode():
DefaultMethod_was_Inserted(false),
Filter_was_Inserted(false),
PasswordIsDefined(false)
#ifndef _7ZIP_ST
, NumThreads(1)
, MultiThreadMixer(true)
#endif
{}
};

View File

@@ -3,7 +3,6 @@
#include "StdAfx.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/LockedStream.h"
#include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h"
@@ -12,50 +11,70 @@
namespace NArchive {
namespace N7z {
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
CBindInfoEx &bindInfo)
class CDecProgress:
public ICompressProgressInfo,
public CMyUnknownImp
{
bindInfo.Clear();
bindInfo.BindPairs.ClearAndSetSize(folder.BindPairs.Size());
CMyComPtr<ICompressProgressInfo> _progress;
public:
CDecProgress(ICompressProgressInfo *progress): _progress(progress) {}
MY_UNKNOWN_IMP1(ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
STDMETHODIMP CDecProgress::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 *outSize)
{
return _progress->SetRatioInfo(NULL, outSize);
}
static void Convert_FolderInfo_to_BindInfo(const CFolderEx &folder, CBindInfoEx &bi)
{
bi.Clear();
bi.Bonds.ClearAndSetSize(folder.Bonds.Size());
unsigned i;
for (i = 0; i < folder.BindPairs.Size(); i++)
for (i = 0; i < folder.Bonds.Size(); i++)
{
NCoderMixer::CBindPair &bindPair = bindInfo.BindPairs[i];
bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
NCoderMixer2::CBond &bond = bi.Bonds[i];
const N7z::CBond &folderBond = folder.Bonds[i];
bond.PackIndex = folderBond.PackIndex;
bond.UnpackIndex = folderBond.UnpackIndex;
}
bindInfo.Coders.ClearAndSetSize(folder.Coders.Size());
bindInfo.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size());
UInt32 outStreamIndex = 0;
bi.Coders.ClearAndSetSize(folder.Coders.Size());
bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size());
for (i = 0; i < folder.Coders.Size(); i++)
{
NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
const CCoderInfo &coderInfo = folder.Coders[i];
coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
bindInfo.CoderMethodIDs[i] = coderInfo.MethodID;
for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
bindInfo.OutStreams.Add(outStreamIndex);
bi.Coders[i].NumStreams = coderInfo.NumStreams;
bi.CoderMethodIDs[i] = coderInfo.MethodID;
}
bindInfo.InStreams.ClearAndSetSize(folder.PackStreams.Size());
/*
if (!bi.SetUnpackCoder())
throw 1112;
*/
bi.UnpackCoder = folder.UnpackCoder;
bi.PackStreams.ClearAndSetSize(folder.PackStreams.Size());
for (i = 0; i < folder.PackStreams.Size(); i++)
bindInfo.InStreams[i] = (UInt32)folder.PackStreams[i];
bi.PackStreams[i] = folder.PackStreams[i];
}
static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1,
const NCoderMixer::CCoderStreamsInfo &a2)
static inline bool AreCodersEqual(
const NCoderMixer2::CCoderStreamsInfo &a1,
const NCoderMixer2::CCoderStreamsInfo &a2)
{
return (a1.NumInStreams == a2.NumInStreams) &&
(a1.NumOutStreams == a2.NumOutStreams);
return (a1.NumStreams == a2.NumStreams);
}
static bool AreBindPairsEqual(const NCoderMixer::CBindPair &a1, const NCoderMixer::CBindPair &a2)
static inline bool AreBondsEqual(
const NCoderMixer2::CBond &a1,
const NCoderMixer2::CBond &a2)
{
return (a1.InIndex == a2.InIndex) &&
(a1.OutIndex == a2.OutIndex);
return
(a1.PackIndex == a2.PackIndex) &&
(a1.UnpackIndex == a2.UnpackIndex);
}
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
@@ -66,186 +85,284 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
for (i = 0; i < a1.Coders.Size(); i++)
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
return false;
if (a1.BindPairs.Size() != a2.BindPairs.Size())
if (a1.Bonds.Size() != a2.Bonds.Size())
return false;
for (i = 0; i < a1.BindPairs.Size(); i++)
if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
for (i = 0; i < a1.Bonds.Size(); i++)
if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i]))
return false;
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
return false;
if (a1.InStreams.Size() != a2.InStreams.Size())
if (a1.PackStreams.Size() != a2.PackStreams.Size())
return false;
if (a1.OutStreams.Size() != a2.OutStreams.Size())
for (i = 0; i < a1.PackStreams.Size(); i++)
if (a1.PackStreams[i] != a2.PackStreams[i])
return false;
/*
if (a1.UnpackCoder != a2.UnpackCoder)
return false;
*/
return true;
}
CDecoder::CDecoder(bool multiThread)
CDecoder::CDecoder(bool useMixerMT):
_bindInfoPrev_Defined(false),
_useMixerMT(useMixerMT)
{}
struct CLockedInStream:
public IUnknown,
public CMyUnknownImp
{
#ifndef _ST_MODE
multiThread = true;
CMyComPtr<IInStream> Stream;
UInt64 Pos;
MY_UNKNOWN_IMP
#ifdef USE_MIXER_MT
NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
_multiThread = multiThread;
_bindInfoExPrevIsDefined = false;
};
#ifdef USE_MIXER_MT
class CLockedSequentialInStreamMT:
public ISequentialInStream,
public CMyUnknownImp
{
CLockedInStream *_glob;
UInt64 _pos;
CMyComPtr<IUnknown> _globRef;
public:
void Init(CLockedInStream *lockedInStream, UInt64 startPos)
{
_globRef = lockedInStream;
_glob = lockedInStream;
_pos = startPos;
}
MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *processedSize)
{
NWindows::NSynchronization::CCriticalSectionLock lock(_glob->CriticalSection);
if (_pos != _glob->Pos)
{
RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
_glob->Pos = _pos;
}
UInt32 realProcessedSize = 0;
HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
_pos += realProcessedSize;
_glob->Pos = _pos;
if (processedSize)
*processedSize = realProcessedSize;
return res;
}
#endif
#ifdef USE_MIXER_ST
class CLockedSequentialInStreamST:
public ISequentialInStream,
public CMyUnknownImp
{
CLockedInStream *_glob;
UInt64 _pos;
CMyComPtr<IUnknown> _globRef;
public:
void Init(CLockedInStream *lockedInStream, UInt64 startPos)
{
_globRef = lockedInStream;
_glob = lockedInStream;
_pos = startPos;
}
MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (_pos != _glob->Pos)
{
RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
_glob->Pos = _pos;
}
UInt32 realProcessedSize = 0;
HRESULT res = _glob->Stream->Read(data, size, &realProcessedSize);
_pos += realProcessedSize;
_glob->Pos = _pos;
if (processedSize)
*processedSize = realProcessedSize;
return res;
}
#endif
HRESULT CDecoder::Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
const CFolders &folders, int folderIndex,
ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress
const CFolders &folders, unsigned folderIndex,
const UInt64 *unpackSize
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
, ISequentialInStream **
#ifdef USE_MIXER_ST
inStreamMainRes
#endif
_7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#endif
)
{
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
CFolder folderInfo;
folders.ParseFolderInfo(folderIndex, folderInfo);
CFolderEx folderInfo;
folders.ParseFolderEx(folderIndex, folderInfo);
if (!folderInfo.CheckStructure(folders.GetNumFolderUnpackSizes(folderIndex)))
if (!folderInfo.IsDecodingSupported())
return E_NOTIMPL;
CBindInfoEx bindInfo;
Convert_FolderInfo_to_BindInfo(folderInfo, bindInfo);
if (!bindInfo.CalcMapsAndCheck())
return E_NOTIMPL;
UInt64 folderUnpackSize = folders.GetFolderUnpackSize(folderIndex);
bool fullUnpack = true;
if (unpackSize)
{
if (*unpackSize > folderUnpackSize)
return E_FAIL;
fullUnpack = (*unpackSize == folderUnpackSize);
}
/*
We don't need to init isEncrypted and passwordIsDefined
We must upgrade them only
#ifndef _NO_CRYPTO
isEncrypted = false;
passwordIsDefined = false;
#endif
*/
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
CLockedInStream lockedInStream;
lockedInStream.Init(inStream);
for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev))
{
CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp;
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
lockedStreamImpSpec->Init(&lockedInStream, startPos + packPositions[j]);
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream = streamSpec;
streamSpec->SetStream(lockedStreamImp);
streamSpec->Init(packPositions[j + 1] - packPositions[j]);
inStreams.Add(inStream);
}
unsigned numCoders = folderInfo.Coders.Size();
CBindInfoEx bindInfo;
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
bool createNewCoders;
if (!_bindInfoExPrevIsDefined)
createNewCoders = true;
else
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
if (createNewCoders)
{
unsigned i;
_decoders.Clear();
// _decoders2.Clear();
_mixerCoder.Release();
_mixerRef.Release();
if (_multiThread)
#ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
if (_useMixerMT)
#endif
{
_mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
_mixerCoder = _mixerCoderMTSpec;
_mixerCoderCommon = _mixerCoderMTSpec;
_mixerMT = new NCoderMixer2::CMixerMT(false);
_mixerRef = _mixerMT;
_mixer = _mixerMT;
}
#ifdef USE_MIXER_ST
else
#endif
#endif
{
#ifdef _ST_MODE
_mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
_mixerCoder = _mixerCoderSTSpec;
_mixerCoderCommon = _mixerCoderSTSpec;
#ifdef USE_MIXER_ST
_mixerST = new NCoderMixer2::CMixerST(false);
_mixerRef = _mixerST;
_mixer = _mixerST;
#endif
}
RINOK(_mixerCoderCommon->SetBindInfo(bindInfo));
for (i = 0; i < numCoders; i++)
RINOK(_mixer->SetBindInfo(bindInfo));
FOR_VECTOR(i, folderInfo.Coders)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
CMyComPtr<ICompressCoder> decoder;
CMyComPtr<ICompressCoder2> decoder2;
CCreatedCoder cod;
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
coderInfo.MethodID, decoder, decoder2, false));
CMyComPtr<IUnknown> decoderUnknown;
coderInfo.MethodID, false, cod));
if (coderInfo.IsSimpleCoder())
{
if (decoder == 0)
if (!cod.Coder)
return E_NOTIMPL;
decoderUnknown = (IUnknown *)decoder;
if (_multiThread)
_mixerCoderMTSpec->AddCoder(decoder);
#ifdef _ST_MODE
else
_mixerCoderSTSpec->AddCoder(decoder, false);
#endif
// CMethodId m = coderInfo.MethodID;
// isFilter = (IsFilterMethod(m) || m == k_AES);
}
else
{
if (decoder2 == 0)
if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams)
return E_NOTIMPL;
decoderUnknown = (IUnknown *)decoder2;
if (_multiThread)
_mixerCoderMTSpec->AddCoder2(decoder2);
#ifdef _ST_MODE
else
_mixerCoderSTSpec->AddCoder2(decoder2, false);
#endif
}
_decoders.Add(decoderUnknown);
_mixer->AddCoder(cod);
// now there is no codec that uses another external codec
/*
#ifdef EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
// we must use g_ExternalCodecs also
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
}
#endif
*/
}
_bindInfoExPrev = bindInfo;
_bindInfoExPrevIsDefined = true;
_bindInfoPrev = bindInfo;
_bindInfoPrev_Defined = true;
}
unsigned i;
_mixerCoderCommon->ReInit();
_mixer->ReInit();
UInt32 packStreamIndex = 0;
UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
UInt32 unpackStreamIndex = unpackStreamIndexStart;
UInt32 coderIndex = 0;
// UInt32 coder2Index = 0;
for (i = 0; i < numCoders; i++)
unsigned i;
for (i = 0; i < folderInfo.Coders.Size(); i++)
{
const CCoderInfo &coderInfo = folderInfo.Coders[i];
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
IUnknown *decoder = _mixer->GetCoder(i).GetUnknown();
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
const CByteBuffer &props = coderInfo.Props;
size_t size = props.Size();
if (size > 0xFFFFFFFF)
return E_NOTIMPL;
// if (size > 0)
{
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
}
HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size);
if (res == E_INVALIDARG)
res = E_NOTIMPL;
RINOK(res);
}
}
@@ -253,7 +370,7 @@ HRESULT CDecoder::Decode(
if (mtMode)
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
@@ -264,7 +381,7 @@ HRESULT CDecoder::Decode(
#ifndef _NO_CRYPTO
{
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword);
if (cryptoSetPassword)
{
isEncrypted = true;
@@ -273,9 +390,13 @@ HRESULT CDecoder::Decode(
CMyComBSTR passwordBSTR;
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
passwordIsDefined = true;
password.Empty();
size_t len = 0;
if (passwordBSTR)
len = MyStringLen((BSTR)passwordBSTR);
{
password = passwordBSTR;
len = password.Len();
}
CByteBuffer buffer(len * 2);
for (size_t i = 0; i < len; i++)
{
@@ -288,56 +409,129 @@ HRESULT CDecoder::Decode(
}
#endif
coderIndex++;
UInt32 numInStreams = (UInt32)coderInfo.NumInStreams;
UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams;
CObjArray<UInt64> packSizes(numInStreams);
CObjArray<const UInt64 *> packSizesPointers(numInStreams);
CObjArray<const UInt64 *> unpackSizesPointers(numOutStreams);
UInt32 j;
for (j = 0; j < numOutStreams; j++, unpackStreamIndex++)
unpackSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndex];
for (j = 0; j < numInStreams; j++, packStreamIndex++)
{
int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex);
if (bindPairIndex >= 0)
packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + (UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex];
else
CMyComPtr<ICompressSetFinishMode> setFinishMode;
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
if (setFinishMode)
{
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
if (index < 0)
return S_FALSE; // check it
packSizes[j] = packPositions[index + 1] - packPositions[index];
packSizesPointers[j] = &packSizes[j];
RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
}
}
_mixerCoderCommon->SetCoderInfo(i, packSizesPointers, unpackSizesPointers);
}
UInt32 mainCoder, temp;
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
UInt32 numStreams = (UInt32)coderInfo.NumStreams;
CObjArray<UInt64> packSizes(numStreams);
CObjArray<const UInt64 *> packSizesPointers(numStreams);
for (UInt32 j = 0; j < numStreams; j++, packStreamIndex++)
{
int bond = folderInfo.FindBond_for_PackStream(packStreamIndex);
if (bond >= 0)
packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + folderInfo.Bonds[(unsigned)bond].UnpackIndex];
else
{
int index = folderInfo.Find_in_PackStreams(packStreamIndex);
if (index < 0)
return E_NOTIMPL;
packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index];
packSizesPointers[j] = &packSizes[j];
}
}
if (_multiThread)
_mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
/*
else
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
*/
const UInt64 *unpackSizesPointer =
(unpackSize && i == bindInfo.UnpackCoder) ?
unpackSize :
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
_mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
}
if (outStream)
{
_mixer->SelectMainCoder(!fullUnpack);
}
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
CLockedInStream *lockedInStreamSpec = new CLockedInStream;
CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec;
bool needMtLock = false;
if (folderInfo.PackStreams.Size() > 1)
{
// lockedInStream.Pos = (UInt64)(Int64)-1;
// RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos));
RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
lockedInStreamSpec->Stream = inStream;
#ifdef USE_MIXER_ST
if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
#endif
needMtLock = true;
}
for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
{
CMyComPtr<ISequentialInStream> packStream;
UInt64 packPos = startPos + packPositions[j];
if (folderInfo.PackStreams.Size() == 1)
{
RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL));
packStream = inStream;
}
else
{
#ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
if (_useMixerMT || needMtLock)
#endif
{
CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT;
packStream = lockedStreamImpSpec;
lockedStreamImpSpec->Init(lockedInStreamSpec, packPos);
}
#ifdef USE_MIXER_ST
else
#endif
#endif
{
#ifdef USE_MIXER_ST
CLockedSequentialInStreamST *lockedStreamImpSpec = new CLockedSequentialInStreamST;
packStream = lockedStreamImpSpec;
lockedStreamImpSpec->Init(lockedInStreamSpec, packPos);
#endif
}
}
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
inStreams.AddNew() = streamSpec;
streamSpec->SetStream(packStream);
streamSpec->Init(packPositions[j + 1] - packPositions[j]);
}
if (numCoders == 0)
return 0;
unsigned num = inStreams.Size();
CObjArray<ISequentialInStream *> inStreamPointers(num);
for (i = 0; i < num; i++)
inStreamPointers[i] = inStreams[i];
ISequentialOutStream *outStreamPointer = outStream;
return _mixerCoder->Code(
inStreamPointers, NULL, num,
&outStreamPointer, NULL, 1,
compressProgress);
if (outStream)
{
CMyComPtr<ICompressProgressInfo> progress2;
if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex))
progress2 = new CDecProgress(compressProgress);
ISequentialOutStream *outStreamPointer = outStream;
return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
}
#ifdef USE_MIXER_ST
return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes);
#else
return E_FAIL;
#endif
}
}}

View File

@@ -3,25 +3,17 @@
#ifndef __7Z_DECODE_H
#define __7Z_DECODE_H
#include "../../IStream.h"
#include "../../IPassword.h"
#include "../Common/CoderMixer2.h"
#include "../Common/CoderMixer2MT.h"
#ifdef _ST_MODE
#include "../Common/CoderMixer2ST.h"
#endif
#include "../../Common/CreateCoder.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
struct CBindInfoEx: public NCoderMixer::CBindInfo
struct CBindInfoEx: public NCoderMixer2::CBindInfo
{
CRecordVector<CMethodId> CoderMethodIDs;
void Clear()
{
CBindInfo::Clear();
@@ -31,29 +23,40 @@ struct CBindInfoEx: public NCoderMixer::CBindInfo
class CDecoder
{
bool _bindInfoExPrevIsDefined;
CBindInfoEx _bindInfoExPrev;
bool _bindInfoPrev_Defined;
CBindInfoEx _bindInfoPrev;
bool _multiThread;
#ifdef _ST_MODE
NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
bool _useMixerMT;
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
CMyComPtr<ICompressCoder2> _mixerCoder;
CObjectVector<CMyComPtr<IUnknown> > _decoders;
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
#ifdef USE_MIXER_MT
NCoderMixer2::CMixerMT *_mixerMT;
#endif
NCoderMixer2::CMixer *_mixer;
CMyComPtr<IUnknown> _mixerRef;
public:
CDecoder(bool multiThread);
CDecoder(bool useMixerMT);
HRESULT Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream,
UInt64 startPos,
const CFolders &folders, int folderIndex,
ISequentialOutStream *outStream,
ICompressProgressInfo *compressProgress
const CFolders &folders, unsigned folderIndex,
const UInt64 *unpackSize // if (!unpackSize), then full folder is required
// if (unpackSize), then only *unpackSize bytes from folder are required
, ISequentialOutStream *outStream
, ICompressProgressInfo *compressProgress
, ISequentialInStream **inStreamMainRes
_7Z_DECODER_CRYPRO_VARS_DECL
#if !defined(_7ZIP_ST) && !defined(_SFX)
, bool mtMode, UInt32 numThreads
#endif

View File

@@ -12,43 +12,80 @@
#include "7zEncode.h"
#include "7zSpecStream.h"
static const UInt64 k_Delta = 0x03;
static const UInt64 k_BCJ = 0x03030103;
static const UInt64 k_BCJ2 = 0x0303011B;
namespace NArchive {
namespace N7z {
static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
const CRecordVector<CMethodId> decompressionMethods,
CFolder &folder)
void CEncoder::InitBindConv()
{
// bindInfo.CoderMethodIDs.Clear();
// folder.OutStreams.Clear();
folder.BindPairs.SetSize(bindInfo.BindPairs.Size());
unsigned i;
for (i = 0; i < bindInfo.BindPairs.Size(); i++)
unsigned numIn = _bindInfo.Coders.Size();
_SrcIn_to_DestOut.ClearAndSetSize(numIn);
_DestOut_to_SrcIn.ClearAndSetSize(numIn);
unsigned numOut = _bindInfo.GetNum_Bonds_and_PackStreams();
_SrcOut_to_DestIn.ClearAndSetSize(numOut);
// _DestIn_to_SrcOut.ClearAndSetSize(numOut);
UInt32 destIn = 0;
UInt32 destOut = 0;
for (unsigned i = _bindInfo.Coders.Size(); i != 0;)
{
CBindPair &bp = folder.BindPairs[i];
const NCoderMixer::CBindPair &mixerBp = bindInfo.BindPairs[i];
bp.InIndex = mixerBp.InIndex;
bp.OutIndex = mixerBp.OutIndex;
i--;
const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i];
numIn--;
numOut -= coder.NumStreams;
_SrcIn_to_DestOut[numIn] = destOut;
_DestOut_to_SrcIn[destOut] = numIn;
destOut++;
for (UInt32 j = 0; j < coder.NumStreams; j++, destIn++)
{
UInt32 index = numOut + j;
_SrcOut_to_DestIn[index] = destIn;
// _DestIn_to_SrcOut[destIn] = index;
}
}
folder.Coders.SetSize(bindInfo.Coders.Size());
for (i = 0; i < bindInfo.Coders.Size(); i++)
}
void CEncoder::SetFolder(CFolder &folder)
{
folder.Bonds.SetSize(_bindInfo.Bonds.Size());
unsigned i;
for (i = 0; i < _bindInfo.Bonds.Size(); i++)
{
CBond &fb = folder.Bonds[i];
const NCoderMixer2::CBond &mixerBond = _bindInfo.Bonds[_bindInfo.Bonds.Size() - 1 - i];
fb.PackIndex = _SrcOut_to_DestIn[mixerBond.PackIndex];
fb.UnpackIndex = _SrcIn_to_DestOut[mixerBond.UnpackIndex];
}
folder.Coders.SetSize(_bindInfo.Coders.Size());
for (i = 0; i < _bindInfo.Coders.Size(); i++)
{
CCoderInfo &coderInfo = folder.Coders[i];
const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
coderInfo.MethodID = decompressionMethods[i];
// coderInfo.Props can be nonFree;
const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i];
coderInfo.NumStreams = coderStreamsInfo.NumStreams;
coderInfo.MethodID = _decompressionMethods[i];
// we don't free coderInfo.Props here. So coderInfo.Props can be non-empty.
}
folder.PackStreams.SetSize(bindInfo.InStreams.Size());
for (i = 0; i < bindInfo.InStreams.Size(); i++)
folder.PackStreams[i] = bindInfo.InStreams[i];
folder.PackStreams.SetSize(_bindInfo.PackStreams.Size());
for (i = 0; i < _bindInfo.PackStreams.Size(); i++)
folder.PackStreams[i] = _SrcOut_to_DestIn[_bindInfo.PackStreams[i]];
}
static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
{
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
@@ -58,30 +95,75 @@ static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce,
return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
}
void CMtEncMultiProgress::Init(ICompressProgressInfo *progress)
{
_progress = progress;
OutSize = 0;
}
STDMETHODIMP CMtEncMultiProgress::SetRatioInfo(const UInt64 *inSize, const UInt64 * /* outSize */)
{
UInt64 outSize2;
{
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
#endif
outSize2 = OutSize;
}
if (_progress)
return _progress->SetRatioInfo(inSize, &outSize2);
return S_OK;
}
HRESULT CEncoder::CreateMixerCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce)
{
_mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
_mixerCoder = _mixerCoderSpec;
RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
#ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
if (_options.MultiThreadMixer)
#endif
{
_mixerMT = new NCoderMixer2::CMixerMT(true);
_mixerRef = _mixerMT;
_mixer = _mixerMT;
}
#ifdef USE_MIXER_ST
else
#endif
#endif
{
#ifdef USE_MIXER_ST
_mixerST = new NCoderMixer2::CMixerST(true);
_mixerRef = _mixerST;
_mixer = _mixerST;
#endif
}
RINOK(_mixer->SetBindInfo(_bindInfo));
FOR_VECTOR (i, _options.Methods)
{
const CMethodFull &methodFull = _options.Methods[i];
CCoderInfo &encodingInfo = _codersInfo.AddNew();
encodingInfo.MethodID = methodFull.Id;
CMyComPtr<ICompressCoder> encoder;
CMyComPtr<ICompressCoder2> encoder2;
CCreatedCoder cod;
RINOK(CreateCoder(
EXTERNAL_CODECS_LOC_VARS
methodFull.Id, encoder, encoder2, true));
methodFull.Id, true, cod));
if (!encoder && !encoder2)
if (cod.NumStreams != methodFull.NumStreams)
return E_FAIL;
if (!cod.Coder && !cod.Coder2)
return E_FAIL;
CMyComPtr<IUnknown> encoderCommon = encoder ? (IUnknown *)encoder : (IUnknown *)encoder2;
CMyComPtr<IUnknown> encoderCommon = cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2;
#ifndef _7ZIP_ST
{
@@ -105,21 +187,25 @@ HRESULT CEncoder::CreateMixerCoder(
}
*/
// now there is no codec that uses another external codec
/*
#ifdef EXTERNAL_CODECS
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
if (setCompressCodecsInfo)
{
// we must use g_ExternalCodecs also
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
}
#endif
*/
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
if (cryptoSetPassword)
{
const UInt32 sizeInBytes = _options.Password.Len() * 2;
const unsigned sizeInBytes = _options.Password.Len() * 2;
CByteBuffer buffer(sizeInBytes);
for (unsigned i = 0; i < _options.Password.Len(); i++)
{
@@ -127,21 +213,79 @@ HRESULT CEncoder::CreateMixerCoder(
((Byte *)buffer)[i * 2] = (Byte)c;
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
}
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));
RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)sizeInBytes));
}
if (encoder)
_mixerCoderSpec->AddCoder(encoder);
else
_mixerCoderSpec->AddCoder2(encoder2);
_mixer->AddCoder(cod);
}
return S_OK;
}
class CSequentialOutTempBufferImp2:
public ISequentialOutStream,
public CMyUnknownImp
{
CInOutTempBuffer *_buf;
public:
CMtEncMultiProgress *_mtProgresSpec;
CSequentialOutTempBufferImp2(): _buf(0), _mtProgresSpec(NULL) {}
void Init(CInOutTempBuffer *buffer) { _buf = buffer; }
MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)
{
if (!_buf->Write(data, size))
{
if (processed)
*processed = 0;
return E_FAIL;
}
if (processed)
*processed = size;
if (_mtProgresSpec)
_mtProgresSpec->AddOutSize(size);
return S_OK;
}
class CSequentialOutMtNotify:
public ISequentialOutStream,
public CMyUnknownImp
{
public:
CMyComPtr<ISequentialOutStream> _stream;
CMtEncMultiProgress *_mtProgresSpec;
CSequentialOutMtNotify(): _mtProgresSpec(NULL) {}
MY_UNKNOWN_IMP1(ISequentialOutStream)
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
};
STDMETHODIMP CSequentialOutMtNotify::Write(const void *data, UInt32 size, UInt32 *processed)
{
UInt32 realProcessed = 0;
HRESULT res = _stream->Write(data, size, &realProcessed);
if (processed)
*processed = realProcessed;
if (_mtProgresSpec)
_mtProgresSpec->AddOutSize(size);
return res;
}
HRESULT CEncoder::Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
// const UInt64 *inStreamSize,
const UInt64 *inSizeForReduce,
CFolder &folderItem,
CRecordVector<UInt64> &coderUnpackSizes,
UInt64 &unpackSize,
@@ -151,27 +295,37 @@ HRESULT CEncoder::Encode(
{
RINOK(EncoderConstr());
if (!_mixerCoderSpec)
if (!_mixerRef)
{
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
}
_mixerCoderSpec->ReInit();
// _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);
_mixer->ReInit();
CMtEncMultiProgress *mtProgressSpec = NULL;
CMyComPtr<ICompressProgressInfo> mtProgress;
CSequentialOutMtNotify *mtOutStreamNotifySpec = NULL;
CMyComPtr<ISequentialOutStream> mtOutStreamNotify;
CObjectVector<CInOutTempBuffer> inOutTempBuffers;
CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
CObjectVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs;
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
unsigned numMethods = _bindInfo.Coders.Size();
unsigned i;
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
iotb.Create();
iotb.InitWriting();
}
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
CSequentialOutTempBufferImp *tempBufferSpec = new CSequentialOutTempBufferImp;
CSequentialOutTempBufferImp2 *tempBufferSpec = new CSequentialOutTempBufferImp2;
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
tempBuffers.Add(tempBuffer);
@@ -179,94 +333,111 @@ HRESULT CEncoder::Encode(
}
for (i = 0; i < numMethods; i++)
_mixerCoderSpec->SetCoderInfo(i, NULL, NULL);
_mixer->SetCoderInfo(i, NULL, NULL);
if (_bindInfo.InStreams.IsEmpty())
return E_FAIL;
UInt32 mainCoderIndex, mainStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
/* inStreamSize can be used by BCJ2 to set optimal range of conversion.
But current BCJ2 encoder uses also another way to check exact size of current file.
So inStreamSize is not required. */
/*
if (inStreamSize)
{
CRecordVector<const UInt64 *> sizePointers;
for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)
if (i == mainStreamIndex)
sizePointers.Add(inStreamSize);
else
sizePointers.Add(NULL);
_mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);
}
_mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL);
*/
// UInt64 outStreamStartPos;
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
CMyComPtr<ISequentialOutStream> outStreamSizeCount;
inStreamSizeCountSpec->Init(inStream);
CRecordVector<ISequentialInStream *> inStreamPointers;
ISequentialInStream *inStreamPointer = inStreamSizeCount;
CRecordVector<ISequentialOutStream *> outStreamPointers;
inStreamPointers.Add(inStreamSizeCount);
if (_bindInfo.OutStreams.Size() != 0)
{
outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
outStreamSizeCount = outStreamSizeCountSpec;
outStreamSizeCountSpec->SetStream(outStream);
outStreamSizeCountSpec->Init();
outStreamPointers.Add(outStreamSizeCount);
}
SetFolder(folderItem);
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
outStreamPointers.Add(tempBuffers[i - 1]);
for (i = 0; i < _codersInfo.Size(); i++)
for (i = 0; i < numMethods; i++)
{
CCoderInfo &encodingInfo = _codersInfo[i];
IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
CMyComPtr<ICryptoResetInitVector> resetInitVector;
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
if (resetInitVector)
{
resetInitVector->ResetInitVector();
}
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
CByteBuffer &props = folderItem.Coders[numMethods - 1 - i].Props;
if (writeCoderProperties)
{
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream);
outStreamSpec->CopyToBuffer(encodingInfo.Props);
writeCoderProperties->WriteCoderProperties(dynOutStream);
outStreamSpec->CopyToBuffer(props);
}
else
props.Free();
}
_mixer->SelectMainCoder(false);
UInt32 mainCoder = _mixer->MainCoderIndex;
bool useMtProgress = false;
if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder))
{
#ifdef _7ZIP_ST
if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder))
#endif
useMtProgress = true;
}
if (useMtProgress)
{
mtProgressSpec = new CMtEncMultiProgress;
mtProgress = mtProgressSpec;
mtProgressSpec->Init(compressProgress);
mtOutStreamNotifySpec = new CSequentialOutMtNotify;
mtOutStreamNotify = mtOutStreamNotifySpec;
mtOutStreamNotifySpec->_stream = outStream;
mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
FOR_VECTOR(i, tempBufferSpecs)
{
tempBufferSpecs[i]->_mtProgresSpec = mtProgressSpec;
}
}
UInt32 progressIndex = mainCoderIndex;
for (i = 0; i + 1 < _codersInfo.Size(); i++)
if (_bindInfo.PackStreams.Size() != 0)
{
UInt64 m = _codersInfo[i].MethodID;
if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
progressIndex = i + 1;
outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
outStreamSizeCount = outStreamSizeCountSpec;
outStreamSizeCountSpec->SetStream(mtOutStreamNotify ? (ISequentialOutStream *)mtOutStreamNotify : outStream);
outStreamSizeCountSpec->Init();
outStreamPointers.Add(outStreamSizeCount);
}
_mixerCoderSpec->SetProgressCoderIndex(progressIndex);
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
outStreamPointers.Add(tempBuffers[i - 1]);
RINOK(_mixer->Code(
&inStreamPointer,
&outStreamPointers.Front(),
mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
if (_bindInfo.OutStreams.Size() != 0)
if (_bindInfo.PackStreams.Size() != 0)
packSizes.Add(outStreamSizeCountSpec->GetSize());
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
{
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
RINOK(inOutTempBuffer.WriteToStream(outStream));
@@ -274,37 +445,45 @@ HRESULT CEncoder::Encode(
}
unpackSize = 0;
for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
for (i = 0; i < _bindInfo.Coders.Size(); i++)
{
int binder = _bindInfo.FindBinderForInStream(
_bindReverseConverter->DestOutToSrcInMap[i]);
int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]);
UInt64 streamSize;
if (binder < 0)
if (bond < 0)
{
streamSize = inStreamSizeCountSpec->GetSize();
unpackSize = streamSize;
}
else
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
streamSize = _mixer->GetBondStreamSize(bond);
coderUnpackSizes.Add(streamSize);
}
for (i = 0; i < numMethods; i++)
folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
return S_OK;
}
CEncoder::CEncoder(const CCompressionMethodMode &options):
_bindReverseConverter(0),
_constructed(false)
_constructed(false)
{
if (options.IsEmpty())
throw 1;
_options = options;
_mixerCoderSpec = NULL;
#ifdef USE_MIXER_ST
_mixerST = NULL;
#endif
#ifdef USE_MIXER_MT
_mixerMT = NULL;
#endif
_mixer = NULL;
}
HRESULT CEncoder::EncoderConstr()
{
if (_constructed)
@@ -314,112 +493,125 @@ HRESULT CEncoder::EncoderConstr()
// it has only password method;
if (!_options.PasswordIsDefined)
throw 1;
if (!_options.Binds.IsEmpty())
if (!_options.Bonds.IsEmpty())
throw 1;
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
CMethodFull method;
method.NumInStreams = 1;
method.NumOutStreams = 1;
coderStreamsInfo.NumInStreams = 1;
coderStreamsInfo.NumOutStreams = 1;
method.Id = k_AES;
method.NumStreams = 1;
_options.Methods.Add(method);
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
coderStreamsInfo.NumStreams = 1;
_bindInfo.Coders.Add(coderStreamsInfo);
_bindInfo.InStreams.Add(0);
_bindInfo.OutStreams.Add(0);
_bindInfo.PackStreams.Add(0);
_bindInfo.UnpackCoder = 0;
}
else
{
UInt32 numInStreams = 0, numOutStreams = 0;
UInt32 numOutStreams = 0;
unsigned i;
for (i = 0; i < _options.Methods.Size(); i++)
{
const CMethodFull &methodFull = _options.Methods[i];
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
if (_options.Binds.IsEmpty())
NCoderMixer2::CCoderStreamsInfo cod;
cod.NumStreams = methodFull.NumStreams;
if (_options.Bonds.IsEmpty())
{
if (i < _options.Methods.Size() - 1)
// if there are no bonds in options, we create bonds via first streams of coders
if (i != _options.Methods.Size() - 1)
{
NCoderMixer::CBindPair bindPair;
bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
bindPair.OutIndex = numOutStreams;
_bindInfo.BindPairs.Add(bindPair);
NCoderMixer2::CBond bond;
bond.PackIndex = numOutStreams;
bond.UnpackIndex = i + 1; // it's next coder
_bindInfo.Bonds.Add(bond);
}
else if (coderStreamsInfo.NumOutStreams != 0)
_bindInfo.OutStreams.Insert(0, numOutStreams);
for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
_bindInfo.OutStreams.Add(numOutStreams + j);
else if (cod.NumStreams != 0)
_bindInfo.PackStreams.Insert(0, numOutStreams);
for (UInt32 j = 1; j < cod.NumStreams; j++)
_bindInfo.PackStreams.Add(numOutStreams + j);
}
numInStreams += coderStreamsInfo.NumInStreams;
numOutStreams += coderStreamsInfo.NumOutStreams;
numOutStreams += cod.NumStreams;
_bindInfo.Coders.Add(coderStreamsInfo);
_bindInfo.Coders.Add(cod);
}
if (!_options.Binds.IsEmpty())
if (!_options.Bonds.IsEmpty())
{
for (i = 0; i < _options.Binds.Size(); i++)
for (i = 0; i < _options.Bonds.Size(); i++)
{
NCoderMixer::CBindPair bindPair;
const CBind &bind = _options.Binds[i];
bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
_bindInfo.BindPairs.Add(bindPair);
NCoderMixer2::CBond mixerBond;
const CBond2 &bond = _options.Bonds[i];
if (bond.InCoder >= _bindInfo.Coders.Size()
|| bond.OutCoder >= _bindInfo.Coders.Size()
|| bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams)
return E_INVALIDARG;
mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream;
mixerBond.UnpackIndex = bond.InCoder;
_bindInfo.Bonds.Add(mixerBond);
}
for (i = 0; i < (int)numOutStreams; i++)
if (_bindInfo.FindBinderForOutStream(i) == -1)
_bindInfo.OutStreams.Add(i);
for (i = 0; i < numOutStreams; i++)
if (_bindInfo.FindBond_for_PackStream(i) == -1)
_bindInfo.PackStreams.Add(i);
}
for (i = 0; i < (int)numInStreams; i++)
if (_bindInfo.FindBinderForInStream(i) == -1)
_bindInfo.InStreams.Add(i);
if (!_bindInfo.SetUnpackCoder())
return E_INVALIDARG;
if (_bindInfo.InStreams.IsEmpty())
throw 1; // this is error
if (!_bindInfo.CalcMapsAndCheck())
return E_INVALIDARG;
// Make main stream first in list
int inIndex = _bindInfo.InStreams[0];
for (;;)
if (_bindInfo.PackStreams.Size() != 1)
{
UInt32 coderIndex, coderStreamIndex;
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
int binder = _bindInfo.FindBinderForOutStream(outIndex);
if (binder >= 0)
/* main_PackStream is pack stream of main path of coders tree.
We find main_PackStream, and place to start of list of out streams.
It allows to use more optimal memory usage for temp buffers,
if main_PackStream is largest stream. */
UInt32 ci = _bindInfo.UnpackCoder;
for (;;)
{
inIndex = _bindInfo.BindPairs[binder].InIndex;
continue;
}
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
if (_bindInfo.OutStreams[i] == outIndex)
{
_bindInfo.OutStreams.Delete(i);
_bindInfo.OutStreams.Insert(0, outIndex);
if (_bindInfo.Coders[ci].NumStreams == 0)
break;
UInt32 outIndex = _bindInfo.Coder_to_Stream[ci];
int bond = _bindInfo.FindBond_for_PackStream(outIndex);
if (bond >= 0)
{
ci = _bindInfo.Bonds[bond].UnpackIndex;
continue;
}
break;
int i = _bindInfo.FindStream_in_PackStreams(outIndex);
if (i >= 0)
_bindInfo.PackStreams.MoveToFront(i);
break;
}
}
if (_options.PasswordIsDefined)
{
unsigned numCryptoStreams = _bindInfo.OutStreams.Size();
unsigned numCryptoStreams = _bindInfo.PackStreams.Size();
unsigned numInStreams = _bindInfo.Coders.Size();
for (i = 0; i < numCryptoStreams; i++)
{
NCoderMixer::CBindPair bindPair;
bindPair.InIndex = numInStreams + i;
bindPair.OutIndex = _bindInfo.OutStreams[i];
_bindInfo.BindPairs.Add(bindPair);
NCoderMixer2::CBond bond;
bond.UnpackIndex = numInStreams + i;
bond.PackIndex = _bindInfo.PackStreams[i];
_bindInfo.Bonds.Add(bond);
}
_bindInfo.OutStreams.Clear();
_bindInfo.PackStreams.Clear();
/*
if (numCryptoStreams == 0)
@@ -428,37 +620,37 @@ HRESULT CEncoder::EncoderConstr()
for (i = 0; i < numCryptoStreams; i++)
{
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
CMethodFull method;
method.NumInStreams = 1;
method.NumOutStreams = 1;
coderStreamsInfo.NumInStreams = method.NumOutStreams;
coderStreamsInfo.NumOutStreams = method.NumInStreams;
method.NumStreams = 1;
method.Id = k_AES;
_options.Methods.Add(method);
_bindInfo.Coders.Add(coderStreamsInfo);
_bindInfo.OutStreams.Add(numOutStreams + i);
NCoderMixer2::CCoderStreamsInfo cod;
cod.NumStreams = 1;
_bindInfo.Coders.Add(cod);
_bindInfo.PackStreams.Add(numOutStreams++);
}
}
}
for (int i = _options.Methods.Size() - 1; i >= 0; i--)
{
const CMethodFull &methodFull = _options.Methods[i];
_decompressionMethods.Add(methodFull.Id);
}
for (unsigned i = _options.Methods.Size(); i != 0;)
_decompressionMethods.Add(_options.Methods[--i].Id);
_bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
_bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
if (_bindInfo.Coders.Size() > 16)
return E_INVALIDARG;
if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16)
return E_INVALIDARG;
if (!_bindInfo.CalcMapsAndCheck())
return E_INVALIDARG;
InitBindConv();
_constructed = true;
return S_OK;
}
CEncoder::~CEncoder()
{
delete _bindReverseConverter;
}
CEncoder::~CEncoder() {}
}}

View File

@@ -3,47 +3,82 @@
#ifndef __7Z_ENCODE_H
#define __7Z_ENCODE_H
// #include "../../Common/StreamObjects.h"
#include "7zCompressionMode.h"
#include "../Common/CoderMixer2.h"
#include "../Common/CoderMixer2MT.h"
#ifdef _ST_MODE
#include "../Common/CoderMixer2ST.h"
#endif
#include "7zItem.h"
#include "../../Common/CreateCoder.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
class CMtEncMultiProgress:
public ICompressProgressInfo,
public CMyUnknownImp
{
CMyComPtr<ICompressProgressInfo> _progress;
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSection CriticalSection;
#endif
public:
UInt64 OutSize;
CMtEncMultiProgress(): OutSize(0) {}
void Init(ICompressProgressInfo *progress);
void AddOutSize(UInt64 addOutSize)
{
#ifndef _7ZIP_ST
NWindows::NSynchronization::CCriticalSectionLock lock(CriticalSection);
#endif
OutSize += addOutSize;
}
MY_UNKNOWN_IMP1(ICompressProgressInfo)
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
class CEncoder
{
NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;
CMyComPtr<ICompressCoder2> _mixerCoder;
CObjectVector<CCoderInfo> _codersInfo;
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
#endif
#ifdef USE_MIXER_MT
NCoderMixer2::CMixerMT *_mixerMT;
#endif
NCoderMixer2::CMixer *_mixer;
CMyComPtr<IUnknown> _mixerRef;
CCompressionMethodMode _options;
NCoderMixer::CBindInfo _bindInfo;
NCoderMixer::CBindInfo _decompressBindInfo;
NCoderMixer::CBindReverseConverter *_bindReverseConverter;
NCoderMixer2::CBindInfo _bindInfo;
CRecordVector<CMethodId> _decompressionMethods;
CRecordVector<UInt32> _SrcIn_to_DestOut;
CRecordVector<UInt32> _SrcOut_to_DestIn;
// CRecordVector<UInt32> _DestIn_to_SrcOut;
CRecordVector<UInt32> _DestOut_to_SrcIn;
void InitBindConv();
void SetFolder(CFolder &folder);
HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce);
bool _constructed;
public:
CEncoder(const CCompressionMethodMode &options);
~CEncoder();
HRESULT EncoderConstr();
HRESULT Encode(
DECL_EXTERNAL_CODECS_LOC_VARS
ISequentialInStream *inStream,
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
// const UInt64 *inStreamSize,
const UInt64 *inSizeForReduce,
CFolder &folderItem,
CRecordVector<UInt64> &coderUnpackSizes,
UInt64 &unpackSize,

View File

@@ -2,205 +2,327 @@
#include "StdAfx.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/ComTry.h"
#include "../../Common/ProgressUtils.h"
#include "7zDecode.h"
// #include "7z1Decode.h"
#include "7zFolderOutStream.h"
#include "7zHandler.h"
// EXTERN_g_ExternalCodecs
namespace NArchive {
namespace N7z {
struct CExtractFolderInfo
class CFolderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
#ifdef _7Z_VOL
int VolumeIndex;
#endif
CNum FileIndex;
CNum FolderIndex;
CBoolVector ExtractStatuses;
UInt64 UnpackSize;
CExtractFolderInfo(
#ifdef _7Z_VOL
int volumeIndex,
#endif
CNum fileIndex, CNum folderIndex):
#ifdef _7Z_VOL
VolumeIndex(volumeIndex),
#endif
FileIndex(fileIndex),
FolderIndex(folderIndex),
UnpackSize(0)
{
if (fileIndex != kNumNoIndex)
{
ExtractStatuses.ClearAndSetSize(1);
ExtractStatuses[0] = true;
}
};
CMyComPtr<ISequentialOutStream> _stream;
public:
bool TestMode;
bool CheckCrc;
private:
bool _fileIsOpen;
bool _calcCrc;
UInt32 _crc;
UInt64 _rem;
const UInt32 *_indexes;
unsigned _numFiles;
unsigned _fileIndex;
HRESULT OpenFile(bool isCorrupted = false);
HRESULT CloseFile_and_SetResult(Int32 res);
HRESULT CloseFile();
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP1(ISequentialOutStream)
const CDbEx *_db;
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
bool ExtraWriteWasCut;
CFolderOutStream():
TestMode(false),
CheckCrc(true)
{}
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles);
HRESULT FlushCorrupted(Int32 callbackOperationResult);
bool WasWritingFinished() const { return _numFiles == 0; }
};
HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles)
{
_fileIndex = startIndex;
_indexes = indexes;
_numFiles = numFiles;
_fileIsOpen = false;
ExtraWriteWasCut = false;
return ProcessEmptyFiles();
}
HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
{
const CFileItem &fi = _db->Files[_fileIndex];
UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
Int32 askMode = (_fileIndex == nextFileIndex) ?
(TestMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
if (isCorrupted
&& askMode == NExtract::NAskMode::kExtract
&& !_db->IsItemAnti(_fileIndex)
&& !fi.IsDir)
askMode = NExtract::NAskMode::kTest;
CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode));
_stream = realOutStream;
_crc = CRC_INIT_VAL;
_calcCrc = (CheckCrc && fi.CrcDefined && !fi.IsDir);
_fileIsOpen = true;
_rem = fi.Size;
if (askMode == NExtract::NAskMode::kExtract
&& !realOutStream
&& !_db->IsItemAnti(_fileIndex)
&& !fi.IsDir)
askMode = NExtract::NAskMode::kSkip;
return ExtractCallback->PrepareOperation(askMode);
}
HRESULT CFolderOutStream::CloseFile_and_SetResult(Int32 res)
{
_stream.Release();
_fileIsOpen = false;
if (!_indexes)
_numFiles--;
else if (*_indexes == _fileIndex)
{
_indexes++;
_numFiles--;
}
_fileIndex++;
return ExtractCallback->SetOperationResult(res);
}
HRESULT CFolderOutStream::CloseFile()
{
const CFileItem &fi = _db->Files[_fileIndex];
return CloseFile_and_SetResult((!_calcCrc || fi.Crc == CRC_GET_DIGEST(_crc)) ?
NExtract::NOperationResult::kOK :
NExtract::NOperationResult::kCRCError);
}
HRESULT CFolderOutStream::ProcessEmptyFiles()
{
while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0)
{
RINOK(OpenFile());
RINOK(CloseFile());
}
return S_OK;
}
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
while (size != 0)
{
if (_fileIsOpen)
{
UInt32 cur = (size < _rem ? size : (UInt32)_rem);
HRESULT result = S_OK;
if (_stream)
result = _stream->Write(data, cur, &cur);
if (_calcCrc)
_crc = CrcUpdate(_crc, data, cur);
if (processedSize)
*processedSize += cur;
data = (const Byte *)data + cur;
size -= cur;
_rem -= cur;
if (_rem == 0)
{
RINOK(CloseFile());
RINOK(ProcessEmptyFiles());
}
RINOK(result);
if (cur == 0)
break;
continue;
}
RINOK(ProcessEmptyFiles());
if (_numFiles == 0)
{
// we support partial extracting
/*
if (processedSize)
*processedSize += size;
break;
*/
ExtraWriteWasCut = true;
// return S_FALSE;
return k_My_HRESULT_WritingWasCut;
}
RINOK(OpenFile());
}
return S_OK;
}
HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
{
while (_numFiles != 0)
{
if (_fileIsOpen)
{
RINOK(CloseFile_and_SetResult(callbackOperationResult));
}
else
{
RINOK(OpenFile(true));
}
}
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{
COM_TRY_BEGIN
bool testMode = (testModeSpec != 0);
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UInt64 importantTotalUnpacked = 0;
// numItems = (UInt32)(Int32)-1;
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems =
#ifdef _7Z_VOL
_refs.Size();
#else
_db.Files.Size();
#endif
numItems = _db.Files.Size();
if(numItems == 0)
if (numItems == 0)
return S_OK;
/*
if(_volumes.Size() != 1)
return E_FAIL;
const CVolume &volume = _volumes.Front();
const CDbEx &_db = volume.Database;
IInStream *_inStream = volume.Stream;
*/
CObjectVector<CExtractFolderInfo> extractFolderInfoVector;
for (UInt32 ii = 0; ii < numItems; ii++)
{
// UInt32 fileIndex = allFilesMode ? indexIndex : indices[indexIndex];
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
// const CRef2 &ref2 = _refs[ref2Index];
// for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
CNum prevFolder = kNumNoIndex;
UInt32 nextFile = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
#ifdef _7Z_VOL
// const CRef &ref = ref2.Refs[ri];
const CRef &ref = _refs[ref2Index];
int volumeIndex = ref.VolumeIndex;
const CVolume &volume = _volumes[volumeIndex];
const CDbEx &db = volume.Database;
UInt32 fileIndex = ref.ItemIndex;
#else
const CDbEx &db = _db;
UInt32 fileIndex = ref2Index;
#endif
CNum folderIndex = db.FileIndexToFolderIndexMap[fileIndex];
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
if (folderIndex == kNumNoIndex)
{
extractFolderInfoVector.Add(CExtractFolderInfo(
#ifdef _7Z_VOL
volumeIndex,
#endif
fileIndex, kNumNoIndex));
continue;
}
if (extractFolderInfoVector.IsEmpty() ||
folderIndex != extractFolderInfoVector.Back().FolderIndex
#ifdef _7Z_VOL
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
#endif
)
{
extractFolderInfoVector.Add(CExtractFolderInfo(
#ifdef _7Z_VOL
volumeIndex,
#endif
kNumNoIndex, folderIndex));
UInt64 unpackSize = db.GetFolderUnpackSize(folderIndex);
importantTotalUnpacked += unpackSize;
extractFolderInfoVector.Back().UnpackSize = unpackSize;
}
CExtractFolderInfo &efi = extractFolderInfoVector.Back();
// const CFolderInfo &folderInfo = m_dam_Folders[folderIndex];
CNum startIndex = db.FolderStartFileIndex[folderIndex];
for (CNum index = efi.ExtractStatuses.Size();
index <= fileIndex - startIndex; index++)
{
// UInt64 unpackSize = _db.Files[startIndex + index].UnpackSize;
// Count partial_folder_size
// efi.UnpackSize += unpackSize;
// importantTotalUnpacked += unpackSize;
efi.ExtractStatuses.Add(index == fileIndex - startIndex);
}
if (folderIndex != prevFolder || fileIndex < nextFile)
nextFile = _db.FolderStartFileIndex[folderIndex];
for (CNum index = nextFile; index <= fileIndex; index++)
importantTotalUnpacked += _db.Files[index].Size;
nextFile = fileIndex + 1;
prevFolder = folderIndex;
}
}
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
CDecoder decoder(
#ifdef _ST_MODE
false
#else
true
#endif
);
// CDecoder1 decoder;
UInt64 totalPacked = 0;
UInt64 totalUnpacked = 0;
UInt64 curPacked, curUnpacked;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for (unsigned i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
CDecoder decoder(
#ifndef USE_MIXER_ST
false
#else
_useMultiThreadMixer
#endif
);
UInt64 curPacked, curUnpacked;
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
folderOutStream->_db = &_db;
folderOutStream->ExtractCallback = extractCallback;
folderOutStream->TestMode = (testModeSpec != 0);
folderOutStream->CheckCrc = (_crcSize != 0);
for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
{
lps->OutSize = totalUnpacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
if (i >= extractFolderInfoVector.Size())
if (i >= numItems)
break;
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
curUnpacked = efi.UnpackSize;
curUnpacked = 0;
curPacked = 0;
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
UInt32 fileIndex = allFilesMode ? i : indices[i];
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
#ifdef _7Z_VOL
const CVolume &volume = _volumes[efi.VolumeIndex];
const CDbEx &db = volume.Database;
#else
const CDbEx &db = _db;
#endif
UInt32 numSolidFiles = 1;
CNum startIndex;
if (efi.FileIndex != kNumNoIndex)
startIndex = efi.FileIndex;
else
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
if (folderIndex != kNumNoIndex)
{
curPacked = _db.GetFolderFullPackSize(folderIndex);
UInt32 nextFile = fileIndex + 1;
fileIndex = _db.FolderStartFileIndex[folderIndex];
UInt32 k;
HRESULT result = folderOutStream->Init(&db,
#ifdef _7Z_VOL
volume.StartRef2Index,
#else
0,
#endif
startIndex,
&efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
for (k = i + 1; k < numItems; k++)
{
UInt32 fileIndex2 = allFilesMode ? k : indices[k];
if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex
|| fileIndex2 < nextFile)
break;
nextFile = fileIndex2 + 1;
}
numSolidFiles = k - i;
for (k = fileIndex; k < nextFile; k++)
curUnpacked += _db.Files[k].Size;
}
HRESULT result = folderOutStream->Init(fileIndex,
allFilesMode ? NULL : indices + i,
numSolidFiles);
i += numSolidFiles;
RINOK(result);
if (efi.FileIndex != kNumNoIndex)
// to test solid block with zero unpacked size we disable that code
if (folderOutStream->WasWritingFinished())
continue;
CNum folderIndex = efi.FolderIndex;
curPacked = _db.GetFolderFullPackSize(folderIndex);
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
if (extractCallback)
@@ -212,50 +334,64 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
#ifndef _NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
UString password;
#endif
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
volume.Stream,
#else
_inStream,
#endif
db.ArcInfo.DataStartPosition,
db, folderIndex,
_inStream,
_db.ArcInfo.DataStartPosition,
_db, folderIndex,
&curUnpacked,
outStream,
progress
progress,
NULL // *inStreamMainRes
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, true, _numThreads
#endif
);
if (result == S_FALSE)
if (result == S_FALSE || result == E_NOTIMPL)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
continue;
}
if (result == E_NOTIMPL)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kUnsupportedMethod));
bool wasFinished = folderOutStream->WasWritingFinished();
int resOp = (result == S_FALSE ?
NExtract::NOperationResult::kDataError :
NExtract::NOperationResult::kUnsupportedMethod);
RINOK(folderOutStream->FlushCorrupted(resOp));
if (wasFinished)
{
// we don't show error, if it's after required files
if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage)
{
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp));
}
}
continue;
}
if (result != S_OK)
return result;
if (folderOutStream->WasWritingFinished() != S_OK)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
continue;
}
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
continue;
}
catch(...)
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
continue;
// continue;
return E_FAIL;
}
}
return S_OK;
COM_TRY_END
}

View File

@@ -7,96 +7,103 @@
namespace NArchive {
namespace N7z {
CFolderInStream::CFolderInStream()
{
_inStreamWithHashSpec = new CSequentialInStreamWithCRC;
_inStreamWithHash = _inStreamWithHashSpec;
}
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
const UInt32 *fileIndices, UInt32 numFiles)
const UInt32 *indexes, unsigned numFiles)
{
_updateCallback = updateCallback;
_indexes = indexes;
_numFiles = numFiles;
_fileIndex = 0;
_fileIndices = fileIndices;
Processed.Clear();
CRCs.Clear();
Sizes.Clear();
_fileIsOpen = false;
_currentSizeIsDefined = false;
_index = 0;
Processed.ClearAndReserve(numFiles);
CRCs.ClearAndReserve(numFiles);
Sizes.ClearAndReserve(numFiles);
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
_stream.Release();
}
HRESULT CFolderInStream::OpenStream()
{
_filePos = 0;
while (_fileIndex < _numFiles)
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
while (_index < _numFiles)
{
CMyComPtr<ISequentialInStream> stream;
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
if (result != S_OK && result != S_FALSE)
return result;
_fileIndex++;
_inStreamWithHashSpec->SetStream(stream);
_inStreamWithHashSpec->Init();
HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
if (result != S_OK)
{
if (result != S_FALSE)
return result;
}
_stream = stream;
if (stream)
{
_fileIsOpen = true;
CMyComPtr<IStreamGetSize> streamGetSize;
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
if (streamGetSize)
{
RINOK(streamGetSize->GetSize(&_currentSize));
_currentSizeIsDefined = true;
if (streamGetSize->GetSize(&_size) == S_OK)
_size_Defined = true;
}
return S_OK;
}
_index++;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
Sizes.Add(0);
Processed.Add(result == S_OK);
AddDigest();
AddFileInfo(result == S_OK);
}
return S_OK;
}
void CFolderInStream::AddDigest()
void CFolderInStream::AddFileInfo(bool isProcessed)
{
CRCs.Add(_inStreamWithHashSpec->GetCRC());
}
HRESULT CFolderInStream::CloseStream()
{
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
_inStreamWithHashSpec->ReleaseStream();
_fileIsOpen = false;
_currentSizeIsDefined = false;
Processed.Add(true);
Sizes.Add(_filePos);
AddDigest();
return S_OK;
Processed.Add(isProcessed);
Sizes.Add(_pos);
CRCs.Add(CRC_GET_DIGEST(_crc));
}
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != 0)
if (processedSize)
*processedSize = 0;
while (size > 0)
while (size != 0)
{
if (_fileIsOpen)
if (_stream)
{
UInt32 processed2;
RINOK(_inStreamWithHash->Read(data, size, &processed2));
if (processed2 == 0)
RINOK(_stream->Read(data, size, &processed2));
if (processed2 != 0)
{
RINOK(CloseStream());
continue;
_crc = CrcUpdate(_crc, data, processed2);
_pos += processed2;
if (processedSize)
*processedSize = processed2;
return S_OK;
}
if (processedSize != 0)
*processedSize = processed2;
_filePos += processed2;
break;
_stream.Release();
_index++;
AddFileInfo(true);
_pos = 0;
_crc = CRC_INIT_VAL;
_size_Defined = false;
_size = 0;
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
if (_fileIndex >= _numFiles)
if (_index >= _numFiles)
break;
RINOK(OpenStream());
}
@@ -106,17 +113,23 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
unsigned index2 = (unsigned)subStream;
if (subStream > Sizes.Size())
return E_FAIL;
if (index2 < Sizes.Size())
return S_FALSE; // E_FAIL;
unsigned index = (unsigned)subStream;
if (index < Sizes.Size())
{
*value = Sizes[index2];
*value = Sizes[index];
return S_OK;
}
if (!_currentSizeIsDefined)
if (!_size_Defined)
{
*value = _pos;
return S_FALSE;
*value = _currentSize;
}
*value = (_pos > _size ? _pos : _size);
return S_OK;
}

View File

@@ -3,11 +3,13 @@
#ifndef __7Z_FOLDER_IN_STREAM_H
#define __7Z_FOLDER_IN_STREAM_H
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyVector.h"
#include "../../ICoder.h"
#include "../IArchive.h"
#include "../Common/InStreamWithCRC.h"
#include "7zItem.h"
namespace NArchive {
namespace N7z {
@@ -17,33 +19,34 @@ class CFolderInStream:
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
CMyComPtr<ISequentialInStream> _inStreamWithHash;
CMyComPtr<ISequentialInStream> _stream;
UInt64 _pos;
UInt32 _crc;
bool _size_Defined;
UInt64 _size;
const UInt32 *_indexes;
unsigned _numFiles;
unsigned _index;
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
bool _currentSizeIsDefined;
bool _fileIsOpen;
UInt64 _currentSize;
UInt64 _filePos;
const UInt32 *_fileIndices;
UInt32 _numFiles;
UInt32 _fileIndex;
HRESULT OpenStream();
HRESULT CloseStream();
void AddDigest();
void AddFileInfo(bool isProcessed);
public:
CRecordVector<bool> Processed;
CRecordVector<UInt32> CRCs;
CRecordVector<UInt64> Sizes;
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
CFolderInStream();
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
bool WasFinished() const { return _index == _numFiles; }
UInt64 GetFullSize() const
{
UInt64 size = 0;

View File

@@ -1,149 +1,3 @@
// 7zFolderOutStream.cpp
#include "StdAfx.h"
#include "7zFolderOutStream.h"
namespace NArchive {
namespace N7z {
CFolderOutStream::CFolderOutStream()
{
_crcStreamSpec = new COutStreamWithCRC;
_crcStream = _crcStreamSpec;
}
HRESULT CFolderOutStream::Init(
const CDbEx *db,
UInt32 ref2Offset, UInt32 startIndex,
const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback,
bool testMode, bool checkCrc)
{
_db = db;
_ref2Offset = ref2Offset;
_startIndex = startIndex;
_extractStatuses = extractStatuses;
_extractCallback = extractCallback;
_testMode = testMode;
_checkCrc = checkCrc;
_currentIndex = 0;
_fileIsOpen = false;
return ProcessEmptyFiles();
}
HRESULT CFolderOutStream::OpenFile()
{
Int32 askMode = ((*_extractStatuses)[_currentIndex]) ? (_testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
CMyComPtr<ISequentialOutStream> realOutStream;
UInt32 index = _startIndex + _currentIndex;
RINOK(_extractCallback->GetStream(_ref2Offset + index, &realOutStream, askMode));
_crcStreamSpec->SetStream(realOutStream);
_crcStreamSpec->Init(_checkCrc);
_fileIsOpen = true;
const CFileItem &fi = _db->Files[index];
_rem = fi.Size;
if (askMode == NExtract::NAskMode::kExtract && !realOutStream &&
!_db->IsItemAnti(index) && !fi.IsDir)
askMode = NExtract::NAskMode::kSkip;
return _extractCallback->PrepareOperation(askMode);
}
HRESULT CFolderOutStream::CloseFileAndSetResult(Int32 res)
{
_crcStreamSpec->ReleaseStream();
_fileIsOpen = false;
_currentIndex++;
return _extractCallback->SetOperationResult(res);
}
HRESULT CFolderOutStream::CloseFileAndSetResult()
{
const CFileItem &fi = _db->Files[_startIndex + _currentIndex];
return CloseFileAndSetResult(
(fi.IsDir || !fi.CrcDefined || !_checkCrc || fi.Crc == _crcStreamSpec->GetCRC()) ?
NExtract::NOperationResult::kOK :
NExtract::NOperationResult::kCRCError);
}
HRESULT CFolderOutStream::ProcessEmptyFiles()
{
while (_currentIndex < _extractStatuses->Size() && _db->Files[_startIndex + _currentIndex].Size == 0)
{
RINOK(OpenFile());
RINOK(CloseFileAndSetResult());
}
return S_OK;
}
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != NULL)
*processedSize = 0;
while (size != 0)
{
if (_fileIsOpen)
{
UInt32 cur = size < _rem ? size : (UInt32)_rem;
RINOK(_crcStream->Write(data, cur, &cur));
if (cur == 0)
break;
data = (const Byte *)data + cur;
size -= cur;
_rem -= cur;
if (processedSize != NULL)
*processedSize += cur;
if (_rem == 0)
{
RINOK(CloseFileAndSetResult());
RINOK(ProcessEmptyFiles());
continue;
}
}
else
{
RINOK(ProcessEmptyFiles());
if (_currentIndex == _extractStatuses->Size())
{
// we support partial extracting
if (processedSize != NULL)
*processedSize += size;
break;
}
RINOK(OpenFile());
}
}
return S_OK;
}
STDMETHODIMP CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
{
*value = 0;
if ((int)subStream >= _extractStatuses->Size())
return S_FALSE;
*value = _db->Files[_startIndex + (int)subStream].Size;
return S_OK;
}
HRESULT CFolderOutStream::FlushCorrupted(Int32 resultEOperationResult)
{
while (_currentIndex < _extractStatuses->Size())
{
if (_fileIsOpen)
{
RINOK(CloseFileAndSetResult(resultEOperationResult));
}
else
{
RINOK(OpenFile());
}
}
return S_OK;
}
}}

View File

@@ -3,56 +3,4 @@
#ifndef __7Z_FOLDER_OUT_STREAM_H
#define __7Z_FOLDER_OUT_STREAM_H
#include "../../IStream.h"
#include "../IArchive.h"
#include "../Common/OutStreamWithCRC.h"
#include "7zIn.h"
namespace NArchive {
namespace N7z {
class CFolderOutStream:
public ISequentialOutStream,
public ICompressGetSubStreamSize,
public CMyUnknownImp
{
COutStreamWithCRC *_crcStreamSpec;
CMyComPtr<ISequentialOutStream> _crcStream;
const CDbEx *_db;
const CBoolVector *_extractStatuses;
CMyComPtr<IArchiveExtractCallback> _extractCallback;
UInt32 _ref2Offset;
UInt32 _startIndex;
unsigned _currentIndex;
bool _testMode;
bool _checkCrc;
bool _fileIsOpen;
UInt64 _rem;
HRESULT OpenFile();
HRESULT CloseFileAndSetResult(Int32 res);
HRESULT CloseFileAndSetResult();
HRESULT ProcessEmptyFiles();
public:
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
CFolderOutStream();
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
HRESULT Init(
const CDbEx *db,
UInt32 ref2Offset, UInt32 startIndex,
const CBoolVector *extractStatuses,
IArchiveExtractCallback *extractCallback,
bool testMode, bool checkCrc);
HRESULT FlushCorrupted(Int32 resultEOperationResult);
HRESULT WasWritingFinished() const
{ return (_currentIndex == _extractStatuses->Size()) ? S_OK: E_FAIL; }
};
}}
#endif

View File

@@ -150,22 +150,12 @@ static char *AddProp32(char *s, const char *name, UInt32 v)
void CHandler::AddMethodName(AString &s, UInt64 id)
{
UString methodName;
FindMethod(EXTERNAL_CODECS_VARS id, methodName);
if (methodName.IsEmpty())
{
for (unsigned i = 0; i < methodName.Len(); i++)
if (methodName[i] >= 0x80)
{
methodName.Empty();
break;
}
}
if (methodName.IsEmpty())
AString name;
FindMethod(EXTERNAL_CODECS_VARS id, name);
if (name.IsEmpty())
ConvertMethodIdToString(s, id);
else
for (unsigned i = 0; i < methodName.Len(); i++)
s += (char)methodName[i];
s += name;
}
#endif
@@ -186,8 +176,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
FOR_VECTOR (i, pm.IDs)
{
UInt64 id = pm.IDs[i];
if (!s.IsEmpty())
s += ' ';
s.Add_Space_if_NotEmpty();
char temp[16];
if (id == k_LZMA2)
{
@@ -376,6 +365,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
// numCoders == 0 ???
CNum numCoders = inByte.ReadNum();
bool needSpace = false;
for (; numCoders != 0; numCoders--, needSpace = true)
{
if (pos < 32) // max size of property
@@ -500,17 +490,8 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
}
else
{
UString methodName;
AString methodName;
FindMethod(EXTERNAL_CODECS_VARS id64, methodName);
if (methodName.IsEmpty())
{
for (unsigned j = 0; j < methodName.Len(); j++)
if (methodName[j] >= 0x80)
{
methodName.Empty();
break;
}
}
if (needSpace)
temp[--pos] = ' ';
if (methodName.IsEmpty())
@@ -522,10 +503,11 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
break;
pos -= len;
for (unsigned i = 0; i < len; i++)
temp[pos + i] = (char)methodName[i];
temp[pos + i] = methodName[i];
}
}
}
if (numCoders != 0 && pos >= 4)
{
temp[--pos] = ' ';
@@ -533,6 +515,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
temp[--pos] = '.';
temp[--pos] = '.';
}
return PropVarEm_Set_Str(prop, temp + pos);
// }
}
@@ -555,7 +538,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
const CFileItem &item = _db.Files[index];
UInt32 index2 = index;
switch(propID)
switch (propID)
{
case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break;
case kpidSize:
@@ -608,7 +591,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
*/
case kpidPath: return _db.GetPath_Prop(index, value);
#ifndef _SFX
case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
case kpidBlock:
{
@@ -617,30 +602,29 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
}
break;
/*
case kpidPackedSize0:
case kpidPackedSize1:
case kpidPackedSize2:
case kpidPackedSize3:
case kpidPackedSize4:
{
/*
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
const CFolder &folderInfo = _db.Folders[folderIndex];
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
_db.FoStartPackStreamIndex[folderIndex + 1] -
_db.FoStartPackStreamIndex[folderIndex] > (propID - kpidPackedSize0))
{
prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
PropVarEm_Set_UInt64(value, _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0));
}
else
prop = (UInt64)0;
}
else
prop = (UInt64)0;
*/
PropVarEm_Set_UInt64(value, 0);
}
break;
*/
#endif
}
// prop.Detach(value);
@@ -668,7 +652,13 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
#endif
CInArchive archive;
CInArchive archive(
#ifdef __7Z_SET_PROPERTIES
_useMultiThreadMixer
#else
true
#endif
);
_db.IsArc = false;
RINOK(archive.Open(stream, maxCheckStartPosition));
_db.IsArc = true;
@@ -677,7 +667,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
EXTERNAL_CODECS_VARS
_db
#ifndef _NO_CRYPTO
, getTextPassword, _isEncrypted, _passwordIsDefined
, getTextPassword, _isEncrypted, _passwordIsDefined, _password
#endif
);
RINOK(result);
@@ -688,8 +678,9 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{
Close();
// return E_INVALIDARG;
// return S_FALSE;
// we must return out_of_memory here
return S_FALSE;
return E_OUTOFMEMORY;
}
// _inStream = stream;
#ifndef _SFX
@@ -707,6 +698,7 @@ STDMETHODIMP CHandler::Close()
#ifndef _NO_CRYPTO
_isEncrypted = false;
_passwordIsDefined = false;
_password.Empty();
#endif
return S_OK;
COM_TRY_END
@@ -715,11 +707,12 @@ STDMETHODIMP CHandler::Close()
#ifdef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
_numThreads = numProcessors;
_useMultiThreadMixer = true;
for (UInt32 i = 0; i < numProps; i++)
{
@@ -732,7 +725,8 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
int index = ParseStringToUInt32(name, number);
if (index == 0)
{
if (name.IsPrefixedBy(L"mt"))
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
if (name.IsPrefixedBy_Ascii_NoCase("mt"))
{
RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
continue;

View File

@@ -18,16 +18,6 @@
namespace NArchive {
namespace N7z {
const UInt32 k_Copy = 0x0;
const UInt32 k_Delta = 3;
const UInt32 k_LZMA2 = 0x21;
const UInt32 k_LZMA = 0x030101;
const UInt32 k_PPMD = 0x030401;
const UInt32 k_BCJ = 0x03030103;
const UInt32 k_BCJ2 = 0x0303011B;
const UInt32 k_Deflate = 0x040108;
const UInt32 k_BZip2 = 0x040202;
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -64,7 +54,9 @@ public:
CBoolPair Write_ATime;
CBoolPair Write_MTime;
bool _volumeMode;
bool _useMultiThreadMixer;
// bool _volumeMode;
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
@@ -117,7 +109,7 @@ public:
INTERFACE_IArchiveGetRawProps(;)
#ifdef __7Z_SET_PROPERTIES
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps);
STDMETHOD(SetProperties)(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps);
#endif
#ifndef EXTRACT_ONLY
@@ -131,28 +123,29 @@ public:
private:
CMyComPtr<IInStream> _inStream;
NArchive::N7z::CDbEx _db;
#ifndef _NO_CRYPTO
bool _isEncrypted;
bool _passwordIsDefined;
UString _password;
#endif
#ifdef EXTRACT_ONLY
#ifdef __7Z_SET_PROPERTIES
UInt32 _numThreads;
bool _useMultiThreadMixer;
#endif
UInt32 _crcSize;
#else
CRecordVector<CBind> _binds;
CRecordVector<CBond2> _bonds;
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
void AddDefaultMethod();
HRESULT SetMainMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo
HRESULT SetMainMethod(CCompressionMethodMode &method
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif

View File

@@ -18,11 +18,11 @@ using namespace NWindows;
namespace NArchive {
namespace N7z {
static const wchar_t *k_LZMA_Name = L"LZMA";
static const wchar_t *kDefaultMethodName = L"LZMA2";
static const wchar_t *k_Copy_Name = L"Copy";
static const char *k_LZMA_Name = "LZMA";
static const char *kDefaultMethodName = "LZMA2";
static const char *k_Copy_Name = "Copy";
static const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
static const char *k_MatchFinder_ForHeaders = "BT2";
static const UInt32 k_NumFastBytes_ForHeaders = 273;
static const UInt32 k_Level_ForHeaders = 5;
static const UInt32 k_Dictionary_ForHeaders =
@@ -42,7 +42,7 @@ HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodI
{
if (!FindMethod(
EXTERNAL_CODECS_VARS
m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
m.MethodName, dest.Id, dest.NumStreams))
return E_INVALIDARG;
(CProps &)dest = (CProps &)m;
return S_OK;
@@ -54,48 +54,62 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
return S_OK;
COneMethodInfo m;
m.MethodName = k_LZMA_Name;
m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
m.AddProp_Ascii(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
m.AddProp_Level(k_Level_ForHeaders);
m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
m.AddNumThreadsProp(1);
m.AddProp_NumThreads(1);
CMethodFull methodFull;
RINOK(PropsMethod_To_FullMethod(methodFull, m));
headerMethod.Methods.Add(methodFull);
return S_OK;
}
void CHandler::AddDefaultMethod()
{
FOR_VECTOR (i, _methods)
{
UString &methodName = _methods[i].MethodName;
if (methodName.IsEmpty())
methodName = kDefaultMethodName;
}
if (_methods.IsEmpty())
{
COneMethodInfo m;
m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
_methods.Add(m);
}
CMethodFull &methodFull = headerMethod.Methods.AddNew();
return PropsMethod_To_FullMethod(methodFull, m);
}
HRESULT CHandler::SetMainMethod(
CCompressionMethodMode &methodMode,
CObjectVector<COneMethodInfo> &methods
CCompressionMethodMode &methodMode
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
AddDefaultMethod();
methodMode.Bonds = _bonds;
CObjectVector<COneMethodInfo> methods = _methods;
{
FOR_VECTOR (i, methods)
{
AString &methodName = methods[i].MethodName;
if (methodName.IsEmpty())
methodName = kDefaultMethodName;
}
if (methods.IsEmpty())
{
COneMethodInfo &m = methods.AddNew();
m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
methodMode.DefaultMethod_was_Inserted = true;
}
}
if (!_filterMethod.MethodName.IsEmpty())
{
// if (methodMode.Bonds.IsEmpty())
{
FOR_VECTOR (k, methodMode.Bonds)
{
CBond2 &bond = methodMode.Bonds[k];
bond.InCoder++;
bond.OutCoder++;
}
methods.Insert(0, _filterMethod);
methodMode.Filter_was_Inserted = true;
}
}
const UInt64 kSolidBytes_Min = (1 << 24);
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
bool needSolid = false;
FOR_VECTOR (i, methods)
{
COneMethodInfo &oneMethodInfo = methods[i];
@@ -105,9 +119,8 @@ HRESULT CHandler::SetMainMethod(
#endif
);
CMethodFull methodFull;
CMethodFull &methodFull = methodMode.Methods.AddNew();
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
methodMode.Methods.Add(methodFull);
if (methodFull.Id != k_Copy)
needSolid = true;
@@ -125,6 +138,7 @@ HRESULT CHandler::SetMainMethod(
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
default: continue;
}
_numSolidBytes = (UInt64)dicSize << 7;
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
@@ -517,18 +531,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CCompressionMethodMode methodMode, headerMethod;
HRESULT res = SetMainMethod(methodMode, _methods
HRESULT res = SetMainMethod(methodMode
#ifndef _7ZIP_ST
, _numThreads
#endif
);
RINOK(res);
methodMode.Binds = _binds;
RINOK(SetHeaderMethod(headerMethod));
#ifndef _7ZIP_ST
methodMode.NumThreads = _numThreads;
methodMode.MultiThreadMixer = _useMultiThreadMixer;
headerMethod.NumThreads = 1;
headerMethod.MultiThreadMixer = _useMultiThreadMixer;
#endif
CMyComPtr<ICryptoGetTextPassword2> getPassword2;
@@ -542,7 +558,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
Int32 passwordIsDefined;
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
if (methodMode.PasswordIsDefined && (BSTR)password)
if (methodMode.PasswordIsDefined && password)
methodMode.Password = password;
}
@@ -550,6 +566,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool encryptHeaders = false;
#ifndef _NO_CRYPTO
if (!methodMode.PasswordIsDefined && _passwordIsDefined)
{
// if header is compressed, we use that password for updated archive
methodMode.PasswordIsDefined = true;
methodMode.Password = _password;
}
#endif
if (methodMode.PasswordIsDefined)
{
if (_encryptHeadersSpecified)
@@ -569,12 +594,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (numItems < 2)
compressMainHeader = false;
int level = GetLevel();
CUpdateOptions options;
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
int level = GetLevel();
options.UseFilters = level != 0 && _autoFilter;
options.MaxFilter = level >= 8;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
options.MaxFilter = (level >= 8);
options.AnalysisLevel = GetAnalysisLevel();
options.HeaderOptions.CompressMainHeader = compressMainHeader;
/*
@@ -587,7 +614,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
options.RemoveSfxBlock = _removeSfxBlock;
options.VolumeMode = _volumeMode;
// options.VolumeMode = _volumeMode;
options.MultiThreadMixer = _useMultiThreadMixer;
COutArchive archive;
CArchiveDatabaseOut newDatabase;
@@ -635,20 +664,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END
}
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
{
stream = 0;
int index = ParseStringToUInt32(srcString, coder);
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
srcString.DeleteFrontal(index);
if (srcString[0] == 's')
{
srcString.Delete(0);
int index = ParseStringToUInt32(srcString, stream);
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
srcString.DeleteFrontal(index);
}
return S_OK;
}
@@ -667,7 +696,10 @@ void COutHandler::InitProps()
Write_ATime.Init();
Write_MTime.Init();
_volumeMode = false;
_useMultiThreadMixer = true;
// _volumeMode = false;
InitSolid();
}
@@ -762,7 +794,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
UInt32 number;
int index = ParseStringToUInt32(name, number);
UString realName = name.Ptr(index);
// UString realName = name.Ptr(index);
if (index == 0)
{
if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
@@ -787,15 +819,17 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
// if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
}
return CMultiMethodProps::SetProperty(name, value);
}
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
{
COM_TRY_BEGIN
_binds.Clear();
_bonds.Clear();
InitProps();
for (UInt32 i = 0; i < numProps; i++)
@@ -812,15 +846,19 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (value.vt != VT_EMPTY)
return E_INVALIDARG;
name.Delete(0);
CBind bind;
RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
CBond2 bond;
RINOK(ParseBond(name, bond.OutCoder, bond.OutStream));
if (name[0] != ':')
return E_INVALIDARG;
name.Delete(0);
RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
UInt32 inStream = 0;
RINOK(ParseBond(name, bond.InCoder, inStream));
if (inStream != 0)
return E_INVALIDARG;
if (!name.IsEmpty())
return E_INVALIDARG;
_binds.Add(bind);
_bonds.Add(bond);
continue;
}
@@ -831,40 +869,27 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (numEmptyMethods > 0)
{
unsigned k;
for (k = 0; k < _binds.Size(); k++)
for (k = 0; k < _bonds.Size(); k++)
{
const CBind &bind = _binds[k];
if (bind.InCoder < (UInt32)numEmptyMethods ||
bind.OutCoder < (UInt32)numEmptyMethods)
const CBond2 &bond = _bonds[k];
if (bond.InCoder < (UInt32)numEmptyMethods ||
bond.OutCoder < (UInt32)numEmptyMethods)
return E_INVALIDARG;
}
for (k = 0; k < _binds.Size(); k++)
for (k = 0; k < _bonds.Size(); k++)
{
CBind &bind = _binds[k];
bind.InCoder -= (UInt32)numEmptyMethods;
bind.OutCoder -= (UInt32)numEmptyMethods;
CBond2 &bond = _bonds[k];
bond.InCoder -= (UInt32)numEmptyMethods;
bond.OutCoder -= (UInt32)numEmptyMethods;
}
_methods.DeleteFrontal(numEmptyMethods);
}
AddDefaultMethod();
if (!_filterMethod.MethodName.IsEmpty())
FOR_VECTOR (k, _bonds)
{
FOR_VECTOR (k, _binds)
{
CBind &bind = _binds[k];
bind.InCoder++;
bind.OutCoder++;
}
_methods.Insert(0, _filterMethod);
}
FOR_VECTOR (k, _binds)
{
const CBind &bind = _binds[k];
if (bind.InCoder >= (UInt32)_methods.Size() ||
bind.OutCoder >= (UInt32)_methods.Size())
const CBond2 &bond = _bonds[k];
if (bond.InCoder >= (UInt32)_methods.Size() ||
bond.OutCoder >= (UInt32)_methods.Size())
return E_INVALIDARG;
}

View File

@@ -96,6 +96,53 @@ namespace NID
};
}
const UInt32 k_Copy = 0;
const UInt32 k_Delta = 3;
const UInt32 k_LZMA2 = 0x21;
const UInt32 k_SWAP2 = 0x20302;
const UInt32 k_SWAP4 = 0x20304;
const UInt32 k_LZMA = 0x30101;
const UInt32 k_PPMD = 0x30401;
const UInt32 k_Deflate = 0x40108;
const UInt32 k_BZip2 = 0x40202;
const UInt32 k_BCJ = 0x3030103;
const UInt32 k_BCJ2 = 0x303011B;
const UInt32 k_PPC = 0x3030205;
const UInt32 k_IA64 = 0x3030401;
const UInt32 k_ARM = 0x3030501;
const UInt32 k_ARMT = 0x3030701;
const UInt32 k_SPARC = 0x3030805;
const UInt32 k_AES = 0x6F10701;
static inline bool IsFilterMethod(UInt64 m)
{
if (m > (UInt64)0xFFFFFFFF)
return false;
switch ((UInt32)m)
{
case k_Delta:
case k_BCJ:
case k_BCJ2:
case k_PPC:
case k_IA64:
case k_ARM:
case k_ARMT:
case k_SPARC:
case k_SWAP2:
case k_SWAP4:
return true;
}
return false;
}
}}
#endif

View File

@@ -32,9 +32,6 @@ using namespace NCOM;
namespace NArchive {
namespace N7z {
static const UInt32 k_LZMA2 = 0x21;
static const UInt32 k_LZMA = 0x030101;
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
{
v.ClearAndSetSize(size);
@@ -43,78 +40,6 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
static bool BoolVector_GetAndSet(CBoolVector &v, UInt32 index)
{
if (index >= (UInt32)v.Size())
return true;
bool res = v[index];
v[index] = true;
return res;
}
bool CFolder::CheckStructure(unsigned numUnpackSizes) const
{
const unsigned kNumCodersMax = sizeof(UInt32) * 8; // don't change it
const unsigned kMaskSize = sizeof(UInt32) * 8; // it must be >= kNumCodersMax
const unsigned kNumBindsMax = 32;
if (Coders.Size() > kNumCodersMax || BindPairs.Size() > kNumBindsMax)
return false;
{
CBoolVector v;
BoolVector_Fill_False(v, BindPairs.Size() + PackStreams.Size());
unsigned i;
for (i = 0; i < BindPairs.Size(); i++)
if (BoolVector_GetAndSet(v, BindPairs[i].InIndex))
return false;
for (i = 0; i < PackStreams.Size(); i++)
if (BoolVector_GetAndSet(v, PackStreams[i]))
return false;
BoolVector_Fill_False(v, numUnpackSizes);
for (i = 0; i < BindPairs.Size(); i++)
if (BoolVector_GetAndSet(v, BindPairs[i].OutIndex))
return false;
}
UInt32 mask[kMaskSize];
unsigned i;
for (i = 0; i < kMaskSize; i++)
mask[i] = 0;
{
CUIntVector inStreamToCoder, outStreamToCoder;
for (i = 0; i < Coders.Size(); i++)
{
CNum j;
const CCoderInfo &coder = Coders[i];
for (j = 0; j < coder.NumInStreams; j++)
inStreamToCoder.Add(i);
for (j = 0; j < coder.NumOutStreams; j++)
outStreamToCoder.Add(i);
}
for (i = 0; i < BindPairs.Size(); i++)
{
const CBindPair &bp = BindPairs[i];
mask[inStreamToCoder[bp.InIndex]] |= (1 << outStreamToCoder[bp.OutIndex]);
}
}
for (i = 0; i < kMaskSize; i++)
for (unsigned j = 0; j < kMaskSize; j++)
if (((1 << j) & mask[i]) != 0)
mask[i] |= mask[j];
for (i = 0; i < kMaskSize; i++)
if (((1 << i) & mask[i]) != 0)
return false;
return true;
}
class CInArchiveException {};
class CUnsupportedFeatureException: public CInArchiveException {};
@@ -193,6 +118,8 @@ Byte CInByte2::ReadByte()
void CInByte2::ReadBytes(Byte *data, size_t size)
{
if (size == 0)
return;
if (size > _size - _pos)
ThrowEndOfData();
memcpy(data, _buffer + _pos, size);
@@ -218,41 +145,48 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
processed = 0;
return 0;
}
Byte firstByte = *p++;
unsigned b = *p++;
size--;
if ((firstByte & 0x80) == 0)
if ((b & 0x80) == 0)
{
processed = 1;
return firstByte;
return b;
}
Byte mask = 0x40;
if (size == 0)
{
processed = 0;
return 0;
}
UInt64 value = (UInt64)*p;
p++;
size--;
for (unsigned i = 1; i < 8; i++)
{
if ((firstByte & mask) == 0)
unsigned mask = (unsigned)0x80 >> i;
if ((b & mask) == 0)
{
UInt64 highPart = firstByte & (mask - 1);
value += (highPart << (i * 8));
UInt64 high = b & (mask - 1);
value |= (high << (i * 8));
processed = i + 1;
return value;
}
if (size == 0)
{
processed = 0;
return 0;
}
value |= ((UInt64)*p << (i * 8));
p++;
size--;
mask >>= 1;
}
processed = 9;
return value;
}
@@ -344,6 +278,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
for (;;)
{
UInt32 readSize = kBufSize - kHeaderSize;
if (searchHeaderSizeLimit)
{
UInt64 rem = *searchHeaderSizeLimit - offset;
if (readSize > rem)
@@ -351,10 +286,12 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (readSize == 0)
return S_FALSE;
}
UInt32 processed = 0;
RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
if (processed == 0)
return S_FALSE;
for (UInt32 pos = 0;;)
{
const Byte *p = buf + pos + 1;
@@ -376,6 +313,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
}
}
offset += processed;
memmove(buf, buf + processed, kHeaderSize);
}
@@ -415,13 +353,15 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
void CInByte2::ParseFolder(CFolder &folder)
{
CNum numCoders = ReadNum();
UInt32 numCoders = ReadNum();
if (numCoders == 0)
ThrowUnsupported();
folder.Coders.SetSize(numCoders);
CNum numInStreams = 0;
CNum numOutStreams = 0;
CNum i;
UInt32 numInStreams = 0;
UInt32 i;
for (i = 0; i < numCoders; i++)
{
CCoderInfo &coder = folder.Coders[i];
@@ -441,14 +381,14 @@ void CInByte2::ParseFolder(CFolder &folder)
if ((mainByte & 0x10) != 0)
{
coder.NumInStreams = ReadNum();
coder.NumOutStreams = ReadNum();
coder.NumStreams = ReadNum();
/* numOutStreams = */ ReadNum();
}
else
{
coder.NumInStreams = 1;
coder.NumOutStreams = 1;
coder.NumStreams = 1;
}
if ((mainByte & 0x20) != 0)
{
CNum propsSize = ReadNum();
@@ -458,27 +398,27 @@ void CInByte2::ParseFolder(CFolder &folder)
else
coder.Props.Free();
}
numInStreams += coder.NumInStreams;
numOutStreams += coder.NumOutStreams;
numInStreams += coder.NumStreams;
}
CNum numBindPairs = numOutStreams - 1;
folder.BindPairs.SetSize(numBindPairs);
for (i = 0; i < numBindPairs; i++)
UInt32 numBonds = numCoders - 1;
folder.Bonds.SetSize(numBonds);
for (i = 0; i < numBonds; i++)
{
CBindPair &bp = folder.BindPairs[i];
bp.InIndex = ReadNum();
bp.OutIndex = ReadNum();
CBond &bp = folder.Bonds[i];
bp.PackIndex = ReadNum();
bp.UnpackIndex = ReadNum();
}
if (numInStreams < numBindPairs)
if (numInStreams < numBonds)
ThrowUnsupported();
CNum numPackStreams = numInStreams - numBindPairs;
UInt32 numPackStreams = numInStreams - numBonds;
folder.PackStreams.SetSize(numPackStreams);
if (numPackStreams == 1)
{
for (i = 0; i < numInStreams; i++)
if (folder.FindBindPairForInStream(i) < 0)
if (folder.FindBond_for_PackStream(i) < 0)
{
folder.PackStreams[0] = i;
break;
@@ -509,12 +449,12 @@ void CDatabase::GetPath(unsigned index, UString &path) const
return;
size_t offset = NameOffsets[index];
size_t size = NameOffsets[index + 1] - offset - 1;
size_t size = NameOffsets[index + 1] - offset;
if (size >= (1 << 20))
if (size >= (1 << 28))
return;
wchar_t *s = path.GetBuffer((unsigned)size);
wchar_t *s = path.GetBuf((unsigned)size - 1);
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
@@ -533,7 +473,7 @@ void CDatabase::GetPath(unsigned index, UString &path) const
#endif
path.ReleaseBuffer((unsigned)size);
path.ReleaseBuf_SetLen((unsigned)size - 1);
}
HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
@@ -592,7 +532,7 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
{
unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1);
const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2;
do
for (; len != 0; len--)
{
p -= 2;
--s;
@@ -601,7 +541,7 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
c = WCHAR_PATH_SEPARATOR;
*s = c;
}
while (--len);
const CFileItem &file = Files[cur];
cur = file.Parent;
if (cur < 0)
@@ -639,6 +579,9 @@ void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
}
}
#define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
void CInArchive::ReadPackInfo(CFolders &f)
{
CNum numPackStreams = ReadNum();
@@ -692,27 +635,31 @@ void CInArchive::ReadUnpackInfo(
folders.FoCodersDataOffset.Alloc(numFolders + 1);
folders.FoToCoderUnpackSizes.Alloc(numFolders + 1);
CRecordVector<bool> InStreamUsed;
CRecordVector<bool> OutStreamUsed;
CBoolVector StreamUsed;
CBoolVector CoderUsed;
CNum packStreamIndex = 0;
CNum fo;
CInByte2 *inByte = _inByteBack;
for (fo = 0; fo < numFolders; fo++)
{
UInt32 numOutStreams = 0;
UInt32 indexOfMainStream = 0;
UInt32 numPackStreams = 0;
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
numOutStreams = 0;
CNum numInStreams = 0;
CNum numCoders = inByte->ReadNum();
if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
ThrowUnsupported();
for (CNum ci = 0; ci < numCoders; ci++)
{
Byte mainByte = inByte->ReadByte();
if ((mainByte & 0xC0) != 0)
ThrowUnsupported();
unsigned idSize = (mainByte & 0xF);
if (idSize > 8)
ThrowUnsupported();
@@ -725,19 +672,21 @@ void CInArchive::ReadUnpackInfo(
inByte->SkipDataNoCheck(idSize);
if (folders.ParsedMethods.IDs.Size() < 128)
folders.ParsedMethods.IDs.AddToUniqueSorted(id);
CNum coderInStreams = 1;
CNum coderOutStreams = 1;
if ((mainByte & 0x10) != 0)
{
coderInStreams = inByte->ReadNum();
coderOutStreams = inByte->ReadNum();
if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
ThrowUnsupported();
if (inByte->ReadNum() != 1)
ThrowUnsupported();
}
numInStreams += coderInStreams;
if (numInStreams < coderInStreams)
ThrowUnsupported();
numOutStreams += coderOutStreams;
if (numOutStreams < coderOutStreams)
if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
ThrowUnsupported();
if ((mainByte & 0x20) != 0)
{
CNum propsSize = inByte->ReadNum();
@@ -759,7 +708,7 @@ void CInArchive::ReadUnpackInfo(
}
}
if (numOutStreams == 1 && numInStreams == 1)
if (numCoders == 1 && numInStreams == 1)
{
indexOfMainStream = 0;
numPackStreams = 1;
@@ -767,55 +716,55 @@ void CInArchive::ReadUnpackInfo(
else
{
UInt32 i;
if (numOutStreams == 0)
ThrowUnsupported();
CNum numBindPairs = numOutStreams - 1;
if (numInStreams < numBindPairs)
ThrowUnsupported();
if (numInStreams >= 256 || numOutStreams >= 256)
CNum numBonds = numCoders - 1;
if (numInStreams < numBonds)
ThrowUnsupported();
InStreamUsed.ClearAndSetSize(numInStreams);
for (i = 0; i < numInStreams; i++)
InStreamUsed[i] = false;
BoolVector_Fill_False(StreamUsed, numInStreams);
BoolVector_Fill_False(CoderUsed, numCoders);
OutStreamUsed.ClearAndSetSize(numOutStreams);
for (i = 0; i < numOutStreams; i++)
OutStreamUsed[i] = false;
for (i = 0; i < numBindPairs; i++)
for (i = 0; i < numBonds; i++)
{
CNum index = ReadNum();
if (index >= numInStreams || InStreamUsed[index])
if (index >= numInStreams || StreamUsed[index])
ThrowUnsupported();
InStreamUsed[index] = true;
StreamUsed[index] = true;
index = ReadNum();
if (index >= numOutStreams || OutStreamUsed[index])
if (index >= numCoders || CoderUsed[index])
ThrowUnsupported();
OutStreamUsed[index] = true;
CoderUsed[index] = true;
}
numPackStreams = numInStreams - numBindPairs;
numPackStreams = numInStreams - numBonds;
if (numPackStreams != 1)
for (i = 0; i < numPackStreams; i++)
inByte->ReadNum(); // PackStreams
{
CNum index = inByte->ReadNum(); // PackStreams
if (index >= numInStreams || StreamUsed[index])
ThrowUnsupported();
StreamUsed[index] = true;
}
for (i = 0; i < numOutStreams; i++)
if (!OutStreamUsed[i])
for (i = 0; i < numCoders; i++)
if (!CoderUsed[i])
{
indexOfMainStream = i;
break;
}
if (i == numOutStreams)
if (i == numCoders)
ThrowUnsupported();
}
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
numCodersOutStreams += numOutStreams;
numCodersOutStreams += numCoders;
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
packStreamIndex += numPackStreams;
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
}
size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
@@ -1105,13 +1054,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
unpackSizes,
digests);
CDecoder decoder(
#ifdef _ST_MODE
false
#else
true
#endif
);
CDecoder decoder(_useMixerMT);
for (CNum i = 0; i < folders.NumFolders; i++)
{
@@ -1127,14 +1070,20 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
outStreamSpec->Init(data, unpackSize);
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
_stream, baseOffset + dataOffset,
folders, i,
outStream, NULL
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, false, 1
#endif
EXTERNAL_CODECS_LOC_VARS
_stream, baseOffset + dataOffset,
folders, i,
NULL, // *unpackSize
outStream,
NULL, // *compressProgress
NULL // **inStreamMainRes
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, false // mtMode
, 1 // numThreads
#endif
);
RINOK(result);
@@ -1208,7 +1157,7 @@ HRESULT CInArchive::ReadHeader(
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
// if (!db.PackSizes.IsEmpty())
db.ArcInfo.FileInfoPopIDs.Add(NID::kPackInfo);
if (numFiles > 0 && !digests.Defs.IsEmpty())
if (numFiles > 0 && !digests.Defs.IsEmpty())
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
@@ -1396,6 +1345,9 @@ HRESULT CInArchive::ReadHeader(
type = ReadID(); // Read (NID::kEnd) end of headers
if (numFiles - numEmptyStreams != unpackSizes.Size())
ThrowUnsupported();
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
@@ -1403,7 +1355,7 @@ HRESULT CInArchive::ReadHeader(
for (i = 0; i < numEmptyStreams; i++)
if (antiFileVector[i])
numAntiItems++;
for (i = 0; i < numFiles; i++)
{
CFileItem &file = db.Files[i];
@@ -1444,13 +1396,13 @@ HRESULT CInArchive::ReadHeader(
void CDbEx::FillLinks()
{
FolderStartFileIndex.ClearAndSetSize(NumFolders);
FileIndexToFolderIndexMap.ClearAndSetSize(Files.Size());
FolderStartFileIndex.Alloc(NumFolders);
FileIndexToFolderIndexMap.Alloc(Files.Size());
CNum folderIndex = 0;
CNum indexInFolder = 0;
unsigned i;
for (i = 0; i < Files.Size(); i++)
{
bool emptyStream = !Files[i].HasStream;
@@ -1489,6 +1441,7 @@ void CDbEx::FillLinks()
if (indexInFolder != 0)
ThrowIncorrect();
*/
for (;;)
{
if (folderIndex >= NumFolders)

View File

@@ -26,8 +26,8 @@ namespace N7z {
#define _7Z_DECODER_CRYPRO_VARS_DECL
#define _7Z_DECODER_CRYPRO_VARS
#else
#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined
#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined
#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
#endif
struct CParsedMethods
@@ -39,6 +39,11 @@ struct CParsedMethods
CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
};
struct CFolderEx: public CFolder
{
unsigned UnpackCoder;
};
struct CFolders
{
CNum NumPackStreams;
@@ -47,10 +52,10 @@ struct CFolders
CObjArray<UInt64> PackPositions; // NumPackStreams + 1
// CUInt32DefVector PackCRCs; // we don't use PackCRCs now
CUInt32DefVector FolderCRCs; // NumFolders
CUInt32DefVector FolderCRCs; // NumFolders
CObjArray<CNum> NumUnpackStreamsVector; // NumFolders
CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders
CObjArray<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
CObjArray<CNum> FoToCoderUnpackSizes; // NumFolders + 1
CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
@@ -61,10 +66,15 @@ struct CFolders
CParsedMethods ParsedMethods;
void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const
{
ParseFolderInfo(folderIndex, folder);
folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex];
}
unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
{
return FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex];
return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
}
UInt64 GetFolderUnpackSize(unsigned folderIndex) const
@@ -103,9 +113,9 @@ struct CDatabase: public CFolders
CUInt64DefVector ATime;
CUInt64DefVector MTime;
CUInt64DefVector StartPos;
CRecordVector<bool> IsAnti;
CBoolVector IsAnti;
/*
CRecordVector<bool> IsAux;
CBoolVector IsAux;
CByteBuffer SecureBuf;
CRecordVector<UInt32> SecureIDs;
*/
@@ -148,13 +158,14 @@ struct CDatabase: public CFolders
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
const void * GetName(unsigned index) const
/*
const void* GetName(unsigned index) const
{
if (!NameOffsets || !NamesBuf)
return NULL;
return (const void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
};
*/
void GetPath(unsigned index, UString &path) const;
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
};
@@ -181,8 +192,9 @@ struct CInArchiveInfo
struct CDbEx: public CDatabase
{
CInArchiveInfo ArcInfo;
CRecordVector<CNum> FolderStartFileIndex;
CRecordVector<CNum> FileIndexToFolderIndexMap;
CObjArray<CNum> FolderStartFileIndex;
CObjArray<CNum> FileIndexToFolderIndexMap;
UInt64 HeadersSize;
UInt64 PhySize;
@@ -234,8 +246,8 @@ struct CDbEx: public CDatabase
// SecureOffsets.Clear();
ArcInfo.Clear();
FolderStartFileIndex.Clear();
FileIndexToFolderIndexMap.Clear();
FolderStartFileIndex.Free();
FileIndexToFolderIndexMap.Free();
HeadersSize = 0;
PhySize = 0;
@@ -243,22 +255,22 @@ struct CDbEx: public CDatabase
void FillLinks();
UInt64 GetFolderStreamPos(unsigned folderIndex, unsigned indexInFolder) const
UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const
{
return ArcInfo.DataStartPosition +
PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
}
UInt64 GetFolderFullPackSize(unsigned folderIndex) const
UInt64 GetFolderFullPackSize(CNum folderIndex) const
{
return
PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
PackPositions[FoStartPackStreamIndex[folderIndex]];
}
UInt64 GetFolderPackStreamSize(unsigned folderIndex, unsigned streamIndex) const
UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const
{
unsigned i = FoStartPackStreamIndex[folderIndex] + streamIndex;
size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex;
return PackPositions[i + 1] - PackPositions[i];
}
@@ -327,6 +339,8 @@ class CInArchive
UInt64 HeadersSize;
bool _useMixerMT;
void AddByteStream(const Byte *buffer, size_t size);
void DeleteByteStream(bool needUpdatePos)
@@ -340,7 +354,6 @@ class CInArchive
}
}
private:
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
@@ -396,7 +409,11 @@ private:
_7Z_DECODER_CRYPRO_VARS_DECL
);
public:
CInArchive(): _numInByteBufs(0) { }
CInArchive(bool useMixerMT):
_numInByteBufs(0),
_useMixerMT(useMixerMT)
{}
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
void Close();

View File

@@ -13,8 +13,6 @@
namespace NArchive {
namespace N7z {
const UInt64 k_AES = 0x06F10701;
typedef UInt32 CNum;
const CNum kNumMax = 0x7FFFFFFF;
const CNum kNumNoIndex = 0xFFFFFFFF;
@@ -23,71 +21,70 @@ struct CCoderInfo
{
CMethodId MethodID;
CByteBuffer Props;
CNum NumInStreams;
CNum NumOutStreams;
UInt32 NumStreams;
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
bool IsSimpleCoder() const { return NumStreams == 1; }
};
struct CBindPair
struct CBond
{
CNum InIndex;
CNum OutIndex;
UInt32 PackIndex;
UInt32 UnpackIndex;
};
struct CFolder
{
CLASS_NO_COPY(CFolder)
public:
CObjArray2<CCoderInfo> Coders;
CObjArray2<CBindPair> BindPairs;
CObjArray2<CNum> PackStreams;
CObjArray2<CBond> Bonds;
CObjArray2<UInt32> PackStreams;
CNum GetNumOutStreams() const
{
CNum result = 0;
FOR_VECTOR(i, Coders)
result += Coders[i].NumOutStreams;
return result;
}
CFolder() {}
int FindBindPairForInStream(CNum inStreamIndex) const
{
FOR_VECTOR(i, BindPairs)
if (BindPairs[i].InIndex == inStreamIndex)
return i;
return -1;
}
int FindBindPairForOutStream(CNum outStreamIndex) const
{
FOR_VECTOR(i, BindPairs)
if (BindPairs[i].OutIndex == outStreamIndex)
return i;
return -1;
}
int FindPackStreamArrayIndex(CNum inStreamIndex) const
bool IsDecodingSupported() const { return Coders.Size() <= 32; }
int Find_in_PackStreams(UInt32 packStream) const
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == inStreamIndex)
if (PackStreams[i] == packStream)
return i;
return -1;
}
int GetIndexOfMainOutStream() const
int FindBond_for_PackStream(UInt32 packStream) const
{
for (int i = (int)GetNumOutStreams() - 1; i >= 0; i--)
if (FindBindPairForOutStream(i) < 0)
FOR_VECTOR(i, Bonds)
if (Bonds[i].PackIndex == packStream)
return i;
throw 1;
return -1;
}
/*
int FindBond_for_UnpackStream(UInt32 unpackStream) const
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
return i;
return -1;
}
int FindOutCoder() const
{
for (int i = (int)Coders.Size() - 1; i >= 0; i--)
if (FindBond_for_UnpackStream(i) < 0)
return i;
return -1;
}
*/
bool IsEncrypted() const
{
for (int i = Coders.Size() - 1; i >= 0; i--)
FOR_VECTOR(i, Coders)
if (Coders[i].MethodID == k_AES)
return true;
return false;
}
bool CheckStructure(unsigned numUnpackSizes) const;
};
struct CUInt32DefVector

View File

@@ -199,7 +199,7 @@ void COutArchive::WriteNumber(UInt64 value)
mask >>= 1;
}
WriteByte(firstByte);
for (;i > 0; i--)
for (; i > 0; i--)
{
WriteByte((Byte)value);
value >>= 8;
@@ -254,31 +254,33 @@ void COutArchive::WriteFolder(const CFolder &folder)
{
WriteNumber(folder.Coders.Size());
unsigned i;
for (i = 0; i < folder.Coders.Size(); i++)
{
const CCoderInfo &coder = folder.Coders[i];
{
size_t propsSize = coder.Props.Size();
UInt64 id = coder.MethodID;
int idSize;
unsigned idSize;
for (idSize = 1; idSize < sizeof(id); idSize++)
if ((id >> (8 * idSize)) == 0)
break;
Byte longID[15];
for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
longID[t] = (Byte)(id & 0xFF);
Byte b;
b = (Byte)(idSize & 0xF);
idSize &= 0xF;
Byte temp[16];
for (unsigned t = idSize; t != 0; t--, id >>= 8)
temp[t] = (Byte)(id & 0xFF);
Byte b = (Byte)(idSize);
bool isComplex = !coder.IsSimpleCoder();
b |= (isComplex ? 0x10 : 0);
b |= ((propsSize != 0) ? 0x20 : 0 );
WriteByte(b);
WriteBytes(longID, idSize);
size_t propsSize = coder.Props.Size();
b |= ((propsSize != 0) ? 0x20 : 0);
temp[0] = b;
WriteBytes(temp, idSize + 1);
if (isComplex)
{
WriteNumber(coder.NumInStreams);
WriteNumber(coder.NumOutStreams);
WriteNumber(coder.NumStreams);
WriteNumber(1); // NumOutStreams;
}
if (propsSize == 0)
continue;
@@ -286,17 +288,17 @@ void COutArchive::WriteFolder(const CFolder &folder)
WriteBytes(coder.Props, propsSize);
}
}
for (i = 0; i < folder.BindPairs.Size(); i++)
for (i = 0; i < folder.Bonds.Size(); i++)
{
const CBindPair &bindPair = folder.BindPairs[i];
WriteNumber(bindPair.InIndex);
WriteNumber(bindPair.OutIndex);
const CBond &bond = folder.Bonds[i];
WriteNumber(bond.PackIndex);
WriteNumber(bond.UnpackIndex);
}
if (folder.PackStreams.Size() > 1)
for (i = 0; i < folder.PackStreams.Size(); i++)
{
WriteNumber(folder.PackStreams[i]);
}
}
void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
@@ -521,7 +523,10 @@ HRESULT COutArchive::EncodeStream(
UInt64 unpackSize;
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
stream, NULL, &dataSize64, folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
stream,
// NULL,
&dataSize64,
folders.AddNew(), outFolders.CoderUnpackSizes, unpackSize, SeqStream, packSizes, NULL))
return S_OK;
}

View File

@@ -29,6 +29,8 @@ public:
}
void WriteBytes(const void *data, size_t size)
{
if (size == 0)
return;
if (size > _size - _pos)
throw 1;
memcpy(_data + _pos, data, size);
@@ -92,7 +94,7 @@ struct COutFolders
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
CRecordVector<CNum> NumUnpackStreamsVector;
CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders
CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
void OutFoldersClear()
{

View File

@@ -13,7 +13,7 @@ namespace N7z {
struct CPropMap
{
UInt64 FilePropID;
UInt32 FilePropID;
STATPROPSTG StatPROPSTG;
};
@@ -35,7 +35,7 @@ static const CPropMap kPropMap[] =
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
{ NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
{ NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
{ NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
@@ -44,20 +44,12 @@ static const CPropMap kPropMap[] =
#ifndef _SFX
,
{ 97, { NULL,kpidEncrypted, VT_BOOL } },
{ 98, { NULL,kpidMethod, VT_BSTR } },
{ 99, { NULL,kpidBlock, VT_UI4 } }
{ 97, { NULL, kpidEncrypted, VT_BOOL } },
{ 98, { NULL, kpidMethod, VT_BSTR } },
{ 99, { NULL, kpidBlock, VT_UI4 } }
#endif
};
static int FindPropInMap(UInt64 filePropID)
{
for (int i = 0; i < ARRAY_SIZE(kPropMap); i++)
if (kPropMap[i].FilePropID == filePropID)
return i;
return -1;
}
static void CopyOneItem(CRecordVector<UInt64> &src,
CRecordVector<UInt64> &dest, UInt32 item)
{
@@ -131,6 +123,7 @@ void CHandler::FillPopIDs()
_fileInfoPopIDs.Add(98);
_fileInfoPopIDs.Add(99);
#endif
#ifdef _MULTI_PACK
_fileInfoPopIDs.Add(100);
_fileInfoPopIDs.Add(101);
@@ -155,16 +148,27 @@ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
{
if ((int)index >= _fileInfoPopIDs.Size())
if (index >= _fileInfoPopIDs.Size())
return E_INVALIDARG;
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
if (indexInMap == -1)
return E_INVALIDARG;
const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
*propID = srcItem.propid;
*varType = srcItem.vt;
*name = 0;
return S_OK;
UInt64 id = _fileInfoPopIDs[index];
for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
{
const CPropMap &pr = kPropMap[i];
if (pr.FilePropID == id)
{
const STATPROPSTG &st = pr.StatPROPSTG;
*propID = st.propid;
*varType = st.vt;
/*
if (st.lpwstrName)
*name = ::SysAllocString(st.lpwstrName);
else
*/
*name = NULL;
return S_OK;
}
}
return E_INVALIDARG;
}
}}

View File

@@ -9,17 +9,13 @@
namespace NArchive {
namespace N7z {
IMP_CreateArcIn
IMP_CreateArcOut
static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
static CArcInfo g_ArcInfo =
{ "7z", "7z", 0, 7,
6, {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C},
REGISTER_ARC_IO_DECREMENT_SIG(
"7z", "7z", NULL, 7,
k_Signature_Dec,
0,
NArcInfoFlags::kFindSignature,
REF_CreateArc_Pair };
REGISTER_ARC_DEC_SIG(7z)
// REGISTER_ARC(7z)
NULL);
}}

View File

@@ -3,10 +3,10 @@
#ifndef __7Z_SPEC_STREAM_H
#define __7Z_SPEC_STREAM_H
#include "../../IStream.h"
#include "../../ICoder.h"
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
class CSequentialInStreamSizeCount2:
public ISequentialInStream,
public ICompressGetSubStreamSize,
@@ -18,14 +18,14 @@ class CSequentialInStreamSizeCount2:
public:
void Init(ISequentialInStream *stream)
{
_stream = stream;
_getSubStreamSize = 0;
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
_size = 0;
_getSubStreamSize.Release();
_stream = stream;
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
}
UInt64 GetSize() const { return _size; }
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);

View File

File diff suppressed because it is too large Load Diff

View File

@@ -65,6 +65,7 @@ struct CUpdateItem
// int SecureIndex; // 0 means (no_security)
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
// bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes
CUpdateItem():
// ParentSortIndex(-1),
@@ -77,18 +78,19 @@ struct CUpdateItem
MTimeDefined(false)
// SecureIndex(0)
{}
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
int GetExtensionPos() const;
UString GetExtension() const;
// unsigned GetExtensionPos() const;
// UString GetExtension() const;
};
struct CUpdateOptions
{
const CCompressionMethodMode *Method;
const CCompressionMethodMode *HeaderMethod;
bool UseFilters;
bool MaxFilter;
bool UseFilters; // use additional filters for some files
bool MaxFilter; // use BCJ2 filter instead of BCJ
int AnalysisLevel;
CHeaderOptions HeaderOptions;
@@ -96,7 +98,20 @@ struct CUpdateOptions
UInt64 NumSolidBytes;
bool SolidExtension;
bool RemoveSfxBlock;
bool VolumeMode;
bool MultiThreadMixer;
CUpdateOptions():
Method(NULL),
HeaderMethod(NULL),
UseFilters(false),
MaxFilter(false),
AnalysisLevel(-1),
NumSolidFiles((UInt64)(Int64)(-1)),
NumSolidBytes((UInt64)(Int64)(-1)),
SolidExtension(false),
RemoveSfxBlock(false),
MultiThreadMixer(true)
{}
};
HRESULT Update(

View File

@@ -376,15 +376,13 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
COM_TRY_END
}
IMP_CreateArcIn
static const Byte k_Signature[] = { kSig0, kSig1 };
static CArcInfo g_ArcInfo =
{ "APM", "apm", 0, 0xD4,
2, { kSig0, kSig1 },
REGISTER_ARC_I(
"APM", "apm", 0, 0xD4,
k_Signature,
0,
0,
CreateArc, NULL, IsArc_Apm };
REGISTER_ARC(Apm)
IsArc_Apm)
}}

View File

@@ -77,7 +77,7 @@ enum EType
kType_Lib
};
static const char *k_TypeExtionsions[] =
static const char * const k_TypeExtionsions[] =
{
"ar"
, "a"
@@ -121,7 +121,7 @@ struct CItem
int SameNameIndex;
CItem(): TextFileIndex(-1), SameNameIndex(-1) {}
UInt64 GetDataPos() const { return HeaderPos + HeaderSize; };
UInt64 GetDataPos() const { return HeaderPos + HeaderSize; }
};
class CInArchive
@@ -257,10 +257,9 @@ HRESULT CInArchive::GetNextItem(CItem &item, bool &filled)
{
SubType = kSubType_BSD;
size_t processedSize = longNameLen;
char *s = item.Name.GetBuffer(longNameLen);
char *s = item.Name.GetBuf(longNameLen);
HRESULT res = ReadStream(m_Stream, s, &processedSize);
s[longNameLen] = 0;
item.Name.ReleaseBuffer();
item.Name.ReleaseBuf_CalcLen(longNameLen);
RINOK(res);
if (processedSize != longNameLen)
return S_OK;
@@ -683,11 +682,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case kpidPhySize: prop = _phySize; break;
case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break;
case kpidExtension: prop = k_TypeExtionsions[_type]; break;
case kpidExtension: prop = k_TypeExtionsions[(unsigned)_type]; break;
case kpidShortComment:
case kpidSubType:
{
AString s = k_TypeExtionsions[_type];
AString s = k_TypeExtionsions[(unsigned)_type];
if (_subType == kSubType_BSD)
s += ":BSD";
prop = s;
@@ -724,7 +723,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSize:
case kpidPackSize:
if (item.TextFileIndex >= 0)
prop = (UInt64)_libFiles[item.TextFileIndex].Len();
prop = (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len();
else
prop = item.Size;
break;
@@ -766,7 +765,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const CItem &item = _items[allFilesMode ? i : indices[i]];
totalSize +=
(item.TextFileIndex >= 0) ?
(UInt64)_libFiles[item.TextFileIndex].Len() : item.Size;
(UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size;
}
extractCallback->SetTotal(totalSize);
@@ -795,7 +794,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const CItem &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
currentTotalSize += (item.TextFileIndex >= 0) ?
(UInt64)_libFiles[item.TextFileIndex].Len() : item.Size;
(UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size;
if (!testMode && !realOutStream)
continue;
@@ -808,7 +807,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool isOk = true;
if (item.TextFileIndex >= 0)
{
const AString &f = _libFiles[item.TextFileIndex];
const AString &f = _libFiles[(unsigned)item.TextFileIndex];
if (realOutStream)
RINOK(WriteStream(realOutStream, f, f.Len()));
}
@@ -834,8 +833,8 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
const CItem &item = _items[index];
if (item.TextFileIndex >= 0)
{
const AString &f = _libFiles[item.TextFileIndex];
Create_BufInStream_WithNewBuf((const void *)(const char *)f, f.Len(), stream);
const AString &f = _libFiles[(unsigned)item.TextFileIndex];
Create_BufInStream_WithNewBuffer((const void *)(const char *)f, f.Len(), stream);
return S_OK;
}
else
@@ -843,15 +842,11 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
COM_TRY_END
}
IMP_CreateArcIn
static CArcInfo g_ArcInfo =
{ "Ar", "ar a deb lib", 0, 0xEC,
kSignatureLen, SIGNATURE,
REGISTER_ARC_I(
"Ar", "ar a deb lib", 0, 0xEC,
kSignature,
0,
0,
CreateArc };
REGISTER_ARC(Ar)
NULL)
}}

View File

@@ -1,6 +1,12 @@
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
CreateObject PRIVATE
GetIsArc PRIVATE
SetCodecs PRIVATE
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE

View File

@@ -1,11 +1,19 @@
EXPORTS
CreateObject PRIVATE
GetHandlerProperty PRIVATE
GetNumberOfFormats PRIVATE
GetHandlerProperty2 PRIVATE
GetIsArc PRIVATE
GetNumberOfMethods PRIVATE
GetMethodProperty PRIVATE
CreateDecoder PRIVATE
CreateEncoder PRIVATE
GetHashers PRIVATE
SetCodecs PRIVATE
SetLargePageMode PRIVATE
SetCaseSensitive PRIVATE
GetIsArc PRIVATE

View File

@@ -22,17 +22,19 @@ void RegisterArc(const CArcInfo *arcInfo) throw()
const char *p = arcInfo->Name;
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
g_DefaultArcIndex = g_NumArcs;
g_Arcs[g_NumArcs] = arcInfo;
g_NumArcs++;
g_Arcs[g_NumArcs++] = arcInfo;
}
}
DEFINE_GUID(CLSID_CArchiveHandler,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
k_7zip_GUID_Data1,
k_7zip_GUID_Data2,
k_7zip_GUID_Data3_Common,
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
static inline HRESULT SetPropString(const char *s, unsigned size, PROPVARIANT *value)
static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value)
{
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
value->vt = VT_BSTR;
@@ -41,18 +43,18 @@ static inline HRESULT SetPropString(const char *s, unsigned size, PROPVARIANT *v
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
{
return SetPropString((const char *)&guid, sizeof(GUID), value);
return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
}
int FindFormatCalssId(const GUID *clsID)
int FindFormatCalssId(const GUID *clsid)
{
GUID cls = *clsID;
GUID cls = *clsid;
CLS_ARC_ID_ITEM(cls) = 0;
if (cls != CLSID_CArchiveHandler)
return -1;
Byte id = CLS_ARC_ID_ITEM(*clsID);
Byte id = CLS_ARC_ID_ITEM(*clsid);
for (unsigned i = 0; i < g_NumArcs; i++)
if (g_Arcs[i]->ClassId == id)
if (g_Arcs[i]->Id == id)
return (int)i;
return -1;
}
@@ -101,7 +103,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
case NArchive::NHandlerPropID::kClassID:
{
GUID clsId = CLSID_CArchiveHandler;
CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
CLS_ARC_ID_ITEM(clsId) = arc.Id;
return SetPropGUID(clsId, value);
}
case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break;
@@ -115,12 +117,12 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
case NArchive::NHandlerPropID::kSignature:
if (!arc.IsMultiSignature())
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
if (arc.SignatureSize != 0 && !arc.IsMultiSignature())
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
case NArchive::NHandlerPropID::kMultiSignature:
if (arc.IsMultiSignature())
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
if (arc.SignatureSize != 0 && arc.IsMultiSignature())
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
break;
}
prop.Detach(value);

View File

@@ -17,13 +17,180 @@
#include "../Common/StreamObjects.h"
#include "../Common/StreamUtils.h"
#include "../Compress/ArjDecoder1.h"
#include "../Compress/ArjDecoder2.h"
#include "../Compress/CopyCoder.h"
#include "../Compress/LzhDecoder.h"
#include "Common/ItemNameUtils.h"
#include "Common/OutStreamWithCRC.h"
namespace NCompress {
namespace NArj {
namespace NDecoder {
static const unsigned kMatchMinLen = 3;
static const UInt32 kWindowSize = 1 << 15; // must be >= (1 << 14)
class CCoder:
public ICompressCoder,
public CMyUnknownImp
{
CLzOutWindow _outWindow;
NBitm::CDecoder<CInBuffer> _inBitStream;
class CCoderReleaser
{
CCoder *_coder;
public:
CCoderReleaser(CCoder *coder): _coder(coder) {}
void Disable() { _coder = NULL; }
~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); }
};
friend class CCoderReleaser;
HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress);
public:
MY_UNKNOWN_IMP
bool FinishMode;
CCoder(): FinishMode(false) {}
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); }
};
HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress)
{
const UInt32 kStep = 1 << 20;
UInt64 next = 0;
if (rem > kStep && progress)
next = rem - kStep;
while (rem != 0)
{
if (rem <= next)
{
if (_inBitStream.ExtraBitsWereRead())
return S_FALSE;
UInt64 packSize = _inBitStream.GetProcessedSize();
UInt64 pos = _outWindow.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &pos));
next = 0;
if (rem > kStep)
next = rem - kStep;
}
UInt32 len;
{
const unsigned kNumBits = 7 + 7;
UInt32 val = _inBitStream.GetValue(kNumBits);
if ((val & (1 << (kNumBits - 1))) == 0)
{
_outWindow.PutByte((Byte)(val >> 5));
_inBitStream.MovePos(1 + 8);
rem--;
continue;
}
UInt32 mask = 1 << (kNumBits - 2);
unsigned w;
for (w = 1; w < 7; w++, mask >>= 1)
if ((val & mask) == 0)
break;
unsigned readBits = (w != 7 ? 1 : 0);
readBits += w + w;
len = (1 << w) - 1 + kMatchMinLen - 1 +
(((val >> (kNumBits - readBits)) & ((1 << w) - 1)));
_inBitStream.MovePos(readBits);
}
{
const unsigned kNumBits = 4 + 13;
UInt32 val = _inBitStream.GetValue(kNumBits);
unsigned readBits = 1;
unsigned w;
if ((val & ((UInt32)1 << 16)) == 0) w = 9;
else if ((val & ((UInt32)1 << 15)) == 0) w = 10;
else if ((val & ((UInt32)1 << 14)) == 0) w = 11;
else if ((val & ((UInt32)1 << 13)) == 0) w = 12;
else { w = 13; readBits = 0; }
readBits += w + w - 9;
UInt32 dist = ((UInt32)1 << w) - (1 << 9) +
(((val >> (kNumBits - readBits)) & ((1 << w) - 1)));
_inBitStream.MovePos(readBits);
if (len > rem)
len = (UInt32)rem;
if (!_outWindow.CopyBlock(dist, len))
return S_FALSE;
rem -= len;
}
}
if (FinishMode)
{
if (_inBitStream.ReadAlignBits() != 0)
return S_FALSE;
}
if (_inBitStream.ExtraBitsWereRead())
return S_FALSE;
return S_OK;
}
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
{
try
{
if (!outSize)
return E_INVALIDARG;
if (!_outWindow.Create(kWindowSize))
return E_OUTOFMEMORY;
if (!_inBitStream.Create(1 << 17))
return E_OUTOFMEMORY;
_outWindow.SetStream(outStream);
_outWindow.Init(false);
_inBitStream.SetStream(inStream);
_inBitStream.Init();
CCoderReleaser coderReleaser(this);
HRESULT res;
{
res = CodeReal(*outSize, progress);
if (res != S_OK)
return res;
}
coderReleaser.Disable();
return _outWindow.Flush();
}
catch(const CInBufferException &e) { return e.ErrorCode; }
catch(const CLzOutWindowException &e) { return e.ErrorCode; }
catch(...) { return S_FALSE; }
}
}}}
using namespace NWindows;
#define Get16(p) GetUi16(p)
@@ -95,7 +262,7 @@ namespace NHostOS
};
}
static const char *kHostOS[] =
static const char * const kHostOS[] =
{
"MSDOS"
, "PRIMOS"
@@ -164,10 +331,10 @@ API_FUNC_static_IsArc IsArc_Arj(const Byte *p, size_t size)
static HRESULT ReadString(const Byte *p, unsigned &size, AString &res)
{
for (unsigned i = 0; i < size;)
unsigned num = size;
for (unsigned i = 0; i < num;)
{
char c = (char)p[i++];
if (c == 0)
if (p[i++] == 0)
{
size = i;
res = (const char *)p;
@@ -656,15 +823,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
const CItem &item = _items[allFilesMode ? i : indices[i]];
totalUnpacked += item.Size;
totalPacked += item.PackSize;
// totalPacked += item.PackSize;
}
extractCallback->SetTotal(totalUnpacked);
totalUnpacked = totalPacked = 0;
UInt64 curUnpacked, curPacked;
CMyComPtr<ICompressCoder> arj1Decoder;
CMyComPtr<ICompressCoder> arj2Decoder;
NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = NULL;
CMyComPtr<ICompressCoder> lzhDecoder;
NCompress::NArj::NDecoder::CCoder *arjDecoderSpec = NULL;
CMyComPtr<ICompressCoder> arjDecoder;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
@@ -741,22 +912,37 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
case NCompressionMethod::kCompressed1b:
case NCompressionMethod::kCompressed1c:
{
if (!arj1Decoder)
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
result = arj1Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
if (!lzhDecoder)
{
lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder;
lzhDecoder = lzhDecoderSpec;
}
lzhDecoderSpec->FinishMode = true;
const UInt32 kHistorySize = 26624;
lzhDecoderSpec->SetDictSize(kHistorySize);
result = lzhDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
if (result == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize)
result = S_FALSE;
break;
}
case NCompressionMethod::kCompressed2:
{
if (!arj2Decoder)
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
result = arj2Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
if (!arjDecoder)
{
arjDecoderSpec = new NCompress::NArj::NDecoder::CCoder;
arjDecoder = arjDecoderSpec;
}
arjDecoderSpec->FinishMode = true;
result = arjDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
if (result == S_OK && arjDecoderSpec->GetInputProcessedSize() != item.PackSize)
result = S_FALSE;
break;
}
default:
opRes = NExtract::NOperationResult::kUnsupportedMethod;
}
}
if (opRes == NExtract::NOperationResult::kOK)
{
if (result == S_FALSE)
@@ -769,23 +955,23 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
NExtract::NOperationResult::kCRCError;
}
}
outStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
}
}
return S_OK;
COM_TRY_END
}
IMP_CreateArcIn
static const Byte k_Signature[] = { kSig0, kSig1 };
static CArcInfo g_ArcInfo =
{ "Arj", "arj", 0, 4,
2, { kSig0, kSig1 },
REGISTER_ARC_I(
"Arj", "arj", 0, 4,
k_Signature,
0,
0,
CreateArc, NULL, IsArc_Arj };
REGISTER_ARC(Arj)
IsArc_Arj)
}}

Some files were not shown because too many files have changed in this diff Show More