mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-17 02:11:49 -06:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a663a6deb7 | ||
|
|
6543c28020 | ||
|
|
f6444c3256 | ||
|
|
cba375916f | ||
|
|
54490d51d5 | ||
|
|
0713a3ab80 | ||
|
|
7e021179cd |
20
C/7z.h
20
C/7z.h
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
10
C/7zAlloc.c
10
C/7zAlloc.c
@@ -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)
|
||||
{
|
||||
|
||||
10
C/7zAlloc.h
10
C/7zAlloc.h
@@ -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
|
||||
|
||||
368
C/7zArcIn.c
368
C/7zArcIn.c
@@ -1,5 +1,5 @@
|
||||
/* 7zArcIn.c -- 7z Input functions
|
||||
2014-06-16 : Igor Pavlov : Public domain */
|
||||
2015-09-28 : 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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
69
C/7zCrc.c
69
C/7zCrc.c
@@ -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
|
||||
}
|
||||
|
||||
87
C/7zCrcOpt.c
87
C/7zCrcOpt.c
@@ -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
|
||||
|
||||
220
C/7zDec.c
220
C/7zDec.c
@@ -1,5 +1,5 @@
|
||||
/* 7zDec.c -- Decoding from 7z folder
|
||||
2014-06-16 : Igor Pavlov : Public domain */
|
||||
2015-08-01 : 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
|
||||
|
||||
@@ -140,11 +144,11 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
const void *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
res = inStream->Look(inStream, &inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -190,11 +197,11 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
const void *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
res = inStream->Look(inStream, &inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
@@ -223,15 +230,18 @@ 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)
|
||||
{
|
||||
void *inBuf;
|
||||
const void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||
RINOK(inStream->Look(inStream, &inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
@@ -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],
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
#define MY_VER_MAJOR 9
|
||||
#define MY_VER_MINOR 35
|
||||
#define MY_VER_BUILD 00
|
||||
#define MY_VERSION "9.35 beta"
|
||||
// #define MY_7ZIP_VERSION "9.35"
|
||||
#define MY_DATE "2014-12-07"
|
||||
#define MY_VER_MAJOR 15
|
||||
#define MY_VER_MINOR 9
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION_NUMBERS "15.09"
|
||||
#define MY_VERSION "15.09 beta"
|
||||
#define MY_DATE "2015-10-16"
|
||||
#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_AUTHOR_NAME "Igor Pavlov"
|
||||
#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
29
C/Aes.c
@@ -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];
|
||||
}
|
||||
|
||||
11
C/Alloc.c
11
C/Alloc.c
@@ -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 };
|
||||
|
||||
15
C/Alloc.h
15
C/Alloc.h
@@ -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
332
C/Bcj2.c
@@ -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)
|
||||
2015-08-01 : 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] ?
|
||||
(unsigned)BCJ2_STREAM_MAIN :
|
||||
(unsigned)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
150
C/Bcj2.h
@@ -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
312
C/Bcj2Enc.c
Normal 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;
|
||||
}
|
||||
}
|
||||
48
C/Blake2.h
Normal file
48
C/Blake2.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Blake2.h -- BLAKE2 Hash
|
||||
2015-06-30 : Igor Pavlov : Public domain
|
||||
2015 : Samuel Neves : Public domain */
|
||||
|
||||
#ifndef __BLAKE2_H
|
||||
#define __BLAKE2_H
|
||||
|
||||
#include "7zTypes.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define BLAKE2S_BLOCK_SIZE 64
|
||||
#define BLAKE2S_DIGEST_SIZE 32
|
||||
#define BLAKE2SP_PARALLEL_DEGREE 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 h[8];
|
||||
UInt32 t[2];
|
||||
UInt32 f[2];
|
||||
Byte buf[BLAKE2S_BLOCK_SIZE];
|
||||
UInt32 bufPos;
|
||||
UInt32 lastNode_f1;
|
||||
UInt32 dummy[2]; /* for sizeof(CBlake2s) alignment */
|
||||
} CBlake2s;
|
||||
|
||||
/* You need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
|
||||
/*
|
||||
void Blake2s_Init0(CBlake2s *p);
|
||||
void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size);
|
||||
void Blake2s_Final(CBlake2s *p, Byte *digest);
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CBlake2s S[BLAKE2SP_PARALLEL_DEGREE];
|
||||
unsigned bufPos;
|
||||
} CBlake2sp;
|
||||
|
||||
|
||||
void Blake2sp_Init(CBlake2sp *p);
|
||||
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size);
|
||||
void Blake2sp_Final(CBlake2sp *p, Byte *digest);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
244
C/Blake2s.c
Normal file
244
C/Blake2s.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/* Blake2s.c -- BLAKE2s and BLAKE2sp Hash
|
||||
2015-06-30 : Igor Pavlov : Public domain
|
||||
2015 : Samuel Neves : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Blake2.h"
|
||||
#include "CpuArch.h"
|
||||
#include "RotateDefs.h"
|
||||
|
||||
#define rotr32 rotrFixed
|
||||
|
||||
#define BLAKE2S_NUM_ROUNDS 10
|
||||
#define BLAKE2S_FINAL_FLAG (~(UInt32)0)
|
||||
|
||||
static const UInt32 k_Blake2s_IV[8] =
|
||||
{
|
||||
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||
};
|
||||
|
||||
static const Byte k_Blake2s_Sigma[BLAKE2S_NUM_ROUNDS][16] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
||||
};
|
||||
|
||||
|
||||
void Blake2s_Init0(CBlake2s *p)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 8; i++)
|
||||
p->h[i] = k_Blake2s_IV[i];
|
||||
p->t[0] = 0;
|
||||
p->t[1] = 0;
|
||||
p->f[0] = 0;
|
||||
p->f[1] = 0;
|
||||
p->bufPos = 0;
|
||||
p->lastNode_f1 = 0;
|
||||
}
|
||||
|
||||
|
||||
static void Blake2s_Compress(CBlake2s *p)
|
||||
{
|
||||
UInt32 m[16];
|
||||
UInt32 v[16];
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
m[i] = GetUi32(p->buf + i * sizeof(m[i]));
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
v[i] = p->h[i];
|
||||
}
|
||||
|
||||
v[ 8] = k_Blake2s_IV[0];
|
||||
v[ 9] = k_Blake2s_IV[1];
|
||||
v[10] = k_Blake2s_IV[2];
|
||||
v[11] = k_Blake2s_IV[3];
|
||||
|
||||
v[12] = p->t[0] ^ k_Blake2s_IV[4];
|
||||
v[13] = p->t[1] ^ k_Blake2s_IV[5];
|
||||
v[14] = p->f[0] ^ k_Blake2s_IV[6];
|
||||
v[15] = p->f[1] ^ k_Blake2s_IV[7];
|
||||
|
||||
#define G(r,i,a,b,c,d) \
|
||||
a += b + m[sigma[2*i+0]]; d ^= a; d = rotr32(d, 16); c += d; b ^= c; b = rotr32(b, 12); \
|
||||
a += b + m[sigma[2*i+1]]; d ^= a; d = rotr32(d, 8); c += d; b ^= c; b = rotr32(b, 7); \
|
||||
|
||||
#define R(r) \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
|
||||
{
|
||||
unsigned r;
|
||||
for (r = 0; r < BLAKE2S_NUM_ROUNDS; r++)
|
||||
{
|
||||
const Byte *sigma = k_Blake2s_Sigma[r];
|
||||
R(r);
|
||||
}
|
||||
/* R(0); R(1); R(2); R(3); R(4); R(5); R(6); R(7); R(8); R(9); */
|
||||
}
|
||||
|
||||
#undef G
|
||||
#undef R
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 8; i++)
|
||||
p->h[i] ^= v[i] ^ v[i + 8];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define Blake2s_Increment_Counter(S, inc) \
|
||||
{ p->t[0] += (inc); p->t[1] += (p->t[0] < (inc)); }
|
||||
|
||||
#define Blake2s_Set_LastBlock(p) \
|
||||
{ p->f[0] = BLAKE2S_FINAL_FLAG; p->f[1] = p->lastNode_f1; }
|
||||
|
||||
|
||||
static void Blake2s_Update(CBlake2s *p, const Byte *data, size_t size)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
unsigned pos = (unsigned)p->bufPos;
|
||||
unsigned rem = BLAKE2S_BLOCK_SIZE - pos;
|
||||
|
||||
if (size <= rem)
|
||||
{
|
||||
memcpy(p->buf + pos, data, size);
|
||||
p->bufPos += (UInt32)size;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(p->buf + pos, data, rem);
|
||||
Blake2s_Increment_Counter(S, BLAKE2S_BLOCK_SIZE);
|
||||
Blake2s_Compress(p);
|
||||
p->bufPos = 0;
|
||||
data += rem;
|
||||
size -= rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Blake2s_Final(CBlake2s *p, Byte *digest)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
Blake2s_Increment_Counter(S, (UInt32)p->bufPos);
|
||||
Blake2s_Set_LastBlock(p);
|
||||
memset(p->buf + p->bufPos, 0, BLAKE2S_BLOCK_SIZE - p->bufPos);
|
||||
Blake2s_Compress(p);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
SetUi32(digest + sizeof(p->h[i]) * i, p->h[i]);
|
||||
}
|
||||
|
||||
|
||||
/* ---------- BLAKE2s ---------- */
|
||||
|
||||
/* we need to xor CBlake2s::h[i] with input parameter block after Blake2s_Init0() */
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
Byte digest_length;
|
||||
Byte key_length;
|
||||
Byte fanout;
|
||||
Byte depth;
|
||||
UInt32 leaf_length;
|
||||
Byte node_offset[6];
|
||||
Byte node_depth;
|
||||
Byte inner_length;
|
||||
Byte salt[BLAKE2S_SALTBYTES];
|
||||
Byte personal[BLAKE2S_PERSONALBYTES];
|
||||
} CBlake2sParam;
|
||||
*/
|
||||
|
||||
|
||||
static void Blake2sp_Init_Spec(CBlake2s *p, unsigned node_offset, unsigned node_depth)
|
||||
{
|
||||
Blake2s_Init0(p);
|
||||
|
||||
p->h[0] ^= (BLAKE2S_DIGEST_SIZE | ((UInt32)BLAKE2SP_PARALLEL_DEGREE << 16) | ((UInt32)2 << 24));
|
||||
p->h[2] ^= ((UInt32)node_offset);
|
||||
p->h[3] ^= ((UInt32)node_depth << 16) | ((UInt32)BLAKE2S_DIGEST_SIZE << 24);
|
||||
/*
|
||||
P->digest_length = BLAKE2S_DIGEST_SIZE;
|
||||
P->key_length = 0;
|
||||
P->fanout = BLAKE2SP_PARALLEL_DEGREE;
|
||||
P->depth = 2;
|
||||
P->leaf_length = 0;
|
||||
store48(P->node_offset, node_offset);
|
||||
P->node_depth = node_depth;
|
||||
P->inner_length = BLAKE2S_DIGEST_SIZE;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void Blake2sp_Init(CBlake2sp *p)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
p->bufPos = 0;
|
||||
|
||||
for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
|
||||
Blake2sp_Init_Spec(&p->S[i], i, 0);
|
||||
|
||||
p->S[BLAKE2SP_PARALLEL_DEGREE - 1].lastNode_f1 = BLAKE2S_FINAL_FLAG;
|
||||
}
|
||||
|
||||
|
||||
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size)
|
||||
{
|
||||
unsigned pos = p->bufPos;
|
||||
while (size != 0)
|
||||
{
|
||||
unsigned index = pos / BLAKE2S_BLOCK_SIZE;
|
||||
unsigned rem = BLAKE2S_BLOCK_SIZE - (pos & (BLAKE2S_BLOCK_SIZE - 1));
|
||||
if (rem > size)
|
||||
rem = (unsigned)size;
|
||||
Blake2s_Update(&p->S[index], data, rem);
|
||||
size -= rem;
|
||||
data += rem;
|
||||
pos += rem;
|
||||
pos &= (BLAKE2S_BLOCK_SIZE * BLAKE2SP_PARALLEL_DEGREE - 1);
|
||||
}
|
||||
p->bufPos = pos;
|
||||
}
|
||||
|
||||
|
||||
void Blake2sp_Final(CBlake2sp *p, Byte *digest)
|
||||
{
|
||||
CBlake2s R;
|
||||
unsigned i;
|
||||
|
||||
Blake2sp_Init_Spec(&R, 0, 1);
|
||||
R.lastNode_f1 = BLAKE2S_FINAL_FLAG;
|
||||
|
||||
for (i = 0; i < BLAKE2SP_PARALLEL_DEGREE; i++)
|
||||
{
|
||||
Byte hash[BLAKE2S_DIGEST_SIZE];
|
||||
Blake2s_Final(&p->S[i], hash);
|
||||
Blake2s_Update(&R, hash, BLAKE2S_DIGEST_SIZE);
|
||||
}
|
||||
|
||||
Blake2s_Final(&R, digest);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Compiler.h -- Compiler ypes
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
/* Compiler.h
|
||||
2015-08-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_COMPILER_H
|
||||
#define __7Z_COMPILER_H
|
||||
@@ -18,6 +18,7 @@
|
||||
#else
|
||||
#pragma warning(disable : 4511) // copy constructor could not be generated
|
||||
#pragma warning(disable : 4512) // assignment operator could not be generated
|
||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed
|
||||
#pragma warning(disable : 4702) // unreachable code
|
||||
#pragma warning(disable : 4710) // not inlined
|
||||
#pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information
|
||||
@@ -25,4 +26,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#define UNUSED_VAR(x) (void)x;
|
||||
/* #define UNUSED_VAR(x) x=x; */
|
||||
|
||||
#endif
|
||||
|
||||
25
C/CpuArch.c
25
C/CpuArch.c
@@ -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));
|
||||
|
||||
101
C/CpuArch.h
101
C/CpuArch.h
@@ -1,5 +1,5 @@
|
||||
/* CpuArch.h -- CPU specific code
|
||||
2013-11-12: Igor Pavlov : Public domain */
|
||||
2015-08-02: 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,50 @@ 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 +109,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 +135,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 +147,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 +181,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();
|
||||
|
||||
497
C/LzFind.c
497
C/LzFind.c
@@ -1,5 +1,5 @@
|
||||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2009-04-22 : Igor Pavlov : Public domain */
|
||||
2015-10-15 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#define kEmptyHashValue 0
|
||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||
#define kMaxHistorySize ((UInt32)3 << 30)
|
||||
#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1))
|
||||
#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,9 +59,12 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||
return;
|
||||
|
||||
/* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */
|
||||
|
||||
if (p->directInput)
|
||||
{
|
||||
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
||||
UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos);
|
||||
if (curSize > p->directInputRem)
|
||||
curSize = (UInt32)p->directInputRem;
|
||||
p->directInputRem -= curSize;
|
||||
@@ -71,12 +73,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 +98,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 +139,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 +157,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 +166,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 +179,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 +221,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 +233,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 +267,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 +279,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)
|
||||
@@ -270,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||
p->posLimit = p->pos + limit;
|
||||
}
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p)
|
||||
void MatchFinder_Init_2(CMatchFinder *p, int readData)
|
||||
{
|
||||
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;
|
||||
p->result = SZ_OK;
|
||||
p->streamEndWasReached = 0;
|
||||
MatchFinder_ReadBlock(p);
|
||||
|
||||
if (readData)
|
||||
MatchFinder_ReadBlock(p);
|
||||
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p)
|
||||
{
|
||||
MatchFinder_Init_2(p, True);
|
||||
}
|
||||
|
||||
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 +339,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 +500,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 +516,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 +539,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 +578,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 +630,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 +762,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 +868,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 +881,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 +892,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 +909,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 +1002,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 +1029,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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
28
C/LzFind.h
28
C/LzFind.h
@@ -1,5 +1,5 @@
|
||||
/* LzFind.h -- Match finder for LZ algorithms
|
||||
2013-01-18 : Igor Pavlov : Public domain */
|
||||
2015-10-15 : 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,30 +34,30 @@ 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)
|
||||
|
||||
#define Inline_MatchFinder_IsFinishedOK(p) \
|
||||
((p)->streamEndWasReached \
|
||||
&& (p)->streamPos == (p)->pos \
|
||||
&& (!(p)->directInput || (p)->directInputRem == 0))
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||
@@ -68,7 +73,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 +87,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 +95,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;
|
||||
@@ -100,9 +103,12 @@ typedef struct _IMatchFinder
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||
|
||||
void MatchFinder_Init_2(CMatchFinder *p, int readData);
|
||||
void MatchFinder_Init(CMatchFinder *p);
|
||||
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
|
||||
|
||||
180
C/LzFindMt.c
180
C/LzFindMt.c
@@ -1,5 +1,5 @@
|
||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
2015-10-15 : 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 (;;)
|
||||
@@ -173,12 +173,12 @@ void HashThreadFunc(CMatchFinderMt *mt)
|
||||
CriticalSection_Enter(&mt->btSync.cs);
|
||||
CriticalSection_Enter(&mt->hashSync.cs);
|
||||
{
|
||||
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
const Byte *afterPtr;
|
||||
const Byte *beforePtr = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||
ptrdiff_t offset;
|
||||
MatchFinder_MoveBlock(mf);
|
||||
afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
mt->pointerToCurPos -= beforePtr - afterPtr;
|
||||
mt->buffer -= beforePtr - afterPtr;
|
||||
offset = beforePtr - Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||
mt->pointerToCurPos -= offset;
|
||||
mt->buffer -= offset;
|
||||
}
|
||||
CriticalSection_Leave(&mt->btSync.cs);
|
||||
CriticalSection_Leave(&mt->hashSync.cs);
|
||||
@@ -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,10 +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];
|
||||
int i = 0;
|
||||
unsigned i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
allocaDummy[i] = (Byte)i;
|
||||
BtThreadFunc((CMatchFinderMt *)p);
|
||||
allocaDummy[i] = (Byte)0;
|
||||
if (allocaDummy[0] == 0)
|
||||
BtThreadFunc((CMatchFinderMt *)p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -471,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;
|
||||
}
|
||||
@@ -494,8 +501,11 @@ void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||
CMatchFinder *mf = p->MatchFinder;
|
||||
p->btBufPos = p->btBufPosLimit = 0;
|
||||
p->hashBufPos = p->hashBufPosLimit = 0;
|
||||
MatchFinder_Init(mf);
|
||||
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
|
||||
/* Init without data reading. We don't want to read data in this thread */
|
||||
MatchFinder_Init_2(mf, False);
|
||||
|
||||
p->pointerToCurPos = Inline_MatchFinder_GetPointerToCurrentPos(mf);
|
||||
p->btNumAvailBytes = 0;
|
||||
p->lzPos = p->historySize + 1;
|
||||
|
||||
@@ -520,13 +530,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);
|
||||
@@ -538,34 +548,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])
|
||||
@@ -573,23 +578,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])
|
||||
{
|
||||
@@ -602,43 +607,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;
|
||||
@@ -660,13 +667,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++;
|
||||
@@ -684,7 +692,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++;
|
||||
@@ -692,6 +700,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));
|
||||
}
|
||||
@@ -707,7 +716,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;
|
||||
@@ -717,41 +726,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
|
||||
}
|
||||
@@ -760,11 +769,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;
|
||||
@@ -780,7 +789,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
43
C/LzHash.h
43
C/LzHash.h
@@ -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
|
||||
|
||||
40
C/Lzma2Dec.c
40
C/Lzma2Dec.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
59
C/Lzma2Enc.c
59
C/Lzma2Enc.c
@@ -1,5 +1,5 @@
|
||||
/* Lzma2Enc.c -- LZMA2 Encoder
|
||||
2012-06-19 : Igor Pavlov : Public domain */
|
||||
2015-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -109,6 +109,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
||||
{
|
||||
size_t destPos = 0;
|
||||
PRF(printf("################# COPY "));
|
||||
|
||||
while (unpackSize > 0)
|
||||
{
|
||||
UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
|
||||
@@ -121,6 +122,7 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
||||
unpackSize -= u;
|
||||
destPos += u;
|
||||
p->srcPos += u;
|
||||
|
||||
if (outStream)
|
||||
{
|
||||
*packSizeRes += destPos;
|
||||
@@ -132,9 +134,11 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
||||
*packSizeRes = destPos;
|
||||
/* needInitState = True; */
|
||||
}
|
||||
|
||||
LzmaEnc_RestoreState(p->enc);
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
{
|
||||
size_t destPos = 0;
|
||||
UInt32 u = unpackSize - 1;
|
||||
@@ -160,11 +164,13 @@ static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
|
||||
if (outStream)
|
||||
if (outStream->Write(outStream, outBuf, destPos) != destPos)
|
||||
return SZ_ERROR_WRITE;
|
||||
|
||||
*packSizeRes = destPos;
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ---------- Lzma2 Props ---------- */
|
||||
|
||||
void Lzma2EncProps_Init(CLzma2EncProps *p)
|
||||
@@ -221,6 +227,8 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
||||
|
||||
LzmaEncProps_Normalize(&p->lzmaProps);
|
||||
|
||||
t1 = p->lzmaProps.numThreads;
|
||||
|
||||
if (p->blockSize == 0)
|
||||
{
|
||||
UInt32 dictSize = p->lzmaProps.dictSize;
|
||||
@@ -232,28 +240,34 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
||||
if (blockSize < dictSize) blockSize = dictSize;
|
||||
p->blockSize = (size_t)blockSize;
|
||||
}
|
||||
if (t2 > 1)
|
||||
|
||||
if (t2 > 1 && p->lzmaProps.reduceSize != (UInt64)(Int64)-1)
|
||||
{
|
||||
UInt64 temp = p->lzmaProps.reduceSize + p->blockSize - 1;
|
||||
if (temp > p->lzmaProps.reduceSize)
|
||||
{
|
||||
UInt64 numBlocks = temp / p->blockSize;
|
||||
if (numBlocks < t2)
|
||||
if (numBlocks < (unsigned)t2)
|
||||
{
|
||||
t2 = (UInt32)numBlocks;
|
||||
t2 = (unsigned)numBlocks;
|
||||
if (t2 == 0)
|
||||
t2 = 1;
|
||||
t3 = t1 * t2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p->numBlockThreads = t2;
|
||||
p->numTotalThreads = t3;
|
||||
}
|
||||
|
||||
|
||||
static SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
|
||||
{
|
||||
return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- Lzma2 ---------- */
|
||||
|
||||
typedef struct
|
||||
@@ -283,15 +297,17 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
||||
UInt64 packTotal = 0;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
if (mainEncoder->outBuf == 0)
|
||||
if (!mainEncoder->outBuf)
|
||||
{
|
||||
mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
|
||||
if (mainEncoder->outBuf == 0)
|
||||
if (!mainEncoder->outBuf)
|
||||
return SZ_ERROR_MEM;
|
||||
}
|
||||
|
||||
RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
|
||||
RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
|
||||
mainEncoder->alloc, mainEncoder->allocBig));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
|
||||
@@ -305,16 +321,20 @@ static SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
|
||||
if (packSize == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
LzmaEnc_Finish(p->enc);
|
||||
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
Byte b = 0;
|
||||
if (outStream->Write(outStream, &b, 1) != 1)
|
||||
return SZ_ERROR_WRITE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
typedef struct
|
||||
@@ -362,10 +382,12 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LzmaEnc_Finish(p->enc);
|
||||
if (res != SZ_OK)
|
||||
return res;
|
||||
}
|
||||
|
||||
if (finished)
|
||||
{
|
||||
if (*destSize == destLim)
|
||||
@@ -378,12 +400,13 @@ static SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *des
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- Lzma2Enc ---------- */
|
||||
|
||||
CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
|
||||
if (p == 0)
|
||||
if (!p)
|
||||
return NULL;
|
||||
Lzma2EncProps_Init(&p->props);
|
||||
Lzma2EncProps_Normalize(&p->props);
|
||||
@@ -395,6 +418,7 @@ CLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
|
||||
p->coders[i].enc = 0;
|
||||
}
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
MtCoder_Construct(&p->mtCoder);
|
||||
#endif
|
||||
@@ -455,22 +479,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
|
||||
|
||||
for (i = 0; i < p->props.numBlockThreads; i++)
|
||||
{
|
||||
CLzma2EncInt *t = &p->coders[i];
|
||||
if (t->enc == NULL)
|
||||
CLzma2EncInt *t = &p->coders[(unsigned)i];
|
||||
if (!t->enc)
|
||||
{
|
||||
t->enc = LzmaEnc_Create(p->alloc);
|
||||
if (t->enc == NULL)
|
||||
if (!t->enc)
|
||||
return SZ_ERROR_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
if (p->props.numBlockThreads <= 1)
|
||||
#endif
|
||||
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
|
||||
if (p->props.numBlockThreads > 1)
|
||||
{
|
||||
CMtCallbackImp mtCallback;
|
||||
|
||||
@@ -485,9 +504,17 @@ SRes Lzma2Enc_Encode(CLzma2EncHandle pp,
|
||||
|
||||
p->mtCoder.blockSize = p->props.blockSize;
|
||||
p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
|
||||
if (p->mtCoder.destBlockSize < p->props.blockSize)
|
||||
{
|
||||
p->mtCoder.destBlockSize = (size_t)0 - 1;
|
||||
if (p->mtCoder.destBlockSize < p->props.blockSize)
|
||||
return SZ_ERROR_FAIL;
|
||||
}
|
||||
p->mtCoder.numThreads = p->props.numBlockThreads;
|
||||
|
||||
return MtCoder_Code(&p->mtCoder);
|
||||
}
|
||||
#endif
|
||||
|
||||
return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
|
||||
}
|
||||
|
||||
187
C/LzmaDec.c
187
C/LzmaDec.c
@@ -1,5 +1,5 @@
|
||||
/* LzmaDec.c -- LZMA Decoder
|
||||
2011-09-03 : Igor Pavlov : Public domain */
|
||||
2015-06-23 : 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 = p->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;
|
||||
@@ -398,26 +438,39 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
||||
if (checkDicSize == 0)
|
||||
{
|
||||
if (distance >= processedPos)
|
||||
{
|
||||
p->dicPos = dicPos;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
else if (distance >= checkDicSize)
|
||||
{
|
||||
p->dicPos = dicPos;
|
||||
return SZ_ERROR_DATA;
|
||||
}
|
||||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
p->dicPos = dicPos;
|
||||
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 +494,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 +520,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 +533,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 +551,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 +580,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 +599,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 +611,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 +687,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 +727,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 +766,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
||||
}
|
||||
|
||||
|
||||
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
|
||||
{
|
||||
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
|
||||
p->range = 0xFFFFFFFF;
|
||||
p->needFlush = 0;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
{
|
||||
p->needFlush = 1;
|
||||
@@ -739,8 +790,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 +813,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 +824,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 +914,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 +978,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 +1022,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 +1048,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;
|
||||
|
||||
320
C/LzmaEnc.c
320
C/LzmaEnc.c
@@ -1,5 +1,5 @@
|
||||
/* LzmaEnc.c -- LZMA Encoder
|
||||
2012-11-20 : Igor Pavlov : Public domain */
|
||||
2015-10-15 Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -20,9 +20,12 @@
|
||||
#endif
|
||||
|
||||
#ifdef SHOW_STAT
|
||||
static int ttt = 0;
|
||||
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)
|
||||
@@ -465,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11,
|
||||
|
||||
static void RangeEnc_Construct(CRangeEnc *p)
|
||||
{
|
||||
p->outStream = 0;
|
||||
p->bufBase = 0;
|
||||
p->outStream = NULL;
|
||||
p->bufBase = NULL;
|
||||
}
|
||||
|
||||
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
|
||||
@@ -474,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p)
|
||||
#define RC_BUF_SIZE (1 << 16)
|
||||
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
|
||||
{
|
||||
if (p->bufBase == 0)
|
||||
if (!p->bufBase)
|
||||
{
|
||||
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
|
||||
if (p->bufBase == 0)
|
||||
if (!p->bufBase)
|
||||
return 0;
|
||||
p->bufLim = p->bufBase + RC_BUF_SIZE;
|
||||
}
|
||||
@@ -518,7 +558,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p)
|
||||
|
||||
static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
|
||||
{
|
||||
if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
|
||||
if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0)
|
||||
{
|
||||
Byte temp = p->cache;
|
||||
do
|
||||
@@ -544,7 +584,7 @@ static void RangeEnc_FlushData(CRangeEnc *p)
|
||||
RangeEnc_ShiftLow(p);
|
||||
}
|
||||
|
||||
static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
|
||||
static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -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)
|
||||
@@ -813,9 +853,10 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32
|
||||
static void MovePos(CLzmaEnc *p, UInt32 num)
|
||||
{
|
||||
#ifdef SHOW_STAT
|
||||
ttt += num;
|
||||
g_STAT_OFFSET += num;
|
||||
printf("\n MovePos %d", num);
|
||||
#endif
|
||||
|
||||
if (num != 0)
|
||||
{
|
||||
p->additionalOffset += num;
|
||||
@@ -828,28 +869,32 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
|
||||
UInt32 lenRes = 0, numPairs;
|
||||
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
|
||||
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
|
||||
|
||||
#ifdef SHOW_STAT
|
||||
printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
|
||||
ttt++;
|
||||
printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2);
|
||||
g_STAT_OFFSET++;
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numPairs; i += 2)
|
||||
printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (numPairs > 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -934,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)
|
||||
{
|
||||
@@ -978,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;
|
||||
@@ -1279,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;
|
||||
@@ -1322,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++);
|
||||
@@ -1439,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;
|
||||
@@ -1522,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++);
|
||||
@@ -1591,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;
|
||||
@@ -1687,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;
|
||||
@@ -1703,15 +1749,15 @@ void LzmaEnc_Construct(CLzmaEnc *p)
|
||||
#endif
|
||||
|
||||
LzmaEnc_InitPriceTables(p->ProbPrices);
|
||||
p->litProbs = 0;
|
||||
p->saveState.litProbs = 0;
|
||||
p->litProbs = NULL;
|
||||
p->saveState.litProbs = NULL;
|
||||
}
|
||||
|
||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
|
||||
{
|
||||
void *p;
|
||||
p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
|
||||
if (p != 0)
|
||||
if (p)
|
||||
LzmaEnc_Construct((CLzmaEnc *)p);
|
||||
return p;
|
||||
}
|
||||
@@ -1720,8 +1766,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->litProbs);
|
||||
alloc->Free(alloc, p->saveState.litProbs);
|
||||
p->litProbs = 0;
|
||||
p->saveState.litProbs = 0;
|
||||
p->litProbs = NULL;
|
||||
p->saveState.litProbs = NULL;
|
||||
}
|
||||
|
||||
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
@@ -1729,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);
|
||||
@@ -1765,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++;
|
||||
@@ -1891,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);
|
||||
@@ -1907,22 +1954,21 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
||||
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
UInt32 beforeSize = kNumOpts;
|
||||
Bool btMode;
|
||||
if (!RangeEnc_Alloc(&p->rc, alloc))
|
||||
return SZ_ERROR_MEM;
|
||||
btMode = (p->matchFinderBase.btMode != 0);
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
p->mtMode = (p->multiThread && !p->fastMode && btMode);
|
||||
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
|
||||
#endif
|
||||
|
||||
{
|
||||
unsigned lclp = p->lc + p->lp;
|
||||
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
|
||||
if (!p->litProbs || !p->saveState.litProbs || 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));
|
||||
if (p->litProbs == 0 || p->saveState.litProbs == 0)
|
||||
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 || !p->saveState.litProbs)
|
||||
{
|
||||
LzmaEnc_FreeLits(p, alloc);
|
||||
return SZ_ERROR_MEM;
|
||||
@@ -1931,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;
|
||||
@@ -1951,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;
|
||||
}
|
||||
|
||||
@@ -1979,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;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -2088,10 +2136,11 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
|
||||
if (p->mtMode)
|
||||
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
|
||||
#else
|
||||
pp = pp;
|
||||
UNUSED_VAR(pp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqOutStream funcTable;
|
||||
@@ -2121,12 +2170,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
|
||||
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
|
||||
}
|
||||
|
||||
|
||||
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
|
||||
{
|
||||
const CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
|
||||
}
|
||||
|
||||
|
||||
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
|
||||
{
|
||||
@@ -2161,23 +2212,23 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
|
||||
#ifndef _7ZIP_ST
|
||||
Byte allocaDummy[0x300];
|
||||
int i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
allocaDummy[i] = (Byte)i;
|
||||
allocaDummy[0] = 0;
|
||||
allocaDummy[1] = allocaDummy[0];
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
|
||||
if (res != SZ_OK || p->finished != 0)
|
||||
if (res != SZ_OK || p->finished)
|
||||
break;
|
||||
if (progress != 0)
|
||||
if (progress)
|
||||
{
|
||||
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
|
||||
if (res != SZ_OK)
|
||||
@@ -2187,10 +2238,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LzmaEnc_Finish(p);
|
||||
|
||||
/*
|
||||
if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase))
|
||||
res = SZ_ERROR_FAIL;
|
||||
}
|
||||
*/
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
@@ -2198,28 +2258,27 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
|
||||
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
||||
}
|
||||
|
||||
|
||||
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++)
|
||||
@@ -2227,6 +2286,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
@@ -2235,19 +2295,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
|
||||
|
||||
CSeqOutStreamBuf outStream;
|
||||
|
||||
LzmaEnc_SetInputBuf(p, src, srcLen);
|
||||
|
||||
outStream.funcTable.Write = MyWrite;
|
||||
outStream.data = dest;
|
||||
outStream.rem = *destLen;
|
||||
outStream.overflow = False;
|
||||
|
||||
p->writeEndMark = writeEndMark;
|
||||
|
||||
p->rc.outStream = &outStream.funcTable;
|
||||
|
||||
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
||||
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
res = LzmaEnc_Encode2(p, progress);
|
||||
if (res == SZ_OK && p->nowPos64 != srcLen)
|
||||
res = SZ_ERROR_FAIL;
|
||||
}
|
||||
|
||||
*destLen -= outStream.rem;
|
||||
if (outStream.overflow)
|
||||
@@ -2255,13 +2318,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
|
||||
SRes res;
|
||||
if (p == 0)
|
||||
if (!p)
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
res = LzmaEnc_SetProps(p, props);
|
||||
|
||||
16
C/LzmaLib.c
16
C/LzmaLib.c
@@ -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;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/* MtCoder.c -- Multi-thread Coder
|
||||
2010-09-24 : Igor Pavlov : Public domain */
|
||||
2015-10-13 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MtCoder.h"
|
||||
|
||||
void LoopThread_Construct(CLoopThread *p)
|
||||
@@ -120,7 +118,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder)
|
||||
LoopThread_Construct(&p->thread);
|
||||
}
|
||||
|
||||
#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; }
|
||||
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||
|
||||
static void CMtThread_CloseEvents(CMtThread *p)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* Ppmd7.c -- PPMdH codec
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
2015-09-28 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Ppmd7.h"
|
||||
|
||||
@@ -66,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p)
|
||||
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||||
{
|
||||
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||||
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
|
||||
do { p->Units2Indx[k++] = (Byte)i; } while (--step);
|
||||
p->Indx2Units[i] = (Byte)k;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx)
|
||||
|
||||
#define MyMem12Cpy(dest, src, num) \
|
||||
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
|
||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
|
||||
|
||||
static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Ppmd7Enc.c -- PPMdH Encoder
|
||||
2010-03-12 : Igor Pavlov : Public domain
|
||||
2015-09-28 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
@@ -26,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p)
|
||||
p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32)));
|
||||
temp = 0xFF;
|
||||
}
|
||||
while(--p->CacheSize != 0);
|
||||
while (--p->CacheSize != 0);
|
||||
p->Cache = (Byte)((UInt32)p->Low >> 24);
|
||||
}
|
||||
p->CacheSize++;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* Ppmd8.c -- PPMdI codec
|
||||
2013-11-12 : Igor Pavlov : Public domain
|
||||
2015-09-28 : Igor Pavlov : Public domain
|
||||
This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Ppmd8.h"
|
||||
|
||||
@@ -67,7 +67,7 @@ void Ppmd8_Construct(CPpmd8 *p)
|
||||
for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++)
|
||||
{
|
||||
unsigned step = (i >= 12 ? 4 : (i >> 2) + 1);
|
||||
do { p->Units2Indx[k++] = (Byte)i; } while(--step);
|
||||
do { p->Units2Indx[k++] = (Byte)i; } while (--step);
|
||||
p->Indx2Units[i] = (Byte)k;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx)
|
||||
|
||||
#define MyMem12Cpy(dest, src, num) \
|
||||
{ UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \
|
||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); }
|
||||
do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); }
|
||||
|
||||
static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU)
|
||||
{
|
||||
|
||||
@@ -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
334
C/Sha1.c
Normal 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
38
C/Sha1.h
Normal 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
|
||||
153
C/Sha256.c
153
C/Sha256.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 7zMain.c - Test application for 7z Decoder
|
||||
2014-06-17 : Igor Pavlov : Public domain */
|
||||
2015-08-02 : 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
|
||||
);
|
||||
@@ -286,22 +328,20 @@ void PrintError(char *sz)
|
||||
printf("\nERROR: %s\n", sz);
|
||||
}
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
static void GetAttribString(UInt32 wa, Bool isDir, char *s)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
s[0] = (char)(((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || isDir) ? 'D' : '.');
|
||||
s[1] = (char)(((wa & FILE_ATTRIBUTE_READONLY ) != 0) ? 'R': '.');
|
||||
s[2] = (char)(((wa & FILE_ATTRIBUTE_HIDDEN ) != 0) ? 'H': '.');
|
||||
s[3] = (char)(((wa & FILE_ATTRIBUTE_SYSTEM ) != 0) ? 'S': '.');
|
||||
s[4] = (char)(((wa & FILE_ATTRIBUTE_ARCHIVE ) != 0) ? 'A': '.');
|
||||
s[5] = '\0';
|
||||
s[5] = 0;
|
||||
#else
|
||||
s[0] = (char)(((wa & (1 << 4)) != 0 || isDir) ? 'D' : '.');
|
||||
s[1] = 0;
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void GetAttribString(UInt32, Bool, char *s)
|
||||
{
|
||||
s[0] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
// #define NUM_PARENTS_MAX 128
|
||||
|
||||
@@ -318,6 +358,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 +370,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,15 +406,18 @@ 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, extractCommand = 0, fullPaths = 0;
|
||||
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) extractCommand = 1;
|
||||
else if (strcmp(command, "x") == 0) { extractCommand = 1; fullPaths = 1; }
|
||||
else if (strcmp(command, "e") == 0) { }
|
||||
else if (strcmp(command, "x") == 0) { fullPaths = 1; }
|
||||
else
|
||||
{
|
||||
PrintError("incorrect command");
|
||||
@@ -397,7 +442,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 +478,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 +498,7 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
printf("\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
fputs(testCommand ?
|
||||
"Testing ":
|
||||
"Extracting ",
|
||||
@@ -459,6 +506,7 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
res = PrintString(temp);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
if (isDir)
|
||||
printf("/");
|
||||
else
|
||||
@@ -470,6 +518,7 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!testCommand)
|
||||
{
|
||||
CSzFile outFile;
|
||||
@@ -477,6 +526,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 +552,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 +579,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 +599,6 @@ int MY_CDECL main(int numargs, char *args[])
|
||||
PrintError("CRC error");
|
||||
else
|
||||
printf("\nERROR #%d\n", res);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
PROG = 7zDec
|
||||
CXX = g++
|
||||
CXX = gcc
|
||||
LIB =
|
||||
RM = rm -f
|
||||
CFLAGS = -c -O2 -Wall
|
||||
|
||||
OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
|
||||
OBJS = 7zMain.o 7zAlloc.o 7zArcIn.o 7zBuf.o 7zBuf2.o 7zCrc.o 7zCrcOpt.o 7zDec.o CpuArch.o Delta.o LzmaDec.o Lzma2Dec.o Bra.o Bra86.o BraIA64.o Bcj2.o Ppmd7.o Ppmd7Dec.o 7zFile.o 7zStream.o
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
@@ -38,6 +38,9 @@ $(PROG): $(OBJS)
|
||||
CpuArch.o: ../../CpuArch.c
|
||||
$(CXX) $(CFLAGS) ../../CpuArch.c
|
||||
|
||||
Delta.o: ../../Delta.c
|
||||
$(CXX) $(CFLAGS) ../../Delta.c
|
||||
|
||||
LzmaDec.o: ../../LzmaDec.c
|
||||
$(CXX) $(CFLAGS) ../../LzmaDec.c
|
||||
|
||||
@@ -50,6 +53,9 @@ Bra.o: ../../Bra.c
|
||||
Bra86.o: ../../Bra86.c
|
||||
$(CXX) $(CFLAGS) ../../Bra86.c
|
||||
|
||||
BraIA64.o: ../../BraIA64.c
|
||||
$(CXX) $(CFLAGS) ../../BraIA64.c
|
||||
|
||||
Bcj2.o: ../../Bcj2.c
|
||||
$(CXX) $(CFLAGS) ../../Bcj2.c
|
||||
|
||||
|
||||
BIN
C/Util/7zipInstall/7zip.ico
Normal file
BIN
C/Util/7zipInstall/7zip.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
1489
C/Util/7zipInstall/7zipInstall.c
Normal file
1489
C/Util/7zipInstall/7zipInstall.c
Normal file
File diff suppressed because it is too large
Load Diff
231
C/Util/7zipInstall/7zipInstall.dsp
Normal file
231
C/Util/7zipInstall/7zipInstall.dsp
Normal 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
|
||||
29
C/Util/7zipInstall/7zipInstall.dsw
Normal file
29
C/Util/7zipInstall/7zipInstall.dsw
Normal 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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
18
C/Util/7zipInstall/7zipInstall.manifest
Normal file
18
C/Util/7zipInstall/7zipInstall.manifest
Normal 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>
|
||||
4
C/Util/7zipInstall/Precomp.c
Normal file
4
C/Util/7zipInstall/Precomp.c
Normal file
@@ -0,0 +1,4 @@
|
||||
/* Precomp.c -- StdAfx
|
||||
2013-01-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
11
C/Util/7zipInstall/Precomp.h
Normal file
11
C/Util/7zipInstall/Precomp.h
Normal 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
|
||||
40
C/Util/7zipInstall/makefile
Normal file
40
C/Util/7zipInstall/makefile
Normal 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)
|
||||
9
C/Util/7zipInstall/resource.h
Normal file
9
C/Util/7zipInstall/resource.h
Normal 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
|
||||
47
C/Util/7zipInstall/resource.rc
Normal file
47
C/Util/7zipInstall/resource.rc
Normal 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
|
||||
1077
C/Util/7zipUninstall/7zipUninstall.c
Normal file
1077
C/Util/7zipUninstall/7zipUninstall.c
Normal file
File diff suppressed because it is too large
Load Diff
124
C/Util/7zipUninstall/7zipUninstall.dsp
Normal file
124
C/Util/7zipUninstall/7zipUninstall.dsp
Normal 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
|
||||
29
C/Util/7zipUninstall/7zipUninstall.dsw
Normal file
29
C/Util/7zipUninstall/7zipUninstall.dsw
Normal 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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
BIN
C/Util/7zipUninstall/7zipUninstall.ico
Normal file
BIN
C/Util/7zipUninstall/7zipUninstall.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
18
C/Util/7zipUninstall/7zipUninstall.manifest
Normal file
18
C/Util/7zipUninstall/7zipUninstall.manifest
Normal 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>
|
||||
4
C/Util/7zipUninstall/Precomp.c
Normal file
4
C/Util/7zipUninstall/Precomp.c
Normal file
@@ -0,0 +1,4 @@
|
||||
/* Precomp.c -- StdAfx
|
||||
2013-01-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
11
C/Util/7zipUninstall/Precomp.h
Normal file
11
C/Util/7zipUninstall/Precomp.h
Normal 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
|
||||
17
C/Util/7zipUninstall/makefile
Normal file
17
C/Util/7zipUninstall/makefile
Normal 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)
|
||||
9
C/Util/7zipUninstall/resource.h
Normal file
9
C/Util/7zipUninstall/resource.h
Normal 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
|
||||
47
C/Util/7zipUninstall/resource.rc
Normal file
47
C/Util/7zipUninstall/resource.rc
Normal 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
|
||||
@@ -1,5 +1,5 @@
|
||||
/* LzmaUtil.c -- Test application for LZMA compression
|
||||
2014-06-17 : 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"
|
||||
@@ -92,7 +88,7 @@ static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inS
|
||||
|
||||
outPos = 0;
|
||||
|
||||
if (res != SZ_OK || thereIsSize && unpackSize == 0)
|
||||
if (res != SZ_OK || (thereIsSize && unpackSize == 0))
|
||||
return res;
|
||||
|
||||
if (inProcessed == 0 && outProcessed == 0)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
|
||||
@@ -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
10
C/Xz.c
@@ -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)
|
||||
|
||||
20
C/Xz.h
20
C/Xz.h
@@ -1,5 +1,5 @@
|
||||
/* Xz.h - Xz interface
|
||||
2013-11-19 : 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);
|
||||
@@ -229,8 +229,8 @@ void XzUnpacker_Free(CXzUnpacker *p);
|
||||
/*
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||
CODER_FINISH_ANY - use smallest number of input bytes
|
||||
CODER_FINISH_END - read EndOfStream marker after decoding
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
@@ -255,7 +255,7 @@ Returns:
|
||||
|
||||
|
||||
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, /* int srcWasFinished, */ int finishMode,
|
||||
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode,
|
||||
ECoderStatus *status);
|
||||
|
||||
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p);
|
||||
|
||||
24
C/XzCrc64.c
24
C/XzCrc64.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
62
C/XzDec.c
62
C/XzDec.c
@@ -1,5 +1,5 @@
|
||||
/* XzDec.c -- Xz Decode
|
||||
2014-05-09 : 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)
|
||||
@@ -209,7 +209,7 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc
|
||||
id != XZ_ID_SPARC)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
p->p = 0;
|
||||
decoder = alloc->Alloc(alloc, sizeof(CBraState));
|
||||
decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState));
|
||||
if (decoder == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
decoder->methodId = (UInt32)id;
|
||||
@@ -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;
|
||||
@@ -315,7 +315,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
|
||||
|
||||
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
||||
{
|
||||
CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));
|
||||
CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec));
|
||||
p->p = decoder;
|
||||
if (decoder == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
@@ -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 = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
||||
if (p->buf == 0)
|
||||
p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
||||
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;
|
||||
}
|
||||
@@ -624,7 +628,7 @@ void XzUnpacker_Free(CXzUnpacker *p)
|
||||
}
|
||||
|
||||
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)
|
||||
const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status)
|
||||
{
|
||||
SizeT destLenOrig = *destLen;
|
||||
SizeT srcLenOrig = *srcLen;
|
||||
|
||||
88
C/XzEnc.c
88
C/XzEnc.c
@@ -1,5 +1,5 @@
|
||||
/* XzEnc.c -- Xz Encode
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
2015-09-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Alloc.h"
|
||||
#include "Bra.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
#ifdef USE_SUBBLOCK
|
||||
#include "Bcj3Enc.c"
|
||||
#include "SbFind.c"
|
||||
@@ -18,14 +19,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;
|
||||
@@ -42,7 +35,7 @@ static SRes WriteBytesAndCrc(ISeqOutStream *s, const void *buf, UInt32 size, UIn
|
||||
return WriteBytes(s, buf, size);
|
||||
}
|
||||
|
||||
SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
||||
static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
||||
{
|
||||
UInt32 crc;
|
||||
Byte header[XZ_STREAM_HEADER_SIZE];
|
||||
@@ -54,17 +47,19 @@ SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStream *s)
|
||||
return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE);
|
||||
}
|
||||
|
||||
SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
||||
|
||||
static 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,14 +68,17 @@ 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);
|
||||
}
|
||||
|
||||
SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||
|
||||
static SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||
{
|
||||
Byte buf[32];
|
||||
UInt64 globalPos;
|
||||
@@ -92,6 +90,7 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||
globalPos = pos;
|
||||
buf[0] = 0;
|
||||
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
||||
|
||||
for (i = 0; i < p->numBlocks; i++)
|
||||
{
|
||||
const CXzBlockSizes *block = &p->blocks[i];
|
||||
@@ -100,7 +99,9 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||
globalPos += pos;
|
||||
RINOK(WriteBytesAndCrc(s, buf, pos, &crc));
|
||||
}
|
||||
|
||||
pos = ((unsigned)globalPos & 3);
|
||||
|
||||
if (pos != 0)
|
||||
{
|
||||
buf[0] = buf[1] = buf[2] = 0;
|
||||
@@ -125,34 +126,36 @@ SRes Xz_WriteFooter(CXzStream *p, ISeqOutStream *s)
|
||||
}
|
||||
}
|
||||
|
||||
SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
|
||||
|
||||
static SRes Xz_AddIndexRecord(CXzStream *p, UInt64 unpackSize, UInt64 totalSize, ISzAlloc *alloc)
|
||||
{
|
||||
if (p->blocks == 0 || p->numBlocksAllocated == p->numBlocks)
|
||||
if (!p->blocks || p->numBlocksAllocated == p->numBlocks)
|
||||
{
|
||||
size_t num = (p->numBlocks + 1) * 2;
|
||||
size_t num = p->numBlocks * 2 + 1;
|
||||
size_t newSize = sizeof(CXzBlockSizes) * num;
|
||||
CXzBlockSizes *blocks;
|
||||
if (newSize / sizeof(CXzBlockSizes) != num)
|
||||
return SZ_ERROR_MEM;
|
||||
blocks = alloc->Alloc(alloc, newSize);
|
||||
if (blocks == 0)
|
||||
blocks = (CXzBlockSizes *)alloc->Alloc(alloc, newSize);
|
||||
if (!blocks)
|
||||
return SZ_ERROR_MEM;
|
||||
if (p->numBlocks != 0)
|
||||
{
|
||||
memcpy(blocks, p->blocks, p->numBlocks * sizeof(CXzBlockSizes));
|
||||
Xz_Free(p, alloc);
|
||||
alloc->Free(alloc, p->blocks);
|
||||
}
|
||||
p->blocks = blocks;
|
||||
p->numBlocksAllocated = num;
|
||||
}
|
||||
{
|
||||
CXzBlockSizes *block = &p->blocks[p->numBlocks++];
|
||||
block->totalSize = totalSize;
|
||||
block->unpackSize = unpackSize;
|
||||
block->totalSize = totalSize;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- CSeqCheckInStream ---------- */
|
||||
|
||||
typedef struct
|
||||
@@ -163,13 +166,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);
|
||||
}
|
||||
@@ -183,6 +186,7 @@ static SRes SeqCheckInStream_Read(void *pp, void *data, size_t *size)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- CSeqSizeOutStream ---------- */
|
||||
|
||||
typedef struct
|
||||
@@ -200,6 +204,7 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- CSeqInFilter ---------- */
|
||||
|
||||
#define FILTER_BUF_SIZE (1 << 20)
|
||||
@@ -222,6 +227,7 @@ static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
|
||||
if (sizeOriginal == 0)
|
||||
return SZ_OK;
|
||||
*size = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!p->srcWasFinished && p->curPos == p->endPos)
|
||||
@@ -279,6 +285,7 @@ static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- CSbEncInStream ---------- */
|
||||
|
||||
#ifdef USE_SUBBLOCK
|
||||
@@ -296,6 +303,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
||||
size_t sizeOriginal = *size;
|
||||
if (sizeOriginal == 0)
|
||||
return S_OK;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (p->enc.needRead && !p->enc.readWasFinished)
|
||||
@@ -310,6 +318,7 @@ static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
|
||||
}
|
||||
p->enc.needRead = False;
|
||||
}
|
||||
|
||||
*size = sizeOriginal;
|
||||
RINOK(SbEnc_Read(&p->enc, data, size));
|
||||
if (*size != 0 || !p->enc.needRead)
|
||||
@@ -362,7 +371,7 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
|
||||
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
|
||||
{
|
||||
p->lzma2 = Lzma2Enc_Create(p->alloc, p->bigAlloc);
|
||||
if (p->lzma2 == 0)
|
||||
if (!p->lzma2)
|
||||
return SZ_ERROR_MEM;
|
||||
return SZ_OK;
|
||||
}
|
||||
@@ -380,10 +389,11 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void XzProps_Init(CXzProps *p)
|
||||
{
|
||||
p->lzma2Props = 0;
|
||||
p->filterProps = 0;
|
||||
p->lzma2Props = NULL;
|
||||
p->filterProps = NULL;
|
||||
p->checkId = XZ_CHECK_CRC32;
|
||||
}
|
||||
|
||||
@@ -391,10 +401,11 @@ void XzFilterProps_Init(CXzFilterProps *p)
|
||||
{
|
||||
p->id = 0;
|
||||
p->delta = 0;
|
||||
p->ip= 0;
|
||||
p->ip = 0;
|
||||
p->ipDefined = False;
|
||||
}
|
||||
|
||||
|
||||
static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||
ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
const CXzProps *props, ICompressProgress *progress)
|
||||
@@ -408,7 +419,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;
|
||||
|
||||
@@ -420,6 +431,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||
filter = &block.filters[filterIndex++];
|
||||
filter->id = fp->id;
|
||||
filter->propsSize = 0;
|
||||
|
||||
if (fp->id == XZ_ID_Delta)
|
||||
{
|
||||
filter->props[0] = (Byte)(fp->delta - 1);
|
||||
@@ -467,14 +479,16 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||
|
||||
{
|
||||
UInt64 packPos = seqSizeOutStream.processed;
|
||||
|
||||
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
|
||||
fp ?
|
||||
#ifdef USE_SUBBLOCK
|
||||
(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
|
||||
#endif
|
||||
&lzmaf->filter.p:
|
||||
&checkInStream.p,
|
||||
progress);
|
||||
fp ?
|
||||
#ifdef USE_SUBBLOCK
|
||||
(fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
|
||||
#endif
|
||||
&lzmaf->filter.p:
|
||||
&checkInStream.p,
|
||||
progress);
|
||||
|
||||
RINOK(res);
|
||||
block.unpackSize = checkInStream.processed;
|
||||
block.packSize = seqSizeOutStream.processed - packPos;
|
||||
@@ -483,7 +497,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||
{
|
||||
unsigned padSize = 0;
|
||||
Byte buf[128];
|
||||
while((((unsigned)block.packSize + padSize) & 3) != 0)
|
||||
while ((((unsigned)block.packSize + padSize) & 3) != 0)
|
||||
buf[padSize++] = 0;
|
||||
SeqCheckInStream_GetDigest(&checkInStream, buf + padSize);
|
||||
RINOK(WriteBytes(&seqSizeOutStream.p, buf, padSize + XzFlags_GetCheckSize(xz->flags)));
|
||||
@@ -493,6 +507,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
||||
return Xz_WriteFooter(xz, outStream);
|
||||
}
|
||||
|
||||
|
||||
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
const CXzProps *props, ICompressProgress *progress)
|
||||
{
|
||||
@@ -509,6 +524,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SRes Xz_EncodeEmpty(ISeqOutStream *outStream)
|
||||
{
|
||||
SRes res;
|
||||
|
||||
71
C/XzIn.c
71
C/XzIn.c
@@ -1,5 +1,5 @@
|
||||
/* XzIn.c - Xz input
|
||||
2013-11-12 : Igor Pavlov : Public domain */
|
||||
2015-04-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Precomp.h"
|
||||
|
||||
@@ -72,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
|
||||
|
||||
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
|
||||
{
|
||||
size_t i, numBlocks, crcStartPos, pos = 1;
|
||||
size_t i, numBlocks, pos = 1;
|
||||
UInt32 crc;
|
||||
|
||||
if (size < 5 || buf[0] != 0)
|
||||
@@ -91,7 +91,6 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
}
|
||||
|
||||
crcStartPos = pos;
|
||||
Xz_Free(p, alloc);
|
||||
if (numBlocks != 0)
|
||||
{
|
||||
@@ -135,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;
|
||||
}
|
||||
@@ -198,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;
|
||||
@@ -292,14 +296,15 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
|
||||
if (data == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
p->numAllocated = newNum;
|
||||
memcpy(data, p->streams, p->num * sizeof(CXzStream));
|
||||
if (p->num != 0)
|
||||
memcpy(data, p->streams, p->num * sizeof(CXzStream));
|
||||
alloc->Free(alloc, p->streams);
|
||||
p->streams = (CXzStream *)data;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -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,290 @@ 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];
|
||||
|
||||
#ifndef _SFX
|
||||
// we don't support RAR codecs here
|
||||
if ((coderInfo.MethodID >> 8) == 0x403)
|
||||
return E_NOTIMPL;
|
||||
#endif
|
||||
|
||||
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 +376,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 +387,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 +396,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 +415,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
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
}}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -321,13 +310,13 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
|
||||
if (/* _db.IsTree && propID == kpidName ||
|
||||
!_db.IsTree && */ propID == kpidPath)
|
||||
{
|
||||
const wchar_t *name = _db.GetName(index);
|
||||
if (name)
|
||||
if (_db.NameOffsets && _db.NamesBuf)
|
||||
{
|
||||
size_t size = (_db.NameOffsets[index + 1] - _db.NameOffsets[index]) * 2;
|
||||
size_t offset = _db.NameOffsets[index];
|
||||
size_t size = (_db.NameOffsets[index + 1] - offset) * 2;
|
||||
if (size < ((UInt32)1 << 31))
|
||||
{
|
||||
*data = (void *)name;
|
||||
*data = (const void *)(_db.NamesBuf + offset * 2);
|
||||
*dataSize = (UInt32)size;
|
||||
*propType = NPropDataType::kUtf16z;
|
||||
}
|
||||
@@ -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:
|
||||
@@ -607,8 +590,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
}
|
||||
*/
|
||||
|
||||
case kpidPath: return _db.GetPath(index, value);
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
@@ -54,6 +44,7 @@ public:
|
||||
UInt64 _numSolidBytes;
|
||||
bool _numSolidBytesDefined;
|
||||
bool _solidExtension;
|
||||
bool _useTypeSorting;
|
||||
|
||||
bool _compressHeaders;
|
||||
bool _encryptHeadersSpecified;
|
||||
@@ -64,7 +55,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); }
|
||||
@@ -102,7 +95,7 @@ class CHandler:
|
||||
{
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IInArchive)
|
||||
// MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
|
||||
MY_QUERYINTERFACE_ENTRY(IArchiveGetRawProps)
|
||||
#ifdef __7Z_SET_PROPERTIES
|
||||
MY_QUERYINTERFACE_ENTRY(ISetProperties)
|
||||
#endif
|
||||
@@ -117,7 +110,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 +124,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
|
||||
|
||||
@@ -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;
|
||||
@@ -268,7 +282,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
|
||||
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
|
||||
bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
|
||||
if (db)
|
||||
|
||||
if (db && !db->Files.IsEmpty())
|
||||
{
|
||||
if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
|
||||
if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
|
||||
@@ -301,10 +316,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
const CFileItem &fi = db->Files[ui.IndexInArchive];
|
||||
if (!ui.NewProps)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(_db.GetPath(ui.IndexInArchive, &prop));
|
||||
if (prop.vt == VT_BSTR)
|
||||
name = prop.bstrVal;
|
||||
_db.GetPath(ui.IndexInArchive, name);
|
||||
}
|
||||
ui.IsDir = fi.IsDir;
|
||||
ui.Size = fi.Size;
|
||||
@@ -497,14 +509,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
|
||||
if (ui.NewData)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
ui.Size = (UInt64)prop.uhVal.QuadPart;
|
||||
if (ui.Size != 0 && ui.IsAnti)
|
||||
return E_INVALIDARG;
|
||||
ui.Size = 0;
|
||||
if (!ui.IsDir)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
|
||||
if (prop.vt != VT_UI8)
|
||||
return E_INVALIDARG;
|
||||
ui.Size = (UInt64)prop.uhVal.QuadPart;
|
||||
if (ui.Size != 0 && ui.IsAnti)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
updateItems.Add(ui);
|
||||
}
|
||||
|
||||
@@ -520,18 +537,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;
|
||||
@@ -545,7 +564,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;
|
||||
}
|
||||
|
||||
@@ -553,6 +572,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)
|
||||
@@ -572,12 +600,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;
|
||||
/*
|
||||
@@ -589,8 +619,12 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
||||
options.NumSolidFiles = _numSolidFiles;
|
||||
options.NumSolidBytes = _numSolidBytes;
|
||||
options.SolidExtension = _solidExtension;
|
||||
options.UseTypeSorting = _useTypeSorting;
|
||||
|
||||
options.RemoveSfxBlock = _removeSfxBlock;
|
||||
options.VolumeMode = _volumeMode;
|
||||
// options.VolumeMode = _volumeMode;
|
||||
|
||||
options.MultiThreadMixer = _useMultiThreadMixer;
|
||||
|
||||
COutArchive archive;
|
||||
CArchiveDatabaseOut newDatabase;
|
||||
@@ -638,20 +672,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;
|
||||
}
|
||||
@@ -670,8 +704,12 @@ void COutHandler::InitProps()
|
||||
Write_ATime.Init();
|
||||
Write_MTime.Init();
|
||||
|
||||
_volumeMode = false;
|
||||
_useMultiThreadMixer = true;
|
||||
|
||||
// _volumeMode = false;
|
||||
|
||||
InitSolid();
|
||||
_useTypeSorting = false;
|
||||
}
|
||||
|
||||
HRESULT COutHandler::SetSolidFromString(const UString &s)
|
||||
@@ -765,7 +803,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);
|
||||
@@ -790,15 +828,19 @@ 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("qs")) return PROPVARIANT_to_bool(value, _useTypeSorting);
|
||||
|
||||
// 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++)
|
||||
@@ -815,15 +857,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;
|
||||
}
|
||||
|
||||
@@ -834,40 +880,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <wchar.h>
|
||||
#else
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "../../../../C/7zCrc.h"
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
@@ -26,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);
|
||||
@@ -37,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 {};
|
||||
|
||||
@@ -187,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);
|
||||
@@ -212,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;
|
||||
}
|
||||
@@ -338,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)
|
||||
@@ -345,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;
|
||||
@@ -370,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);
|
||||
}
|
||||
@@ -409,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];
|
||||
@@ -435,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();
|
||||
@@ -452,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;
|
||||
@@ -496,26 +442,83 @@ void CFolders::ParseFolderInfo(unsigned folderIndex, CFolder &folder) const
|
||||
}
|
||||
|
||||
|
||||
HRESULT CDatabase::GetPath(unsigned index, PROPVARIANT *path) const
|
||||
void CDatabase::GetPath(unsigned index, UString &path) const
|
||||
{
|
||||
path.Empty();
|
||||
if (!NameOffsets || !NamesBuf)
|
||||
return;
|
||||
|
||||
size_t offset = NameOffsets[index];
|
||||
size_t size = NameOffsets[index + 1] - offset;
|
||||
|
||||
if (size >= (1 << 28))
|
||||
return;
|
||||
|
||||
wchar_t *s = path.GetBuf((unsigned)size - 1);
|
||||
|
||||
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
|
||||
|
||||
#if defined(_WIN32) && defined(MY_CPU_LE)
|
||||
|
||||
wmemcpy(s, (const wchar_t *)p, size);
|
||||
|
||||
#else
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
*s = Get16(p);
|
||||
p += 2;
|
||||
s++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
path.ReleaseBuf_SetLen((unsigned)size - 1);
|
||||
}
|
||||
|
||||
HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
||||
{
|
||||
PropVariant_Clear(path);
|
||||
if (!NameOffsets || !NamesBuf)
|
||||
return S_OK;
|
||||
|
||||
size_t offset = NameOffsets[index];
|
||||
size_t size = NameOffsets[index + 1] - offset;
|
||||
|
||||
if (size >= (1 << 14))
|
||||
return S_OK;
|
||||
|
||||
RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
|
||||
wchar_t *s = path->bstrVal;
|
||||
|
||||
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
wchar_t c = Get16(p);
|
||||
p += 2;
|
||||
#if WCHAR_PATH_SEPARATOR != L'/'
|
||||
if (c == L'/')
|
||||
c = WCHAR_PATH_SEPARATOR;
|
||||
#endif
|
||||
*s++ = c;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
unsigned cur = index;
|
||||
unsigned size = 0;
|
||||
|
||||
// for (int i = 0;; i++)
|
||||
for (int i = 0;; i++)
|
||||
{
|
||||
size_t len = NameOffsets[cur + 1] - NameOffsets[cur];
|
||||
size += (unsigned)len;
|
||||
if (/* i > 256 || */ len > (1 << 12) || size > (1 << 14))
|
||||
if (i > 256 || len > (1 << 14) || size > (1 << 14))
|
||||
return PropVarEm_Set_Str(path, "[TOO-LONG]");
|
||||
/*
|
||||
cur = Files[cur].Parent;
|
||||
if (cur < 0)
|
||||
break;
|
||||
*/
|
||||
}
|
||||
size--;
|
||||
|
||||
@@ -529,7 +532,7 @@ HRESULT CDatabase::GetPath(unsigned index, PROPVARIANT *path) const
|
||||
{
|
||||
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;
|
||||
@@ -538,17 +541,14 @@ HRESULT CDatabase::GetPath(unsigned index, PROPVARIANT *path) const
|
||||
c = WCHAR_PATH_SEPARATOR;
|
||||
*s = c;
|
||||
}
|
||||
while (--len);
|
||||
/*
|
||||
|
||||
const CFileItem &file = Files[cur];
|
||||
cur = file.Parent;
|
||||
if (cur < 0)
|
||||
*/
|
||||
return S_OK;
|
||||
/*
|
||||
*(--s) = (file.IsAltStream ? ':' : WCHAR_PATH_SEPARATOR);
|
||||
*/
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CInArchive::WaitId(UInt64 id)
|
||||
@@ -579,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();
|
||||
@@ -632,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();
|
||||
@@ -665,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();
|
||||
@@ -699,7 +708,7 @@ void CInArchive::ReadUnpackInfo(
|
||||
}
|
||||
}
|
||||
|
||||
if (numOutStreams == 1 && numInStreams == 1)
|
||||
if (numCoders == 1 && numInStreams == 1)
|
||||
{
|
||||
indexOfMainStream = 0;
|
||||
numPackStreams = 1;
|
||||
@@ -707,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;
|
||||
@@ -1045,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++)
|
||||
{
|
||||
@@ -1067,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);
|
||||
|
||||
@@ -1148,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;
|
||||
@@ -1171,7 +1180,7 @@ HRESULT CInArchive::ReadHeader(
|
||||
bool isKnownType = true;
|
||||
if (type > ((UInt32)1 << 30))
|
||||
isKnownType = false;
|
||||
else switch((UInt32)type)
|
||||
else switch ((UInt32)type)
|
||||
{
|
||||
case NID::kName:
|
||||
{
|
||||
@@ -1329,13 +1338,16 @@ HRESULT CInArchive::ReadHeader(
|
||||
db.UnsupportedFeatureWarning = true;
|
||||
_inByteBack->SkipRem();
|
||||
}
|
||||
// SkipData worked incorrectly in some versions before v4.59 (7zVer <= 00.02)
|
||||
// SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02)
|
||||
if (_inByteBack->GetRem() != 0)
|
||||
ThrowIncorrect();
|
||||
}
|
||||
|
||||
type = ReadID(); // Read (NID::kEnd) end of headers
|
||||
|
||||
if (numFiles - numEmptyStreams != unpackSizes.Size())
|
||||
ThrowUnsupported();
|
||||
|
||||
CNum emptyFileIndex = 0;
|
||||
CNum sizeIndex = 0;
|
||||
|
||||
@@ -1343,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];
|
||||
@@ -1384,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;
|
||||
@@ -1429,6 +1441,7 @@ void CDbEx::FillLinks()
|
||||
if (indexInFolder != 0)
|
||||
ThrowIncorrect();
|
||||
*/
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (folderIndex >= NumFolders)
|
||||
|
||||
@@ -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,15 +113,15 @@ 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;
|
||||
*/
|
||||
|
||||
CByteBuffer NamesBuf;
|
||||
CObjArray<size_t> NameOffsets; // numFiles + 1, conatins offsets of UINt16 symbols.
|
||||
CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols
|
||||
|
||||
/*
|
||||
void ClearSecure()
|
||||
@@ -148,14 +158,16 @@ 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 wchar_t * GetName(unsigned index) const
|
||||
/*
|
||||
const void* GetName(unsigned index) const
|
||||
{
|
||||
if (!NameOffsets || !NamesBuf)
|
||||
return NULL;
|
||||
return (const wchar_t *)(const Byte *)NamesBuf + NameOffsets[index];
|
||||
return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
|
||||
};
|
||||
|
||||
HRESULT GetPath(unsigned index, PROPVARIANT *path) const;
|
||||
*/
|
||||
void GetPath(unsigned index, UString &path) const;
|
||||
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
|
||||
};
|
||||
|
||||
struct CInArchiveInfo
|
||||
@@ -180,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;
|
||||
@@ -233,8 +246,8 @@ struct CDbEx: public CDatabase
|
||||
|
||||
// SecureOffsets.Clear();
|
||||
ArcInfo.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
FileIndexToFolderIndexMap.Clear();
|
||||
FolderStartFileIndex.Free();
|
||||
FileIndexToFolderIndexMap.Free();
|
||||
|
||||
HeadersSize = 0;
|
||||
PhySize = 0;
|
||||
@@ -242,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];
|
||||
}
|
||||
|
||||
@@ -326,6 +339,8 @@ class CInArchive
|
||||
|
||||
UInt64 HeadersSize;
|
||||
|
||||
bool _useMixerMT;
|
||||
|
||||
void AddByteStream(const Byte *buffer, size_t size);
|
||||
|
||||
void DeleteByteStream(bool needUpdatePos)
|
||||
@@ -339,7 +354,6 @@ class CInArchive
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
|
||||
|
||||
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
|
||||
@@ -395,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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace N7z {
|
||||
|
||||
struct CPropMap
|
||||
{
|
||||
UInt64 FilePropID;
|
||||
STATPROPSTG StatPROPSTG;
|
||||
UInt32 FilePropID;
|
||||
CStatProp StatProp;
|
||||
};
|
||||
|
||||
static const CPropMap kPropMap[] =
|
||||
@@ -24,18 +24,18 @@ static const CPropMap kPropMap[] =
|
||||
{ NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } },
|
||||
|
||||
#ifdef _MULTI_PACK
|
||||
{ 100, { L"Pack0", kpidPackedSize0, VT_UI8 } },
|
||||
{ 101, { L"Pack1", kpidPackedSize1, VT_UI8 } },
|
||||
{ 102, { L"Pack2", kpidPackedSize2, VT_UI8 } },
|
||||
{ 103, { L"Pack3", kpidPackedSize3, VT_UI8 } },
|
||||
{ 104, { L"Pack4", kpidPackedSize4, VT_UI8 } },
|
||||
{ 100, { "Pack0", kpidPackedSize0, VT_UI8 } },
|
||||
{ 101, { "Pack1", kpidPackedSize1, VT_UI8 } },
|
||||
{ 102, { "Pack2", kpidPackedSize2, VT_UI8 } },
|
||||
{ 103, { "Pack3", kpidPackedSize3, VT_UI8 } },
|
||||
{ 104, { "Pack4", kpidPackedSize4, VT_UI8 } },
|
||||
#endif
|
||||
|
||||
{ NID::kCTime, { NULL, kpidCTime, VT_FILETIME } },
|
||||
{ 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)
|
||||
{
|
||||
@@ -98,7 +90,7 @@ void CHandler::FillPopIDs()
|
||||
_fileInfoPopIDs.Clear();
|
||||
|
||||
#ifdef _7Z_VOL
|
||||
if(_volumes.Size() < 1)
|
||||
if (_volumes.Size() < 1)
|
||||
return;
|
||||
const CVolume &volume = _volumes.Front();
|
||||
const CArchiveDatabaseEx &_db = volume.Database;
|
||||
@@ -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 CStatProp &st = pr.StatProp;
|
||||
*propID = st.PropID;
|
||||
*varType = st.vt;
|
||||
/*
|
||||
if (st.lpwstrName)
|
||||
*name = ::SysAllocString(st.lpwstrName);
|
||||
else
|
||||
*/
|
||||
*name = NULL;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user