mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 04:07:02 -06:00
15.05
This commit is contained in:
committed by
Kornel Lesiński
parent
0713a3ab80
commit
54490d51d5
20
C/7z.h
20
C/7z.h
@@ -1,5 +1,5 @@
|
|||||||
/* 7z.h -- 7z interface
|
/* 7z.h -- 7z interface
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2014-02-08 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_H
|
#ifndef __7Z_H
|
||||||
#define __7Z_H
|
#define __7Z_H
|
||||||
@@ -11,7 +11,7 @@ EXTERN_C_BEGIN
|
|||||||
#define k7zStartHeaderSize 0x20
|
#define k7zStartHeaderSize 0x20
|
||||||
#define k7zSignatureSize 6
|
#define k7zSignatureSize 6
|
||||||
|
|
||||||
extern Byte k7zSignature[k7zSignatureSize];
|
extern const Byte k7zSignature[k7zSignatureSize];
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -25,8 +25,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
size_t PropsOffset;
|
size_t PropsOffset;
|
||||||
UInt32 MethodID;
|
UInt32 MethodID;
|
||||||
Byte NumInStreams;
|
Byte NumStreams;
|
||||||
Byte NumOutStreams;
|
|
||||||
Byte PropsSize;
|
Byte PropsSize;
|
||||||
} CSzCoderInfo;
|
} CSzCoderInfo;
|
||||||
|
|
||||||
@@ -34,23 +33,22 @@ typedef struct
|
|||||||
{
|
{
|
||||||
UInt32 InIndex;
|
UInt32 InIndex;
|
||||||
UInt32 OutIndex;
|
UInt32 OutIndex;
|
||||||
} CSzBindPair;
|
} CSzBond;
|
||||||
|
|
||||||
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
|
#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_PACK_STREAMS_IN_FOLDER_MAX 4
|
||||||
#define SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX 4
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 NumCoders;
|
UInt32 NumCoders;
|
||||||
UInt32 NumBindPairs;
|
UInt32 NumBonds;
|
||||||
UInt32 NumPackStreams;
|
UInt32 NumPackStreams;
|
||||||
UInt32 MainOutStream;
|
UInt32 UnpackStream;
|
||||||
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
|
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];
|
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;
|
} CSzFolder;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
10
C/7zAlloc.c
10
C/7zAlloc.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zAlloc.c -- Allocation functions
|
/* 7zAlloc.c -- Allocation functions
|
||||||
2010-10-29 : Igor Pavlov : Public domain */
|
2015-02-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ int g_allocCountTemp = 0;
|
|||||||
|
|
||||||
void *SzAlloc(void *p, size_t size)
|
void *SzAlloc(void *p, size_t size)
|
||||||
{
|
{
|
||||||
p = p;
|
UNUSED_VAR(p);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
@@ -34,7 +34,7 @@ void *SzAlloc(void *p, size_t size)
|
|||||||
|
|
||||||
void SzFree(void *p, void *address)
|
void SzFree(void *p, void *address)
|
||||||
{
|
{
|
||||||
p = p;
|
UNUSED_VAR(p);
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
if (address != 0)
|
if (address != 0)
|
||||||
{
|
{
|
||||||
@@ -47,7 +47,7 @@ void SzFree(void *p, void *address)
|
|||||||
|
|
||||||
void *SzAllocTemp(void *p, size_t size)
|
void *SzAllocTemp(void *p, size_t size)
|
||||||
{
|
{
|
||||||
p = p;
|
UNUSED_VAR(p);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
@@ -62,7 +62,7 @@ void *SzAllocTemp(void *p, size_t size)
|
|||||||
|
|
||||||
void SzFreeTemp(void *p, void *address)
|
void SzFreeTemp(void *p, void *address)
|
||||||
{
|
{
|
||||||
p = p;
|
UNUSED_VAR(p);
|
||||||
#ifdef _SZ_ALLOC_DEBUG
|
#ifdef _SZ_ALLOC_DEBUG
|
||||||
if (address != 0)
|
if (address != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
10
C/7zAlloc.h
10
C/7zAlloc.h
@@ -1,15 +1,23 @@
|
|||||||
/* 7zAlloc.h -- Allocation functions
|
/* 7zAlloc.h -- Allocation functions
|
||||||
2010-10-29 : Igor Pavlov : Public domain */
|
2013-03-25 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_ALLOC_H
|
#ifndef __7Z_ALLOC_H
|
||||||
#define __7Z_ALLOC_H
|
#define __7Z_ALLOC_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
void *SzAlloc(void *p, size_t size);
|
void *SzAlloc(void *p, size_t size);
|
||||||
void SzFree(void *p, void *address);
|
void SzFree(void *p, void *address);
|
||||||
|
|
||||||
void *SzAllocTemp(void *p, size_t size);
|
void *SzAllocTemp(void *p, size_t size);
|
||||||
void SzFreeTemp(void *p, void *address);
|
void SzFreeTemp(void *p, void *address);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
306
C/7zArcIn.c
306
C/7zArcIn.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zArcIn.c -- 7z Input functions
|
/* 7zArcIn.c -- 7z Input functions
|
||||||
2014-06-16 : Igor Pavlov : Public domain */
|
2015-05-16 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -10,9 +10,17 @@
|
|||||||
#include "7zCrc.h"
|
#include "7zCrc.h"
|
||||||
#include "CpuArch.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; }
|
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
|
#define k7zMajorVersion 0
|
||||||
|
|
||||||
enum EIdEnum
|
enum EIdEnum
|
||||||
@@ -48,17 +56,15 @@ enum EIdEnum
|
|||||||
// k7zIsReal
|
// 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;
|
UInt32 i;
|
||||||
for (i = 0; i < p->NumBindPairs; i++)
|
for (i = 0; i < p->NumBonds; i++)
|
||||||
if (p->BindPairs[i].InIndex == inStreamIndex)
|
if (p->Bonds[i].InIndex == inStreamIndex)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
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)
|
static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
p->Defs = 0;
|
||||||
|
p->Vals = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
|
MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
|
||||||
MY_ALLOC(UInt32, p->Vals, num, alloc);
|
MY_ALLOC(UInt32, p->Vals, num, alloc);
|
||||||
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +184,7 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
static int TestSignatureCandidate(Byte *testBytes)
|
static int TestSignatureCandidate(Byte *testBytes)
|
||||||
{
|
{
|
||||||
size_t i;
|
unsigned i;
|
||||||
for (i = 0; i < k7zSignatureSize; i++)
|
for (i = 0; i < k7zSignatureSize; i++)
|
||||||
if (testBytes[i] != k7zSignature[i])
|
if (testBytes[i] != k7zSignature[i])
|
||||||
return 0;
|
return 0;
|
||||||
@@ -224,7 +238,7 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
|
|||||||
Byte b;
|
Byte b;
|
||||||
if ((firstByte & mask) == 0)
|
if ((firstByte & mask) == 0)
|
||||||
{
|
{
|
||||||
UInt64 highPart = firstByte & (mask - 1);
|
UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);
|
||||||
*value |= (highPart << (8 * i));
|
*value |= (highPart << (8 * i));
|
||||||
return SZ_OK;
|
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)
|
static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
Byte allAreDefined;
|
Byte allAreDefined;
|
||||||
UInt32 i;
|
|
||||||
Byte *v2;
|
Byte *v2;
|
||||||
UInt32 numBytes = (numItems + 7) >> 3;
|
UInt32 numBytes = (numItems + 7) >> 3;
|
||||||
|
*v = NULL;
|
||||||
RINOK(SzReadByte(sd, &allAreDefined));
|
RINOK(SzReadByte(sd, &allAreDefined));
|
||||||
|
if (numBytes == 0)
|
||||||
|
return SZ_OK;
|
||||||
if (allAreDefined == 0)
|
if (allAreDefined == 0)
|
||||||
{
|
{
|
||||||
if (numBytes > sd->Size)
|
if (numBytes > sd->Size)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
MY_ALLOC(Byte, *v, numBytes, alloc);
|
MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc);
|
||||||
memcpy(*v, sd->Data, numBytes);
|
|
||||||
SKIP_DATA(sd, numBytes);
|
SKIP_DATA(sd, numBytes);
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
MY_ALLOC(Byte, *v, numBytes, alloc);
|
MY_ALLOC(Byte, *v, numBytes, alloc);
|
||||||
v2 = *v;
|
v2 = *v;
|
||||||
for (i = 0; i < numBytes; i++)
|
memset(v2, 0xFF, (size_t)numBytes);
|
||||||
v2[i] = 0xFF;
|
|
||||||
{
|
{
|
||||||
unsigned numBits = (unsigned)numItems & 7;
|
unsigned numBits = (unsigned)numItems & 7;
|
||||||
if (numBits != 0)
|
if (numBits != 0)
|
||||||
@@ -398,7 +412,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c
|
|||||||
CSzData sd;
|
CSzData sd;
|
||||||
UInt32 *vals;
|
UInt32 *vals;
|
||||||
const Byte *defs;
|
const Byte *defs;
|
||||||
MY_ALLOC(UInt32, crcs->Vals, numItems, alloc);
|
MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc);
|
||||||
sd = *sd2;
|
sd = *sd2;
|
||||||
defs = crcs->Defs;
|
defs = crcs->Defs;
|
||||||
vals = crcs->Vals;
|
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)
|
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
|
||||||
{
|
{
|
||||||
UInt32 numCoders, numBindPairs, numPackStreams, i;
|
UInt32 numCoders, i;
|
||||||
UInt32 numInStreams = 0, numOutStreams = 0;
|
UInt32 numInStreams = 0;
|
||||||
const Byte *dataStart = sd->Data;
|
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));
|
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;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
f->NumCoders = numCoders;
|
|
||||||
|
|
||||||
for (i = 0; i < numCoders; i++)
|
for (i = 0; i < numCoders; i++)
|
||||||
{
|
{
|
||||||
@@ -506,9 +523,11 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
|
|||||||
CSzCoderInfo *coder = f->Coders + i;
|
CSzCoderInfo *coder = f->Coders + i;
|
||||||
unsigned idSize, j;
|
unsigned idSize, j;
|
||||||
UInt64 id;
|
UInt64 id;
|
||||||
|
|
||||||
RINOK(SzReadByte(sd, &mainByte));
|
RINOK(SzReadByte(sd, &mainByte));
|
||||||
if ((mainByte & 0xC0) != 0)
|
if ((mainByte & 0xC0) != 0)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
idSize = (unsigned)(mainByte & 0xF);
|
idSize = (unsigned)(mainByte & 0xF);
|
||||||
if (idSize > sizeof(id))
|
if (idSize > sizeof(id))
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
@@ -525,90 +544,108 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
|
|||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
coder->MethodID = (UInt32)id;
|
coder->MethodID = (UInt32)id;
|
||||||
|
|
||||||
coder->NumInStreams = 1;
|
coder->NumStreams = 1;
|
||||||
coder->NumOutStreams = 1;
|
|
||||||
coder->PropsOffset = 0;
|
coder->PropsOffset = 0;
|
||||||
coder->PropsSize = 0;
|
coder->PropsSize = 0;
|
||||||
|
|
||||||
if ((mainByte & 0x10) != 0)
|
if ((mainByte & 0x10) != 0)
|
||||||
{
|
{
|
||||||
UInt32 numStreams;
|
UInt32 numStreams;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(sd, &numStreams));
|
RINOK(SzReadNumber32(sd, &numStreams));
|
||||||
if (numStreams > NUM_CODER_STREAMS_MAX)
|
if (numStreams > k_NumCodersStreams_in_Folder_MAX)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
coder->NumInStreams = (Byte)numStreams;
|
coder->NumStreams = (Byte)numStreams;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(sd, &numStreams));
|
RINOK(SzReadNumber32(sd, &numStreams));
|
||||||
if (numStreams > NUM_CODER_STREAMS_MAX)
|
if (numStreams != 1)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
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)
|
if ((mainByte & 0x20) != 0)
|
||||||
{
|
{
|
||||||
UInt32 propsSize = 0;
|
UInt32 propsSize = 0;
|
||||||
RINOK(SzReadNumber32(sd, &propsSize));
|
RINOK(SzReadNumber32(sd, &propsSize));
|
||||||
if (propsSize >= 0x40)
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
|
||||||
if (propsSize > sd->Size)
|
if (propsSize > sd->Size)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
if (propsSize >= 0x80)
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
coder->PropsOffset = sd->Data - dataStart;
|
coder->PropsOffset = sd->Data - dataStart;
|
||||||
coder->PropsSize = (Byte)propsSize;
|
coder->PropsSize = (Byte)propsSize;
|
||||||
sd->Data += (size_t)propsSize;
|
sd->Data += (size_t)propsSize;
|
||||||
sd->Size -= (size_t)propsSize;
|
sd->Size -= (size_t)propsSize;
|
||||||
}
|
}
|
||||||
numInStreams += coder->NumInStreams;
|
|
||||||
numOutStreams += coder->NumOutStreams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOutStreams == 0)
|
/*
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
if (numInStreams == 1 && numCoders == 1)
|
||||||
|
{
|
||||||
|
f->NumPackStreams = 1;
|
||||||
|
f->PackStreams[0] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];
|
||||||
|
UInt32 numBonds, numPackStreams;
|
||||||
|
|
||||||
f->NumBindPairs = numBindPairs = numOutStreams - 1;
|
numBonds = numCoders - 1;
|
||||||
if (numInStreams < numBindPairs)
|
if (numInStreams < numBonds)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
if (numInStreams > SZ_NUM_IN_STREAMS_IN_FOLDER_MAX)
|
if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
f->MainOutStream = 0;
|
f->NumBonds = numBonds;
|
||||||
f->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
|
|
||||||
|
numPackStreams = numInStreams - numBonds;
|
||||||
if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
|
if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
f->NumPackStreams = numPackStreams;
|
||||||
|
|
||||||
for (i = 0; i < numInStreams; i++)
|
for (i = 0; i < numInStreams; i++)
|
||||||
inStreamUsed[i] = False;
|
streamUsed[i] = False;
|
||||||
if (numBindPairs != 0)
|
|
||||||
|
if (numBonds != 0)
|
||||||
{
|
{
|
||||||
Byte outStreamUsed[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
|
Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];
|
||||||
|
|
||||||
if (numBindPairs > SZ_NUM_BINDS_IN_FOLDER_MAX)
|
for (i = 0; i < numCoders; i++)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
coderUsed[i] = False;
|
||||||
|
|
||||||
for (i = 0; i < numOutStreams; i++)
|
for (i = 0; i < numBonds; i++)
|
||||||
outStreamUsed[i] = False;
|
|
||||||
|
|
||||||
for (i = 0; i < numBindPairs; i++)
|
|
||||||
{
|
{
|
||||||
CSzBindPair *bp = f->BindPairs + i;
|
CSzBond *bp = f->Bonds + i;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(sd, &bp->InIndex));
|
RINOK(SzReadNumber32(sd, &bp->InIndex));
|
||||||
if (bp->InIndex >= numInStreams)
|
if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex])
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
inStreamUsed[bp->InIndex] = True;
|
streamUsed[bp->InIndex] = True;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(sd, &bp->OutIndex));
|
RINOK(SzReadNumber32(sd, &bp->OutIndex));
|
||||||
if (bp->OutIndex >= numInStreams)
|
if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex])
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
outStreamUsed[bp->OutIndex] = True;
|
coderUsed[bp->OutIndex] = True;
|
||||||
}
|
}
|
||||||
for (i = 0; i < numOutStreams; i++)
|
|
||||||
if (!outStreamUsed[i])
|
for (i = 0; i < numCoders; i++)
|
||||||
|
if (!coderUsed[i])
|
||||||
{
|
{
|
||||||
f->MainOutStream = i;
|
f->UnpackStream = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == numOutStreams)
|
|
||||||
|
if (i == numCoders)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numPackStreams == 1)
|
if (numPackStreams == 1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < numInStreams; i++)
|
for (i = 0; i < numInStreams; i++)
|
||||||
if (!inStreamUsed[i])
|
if (!streamUsed[i])
|
||||||
break;
|
break;
|
||||||
if (i == numInStreams)
|
if (i == numInStreams)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
@@ -617,14 +654,22 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
|
|||||||
else
|
else
|
||||||
for (i = 0; i < numPackStreams; i++)
|
for (i = 0; i < numPackStreams; i++)
|
||||||
{
|
{
|
||||||
RINOK(SzReadNumber32(sd, f->PackStreams + 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 < numOutStreams; i++)
|
for (i = 0; i < numCoders; i++)
|
||||||
{
|
{
|
||||||
RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
|
RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f->NumCoders = numCoders;
|
||||||
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,24 +703,25 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define k_InStreamUsed_MAX 64
|
#define k_Scan_NumCoders_MAX 64
|
||||||
#define k_OutStreamUsed_MAX 64
|
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
|
||||||
|
|
||||||
static SRes ReadUnpackInfo(CSzAr *p,
|
static SRes ReadUnpackInfo(CSzAr *p,
|
||||||
CSzData *sd2,
|
CSzData *sd2,
|
||||||
UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
|
UInt32 numFoldersMax,
|
||||||
|
const CBuf *tempBufs, UInt32 numTempBufs,
|
||||||
ISzAlloc *alloc)
|
ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
CSzData sd;
|
CSzData sd;
|
||||||
Byte inStreamUsed[k_InStreamUsed_MAX];
|
|
||||||
Byte outStreamUsed[k_OutStreamUsed_MAX];
|
|
||||||
UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
|
UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
|
||||||
const Byte *startBufPtr;
|
const Byte *startBufPtr;
|
||||||
Byte external;
|
Byte external;
|
||||||
|
|
||||||
RINOK(WaitId(sd2, k7zIdFolder));
|
RINOK(WaitId(sd2, k7zIdFolder));
|
||||||
|
|
||||||
RINOK(SzReadNumber32(sd2, &numFolders));
|
RINOK(SzReadNumber32(sd2, &numFolders));
|
||||||
if (p->NumFolders > numFoldersMax)
|
if (numFolders > numFoldersMax)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
p->NumFolders = numFolders;
|
p->NumFolders = numFolders;
|
||||||
|
|
||||||
@@ -685,7 +731,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 index;
|
UInt32 index;
|
||||||
SzReadNumber32(sd2, &index);
|
RINOK(SzReadNumber32(sd2, &index));
|
||||||
if (index >= numTempBufs)
|
if (index >= numTempBufs)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
sd.Data = tempBufs[index].data;
|
sd.Data = tempBufs[index].data;
|
||||||
@@ -703,18 +749,19 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
|
|
||||||
for (fo = 0; fo < numFolders; fo++)
|
for (fo = 0; fo < numFolders; fo++)
|
||||||
{
|
{
|
||||||
UInt32 numCoders, ci, numInStreams = 0, numOutStreams = 0;
|
UInt32 numCoders, ci, numInStreams = 0;
|
||||||
|
|
||||||
p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
|
p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(&sd, &numCoders));
|
RINOK(SzReadNumber32(&sd, &numCoders));
|
||||||
if (numCoders > NUM_FOLDER_CODERS_MAX)
|
if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
for (ci = 0; ci < numCoders; ci++)
|
for (ci = 0; ci < numCoders; ci++)
|
||||||
{
|
{
|
||||||
Byte mainByte;
|
Byte mainByte;
|
||||||
unsigned idSize;
|
unsigned idSize;
|
||||||
UInt32 coderInStreams, coderOutStreams;
|
UInt32 coderInStreams;
|
||||||
|
|
||||||
SZ_READ_BYTE_2(mainByte);
|
SZ_READ_BYTE_2(mainByte);
|
||||||
if ((mainByte & 0xC0) != 0)
|
if ((mainByte & 0xC0) != 0)
|
||||||
@@ -727,17 +774,18 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
SKIP_DATA2(sd, idSize);
|
SKIP_DATA2(sd, idSize);
|
||||||
|
|
||||||
coderInStreams = 1;
|
coderInStreams = 1;
|
||||||
coderOutStreams = 1;
|
|
||||||
if ((mainByte & 0x10) != 0)
|
if ((mainByte & 0x10) != 0)
|
||||||
{
|
{
|
||||||
|
UInt32 coderOutStreams;
|
||||||
RINOK(SzReadNumber32(&sd, &coderInStreams));
|
RINOK(SzReadNumber32(&sd, &coderInStreams));
|
||||||
RINOK(SzReadNumber32(&sd, &coderOutStreams));
|
RINOK(SzReadNumber32(&sd, &coderOutStreams));
|
||||||
if (coderInStreams > NUM_CODER_STREAMS_MAX ||
|
if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1)
|
||||||
coderOutStreams > NUM_CODER_STREAMS_MAX)
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
numInStreams += coderInStreams;
|
numInStreams += coderInStreams;
|
||||||
numOutStreams += coderOutStreams;
|
|
||||||
if ((mainByte & 0x20) != 0)
|
if ((mainByte & 0x20) != 0)
|
||||||
{
|
{
|
||||||
UInt32 propsSize;
|
UInt32 propsSize;
|
||||||
@@ -751,64 +799,73 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
{
|
{
|
||||||
UInt32 indexOfMainStream = 0;
|
UInt32 indexOfMainStream = 0;
|
||||||
UInt32 numPackStreams = 1;
|
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 i;
|
||||||
UInt32 numBindPairs = numOutStreams - 1;
|
UInt32 numBonds = numCoders - 1;
|
||||||
if (numOutStreams == 0 || numInStreams < numBindPairs)
|
if (numInStreams < numBonds)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
if (numInStreams > k_InStreamUsed_MAX ||
|
if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
|
||||||
numOutStreams > k_OutStreamUsed_MAX)
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
for (i = 0; i < numInStreams; i++)
|
for (i = 0; i < numInStreams; i++)
|
||||||
inStreamUsed[i] = False;
|
streamUsed[i] = False;
|
||||||
for (i = 0; i < numOutStreams; i++)
|
for (i = 0; i < numCoders; i++)
|
||||||
outStreamUsed[i] = False;
|
coderUsed[i] = False;
|
||||||
|
|
||||||
for (i = 0; i < numBindPairs; i++)
|
for (i = 0; i < numBonds; i++)
|
||||||
{
|
{
|
||||||
UInt32 index;
|
UInt32 index;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(&sd, &index));
|
RINOK(SzReadNumber32(&sd, &index));
|
||||||
if (index >= numInStreams || inStreamUsed[index])
|
if (index >= numInStreams || streamUsed[index])
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
inStreamUsed[index] = True;
|
streamUsed[index] = True;
|
||||||
|
|
||||||
RINOK(SzReadNumber32(&sd, &index));
|
RINOK(SzReadNumber32(&sd, &index));
|
||||||
if (index >= numInStreams || outStreamUsed[index])
|
if (index >= numCoders || coderUsed[index])
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
outStreamUsed[index] = True;
|
coderUsed[index] = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
numPackStreams = numInStreams - numBindPairs;
|
numPackStreams = numInStreams - numBonds;
|
||||||
|
|
||||||
if (numPackStreams != 1)
|
if (numPackStreams != 1)
|
||||||
for (i = 0; i < numPackStreams; i++)
|
for (i = 0; i < numPackStreams; i++)
|
||||||
{
|
{
|
||||||
UInt32 temp;
|
UInt32 index;
|
||||||
RINOK(SzReadNumber32(&sd, &temp));
|
RINOK(SzReadNumber32(&sd, &index));
|
||||||
if (temp >= numInStreams)
|
if (index >= numInStreams || streamUsed[index])
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
streamUsed[index] = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numOutStreams; i++)
|
for (i = 0; i < numCoders; i++)
|
||||||
if (!outStreamUsed[i])
|
if (!coderUsed[i])
|
||||||
{
|
{
|
||||||
indexOfMainStream = i;
|
indexOfMainStream = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == numOutStreams)
|
if (i == numCoders)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->FoStartPackStreamIndex[fo] = packStreamIndex;
|
p->FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||||
p->FoSizesOffsets[fo] = (numOutStreams << 8) | indexOfMainStream;
|
p->FoSizesOffsets[fo] = (numCoders << 8) | indexOfMainStream;
|
||||||
numCodersOutStreams += numOutStreams;
|
numCodersOutStreams += numCoders;
|
||||||
if (numCodersOutStreams < numOutStreams)
|
if (numCodersOutStreams < numCoders)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
packStreamIndex += numPackStreams;
|
packStreamIndex += numPackStreams;
|
||||||
if (packStreamIndex < numPackStreams)
|
if (packStreamIndex < numPackStreams)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
|
||||||
if (packStreamIndex > p->NumPackStreams)
|
if (packStreamIndex > p->NumPackStreams)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
}
|
}
|
||||||
@@ -818,8 +875,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
size_t dataSize = sd.Data - startBufPtr;
|
size_t dataSize = sd.Data - startBufPtr;
|
||||||
p->FoStartPackStreamIndex[fo] = packStreamIndex;
|
p->FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||||
p->FoCodersOffsets[fo] = dataSize;
|
p->FoCodersOffsets[fo] = dataSize;
|
||||||
MY_ALLOC(Byte, p->CodersData, dataSize, alloc);
|
MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc);
|
||||||
memcpy(p->CodersData, startBufPtr, dataSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (external != 0)
|
if (external != 0)
|
||||||
@@ -831,7 +887,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
|
|
||||||
RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
|
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;
|
size_t dataSize = sd.Size;
|
||||||
/*
|
/*
|
||||||
@@ -843,8 +899,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
|
|||||||
*/
|
*/
|
||||||
RINOK(SkipNumbers(&sd, numCodersOutStreams));
|
RINOK(SkipNumbers(&sd, numCodersOutStreams));
|
||||||
dataSize -= sd.Size;
|
dataSize -= sd.Size;
|
||||||
MY_ALLOC(Byte, p->UnpackSizesData, dataSize, alloc);
|
MY_ALLOC_ZE_AND_CPY(p->UnpackSizesData, dataSize, sd.Data - dataSize, alloc);
|
||||||
memcpy(p->UnpackSizesData, sd.Data - dataSize, dataSize);
|
|
||||||
p->UnpackSizesDataSize = dataSize;
|
p->UnpackSizesDataSize = dataSize;
|
||||||
/*
|
/*
|
||||||
const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams);
|
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.Data = p->UnpackSizesData;
|
||||||
sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
|
sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
|
||||||
|
|
||||||
for (fo = 0; fo < p->NumFolders; fo++)
|
for (fo = 0; fo < p->NumFolders; fo++)
|
||||||
Buf_Init(tempBufs + fo);
|
Buf_Init(tempBufs + fo);
|
||||||
|
|
||||||
for (fo = 0; fo < p->NumFolders; fo++)
|
for (fo = 0; fo < p->NumFolders; fo++)
|
||||||
{
|
{
|
||||||
CBuf *tempBuf = tempBufs + fo;
|
CBuf *tempBuf = tempBufs + fo;
|
||||||
@@ -1049,6 +1106,7 @@ static SRes SzReadAndDecodePackedStreams(
|
|||||||
if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
|
if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
|
p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
|
||||||
|
|
||||||
for (fo = 0; fo < p->NumFolders; fo++)
|
for (fo = 0; fo < p->NumFolders; fo++)
|
||||||
@@ -1060,6 +1118,7 @@ static SRes SzReadAndDecodePackedStreams(
|
|||||||
if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
|
if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
|
||||||
return SZ_ERROR_CRC;
|
return SZ_ERROR_CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,6 +1128,8 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
|
|||||||
*offsets++ = 0;
|
*offsets++ = 0;
|
||||||
if (numFiles == 0)
|
if (numFiles == 0)
|
||||||
return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||||
|
if (size < 2)
|
||||||
|
return SZ_ERROR_ARCHIVE;
|
||||||
if (data[size - 2] != 0 || data[size - 1] != 0)
|
if (data[size - 2] != 0 || data[size - 1] != 0)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
do
|
do
|
||||||
@@ -1100,20 +1161,23 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
|
|||||||
CNtfsFileTime *vals;
|
CNtfsFileTime *vals;
|
||||||
Byte *defs;
|
Byte *defs;
|
||||||
Byte external;
|
Byte external;
|
||||||
|
|
||||||
RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
|
RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
|
||||||
|
|
||||||
RINOK(SzReadByte(sd2, &external));
|
RINOK(SzReadByte(sd2, &external));
|
||||||
if (external == 0)
|
if (external == 0)
|
||||||
sd = *sd2;
|
sd = *sd2;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 index;
|
UInt32 index;
|
||||||
SzReadNumber32(sd2, &index);
|
RINOK(SzReadNumber32(sd2, &index));
|
||||||
if (index >= numTempBufs)
|
if (index >= numTempBufs)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
sd.Data = tempBufs[index].data;
|
sd.Data = tempBufs[index].data;
|
||||||
sd.Size = tempBufs[index].size;
|
sd.Size = tempBufs[index].size;
|
||||||
}
|
}
|
||||||
MY_ALLOC(CNtfsFileTime, p->Vals, num, alloc);
|
|
||||||
|
MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc);
|
||||||
vals = p->Vals;
|
vals = p->Vals;
|
||||||
defs = p->Defs;
|
defs = p->Defs;
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
@@ -1127,8 +1191,10 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
vals[i].High = vals[i].Low = 0;
|
vals[i].High = vals[i].Low = 0;
|
||||||
|
|
||||||
if (external == 0)
|
if (external == 0)
|
||||||
*sd2 = sd;
|
*sd2 = sd;
|
||||||
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1141,8 +1207,7 @@ static SRes SzReadHeader2(
|
|||||||
// Byte **emptyFileVector, /* allocTemp */
|
// Byte **emptyFileVector, /* allocTemp */
|
||||||
// Byte **lwtVector, /* allocTemp */
|
// Byte **lwtVector, /* allocTemp */
|
||||||
ILookInStream *inStream,
|
ILookInStream *inStream,
|
||||||
CBuf *tempBufs,
|
CBuf *tempBufs, UInt32 *numTempBufs,
|
||||||
UInt32 *numTempBufs,
|
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp
|
ISzAlloc *allocTemp
|
||||||
)
|
)
|
||||||
@@ -1225,11 +1290,12 @@ static SRes SzReadHeader2(
|
|||||||
RINOK(ReadNumber(sd, &size));
|
RINOK(ReadNumber(sd, &size));
|
||||||
if (size > sd->Size)
|
if (size > sd->Size)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
if ((UInt64)(int)type != type)
|
|
||||||
|
if (type >= ((UInt32)1 << 8))
|
||||||
{
|
{
|
||||||
SKIP_DATA(sd, size);
|
SKIP_DATA(sd, size);
|
||||||
}
|
}
|
||||||
else switch((int)type)
|
else switch((unsigned)type)
|
||||||
{
|
{
|
||||||
case k7zIdName:
|
case k7zIdName:
|
||||||
{
|
{
|
||||||
@@ -1246,7 +1312,7 @@ static SRes SzReadHeader2(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 index;
|
UInt32 index;
|
||||||
SzReadNumber32(sd, &index);
|
RINOK(SzReadNumber32(sd, &index));
|
||||||
if (index >= *numTempBufs)
|
if (index >= *numTempBufs)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
namesData = (tempBufs)[index].data;
|
namesData = (tempBufs)[index].data;
|
||||||
@@ -1255,9 +1321,8 @@ static SRes SzReadHeader2(
|
|||||||
|
|
||||||
if ((namesSize & 1) != 0)
|
if ((namesSize & 1) != 0)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
MY_ALLOC(Byte, p->FileNames, namesSize, allocMain);
|
|
||||||
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, 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))
|
RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
|
||||||
if (external == 0)
|
if (external == 0)
|
||||||
{
|
{
|
||||||
@@ -1290,7 +1355,7 @@ static SRes SzReadHeader2(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 index;
|
UInt32 index;
|
||||||
SzReadNumber32(sd, &index);
|
RINOK(SzReadNumber32(sd, &index));
|
||||||
if (index >= *numTempBufs)
|
if (index >= *numTempBufs)
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
sdSwitch.Data = (tempBufs)[index].data;
|
sdSwitch.Data = (tempBufs)[index].data;
|
||||||
@@ -1352,9 +1417,9 @@ static SRes SzReadHeader2(
|
|||||||
sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
|
sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
|
||||||
|
|
||||||
MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain);
|
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(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));
|
RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));
|
||||||
|
|
||||||
@@ -1660,20 +1725,19 @@ static SRes SzArEx_Open2(
|
|||||||
{
|
{
|
||||||
if (type == k7zIdHeader)
|
if (type == k7zIdHeader)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
CSzData sd2;
|
CSzData sd2;
|
||||||
int ttt;
|
unsigned ttt;
|
||||||
for (ttt = 0; ttt < 1; ttt++)
|
for (ttt = 0; ttt < 40000; ttt++)
|
||||||
// for (ttt = 0; ttt < 40000; ttt++)
|
|
||||||
{
|
{
|
||||||
SzArEx_Free(p, allocMain);
|
SzArEx_Free(p, allocMain);
|
||||||
sd2 = sd;
|
sd2 = sd;
|
||||||
res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp
|
res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp);
|
||||||
);
|
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// res = SzReadHeader(p, &sd, allocMain, allocTemp);
|
res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = SZ_ERROR_UNSUPPORTED;
|
res = SZ_ERROR_UNSUPPORTED;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zBuf2.c -- Byte Buffer
|
/* 7zBuf2.c -- Byte Buffer
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2014-08-22 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#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);
|
alloc->Free(alloc, p->data);
|
||||||
p->data = data;
|
p->data = data;
|
||||||
}
|
}
|
||||||
|
if (size != 0)
|
||||||
|
{
|
||||||
memcpy(p->data + p->pos, buf, size);
|
memcpy(p->data + p->pos, buf, size);
|
||||||
p->pos += size;
|
p->pos += size;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
61
C/7zCrc.c
61
C/7zCrc.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zCrc.c -- CRC32 init
|
/* 7zCrc.c -- CRC32 init
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2015-03-10 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -8,24 +8,28 @@
|
|||||||
|
|
||||||
#define kCrcPoly 0xEDB88320
|
#define kCrcPoly 0xEDB88320
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_LE
|
||||||
#define CRC_NUM_TABLES 8
|
#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
|
#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))
|
#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_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
|
#endif
|
||||||
|
|
||||||
#ifndef MY_CPU_BE
|
#ifndef MY_CPU_BE
|
||||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
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
|
#endif
|
||||||
|
|
||||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
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;
|
CRC_FUNC g_CrcUpdate;
|
||||||
|
|
||||||
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||||
|
|
||||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
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;
|
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()
|
void MY_FAST_CALL CrcGenerateTable()
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
@@ -55,21 +70,42 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CRC_NUM_TABLES < 4
|
||||||
|
|
||||||
|
g_CrcUpdate = CrcUpdateT1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#ifdef MY_CPU_LE
|
#ifdef MY_CPU_LE
|
||||||
|
|
||||||
|
g_CrcUpdateT4 = CrcUpdateT4;
|
||||||
g_CrcUpdate = CrcUpdateT4;
|
g_CrcUpdate = CrcUpdateT4;
|
||||||
|
|
||||||
#if CRC_NUM_TABLES == 8
|
#if CRC_NUM_TABLES >= 8
|
||||||
|
g_CrcUpdateT8 = CrcUpdateT8;
|
||||||
|
|
||||||
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
if (!CPU_Is_InOrder())
|
if (!CPU_Is_InOrder())
|
||||||
g_CrcUpdate = CrcUpdateT8;
|
g_CrcUpdate = CrcUpdateT8;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
#ifndef MY_CPU_BE
|
#ifndef MY_CPU_BE
|
||||||
UInt32 k = 1;
|
UInt32 k = 0x01020304;
|
||||||
if (*(const Byte *)&k == 1)
|
const Byte *p = (const Byte *)&k;
|
||||||
|
if (p[0] == 4 && p[1] == 3)
|
||||||
|
{
|
||||||
|
g_CrcUpdateT4 = CrcUpdateT4;
|
||||||
g_CrcUpdate = 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
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
@@ -78,8 +114,15 @@ void MY_FAST_CALL CrcGenerateTable()
|
|||||||
UInt32 x = g_CrcTable[i - 256];
|
UInt32 x = g_CrcTable[i - 256];
|
||||||
g_CrcTable[i] = CRC_UINT32_SWAP(x);
|
g_CrcTable[i] = CRC_UINT32_SWAP(x);
|
||||||
}
|
}
|
||||||
|
g_CrcUpdateT4 = CrcUpdateT1_BeT4;
|
||||||
g_CrcUpdate = CrcUpdateT1_BeT4;
|
g_CrcUpdate = CrcUpdateT1_BeT4;
|
||||||
|
#if CRC_NUM_TABLES >= 8
|
||||||
|
g_CrcUpdateT8 = CrcUpdateT1_BeT8;
|
||||||
|
// g_CrcUpdate = CrcUpdateT1_BeT8;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
87
C/7zCrcOpt.c
87
C/7zCrcOpt.c
@@ -1,14 +1,14 @@
|
|||||||
/* 7zCrcOpt.c -- CRC32 calculation
|
/* 7zCrcOpt.c -- CRC32 calculation
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2015-03-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
|
||||||
|
|
||||||
#ifndef MY_CPU_BE
|
#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)
|
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
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 ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x300 + (v & 0xFF)] ^
|
table[0x300 + ((v ) & 0xFF)]
|
||||||
table[0x200 + ((v >> 8) & 0xFF)] ^
|
^ table[0x200 + ((v >> 8) & 0xFF)]
|
||||||
table[0x100 + ((v >> 16) & 0xFF)] ^
|
^ table[0x100 + ((v >> 16) & 0xFF)]
|
||||||
table[0x000 + ((v >> 24))];
|
^ table[0x000 + ((v >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *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)
|
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
|
#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_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)
|
UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
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;
|
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)
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
{
|
{
|
||||||
v ^= *(const UInt32 *)p;
|
v ^= *(const UInt32 *)p;
|
||||||
v =
|
v =
|
||||||
table[0x000 + (v & 0xFF)] ^
|
table[0x000 + ((v ) & 0xFF)]
|
||||||
table[0x100 + ((v >> 8) & 0xFF)] ^
|
^ table[0x100 + ((v >> 8) & 0xFF)]
|
||||||
table[0x200 + ((v >> 16) & 0xFF)] ^
|
^ table[0x200 + ((v >> 16) & 0xFF)]
|
||||||
table[0x300 + ((v >> 24))];
|
^ table[0x300 + ((v >> 24))];
|
||||||
}
|
}
|
||||||
table -= 0x100;
|
|
||||||
v = CRC_UINT32_SWAP(v);
|
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
||||||
return v;
|
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
|
#endif
|
||||||
|
|||||||
184
C/7zDec.c
184
C/7zDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* 7zDec.c -- Decoding from 7z folder
|
/* 7zDec.c -- Decoding from 7z folder
|
||||||
2014-06-16 : Igor Pavlov : Public domain */
|
2015-06-13 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "Bcj2.h"
|
#include "Bcj2.h"
|
||||||
#include "Bra.h"
|
#include "Bra.h"
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
#include "Delta.h"
|
||||||
#include "LzmaDec.h"
|
#include "LzmaDec.h"
|
||||||
#include "Lzma2Dec.h"
|
#include "Lzma2Dec.h"
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
@@ -19,14 +20,17 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define k_Copy 0
|
#define k_Copy 0
|
||||||
|
#define k_Delta 3
|
||||||
#define k_LZMA2 0x21
|
#define k_LZMA2 0x21
|
||||||
#define k_LZMA 0x30101
|
#define k_LZMA 0x30101
|
||||||
#define k_BCJ 0x03030103
|
#define k_BCJ 0x3030103
|
||||||
#define k_PPC 0x03030205
|
#define k_BCJ2 0x303011B
|
||||||
#define k_ARM 0x03030501
|
#define k_PPC 0x3030205
|
||||||
#define k_ARMT 0x03030701
|
#define k_IA64 0x3030401
|
||||||
#define k_SPARC 0x03030805
|
#define k_ARM 0x3030501
|
||||||
#define k_BCJ2 0x0303011B
|
#define k_ARMT 0x3030701
|
||||||
|
#define k_SPARC 0x3030805
|
||||||
|
|
||||||
|
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
|
||||||
@@ -174,6 +178,9 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _7Z_NO_METHOD_LZMA2
|
||||||
|
|
||||||
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
|
||||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
@@ -223,6 +230,9 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||||
{
|
{
|
||||||
while (inSize > 0)
|
while (inSize > 0)
|
||||||
@@ -248,7 +258,9 @@ static Bool IS_MAIN_METHOD(UInt32 m)
|
|||||||
{
|
{
|
||||||
case k_Copy:
|
case k_Copy:
|
||||||
case k_LZMA:
|
case k_LZMA:
|
||||||
|
#ifndef _7Z_NO_METHOD_LZMA2
|
||||||
case k_LZMA2:
|
case k_LZMA2:
|
||||||
|
#endif
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
case k_PPMD:
|
case k_PPMD:
|
||||||
#endif
|
#endif
|
||||||
@@ -260,13 +272,12 @@ static Bool IS_MAIN_METHOD(UInt32 m)
|
|||||||
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
c->NumInStreams == 1 &&
|
c->NumStreams == 1
|
||||||
c->NumOutStreams == 1 &&
|
/* && c->MethodID <= (UInt32)0xFFFFFFFF */
|
||||||
/* c->MethodID <= (UInt32)0xFFFFFFFF && */
|
&& IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||||
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)
|
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||||
{
|
{
|
||||||
@@ -276,51 +287,64 @@ static SRes CheckSupportedFolder(const CSzFolder *f)
|
|||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
if (f->NumCoders == 1)
|
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_ERROR_UNSUPPORTED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _7Z_NO_METHODS_FILTERS
|
||||||
|
|
||||||
if (f->NumCoders == 2)
|
if (f->NumCoders == 2)
|
||||||
{
|
{
|
||||||
const CSzCoderInfo *c = &f->Coders[1];
|
const CSzCoderInfo *c = &f->Coders[1];
|
||||||
if (
|
if (
|
||||||
/* c->MethodID > (UInt32)0xFFFFFFFF || */
|
/* c->MethodID > (UInt32)0xFFFFFFFF || */
|
||||||
c->NumInStreams != 1 ||
|
c->NumStreams != 1
|
||||||
c->NumOutStreams != 1 ||
|
|| f->NumPackStreams != 1
|
||||||
f->NumPackStreams != 1 ||
|
|| f->PackStreams[0] != 0
|
||||||
f->PackStreams[0] != 0 ||
|
|| f->NumBonds != 1
|
||||||
f->NumBindPairs != 1 ||
|
|| f->Bonds[0].InIndex != 1
|
||||||
f->BindPairs[0].InIndex != 1 ||
|
|| f->Bonds[0].OutIndex != 0)
|
||||||
f->BindPairs[0].OutIndex != 0)
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
switch ((UInt32)c->MethodID)
|
switch ((UInt32)c->MethodID)
|
||||||
{
|
{
|
||||||
|
case k_Delta:
|
||||||
case k_BCJ:
|
case k_BCJ:
|
||||||
|
case k_PPC:
|
||||||
|
case k_IA64:
|
||||||
|
case k_SPARC:
|
||||||
case k_ARM:
|
case k_ARM:
|
||||||
|
case k_ARMT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (f->NumCoders == 4)
|
if (f->NumCoders == 4)
|
||||||
{
|
{
|
||||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
if (!IS_SUPPORTED_CODER(&f->Coders[1])
|
||||||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
|| !IS_SUPPORTED_CODER(&f->Coders[2])
|
||||||
!IS_BCJ2(&f->Coders[3]))
|
|| !IS_BCJ2(&f->Coders[3]))
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
if (f->NumPackStreams != 4 ||
|
if (f->NumPackStreams != 4
|
||||||
f->PackStreams[0] != 2 ||
|
|| f->PackStreams[0] != 2
|
||||||
f->PackStreams[1] != 6 ||
|
|| f->PackStreams[1] != 6
|
||||||
f->PackStreams[2] != 1 ||
|
|| f->PackStreams[2] != 1
|
||||||
f->PackStreams[3] != 0 ||
|
|| f->PackStreams[3] != 0
|
||||||
f->NumBindPairs != 3 ||
|
|| f->NumBonds != 3
|
||||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
|| f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
|
||||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
|| f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
|
||||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
|| f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +388,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
if (outSizeCur != unpackSize)
|
if (outSizeCur != unpackSize)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||||
if (temp == 0 && outSizeCur != 0)
|
if (!temp && outSizeCur != 0)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
outBufCur = tempBuf[1 - ci] = temp;
|
outBufCur = tempBuf[1 - ci] = temp;
|
||||||
tempSizes[1 - ci] = outSizeCur;
|
tempSizes[1 - ci] = outSizeCur;
|
||||||
@@ -393,47 +417,89 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
{
|
{
|
||||||
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
}
|
}
|
||||||
|
#ifndef _7Z_NO_METHOD_LZMA2
|
||||||
else if (coder->MethodID == k_LZMA2)
|
else if (coder->MethodID == k_LZMA2)
|
||||||
{
|
{
|
||||||
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
|
||||||
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
|
||||||
#else
|
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||||
|
else if (coder->MethodID == k_PPMD)
|
||||||
|
{
|
||||||
|
RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
else if (coder->MethodID == k_BCJ2)
|
else if (coder->MethodID == k_BCJ2)
|
||||||
{
|
{
|
||||||
UInt64 offset = packPositions[1];
|
UInt64 offset = packPositions[1];
|
||||||
UInt64 s3Size = packPositions[2] - offset;
|
UInt64 s3Size = packPositions[2] - offset;
|
||||||
SRes res;
|
|
||||||
if (ci != 3)
|
if (ci != 3)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
|
||||||
tempSizes[2] = (SizeT)s3Size;
|
tempSizes[2] = (SizeT)s3Size;
|
||||||
if (tempSizes[2] != s3Size)
|
if (tempSizes[2] != s3Size)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
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;
|
return SZ_ERROR_MEM;
|
||||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
|
||||||
RINOK(res)
|
|
||||||
|
|
||||||
res = Bcj2_Decode(
|
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||||
tempBuf3, tempSize3,
|
RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
|
||||||
tempBuf[0], tempSizes[0],
|
|
||||||
tempBuf[1], tempSizes[1],
|
if ((tempSizes[0] & 3) != 0 ||
|
||||||
tempBuf[2], tempSizes[2],
|
(tempSizes[1] & 3) != 0 ||
|
||||||
outBuffer, outSize);
|
tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
|
||||||
RINOK(res)
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#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
|
else
|
||||||
{
|
{
|
||||||
if (ci != 1)
|
if (coder->PropsSize != 0)
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
switch (coder->MethodID)
|
switch (coder->MethodID)
|
||||||
{
|
{
|
||||||
@@ -444,15 +510,25 @@ static SRes SzFolder_Decode2(const CSzFolder *folder,
|
|||||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
CASE_BRA_CONV(PPC)
|
||||||
|
CASE_BRA_CONV(IA64)
|
||||||
|
CASE_BRA_CONV(SPARC)
|
||||||
CASE_BRA_CONV(ARM)
|
CASE_BRA_CONV(ARM)
|
||||||
|
CASE_BRA_CONV(ARMT)
|
||||||
default:
|
default:
|
||||||
return SZ_ERROR_UNSUPPORTED;
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return SZ_ERROR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
||||||
ILookInStream *inStream, UInt64 startPos,
|
ILookInStream *inStream, UInt64 startPos,
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
@@ -477,10 +553,10 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
|
|||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.MainOutStream])
|
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.UnpackStream])
|
||||||
return SZ_ERROR_FAIL;
|
return SZ_ERROR_FAIL;
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
Byte *tempBuf[3] = { 0, 0, 0};
|
Byte *tempBuf[3] = { 0, 0, 0};
|
||||||
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
|
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
|
||||||
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
|
p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
#define MY_VER_MAJOR 9
|
#define MY_VER_MAJOR 15
|
||||||
#define MY_VER_MINOR 38
|
#define MY_VER_MINOR 05
|
||||||
#define MY_VER_BUILD 00
|
#define MY_VER_BUILD 00
|
||||||
#define MY_VERSION "9.38 beta"
|
#define MY_VERSION "15.05 beta"
|
||||||
// #define MY_7ZIP_VERSION "9.38"
|
#define MY_DATE "2015-06-14"
|
||||||
#define MY_DATE "2015-01-03"
|
|
||||||
#undef MY_COPYRIGHT
|
#undef MY_COPYRIGHT
|
||||||
#undef MY_VERSION_COPYRIGHT_DATE
|
#undef MY_VERSION_COPYRIGHT_DATE
|
||||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
|
||||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
#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
|
/* Aes.c -- AES encryption / decryption
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2015-02-23 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
static UInt32 T[256 * 4];
|
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,
|
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,
|
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,
|
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 UInt32 D[256 * 4];
|
||||||
static Byte InvS[256];
|
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)
|
#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF)
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ void AesGenTables(void)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
InvS[Sbox[i]] = (Byte)i;
|
InvS[Sbox[i]] = (Byte)i;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -82,9 +83,11 @@ void AesGenTables(void)
|
|||||||
D[0x300 + i] = Ui32(a9, aD, aB, aE);
|
D[0x300 + i] = Ui32(a9, aD, aB, aE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_AesCbc_Encode = AesCbc_Encode;
|
g_AesCbc_Encode = AesCbc_Encode;
|
||||||
g_AesCbc_Decode = AesCbc_Decode;
|
g_AesCbc_Decode = AesCbc_Decode;
|
||||||
g_AesCtr_Code = AesCtr_Code;
|
g_AesCtr_Code = AesCtr_Code;
|
||||||
|
|
||||||
#ifdef MY_CPU_X86_OR_AMD64
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
if (CPU_Is_Aes_Supported())
|
if (CPU_Is_Aes_Supported())
|
||||||
{
|
{
|
||||||
@@ -95,34 +98,38 @@ void AesGenTables(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
|
#define HT(i, x, s) (T + (x << 8))[gb ## x(s[(i + x) & 3])]
|
||||||
|
|
||||||
#define HT4(m, i, s, p) m[i] = \
|
#define HT4(m, i, s, p) m[i] = \
|
||||||
HT(i, 0, s) ^ \
|
HT(i, 0, s) ^ \
|
||||||
HT(i, 1, s) ^ \
|
HT(i, 1, s) ^ \
|
||||||
HT(i, 2, s) ^ \
|
HT(i, 2, s) ^ \
|
||||||
HT(i, 3, s) ^ w[p + i]
|
HT(i, 3, s) ^ w[p + i]
|
||||||
/* such order (2031) in HT16 is for VC6/K8 speed optimization) */
|
|
||||||
#define HT16(m, s, p) \
|
#define HT16(m, s, p) \
|
||||||
HT4(m, 2, s, p); \
|
|
||||||
HT4(m, 0, s, p); \
|
HT4(m, 0, s, p); \
|
||||||
HT4(m, 3, s, p); \
|
|
||||||
HT4(m, 1, 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 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 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 HD(i, x, s) (D + (x << 8))[gb ## x(s[(i - x) & 3])]
|
||||||
|
|
||||||
#define HD4(m, i, s, p) m[i] = \
|
#define HD4(m, i, s, p) m[i] = \
|
||||||
HD(i, 0, s) ^ \
|
HD(i, 0, s) ^ \
|
||||||
HD(i, 1, s) ^ \
|
HD(i, 1, s) ^ \
|
||||||
HD(i, 2, s) ^ \
|
HD(i, 2, s) ^ \
|
||||||
HD(i, 3, s) ^ w[p + i];
|
HD(i, 3, s) ^ w[p + i];
|
||||||
/* such order (0231) in HD16 is for VC6/K8 speed optimization) */
|
|
||||||
#define HD16(m, s, p) \
|
#define HD16(m, s, p) \
|
||||||
HD4(m, 0, s, p); \
|
HD4(m, 0, s, p); \
|
||||||
|
HD4(m, 1, s, p); \
|
||||||
HD4(m, 2, s, p); \
|
HD4(m, 2, s, p); \
|
||||||
HD4(m, 3, s, p); \
|
HD4(m, 3, s, p); \
|
||||||
HD4(m, 1, s, p); \
|
|
||||||
|
|
||||||
#define FD(i, x) InvS[gb ## x(m[(i - x) & 3])]
|
#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];
|
#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.
|
/* Aes_Encode and Aes_Decode functions work with little-endian words.
|
||||||
src and dest are pointers to 4 UInt32 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)
|
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];
|
UInt32 temp[4];
|
||||||
Byte buf[16];
|
Byte buf[16];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (++p[0] == 0)
|
if (++p[0] == 0)
|
||||||
p[1]++;
|
p[1]++;
|
||||||
|
|
||||||
Aes_Encode(p + 4, temp, p);
|
Aes_Encode(p + 4, temp, p);
|
||||||
|
|
||||||
SetUi32(buf, temp[0]);
|
SetUi32(buf, temp[0]);
|
||||||
SetUi32(buf + 4, temp[1]);
|
SetUi32(buf + 4, temp[1]);
|
||||||
SetUi32(buf + 8, temp[2]);
|
SetUi32(buf + 8, temp[2]);
|
||||||
SetUi32(buf + 12, temp[3]);
|
SetUi32(buf + 12, temp[3]);
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
*data++ ^= buf[i];
|
*data++ ^= buf[i];
|
||||||
}
|
}
|
||||||
|
|||||||
11
C/Alloc.c
11
C/Alloc.c
@@ -1,5 +1,5 @@
|
|||||||
/* Alloc.c -- Memory allocation functions
|
/* Alloc.c -- Memory allocation functions
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2015-02-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -125,3 +125,12 @@ void BigFree(void *address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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
|
/* Alloc.h -- Memory allocation functions
|
||||||
2009-02-07 : Igor Pavlov : Public domain */
|
2015-02-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __COMMON_ALLOC_H
|
#ifndef __COMMON_ALLOC_H
|
||||||
#define __COMMON_ALLOC_H
|
#define __COMMON_ALLOC_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include "7zTypes.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
EXTERN_C_BEGIN
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *MyAlloc(size_t size);
|
void *MyAlloc(size_t size);
|
||||||
void MyFree(void *address);
|
void MyFree(void *address);
|
||||||
@@ -31,8 +29,9 @@ void BigFree(void *address);
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
extern ISzAlloc g_Alloc;
|
||||||
}
|
extern ISzAlloc g_BigAlloc;
|
||||||
#endif
|
|
||||||
|
EXTERN_C_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
328
C/Bcj2.c
328
C/Bcj2.c
@@ -1,134 +1,256 @@
|
|||||||
/* Bcj2.c -- Converter for x86 code (BCJ2)
|
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
|
||||||
2008-10-04 : Igor Pavlov : Public domain */
|
2014-11-09 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "Bcj2.h"
|
#include "Bcj2.h"
|
||||||
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#ifdef _LZMA_PROB32
|
|
||||||
#define CProb UInt32
|
|
||||||
#else
|
|
||||||
#define CProb UInt16
|
#define CProb UInt16
|
||||||
#endif
|
|
||||||
|
|
||||||
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
#define kTopValue ((UInt32)1 << 24)
|
||||||
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
#define kNumModelBits 11
|
||||||
|
#define kBitModelTotal (1 << kNumModelBits)
|
||||||
#define kNumTopBits 24
|
|
||||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
|
||||||
|
|
||||||
#define kNumBitModelTotalBits 11
|
|
||||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
|
||||||
#define kNumMoveBits 5
|
#define kNumMoveBits 5
|
||||||
|
|
||||||
#define RC_READ_BYTE (*buffer++)
|
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
|
||||||
#define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; }
|
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
|
||||||
#define RC_INIT2 code = 0; range = 0xFFFFFFFF; \
|
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
|
||||||
{ int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }}
|
|
||||||
|
|
||||||
#define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; }
|
void Bcj2Dec_Init(CBcj2Dec *p)
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
CProb p[256 + 2];
|
unsigned i;
|
||||||
SizeT inPos = 0, outPos = 0;
|
|
||||||
|
|
||||||
const Byte *buffer, *bufferLim;
|
p->state = BCJ2_DEC_STATE_OK;
|
||||||
UInt32 range, code;
|
p->ip = 0;
|
||||||
Byte prevByte = 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;
|
SRes Bcj2Dec_Decode(CBcj2Dec *p)
|
||||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
{
|
||||||
p[i] = kBitModelTotal >> 1;
|
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;
|
||||||
|
|
||||||
buffer = buf3;
|
if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
|
||||||
bufferLim = buffer + size3;
|
{
|
||||||
RC_INIT2
|
p->state = BCJ2_STREAM_RC;
|
||||||
|
|
||||||
if (outSize == 0)
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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 (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte b;
|
if (BCJ2_IS_32BIT_STREAM(p->state))
|
||||||
|
p->state = BCJ2_DEC_STATE_OK;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (p->range < kTopValue)
|
||||||
|
{
|
||||||
|
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])++;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
|
||||||
|
const Byte *srcLim;
|
||||||
|
Byte *dest;
|
||||||
|
SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
|
||||||
|
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
p->state = BCJ2_STREAM_MAIN;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = p->dest;
|
||||||
|
if (num > (SizeT)(p->destLim - dest))
|
||||||
|
{
|
||||||
|
num = p->destLim - dest;
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
p->state = BCJ2_DEC_STATE_ORIG;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srcLim = src + num;
|
||||||
|
|
||||||
|
if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
|
||||||
|
*dest = src[0];
|
||||||
|
else for (;;)
|
||||||
|
{
|
||||||
|
Byte b = *src;
|
||||||
|
*dest = b;
|
||||||
|
if (b != 0x0F)
|
||||||
|
{
|
||||||
|
if ((b & 0xFE) == 0xE8)
|
||||||
|
break;
|
||||||
|
dest++;
|
||||||
|
if (++src != srcLim)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dest++;
|
||||||
|
if (++src == srcLim)
|
||||||
|
break;
|
||||||
|
if ((*src & 0xF0) != 0x80)
|
||||||
|
continue;
|
||||||
|
*dest = *src;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = src - p->bufs[BCJ2_STREAM_MAIN];
|
||||||
|
|
||||||
|
if (src == srcLim)
|
||||||
|
{
|
||||||
|
p->temp[3] = src[-1];
|
||||||
|
p->bufs[BCJ2_STREAM_MAIN] = src;
|
||||||
|
p->ip += (UInt32)num;
|
||||||
|
p->dest += num;
|
||||||
|
p->state =
|
||||||
|
p->bufs[BCJ2_STREAM_MAIN] ==
|
||||||
|
p->lims[BCJ2_STREAM_MAIN] ?
|
||||||
|
BCJ2_STREAM_MAIN :
|
||||||
|
BCJ2_DEC_STATE_ORIG;
|
||||||
|
return SZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
UInt32 bound, ttt;
|
||||||
CProb *prob;
|
CProb *prob;
|
||||||
UInt32 bound;
|
Byte b = src[0];
|
||||||
UInt32 ttt;
|
Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
|
||||||
|
|
||||||
SizeT limit = size0 - inPos;
|
p->temp[3] = b;
|
||||||
if (outSize - outPos < limit)
|
p->bufs[BCJ2_STREAM_MAIN] = src + 1;
|
||||||
limit = outSize - outPos;
|
num++;
|
||||||
while (limit != 0)
|
p->ip += (UInt32)num;
|
||||||
|
p->dest += num;
|
||||||
|
|
||||||
|
prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
|
||||||
|
|
||||||
|
_IF_BIT_0
|
||||||
{
|
{
|
||||||
Byte b = buf0[inPos];
|
_UPDATE_0
|
||||||
outBuf[outPos++] = b;
|
continue;
|
||||||
if (IsJ(prevByte, b))
|
}
|
||||||
break;
|
_UPDATE_1
|
||||||
inPos++;
|
|
||||||
prevByte = b;
|
}
|
||||||
limit--;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit == 0 || outPos == outSize)
|
{
|
||||||
break;
|
UInt32 val;
|
||||||
|
unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
|
||||||
|
const Byte *cur = p->bufs[cj];
|
||||||
|
Byte *dest;
|
||||||
|
SizeT rem;
|
||||||
|
|
||||||
b = buf0[inPos++];
|
if (cur == p->lims[cj])
|
||||||
|
{
|
||||||
|
p->state = cj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (b == 0xE8)
|
val = GetBe32(cur);
|
||||||
prob = p + prevByte;
|
p->bufs[cj] = cur + 4;
|
||||||
else if (b == 0xE9)
|
|
||||||
prob = p + 256;
|
|
||||||
else
|
|
||||||
prob = p + 257;
|
|
||||||
|
|
||||||
IF_BIT_0(prob)
|
p->ip += 4;
|
||||||
|
val -= p->ip;
|
||||||
|
dest = p->dest;
|
||||||
|
rem = p->destLim - dest;
|
||||||
|
|
||||||
|
if (rem < 4)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob)
|
SizeT i;
|
||||||
prevByte = b;
|
SetUi32(p->temp, val);
|
||||||
}
|
for (i = 0; i < rem; i++)
|
||||||
else
|
dest[i] = p->temp[i];
|
||||||
{
|
p->dest = dest + rem;
|
||||||
UInt32 dest;
|
p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
|
||||||
const Byte *v;
|
|
||||||
UPDATE_1(prob)
|
|
||||||
if (b == 0xE8)
|
|
||||||
{
|
|
||||||
v = buf1;
|
|
||||||
if (size1 < 4)
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
buf1 += 4;
|
|
||||||
size1 -= 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v = buf2;
|
|
||||||
if (size2 < 4)
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
buf2 += 4;
|
|
||||||
size2 -= 4;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
break;
|
break;
|
||||||
outBuf[outPos++] = (Byte)(dest >> 8);
|
}
|
||||||
if (outPos == outSize)
|
|
||||||
break;
|
SetUi32(dest, val);
|
||||||
outBuf[outPos++] = (Byte)(dest >> 16);
|
p->temp[3] = (Byte)(val >> 24);
|
||||||
if (outPos == outSize)
|
p->dest = dest + 4;
|
||||||
break;
|
|
||||||
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
/* Bcj2.h -- BCJ2 Converter for x86 code
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2014-11-10 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __BCJ2_H
|
#ifndef __BCJ2_H
|
||||||
#define __BCJ2_H
|
#define __BCJ2_H
|
||||||
@@ -8,26 +8,138 @@
|
|||||||
|
|
||||||
EXTERN_C_BEGIN
|
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:
|
CBcj2Dec / CBcj2Enc
|
||||||
outSize <= FullOutputSize,
|
bufs sizes:
|
||||||
where FullOutputSize is full size of output stream of x86_2 filter.
|
BUF_SIZE(n) = lims[n] - bufs[n]
|
||||||
|
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
|
||||||
If buf0 overlaps outBuf, there are two required conditions:
|
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
|
||||||
1) (buf0 >= outBuf)
|
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
|
||||||
2) (buf0 + size0 >= outBuf + FullOutputSize).
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
SZ_OK
|
|
||||||
SZ_ERROR_DATA - Data error
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Bcj2_Decode(
|
/*
|
||||||
const Byte *buf0, SizeT size0,
|
CBcj2Dec:
|
||||||
const Byte *buf1, SizeT size1,
|
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
|
||||||
const Byte *buf2, SizeT size2,
|
bufs[BCJ2_STREAM_MAIN] >= dest &&
|
||||||
const Byte *buf3, SizeT size3,
|
bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
|
||||||
Byte *outBuf, SizeT outSize);
|
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
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Compiler.h -- Compiler ypes
|
/* Compiler.h
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2015-03-25 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __7Z_COMPILER_H
|
#ifndef __7Z_COMPILER_H
|
||||||
#define __7Z_COMPILER_H
|
#define __7Z_COMPILER_H
|
||||||
@@ -25,4 +25,7 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UNUSED_VAR(x) (void)x;
|
||||||
|
/* #define UNUSED_VAR(x) x=x; */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
25
C/CpuArch.c
25
C/CpuArch.c
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.c -- CPU specific code
|
/* CpuArch.c -- CPU specific code
|
||||||
2012-05-29: Igor Pavlov : Public domain */
|
2015-03-25: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ static UInt32 CheckFlag(UInt32 flag)
|
|||||||
#define CHECK_CPUID_IS_SUPPORTED
|
#define CHECK_CPUID_IS_SUPPORTED
|
||||||
#endif
|
#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
|
#ifdef USE_ASM
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 kVendors[][3] =
|
static const UInt32 kVendors[][3] =
|
||||||
{
|
{
|
||||||
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||||
{ 0x68747541, 0x69746E65, 0x444D4163},
|
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||||
@@ -144,18 +144,21 @@ Bool CPU_Is_InOrder()
|
|||||||
UInt32 family, model;
|
UInt32 family, model;
|
||||||
if (!x86cpuid_CheckAndRead(&p))
|
if (!x86cpuid_CheckAndRead(&p))
|
||||||
return True;
|
return True;
|
||||||
family = x86cpuid_GetFamily(&p);
|
|
||||||
model = x86cpuid_GetModel(&p);
|
family = x86cpuid_GetFamily(p.ver);
|
||||||
|
model = x86cpuid_GetModel(p.ver);
|
||||||
|
|
||||||
firm = x86cpuid_GetFirm(&p);
|
firm = x86cpuid_GetFirm(&p);
|
||||||
|
|
||||||
switch (firm)
|
switch (firm)
|
||||||
{
|
{
|
||||||
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
|
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
|
||||||
/* Atom CPU */
|
/* In-Order Atom CPU */
|
||||||
model == 0x100C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|
model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
|
||||||
|| model == 0x2006 /* 45 nm, Z6xx */
|
|| model == 0x26 /* 45 nm, Z6xx */
|
||||||
|| model == 0x2007 /* 32 nm, Z2460 */
|
|| model == 0x27 /* 32 nm, Z2460 */
|
||||||
|| model == 0x3005 /* 32 nm, Z2760 */
|
|| model == 0x35 /* 32 nm, Z2760 */
|
||||||
|| model == 0x3006 /* 32 nm, N2xxx, D2xxx */
|
|| model == 0x36 /* 32 nm, N2xxx, D2xxx */
|
||||||
)));
|
)));
|
||||||
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||||
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||||
|
|||||||
100
C/CpuArch.h
100
C/CpuArch.h
@@ -1,5 +1,5 @@
|
|||||||
/* CpuArch.h -- CPU specific code
|
/* CpuArch.h -- CPU specific code
|
||||||
2013-11-12: Igor Pavlov : Public domain */
|
2015-03-25: Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __CPU_ARCH_H
|
#ifndef __CPU_ARCH_H
|
||||||
#define __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
|
#define MY_CPU_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
#if defined(MY_CPU_AMD64) \
|
||||||
#define MY_CPU_64BIT
|
|| defined(_M_IA64) \
|
||||||
|
|| defined(__AARCH64EL__) \
|
||||||
|
|| defined(__AARCH64EB__)
|
||||||
|
#define MY_CPU_64BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(__i386__)
|
#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
|
#define MY_CPU_X86_OR_AMD64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
#if defined(MY_CPU_X86) \
|
||||||
#define MY_CPU_32BIT
|
|| defined(_M_ARM) \
|
||||||
|
|| defined(__ARMEL__) \
|
||||||
|
|| defined(__THUMBEL__) \
|
||||||
|
|| defined(__ARMEB__) \
|
||||||
|
|| defined(__THUMBEB__)
|
||||||
|
#define MY_CPU_32BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(_M_ARM)
|
#if defined(_WIN32) && defined(_M_ARM)
|
||||||
@@ -48,30 +56,49 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
|
|||||||
#define MY_CPU_LE_UNALIGN
|
#define MY_CPU_LE_UNALIGN
|
||||||
#endif
|
#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__)
|
#if defined(MY_CPU_X86_OR_AMD64) \
|
||||||
#define MY_CPU_LE
|
|| 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
|
#endif
|
||||||
|
|
||||||
#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
|
#if defined(__BIG_ENDIAN__) \
|
||||||
#define MY_CPU_BE
|
|| defined(__ARMEB__) \
|
||||||
|
|| defined(__THUMBEB__) \
|
||||||
|
|| defined(__AARCH64EB__) \
|
||||||
|
|| defined(__MIPSEB__) \
|
||||||
|
|| defined(__MIPSEB) \
|
||||||
|
|| defined(_MIPSEB) \
|
||||||
|
|| defined(__m68k__)
|
||||||
|
#define MY_CPU_BE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||||
Stop_Compiling_Bad_Endian
|
Stop_Compiling_Bad_Endian
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef MY_CPU_LE_UNALIGN
|
#ifdef MY_CPU_LE_UNALIGN
|
||||||
|
|
||||||
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
|
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
|
||||||
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
|
||||||
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
|
||||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
#define SetUi16(p, v) *(UInt16 *)(p) = (v);
|
||||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
#define SetUi32(p, v) *(UInt32 *)(p) = (v);
|
||||||
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
#define SetUi64(p, v) *(UInt64 *)(p) = (v);
|
||||||
|
|
||||||
#else
|
#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) ( \
|
#define GetUi32(p) ( \
|
||||||
((const Byte *)(p))[0] | \
|
((const Byte *)(p))[0] | \
|
||||||
@@ -81,23 +108,24 @@ Stop_Compiling_Bad_Endian
|
|||||||
|
|
||||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||||
|
|
||||||
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||||
((Byte *)(p))[0] = (Byte)_x_; \
|
_ppp_[0] = (Byte)_vvv_; \
|
||||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
_ppp_[1] = (Byte)(_vvv_ >> 8); }
|
||||||
|
|
||||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
|
||||||
((Byte *)(p))[0] = (Byte)_x_; \
|
_ppp_[0] = (Byte)_vvv_; \
|
||||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
_ppp_[1] = (Byte)(_vvv_ >> 8); \
|
||||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
_ppp_[2] = (Byte)(_vvv_ >> 16); \
|
||||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
_ppp_[3] = (Byte)(_vvv_ >> 24); }
|
||||||
|
|
||||||
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
|
||||||
SetUi32(p, (UInt32)_x64_); \
|
SetUi32(_ppp2_ , (UInt32)_vvv2_); \
|
||||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
|
||||||
|
|
||||||
#endif
|
#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>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@@ -106,6 +134,8 @@ Stop_Compiling_Bad_Endian
|
|||||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||||
|
|
||||||
|
#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define GetBe32(p) ( \
|
#define GetBe32(p) ( \
|
||||||
@@ -116,9 +146,19 @@ Stop_Compiling_Bad_Endian
|
|||||||
|
|
||||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
#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
|
#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
|
#ifdef MY_CPU_X86_OR_AMD64
|
||||||
@@ -140,12 +180,14 @@ enum
|
|||||||
CPU_FIRM_VIA
|
CPU_FIRM_VIA
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
|
||||||
|
|
||||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||||
|
|
||||||
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
|
#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
|
||||||
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
|
#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
|
||||||
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
|
#define x86cpuid_GetStepping(ver) (ver & 0xF)
|
||||||
|
|
||||||
Bool CPU_Is_InOrder();
|
Bool CPU_Is_InOrder();
|
||||||
Bool CPU_Is_Aes_Supported();
|
Bool CPU_Is_Aes_Supported();
|
||||||
|
|||||||
463
C/LzFind.c
463
C/LzFind.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.c -- Match finder for LZ algorithms
|
/* LzFind.c -- Match finder for LZ algorithms
|
||||||
2009-04-22 : Igor Pavlov : Public domain */
|
2015-05-15 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||||
#define kMaxHistorySize ((UInt32)3 << 30)
|
#define kMaxHistorySize ((UInt32)7 << 29)
|
||||||
|
|
||||||
#define kStartMaxLen 3
|
#define kStartMaxLen 3
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
|||||||
if (!p->directInput)
|
if (!p->directInput)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->bufferBase);
|
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;
|
p->blockSize = blockSize;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
if (!p->bufferBase || p->blockSize != blockSize)
|
||||||
{
|
{
|
||||||
LzInWindow_Free(p, alloc);
|
LzInWindow_Free(p, alloc);
|
||||||
p->blockSize = blockSize;
|
p->blockSize = blockSize;
|
||||||
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)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_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; }
|
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||||
|
|
||||||
@@ -60,6 +59,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
|||||||
{
|
{
|
||||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (p->directInput)
|
if (p->directInput)
|
||||||
{
|
{
|
||||||
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
||||||
@@ -71,12 +71,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
|||||||
p->streamEndWasReached = 1;
|
p->streamEndWasReached = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||||
size_t size = (p->bufferBase + p->blockSize - dest);
|
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p->result = p->stream->Read(p->stream, dest, &size);
|
p->result = p->stream->Read(p->stream, dest, &size);
|
||||||
if (p->result != SZ_OK)
|
if (p->result != SZ_OK)
|
||||||
return;
|
return;
|
||||||
@@ -135,15 +137,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
|||||||
void MatchFinder_Construct(CMatchFinder *p)
|
void MatchFinder_Construct(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
p->bufferBase = 0;
|
p->bufferBase = NULL;
|
||||||
p->directInput = 0;
|
p->directInput = 0;
|
||||||
p->hash = 0;
|
p->hash = NULL;
|
||||||
MatchFinder_SetDefaultSettings(p);
|
MatchFinder_SetDefaultSettings(p);
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
UInt32 r = i;
|
UInt32 r = i;
|
||||||
int j;
|
unsigned j;
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||||
p->crc[i] = r;
|
p->crc[i] = r;
|
||||||
@@ -153,7 +155,7 @@ void MatchFinder_Construct(CMatchFinder *p)
|
|||||||
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->hash);
|
alloc->Free(alloc, p->hash);
|
||||||
p->hash = 0;
|
p->hash = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||||
@@ -162,11 +164,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
|||||||
LzInWindow_Free(p, 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);
|
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||||
if (sizeInBytes / sizeof(CLzRef) != num)
|
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||||
return 0;
|
return NULL;
|
||||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,19 +177,24 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||||||
ISzAlloc *alloc)
|
ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt32 sizeReserv;
|
UInt32 sizeReserv;
|
||||||
|
|
||||||
if (historySize > kMaxHistorySize)
|
if (historySize > kMaxHistorySize)
|
||||||
{
|
{
|
||||||
MatchFinder_Free(p, alloc);
|
MatchFinder_Free(p, alloc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sizeReserv = historySize >> 1;
|
sizeReserv = historySize >> 1;
|
||||||
if (historySize > ((UInt32)2 << 30))
|
if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3;
|
||||||
sizeReserv = historySize >> 2;
|
else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2;
|
||||||
|
|
||||||
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||||
|
|
||||||
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||||
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||||
|
|
||||||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||||
|
|
||||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||||
{
|
{
|
||||||
UInt32 newCyclicBufferSize = historySize + 1;
|
UInt32 newCyclicBufferSize = historySize + 1;
|
||||||
@@ -212,6 +219,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||||||
hs = (1 << 24) - 1;
|
hs = (1 << 24) - 1;
|
||||||
else
|
else
|
||||||
hs >>= 1;
|
hs >>= 1;
|
||||||
|
/* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->hashMask = hs;
|
p->hashMask = hs;
|
||||||
@@ -223,24 +231,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
size_t newSize;
|
||||||
UInt32 newSize;
|
size_t numSons;
|
||||||
p->historySize = historySize;
|
p->historySize = historySize;
|
||||||
p->hashSizeSum = hs;
|
p->hashSizeSum = hs;
|
||||||
p->cyclicBufferSize = newCyclicBufferSize;
|
p->cyclicBufferSize = newCyclicBufferSize;
|
||||||
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
|
||||||
newSize = p->hashSizeSum + p->numSons;
|
numSons = newCyclicBufferSize;
|
||||||
if (p->hash != 0 && prevSize == newSize)
|
if (p->btMode)
|
||||||
|
numSons <<= 1;
|
||||||
|
newSize = hs + numSons;
|
||||||
|
|
||||||
|
if (p->hash && p->numRefs == newSize)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||||
|
p->numRefs = newSize;
|
||||||
p->hash = AllocRefs(newSize, alloc);
|
p->hash = AllocRefs(newSize, alloc);
|
||||||
if (p->hash != 0)
|
|
||||||
|
if (p->hash)
|
||||||
{
|
{
|
||||||
p->son = p->hash + p->hashSizeSum;
|
p->son = p->hash + p->hashSizeSum;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchFinder_Free(p, alloc);
|
MatchFinder_Free(p, alloc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -249,9 +265,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
{
|
{
|
||||||
UInt32 limit = kMaxValForNormalize - p->pos;
|
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||||
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||||
|
|
||||||
if (limit2 < limit)
|
if (limit2 < limit)
|
||||||
limit = limit2;
|
limit = limit2;
|
||||||
limit2 = p->streamPos - p->pos;
|
limit2 = p->streamPos - p->pos;
|
||||||
|
|
||||||
if (limit2 <= p->keepSizeAfter)
|
if (limit2 <= p->keepSizeAfter)
|
||||||
{
|
{
|
||||||
if (limit2 > 0)
|
if (limit2 > 0)
|
||||||
@@ -259,8 +277,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
limit2 -= p->keepSizeAfter;
|
limit2 -= p->keepSizeAfter;
|
||||||
|
|
||||||
if (limit2 < limit)
|
if (limit2 < limit)
|
||||||
limit = limit2;
|
limit = limit2;
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 lenLimit = p->streamPos - p->pos;
|
UInt32 lenLimit = p->streamPos - p->pos;
|
||||||
if (lenLimit > p->matchMaxLen)
|
if (lenLimit > p->matchMaxLen)
|
||||||
@@ -273,8 +293,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p)
|
|||||||
void MatchFinder_Init(CMatchFinder *p)
|
void MatchFinder_Init(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = 0; i < p->hashSizeSum; i++)
|
UInt32 *hash = p->hash;
|
||||||
p->hash[i] = kEmptyHashValue;
|
UInt32 num = p->hashSizeSum;
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
hash[i] = kEmptyHashValue;
|
||||||
|
|
||||||
p->cyclicBufferPos = 0;
|
p->cyclicBufferPos = 0;
|
||||||
p->buffer = p->bufferBase;
|
p->buffer = p->bufferBase;
|
||||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||||
@@ -289,9 +312,9 @@ static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
|||||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
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++)
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
UInt32 value = items[i];
|
UInt32 value = items[i];
|
||||||
@@ -306,7 +329,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
|||||||
static void MatchFinder_Normalize(CMatchFinder *p)
|
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||||
{
|
{
|
||||||
UInt32 subValue = MatchFinder_GetSubValue(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);
|
MatchFinder_ReduceOffsets(p, subValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +490,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
|
|||||||
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||||
|
|
||||||
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
#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; }} \
|
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||||
cur = p->buffer;
|
cur = p->buffer;
|
||||||
|
|
||||||
@@ -483,13 +506,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
|||||||
#define SKIP_FOOTER \
|
#define SKIP_FOOTER \
|
||||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
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)
|
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 offset;
|
UInt32 offset;
|
||||||
GET_MATCHES_HEADER(2)
|
GET_MATCHES_HEADER(2)
|
||||||
HASH2_CALC;
|
HASH2_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
GET_MATCHES_FOOTER(offset, 1)
|
GET_MATCHES_FOOTER(offset, 1)
|
||||||
}
|
}
|
||||||
@@ -499,35 +529,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
UInt32 offset;
|
UInt32 offset;
|
||||||
GET_MATCHES_HEADER(3)
|
GET_MATCHES_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
GET_MATCHES_FOOTER(offset, 2)
|
GET_MATCHES_FOOTER(offset, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
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)
|
GET_MATCHES_HEADER(3)
|
||||||
|
|
||||||
HASH3_CALC;
|
HASH3_CALC;
|
||||||
|
|
||||||
delta2 = p->pos - p->hash[hash2Value];
|
hash = p->hash;
|
||||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
pos = p->pos;
|
||||||
|
|
||||||
p->hash[hash2Value] =
|
d2 = pos - hash[h2];
|
||||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
|
||||||
|
|
||||||
|
curMatch = hash[kFix3HashSize + hv];
|
||||||
|
|
||||||
|
hash[h2] = pos;
|
||||||
|
hash[kFix3HashSize + hv] = pos;
|
||||||
|
|
||||||
maxLen = 2;
|
maxLen = 2;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
|
||||||
|
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||||
{
|
{
|
||||||
for (; maxLen != lenLimit; maxLen++)
|
UPDATE_maxLen
|
||||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
|
||||||
break;
|
|
||||||
distances[0] = maxLen;
|
distances[0] = maxLen;
|
||||||
distances[1] = delta2 - 1;
|
distances[1] = d2 - 1;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
@@ -535,44 +568,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_MATCHES_FOOTER(offset, maxLen)
|
GET_MATCHES_FOOTER(offset, maxLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
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)
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
|
|
||||||
delta2 = p->pos - p->hash[ hash2Value];
|
hash = p->hash;
|
||||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
pos = p->pos;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
|
||||||
|
|
||||||
p->hash[ hash2Value] =
|
d2 = pos - hash[ h2];
|
||||||
p->hash[kFix3HashSize + hash3Value] =
|
d3 = pos - hash[kFix3HashSize + h3];
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
|
||||||
|
|
||||||
maxLen = 1;
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
|
|
||||||
|
hash[ h2] = pos;
|
||||||
|
hash[kFix3HashSize + h3] = pos;
|
||||||
|
hash[kFix4HashSize + hv] = pos;
|
||||||
|
|
||||||
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
|
||||||
|
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||||
{
|
{
|
||||||
distances[0] = maxLen = 2;
|
distances[0] = maxLen = 2;
|
||||||
distances[1] = delta2 - 1;
|
distances[1] = d2 - 1;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
}
|
}
|
||||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
|
||||||
|
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
||||||
{
|
{
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
distances[offset + 1] = delta3 - 1;
|
distances[offset + 1] = d3 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
delta2 = delta3;
|
d2 = d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
for (; maxLen != lenLimit; maxLen++)
|
UPDATE_maxLen
|
||||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
|
||||||
break;
|
|
||||||
distances[offset - 2] = maxLen;
|
distances[offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
@@ -580,46 +620,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxLen < 3)
|
if (maxLen < 3)
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
|
|
||||||
GET_MATCHES_FOOTER(offset, maxLen)
|
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)
|
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)
|
GET_MATCHES_HEADER(4)
|
||||||
|
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
|
|
||||||
delta2 = p->pos - p->hash[ hash2Value];
|
hash = p->hash;
|
||||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
pos = p->pos;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
|
||||||
|
|
||||||
p->hash[ hash2Value] =
|
d2 = pos - hash[ h2];
|
||||||
p->hash[kFix3HashSize + hash3Value] =
|
d3 = pos - hash[kFix3HashSize + h3];
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
|
||||||
|
|
||||||
maxLen = 1;
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
|
|
||||||
|
hash[ h2] = pos;
|
||||||
|
hash[kFix3HashSize + h3] = pos;
|
||||||
|
hash[kFix4HashSize + hv] = pos;
|
||||||
|
|
||||||
|
maxLen = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
|
||||||
|
if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur)
|
||||||
{
|
{
|
||||||
distances[0] = maxLen = 2;
|
distances[0] = maxLen = 2;
|
||||||
distances[1] = delta2 - 1;
|
distances[1] = d2 - 1;
|
||||||
offset = 2;
|
offset = 2;
|
||||||
}
|
}
|
||||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
|
||||||
|
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)
|
||||||
{
|
{
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
distances[offset + 1] = delta3 - 1;
|
distances[offset + 1] = d3 - 1;
|
||||||
offset += 2;
|
offset += 2;
|
||||||
delta2 = delta3;
|
d2 = d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != 0)
|
if (offset != 0)
|
||||||
{
|
{
|
||||||
for (; maxLen != lenLimit; maxLen++)
|
UPDATE_maxLen
|
||||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
|
||||||
break;
|
|
||||||
distances[offset - 2] = maxLen;
|
distances[offset - 2] = maxLen;
|
||||||
if (maxLen == lenLimit)
|
if (maxLen == lenLimit)
|
||||||
{
|
{
|
||||||
@@ -627,20 +752,101 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
|||||||
MOVE_POS_RET;
|
MOVE_POS_RET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxLen < 3)
|
if (maxLen < 3)
|
||||||
maxLen = 3;
|
maxLen = 3;
|
||||||
|
|
||||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
distances + offset, maxLen) - (distances));
|
distances + offset, maxLen) - (distances));
|
||||||
MOVE_POS_RET
|
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 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 offset;
|
UInt32 offset;
|
||||||
GET_MATCHES_HEADER(3)
|
GET_MATCHES_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||||
distances, 2) - (distances));
|
distances, 2) - (distances));
|
||||||
MOVE_POS_RET
|
MOVE_POS_RET
|
||||||
@@ -652,8 +858,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
{
|
{
|
||||||
SKIP_HEADER(2)
|
SKIP_HEADER(2)
|
||||||
HASH2_CALC;
|
HASH2_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
@@ -665,8 +871,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
{
|
{
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
@@ -676,12 +882,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value;
|
UInt32 h2;
|
||||||
|
UInt32 *hash;
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH3_CALC;
|
HASH3_CALC;
|
||||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
hash = p->hash;
|
||||||
p->hash[hash2Value] =
|
curMatch = hash[kFix3HashSize + hv];
|
||||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
hash[h2] =
|
||||||
|
hash[kFix3HashSize + hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
while (--num != 0);
|
||||||
@@ -691,43 +899,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 h2, h3;
|
||||||
|
UInt32 *hash;
|
||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
hash = p->hash;
|
||||||
p->hash[ hash2Value] =
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
hash[ h2] =
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
hash[kFix3HashSize + h3] =
|
||||||
|
hash[kFix4HashSize + hv] = p->pos;
|
||||||
SKIP_FOOTER
|
SKIP_FOOTER
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
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)
|
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 h2, h3;
|
||||||
|
UInt32 *hash;
|
||||||
SKIP_HEADER(4)
|
SKIP_HEADER(4)
|
||||||
HASH4_CALC;
|
HASH4_CALC;
|
||||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
hash = p->hash;
|
||||||
p->hash[ hash2Value] =
|
curMatch = hash[kFix4HashSize + hv];
|
||||||
p->hash[kFix3HashSize + hash3Value] =
|
hash[ h2] =
|
||||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
hash[kFix3HashSize + h3] =
|
||||||
|
hash[kFix4HashSize + hv] = p->pos;
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS
|
MOVE_POS
|
||||||
}
|
}
|
||||||
while (--num != 0);
|
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)
|
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
SKIP_HEADER(3)
|
SKIP_HEADER(3)
|
||||||
HASH_ZIP_CALC;
|
HASH_ZIP_CALC;
|
||||||
curMatch = p->hash[hashValue];
|
curMatch = p->hash[hv];
|
||||||
p->hash[hashValue] = p->pos;
|
p->hash[hv] = p->pos;
|
||||||
p->son[p->cyclicBufferPos] = curMatch;
|
p->son[p->cyclicBufferPos] = curMatch;
|
||||||
MOVE_POS
|
MOVE_POS
|
||||||
}
|
}
|
||||||
@@ -737,14 +992,23 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
|||||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||||
{
|
{
|
||||||
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
|
||||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||||
if (!p->btMode)
|
if (!p->btMode)
|
||||||
|
{
|
||||||
|
/* if (p->numHashBytes <= 4) */
|
||||||
{
|
{
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
||||||
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
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)
|
else if (p->numHashBytes == 2)
|
||||||
{
|
{
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
||||||
@@ -755,9 +1019,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
|||||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||||
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||||
}
|
}
|
||||||
else
|
else /* if (p->numHashBytes == 4) */
|
||||||
{
|
{
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||||
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
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;
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
18
C/LzFind.h
18
C/LzFind.h
@@ -1,5 +1,5 @@
|
|||||||
/* LzFind.h -- Match finder for LZ algorithms
|
/* LzFind.h -- Match finder for LZ algorithms
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2015-05-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZ_FIND_H
|
#ifndef __LZ_FIND_H
|
||||||
#define __LZ_FIND_H
|
#define __LZ_FIND_H
|
||||||
@@ -21,6 +21,11 @@ typedef struct _CMatchFinder
|
|||||||
UInt32 cyclicBufferPos;
|
UInt32 cyclicBufferPos;
|
||||||
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||||
|
|
||||||
|
Byte streamEndWasReached;
|
||||||
|
Byte btMode;
|
||||||
|
Byte bigHash;
|
||||||
|
Byte directInput;
|
||||||
|
|
||||||
UInt32 matchMaxLen;
|
UInt32 matchMaxLen;
|
||||||
CLzRef *hash;
|
CLzRef *hash;
|
||||||
CLzRef *son;
|
CLzRef *son;
|
||||||
@@ -29,27 +34,22 @@ typedef struct _CMatchFinder
|
|||||||
|
|
||||||
Byte *bufferBase;
|
Byte *bufferBase;
|
||||||
ISeqInStream *stream;
|
ISeqInStream *stream;
|
||||||
int streamEndWasReached;
|
|
||||||
|
|
||||||
UInt32 blockSize;
|
UInt32 blockSize;
|
||||||
UInt32 keepSizeBefore;
|
UInt32 keepSizeBefore;
|
||||||
UInt32 keepSizeAfter;
|
UInt32 keepSizeAfter;
|
||||||
|
|
||||||
UInt32 numHashBytes;
|
UInt32 numHashBytes;
|
||||||
int directInput;
|
|
||||||
size_t directInputRem;
|
size_t directInputRem;
|
||||||
int btMode;
|
|
||||||
int bigHash;
|
|
||||||
UInt32 historySize;
|
UInt32 historySize;
|
||||||
UInt32 fixedHashSize;
|
UInt32 fixedHashSize;
|
||||||
UInt32 hashSizeSum;
|
UInt32 hashSizeSum;
|
||||||
UInt32 numSons;
|
|
||||||
SRes result;
|
SRes result;
|
||||||
UInt32 crc[256];
|
UInt32 crc[256];
|
||||||
|
size_t numRefs;
|
||||||
} CMatchFinder;
|
} CMatchFinder;
|
||||||
|
|
||||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
#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_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||||
ISzAlloc *alloc);
|
ISzAlloc *alloc);
|
||||||
void MatchFinder_Free(CMatchFinder *p, 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);
|
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||||
|
|
||||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||||
@@ -82,7 +82,6 @@ Conditions:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void (*Mf_Init_Func)(void *object);
|
typedef void (*Mf_Init_Func)(void *object);
|
||||||
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
|
||||||
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||||
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||||
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||||
@@ -91,7 +90,6 @@ typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
|||||||
typedef struct _IMatchFinder
|
typedef struct _IMatchFinder
|
||||||
{
|
{
|
||||||
Mf_Init_Func Init;
|
Mf_Init_Func Init;
|
||||||
Mf_GetIndexByte_Func GetIndexByte;
|
|
||||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||||
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||||
Mf_GetMatches_Func GetMatches;
|
Mf_GetMatches_Func GetMatches;
|
||||||
|
|||||||
154
C/LzFindMt.c
154
C/LzFindMt.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||||
2014-12-29 : Igor Pavlov : Public domain */
|
2015-05-03 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "LzFindMt.h"
|
#include "LzFindMt.h"
|
||||||
|
|
||||||
void MtSync_Construct(CMtSync *p)
|
static void MtSync_Construct(CMtSync *p)
|
||||||
{
|
{
|
||||||
p->wasCreated = False;
|
p->wasCreated = False;
|
||||||
p->csWasInitialized = False;
|
p->csWasInitialized = False;
|
||||||
@@ -20,7 +20,7 @@ void MtSync_Construct(CMtSync *p)
|
|||||||
Semaphore_Construct(&p->filledSemaphore);
|
Semaphore_Construct(&p->filledSemaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MtSync_GetNextBlock(CMtSync *p)
|
static void MtSync_GetNextBlock(CMtSync *p)
|
||||||
{
|
{
|
||||||
if (p->needStart)
|
if (p->needStart)
|
||||||
{
|
{
|
||||||
@@ -48,7 +48,7 @@ void MtSync_GetNextBlock(CMtSync *p)
|
|||||||
|
|
||||||
/* MtSync_StopWriting must be called if Writing was started */
|
/* MtSync_StopWriting must be called if Writing was started */
|
||||||
|
|
||||||
void MtSync_StopWriting(CMtSync *p)
|
static void MtSync_StopWriting(CMtSync *p)
|
||||||
{
|
{
|
||||||
UInt32 myNumBlocks = p->numProcessedBlocks;
|
UInt32 myNumBlocks = p->numProcessedBlocks;
|
||||||
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
||||||
@@ -71,7 +71,7 @@ void MtSync_StopWriting(CMtSync *p)
|
|||||||
p->needStart = True;
|
p->needStart = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MtSync_Destruct(CMtSync *p)
|
static void MtSync_Destruct(CMtSync *p)
|
||||||
{
|
{
|
||||||
if (Thread_WasCreated(&p->thread))
|
if (Thread_WasCreated(&p->thread))
|
||||||
{
|
{
|
||||||
@@ -134,20 +134,20 @@ void MtSync_Init(CMtSync *p) { p->needStart = True; }
|
|||||||
#define kMtMaxValForNormalize 0xFFFFFFFF
|
#define kMtMaxValForNormalize 0xFFFFFFFF
|
||||||
|
|
||||||
#define DEF_GetHeads2(name, v, action) \
|
#define DEF_GetHeads2(name, v, action) \
|
||||||
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
||||||
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
||||||
{ action; for (; numHeads != 0; numHeads--) { \
|
{ action; for (; numHeads != 0; numHeads--) { \
|
||||||
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
||||||
|
|
||||||
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
|
#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(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(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(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) */
|
/* 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;
|
CMtSync *p = &mt->hashSync;
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -192,7 +192,7 @@ void HashThreadFunc(CMatchFinderMt *mt)
|
|||||||
{
|
{
|
||||||
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
||||||
MatchFinder_ReduceOffsets(mf, subValue);
|
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;
|
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);
|
MtSync_GetNextBlock(&p->hashSync);
|
||||||
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
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
|
#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 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||||
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
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
|
#endif
|
||||||
|
|
||||||
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
static void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
UInt32 numProcessed = 0;
|
UInt32 numProcessed = 0;
|
||||||
UInt32 curPos = 2;
|
UInt32 curPos = 2;
|
||||||
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
||||||
|
|
||||||
distances[1] = p->hashNumAvail;
|
distances[1] = p->hashNumAvail;
|
||||||
|
|
||||||
while (curPos < limit)
|
while (curPos < limit)
|
||||||
{
|
{
|
||||||
if (p->hashBufPos == p->hashBufPosLimit)
|
if (p->hashBufPos == p->hashBufPosLimit)
|
||||||
@@ -324,9 +326,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
distances[1] = numProcessed + p->hashNumAvail;
|
distances[1] = numProcessed + p->hashNumAvail;
|
||||||
if (p->hashNumAvail >= p->numHashBytes)
|
if (p->hashNumAvail >= p->numHashBytes)
|
||||||
continue;
|
continue;
|
||||||
|
distances[0] = curPos + p->hashNumAvail;
|
||||||
|
distances += curPos;
|
||||||
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
||||||
distances[curPos++] = 0;
|
*distances++ = 0;
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
||||||
@@ -343,6 +347,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
if (size2 < size)
|
if (size2 < size)
|
||||||
size = size2;
|
size = size2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MFMT_GM_INLINE
|
#ifndef MFMT_GM_INLINE
|
||||||
while (curPos < limit && size-- != 0)
|
while (curPos < limit && size-- != 0)
|
||||||
{
|
{
|
||||||
@@ -360,7 +365,7 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
{
|
{
|
||||||
UInt32 posRes;
|
UInt32 posRes;
|
||||||
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
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;
|
p->hashBufPos += posRes - pos;
|
||||||
cyclicBufferPos += posRes - pos;
|
cyclicBufferPos += posRes - pos;
|
||||||
p->buffer += posRes - pos;
|
p->buffer += posRes - pos;
|
||||||
@@ -376,10 +381,11 @@ void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
p->cyclicBufferPos = cyclicBufferPos;
|
p->cyclicBufferPos = cyclicBufferPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
distances[0] = curPos;
|
distances[0] = curPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
||||||
{
|
{
|
||||||
CMtSync *sync = &p->hashSync;
|
CMtSync *sync = &p->hashSync;
|
||||||
if (!sync->needStart)
|
if (!sync->needStart)
|
||||||
@@ -393,7 +399,7 @@ void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
|||||||
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
||||||
{
|
{
|
||||||
UInt32 subValue = p->pos - p->cyclicBufferSize;
|
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;
|
p->pos -= subValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,15 +438,15 @@ void BtThreadFunc(CMatchFinderMt *mt)
|
|||||||
|
|
||||||
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
p->hashBuf = 0;
|
p->hashBuf = NULL;
|
||||||
MtSync_Construct(&p->hashSync);
|
MtSync_Construct(&p->hashSync);
|
||||||
MtSync_Construct(&p->btSync);
|
MtSync_Construct(&p->btSync);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
static void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->hashBuf);
|
alloc->Free(alloc, p->hashBuf);
|
||||||
p->hashBuf = 0;
|
p->hashBuf = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||||
@@ -457,8 +463,10 @@ 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)
|
static THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
|
||||||
{
|
{
|
||||||
Byte allocaDummy[0x180];
|
Byte allocaDummy[0x180];
|
||||||
allocaDummy[0] = 0;
|
unsigned i = 0;
|
||||||
allocaDummy[1] = allocaDummy[0];
|
for (i = 0; i < 16; i++)
|
||||||
|
allocaDummy[i] = (Byte)0;
|
||||||
|
if (allocaDummy[0] == 0)
|
||||||
BtThreadFunc((CMatchFinderMt *)p);
|
BtThreadFunc((CMatchFinderMt *)p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -470,10 +478,10 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
|||||||
p->historySize = historySize;
|
p->historySize = historySize;
|
||||||
if (kMtBtBlockSize <= matchMaxLen * 4)
|
if (kMtBtBlockSize <= matchMaxLen * 4)
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
if (p->hashBuf == 0)
|
if (!p->hashBuf)
|
||||||
{
|
{
|
||||||
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
||||||
if (p->hashBuf == 0)
|
if (!p->hashBuf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
p->btBuf = p->hashBuf + kHashBufferSize;
|
p->btBuf = p->hashBuf + kHashBufferSize;
|
||||||
}
|
}
|
||||||
@@ -519,13 +527,13 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
|||||||
/* p->MatchFinder->ReleaseStream(); */
|
/* 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);
|
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
|
||||||
p->lzPos = p->historySize + 1;
|
p->lzPos = p->historySize + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
static void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
UInt32 blockIndex;
|
UInt32 blockIndex;
|
||||||
MtSync_GetNextBlock(&p->btSync);
|
MtSync_GetNextBlock(&p->btSync);
|
||||||
@@ -537,34 +545,29 @@ void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
|||||||
MatchFinderMt_Normalize(p);
|
MatchFinderMt_Normalize(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
static const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
||||||
{
|
{
|
||||||
return p->pointerToCurPos;
|
return p->pointerToCurPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
#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;
|
GET_NEXT_BLOCK_IF_REQUIRED;
|
||||||
return p->btNumAvailBytes;
|
return p->btNumAvailBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
static UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||||
{
|
{
|
||||||
return p->pointerToCurPos[index];
|
UInt32 h2, curMatch2;
|
||||||
}
|
|
||||||
|
|
||||||
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|
||||||
{
|
|
||||||
UInt32 hash2Value, curMatch2;
|
|
||||||
UInt32 *hash = p->hash;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH2_CALC
|
MT_HASH2_CALC
|
||||||
|
|
||||||
curMatch2 = hash[hash2Value];
|
curMatch2 = hash[h2];
|
||||||
hash[hash2Value] = lzPos;
|
hash[h2] = lzPos;
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos)
|
if (curMatch2 >= matchMinPos)
|
||||||
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
@@ -572,23 +575,23 @@ UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
*distances++ = 2;
|
*distances++ = 2;
|
||||||
*distances++ = lzPos - curMatch2 - 1;
|
*distances++ = lzPos - curMatch2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distances;
|
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;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ hash2Value];
|
curMatch2 = hash[ h2];
|
||||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
curMatch3 = hash[kFix3HashSize + h3];
|
||||||
|
|
||||||
hash[ hash2Value] =
|
hash[ h2] = lzPos;
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] = lzPos;
|
||||||
lzPos;
|
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
@@ -601,31 +604,32 @@ UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
distances[0] = 2;
|
distances[0] = 2;
|
||||||
distances += 2;
|
distances += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
*distances++ = 3;
|
*distances++ = 3;
|
||||||
*distances++ = lzPos - curMatch3 - 1;
|
*distances++ = lzPos - curMatch3 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distances;
|
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;
|
UInt32 *hash = p->hash;
|
||||||
const Byte *cur = p->pointerToCurPos;
|
const Byte *cur = p->pointerToCurPos;
|
||||||
UInt32 lzPos = p->lzPos;
|
UInt32 lzPos = p->lzPos;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
|
|
||||||
curMatch2 = hash[ hash2Value];
|
curMatch2 = hash[ h2];
|
||||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
curMatch3 = hash[kFix3HashSize + h3];
|
||||||
curMatch4 = hash[kFix4HashSize + hash4Value];
|
curMatch4 = hash[kFix4HashSize + h4];
|
||||||
|
|
||||||
hash[ hash2Value] =
|
hash[ h2] = lzPos;
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] = lzPos;
|
||||||
hash[kFix4HashSize + hash4Value] =
|
hash[kFix4HashSize + h4] = lzPos;
|
||||||
lzPos;
|
|
||||||
|
|
||||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
@@ -638,6 +642,7 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
distances[0] = 2;
|
distances[0] = 2;
|
||||||
distances += 2;
|
distances += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||||
{
|
{
|
||||||
distances[1] = lzPos - curMatch3 - 1;
|
distances[1] = lzPos - curMatch3 - 1;
|
||||||
@@ -659,13 +664,14 @@ UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
|||||||
*distances++ = 4;
|
*distances++ = 4;
|
||||||
*distances++ = lzPos - curMatch4 - 1;
|
*distances++ = lzPos - curMatch4 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return distances;
|
return distances;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
#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;
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
UInt32 len = *btBuf++;
|
UInt32 len = *btBuf++;
|
||||||
@@ -683,7 +689,7 @@ UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
static UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||||
{
|
{
|
||||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||||
UInt32 len = *btBuf++;
|
UInt32 len = *btBuf++;
|
||||||
@@ -691,6 +697,7 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
|
/* change for bt5 ! */
|
||||||
if (p->btNumAvailBytes-- >= 4)
|
if (p->btNumAvailBytes-- >= 4)
|
||||||
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
||||||
}
|
}
|
||||||
@@ -716,41 +723,41 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||||||
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
|
#define SKIP_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);
|
#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_HEADER2_MT { p->btNumAvailBytes--;
|
||||||
SKIP_FOOTER_MT
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
static void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER_MT(2)
|
SKIP_HEADER_MT(2)
|
||||||
UInt32 hash2Value;
|
UInt32 h2;
|
||||||
MT_HASH2_CALC
|
MT_HASH2_CALC
|
||||||
hash[hash2Value] = p->lzPos;
|
hash[h2] = p->lzPos;
|
||||||
SKIP_FOOTER_MT
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
static void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER_MT(3)
|
SKIP_HEADER_MT(3)
|
||||||
UInt32 hash2Value, hash3Value;
|
UInt32 h2, h3;
|
||||||
MT_HASH3_CALC
|
MT_HASH3_CALC
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] =
|
||||||
hash[ hash2Value] =
|
hash[ h2] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER_MT
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
static void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
||||||
{
|
{
|
||||||
SKIP_HEADER_MT(4)
|
SKIP_HEADER_MT(4)
|
||||||
UInt32 hash2Value, hash3Value, hash4Value;
|
UInt32 h2, h3, h4;
|
||||||
MT_HASH4_CALC
|
MT_HASH4_CALC
|
||||||
hash[kFix4HashSize + hash4Value] =
|
hash[kFix4HashSize + h4] =
|
||||||
hash[kFix3HashSize + hash3Value] =
|
hash[kFix3HashSize + h3] =
|
||||||
hash[ hash2Value] =
|
hash[ h2] =
|
||||||
p->lzPos;
|
p->lzPos;
|
||||||
SKIP_FOOTER_MT
|
SKIP_FOOTER_MT
|
||||||
}
|
}
|
||||||
@@ -759,11 +766,11 @@ void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
|||||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
||||||
{
|
{
|
||||||
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
||||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
|
|
||||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
||||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
||||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
||||||
switch(p->MatchFinder->numHashBytes)
|
|
||||||
|
switch (p->MatchFinder->numHashBytes)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p->GetHeadsFunc = GetHeads2;
|
p->GetHeadsFunc = GetHeads2;
|
||||||
@@ -779,7 +786,6 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
|||||||
default:
|
default:
|
||||||
/* case 4: */
|
/* case 4: */
|
||||||
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
||||||
/* p->GetHeadsFunc = GetHeads4; */
|
|
||||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
||||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
/* 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
|
#ifndef __LZ_FIND_MT_H
|
||||||
#define __LZ_FIND_MT_H
|
#define __LZ_FIND_MT_H
|
||||||
@@ -75,7 +75,7 @@ typedef struct _CMatchFinderMt
|
|||||||
UInt32 matchMaxLen;
|
UInt32 matchMaxLen;
|
||||||
UInt32 numHashBytes;
|
UInt32 numHashBytes;
|
||||||
UInt32 pos;
|
UInt32 pos;
|
||||||
Byte *buffer;
|
const Byte *buffer;
|
||||||
UInt32 cyclicBufferPos;
|
UInt32 cyclicBufferPos;
|
||||||
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
||||||
UInt32 cutValue;
|
UInt32 cutValue;
|
||||||
|
|||||||
43
C/LzHash.h
43
C/LzHash.h
@@ -1,5 +1,5 @@
|
|||||||
/* LzHash.h -- HASH functions for LZ algorithms
|
/* 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
|
#ifndef __LZ_HASH_H
|
||||||
#define __LZ_HASH_H
|
#define __LZ_HASH_H
|
||||||
@@ -12,43 +12,46 @@
|
|||||||
#define kFix4HashSize (kHash2Size + kHash3Size)
|
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||||
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
#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 { \
|
#define HASH3_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
hv = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||||
|
|
||||||
#define HASH4_CALC { \
|
#define HASH4_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
temp ^= ((UInt32)cur[2] << 8); \
|
||||||
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
h3 = temp & (kHash3Size - 1); \
|
||||||
|
hv = (temp ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||||
|
|
||||||
#define HASH5_CALC { \
|
#define HASH5_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
temp ^= ((UInt32)cur[2] << 8); \
|
||||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
h3 = temp & (kHash3Size - 1); \
|
||||||
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
temp ^= (p->crc[cur[3]] << 5); \
|
||||||
hash4Value &= (kHash4Size - 1); }
|
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 hv = ((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[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
#define MT_HASH2_CALC \
|
#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 { \
|
#define MT_HASH3_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||||
|
|
||||||
#define MT_HASH4_CALC { \
|
#define MT_HASH4_CALC { \
|
||||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||||
hash2Value = temp & (kHash2Size - 1); \
|
h2 = temp & (kHash2Size - 1); \
|
||||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
temp ^= ((UInt32)cur[2] << 8); \
|
||||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
h3 = temp & (kHash3Size - 1); \
|
||||||
|
h4 = (temp ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
40
C/Lzma2Dec.c
40
C/Lzma2Dec.c
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Dec.c -- LZMA2 Decoder
|
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||||
2010-12-15 : Igor Pavlov : Public domain */
|
2014-10-29 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
/* #define SHOW_DEBUG_INFO */
|
/* #define SHOW_DEBUG_INFO */
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ void Lzma2Dec_Init(CLzma2Dec *p)
|
|||||||
|
|
||||||
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
||||||
{
|
{
|
||||||
switch(p->state)
|
switch (p->state)
|
||||||
{
|
{
|
||||||
case LZMA2_STATE_CONTROL:
|
case LZMA2_STATE_CONTROL:
|
||||||
p->control = b;
|
p->control = b;
|
||||||
@@ -140,7 +140,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
|||||||
|
|
||||||
case LZMA2_STATE_PROP:
|
case LZMA2_STATE_PROP:
|
||||||
{
|
{
|
||||||
int lc, lp;
|
unsigned lc, lp;
|
||||||
if (b >= (9 * 5 * 5))
|
if (b >= (9 * 5 * 5))
|
||||||
return LZMA2_STATE_ERROR;
|
return LZMA2_STATE_ERROR;
|
||||||
lc = b % 9;
|
lc = b % 9;
|
||||||
@@ -179,13 +179,16 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
while (p->state != LZMA2_STATE_FINISHED)
|
while (p->state != LZMA2_STATE_FINISHED)
|
||||||
{
|
{
|
||||||
SizeT dicPos = p->decoder.dicPos;
|
SizeT dicPos = p->decoder.dicPos;
|
||||||
|
|
||||||
if (p->state == LZMA2_STATE_ERROR)
|
if (p->state == LZMA2_STATE_ERROR)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||||
{
|
{
|
||||||
*status = LZMA_STATUS_NOT_FINISHED;
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
||||||
{
|
{
|
||||||
if (*srcLen == inSize)
|
if (*srcLen == inSize)
|
||||||
@@ -195,8 +198,15 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
}
|
}
|
||||||
(*srcLen)++;
|
(*srcLen)++;
|
||||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||||
|
|
||||||
|
if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
|
||||||
|
{
|
||||||
|
p->state = LZMA2_STATE_ERROR;
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SizeT destSizeCur = dicLimit - dicPos;
|
SizeT destSizeCur = dicLimit - dicPos;
|
||||||
SizeT srcSizeCur = inSize - *srcLen;
|
SizeT srcSizeCur = inSize - *srcLen;
|
||||||
@@ -222,7 +232,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
if (initDic)
|
if (initDic)
|
||||||
p->needInitProp = p->needInitState = True;
|
p->needInitProp = p->needInitState = True;
|
||||||
else if (p->needInitDic)
|
else if (p->needInitDic)
|
||||||
|
{
|
||||||
|
p->state = LZMA2_STATE_ERROR;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
p->needInitDic = False;
|
p->needInitDic = False;
|
||||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||||
}
|
}
|
||||||
@@ -231,7 +244,10 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
srcSizeCur = destSizeCur;
|
srcSizeCur = destSizeCur;
|
||||||
|
|
||||||
if (srcSizeCur == 0)
|
if (srcSizeCur == 0)
|
||||||
|
{
|
||||||
|
p->state = LZMA2_STATE_ERROR;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||||
|
|
||||||
@@ -247,17 +263,21 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
|
|
||||||
if (p->state == LZMA2_STATE_DATA)
|
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 initDic = (mode == 3);
|
||||||
Bool initState = (mode > 0);
|
Bool initState = (mode != 0);
|
||||||
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||||
|
{
|
||||||
|
p->state = LZMA2_STATE_ERROR;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||||
p->needInitDic = False;
|
p->needInitDic = False;
|
||||||
p->needInitState = False;
|
p->needInitState = False;
|
||||||
p->state = LZMA2_STATE_DATA_CONT;
|
p->state = LZMA2_STATE_DATA_CONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcSizeCur > p->packSize)
|
if (srcSizeCur > p->packSize)
|
||||||
srcSizeCur = (SizeT)p->packSize;
|
srcSizeCur = (SizeT)p->packSize;
|
||||||
|
|
||||||
@@ -276,16 +296,22 @@ SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
|||||||
|
|
||||||
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
||||||
{
|
{
|
||||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||||
p->unpackSize != 0 || p->packSize != 0)
|
|| p->unpackSize != 0
|
||||||
|
|| p->packSize != 0)
|
||||||
|
{
|
||||||
|
p->state = LZMA2_STATE_ERROR;
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
}
|
||||||
p->state = LZMA2_STATE_CONTROL;
|
p->state = LZMA2_STATE_CONTROL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||||
*status = LZMA_STATUS_NOT_FINISHED;
|
*status = LZMA_STATUS_NOT_FINISHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* Lzma2Dec.h -- LZMA2 Decoder
|
/* Lzma2Dec.h -- LZMA2 Decoder
|
||||||
2013-01-18 : Igor Pavlov : Public domain */
|
2015-05-13 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __LZMA2_DEC_H
|
#ifndef __LZMA2_DEC_H
|
||||||
#define __LZMA2_DEC_H
|
#define __LZMA2_DEC_H
|
||||||
@@ -15,7 +15,7 @@ typedef struct
|
|||||||
CLzmaDec decoder;
|
CLzmaDec decoder;
|
||||||
UInt32 packSize;
|
UInt32 packSize;
|
||||||
UInt32 unpackSize;
|
UInt32 unpackSize;
|
||||||
int state;
|
unsigned state;
|
||||||
Byte control;
|
Byte control;
|
||||||
Bool needInitDic;
|
Bool needInitDic;
|
||||||
Bool needInitState;
|
Bool needInitState;
|
||||||
|
|||||||
@@ -238,9 +238,9 @@ void Lzma2EncProps_Normalize(CLzma2EncProps *p)
|
|||||||
if (temp > p->lzmaProps.reduceSize)
|
if (temp > p->lzmaProps.reduceSize)
|
||||||
{
|
{
|
||||||
UInt64 numBlocks = temp / p->blockSize;
|
UInt64 numBlocks = temp / p->blockSize;
|
||||||
if (numBlocks < t2)
|
if (numBlocks < (unsigned)t2)
|
||||||
{
|
{
|
||||||
t2 = (UInt32)numBlocks;
|
t2 = (unsigned)numBlocks;
|
||||||
t3 = t1 * t2;
|
t3 = t1 * t2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
172
C/LzmaDec.c
172
C/LzmaDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaDec.c -- LZMA Decoder
|
/* LzmaDec.c -- LZMA Decoder
|
||||||
2015-01-01 : Igor Pavlov : Public domain */
|
2015-05-14 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -114,14 +114,14 @@
|
|||||||
#define Literal (RepLenCoder + kNumLenProbs)
|
#define Literal (RepLenCoder + kNumLenProbs)
|
||||||
|
|
||||||
#define LZMA_BASE_SIZE 1846
|
#define LZMA_BASE_SIZE 1846
|
||||||
#define LZMA_LIT_SIZE 768
|
#define LZMA_LIT_SIZE 0x300
|
||||||
|
|
||||||
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
|
||||||
|
|
||||||
#if Literal != LZMA_BASE_SIZE
|
#if Literal != LZMA_BASE_SIZE
|
||||||
StopCompilingDueBUG
|
StopCompilingDueBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
|
||||||
|
|
||||||
#define LZMA_DIC_MIN (1 << 12)
|
#define LZMA_DIC_MIN (1 << 12)
|
||||||
|
|
||||||
/* First LZMA-symbol is always decoded.
|
/* First LZMA-symbol is always decoded.
|
||||||
@@ -133,8 +133,8 @@ Out:
|
|||||||
p->remainLen:
|
p->remainLen:
|
||||||
< kMatchSpecLenStart : normal remain
|
< kMatchSpecLenStart : normal remain
|
||||||
= kMatchSpecLenStart : finished
|
= kMatchSpecLenStart : finished
|
||||||
= kMatchSpecLenStart + 1 : Flush marker
|
= kMatchSpecLenStart + 1 : Flush marker (unused now)
|
||||||
= kMatchSpecLenStart + 2 : State Init Marker
|
= kMatchSpecLenStart + 2 : State Init Marker (unused now)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
|
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;
|
unsigned symbol;
|
||||||
UPDATE_0(prob);
|
UPDATE_0(prob);
|
||||||
prob = probs + Literal;
|
prob = probs + Literal;
|
||||||
if (checkDicSize != 0 || processedPos != 0)
|
if (processedPos != 0 || checkDicSize != 0)
|
||||||
prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
|
||||||
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
(dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
|
||||||
|
processedPos++;
|
||||||
|
|
||||||
if (state < kNumLitStates)
|
if (state < kNumLitStates)
|
||||||
{
|
{
|
||||||
@@ -195,7 +196,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned matchByte = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||||
unsigned offs = 0x100;
|
unsigned offs = 0x100;
|
||||||
state -= (state < 10) ? 3 : 6;
|
state -= (state < 10) ? 3 : 6;
|
||||||
symbol = 1;
|
symbol = 1;
|
||||||
@@ -222,11 +223,11 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
dic[dicPos++] = (Byte)symbol;
|
dic[dicPos++] = (Byte)symbol;
|
||||||
processedPos++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
{
|
||||||
UPDATE_1(prob);
|
UPDATE_1(prob);
|
||||||
prob = probs + IsRep + state;
|
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)
|
IF_BIT_0(prob)
|
||||||
{
|
{
|
||||||
UPDATE_0(prob);
|
UPDATE_0(prob);
|
||||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||||
dicPos++;
|
dicPos++;
|
||||||
processedPos++;
|
processedPos++;
|
||||||
state = state < kNumLitStates ? 9 : 11;
|
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;
|
state = state < kNumLitStates ? 8 : 11;
|
||||||
prob = probs + RepLenCoder;
|
prob = probs + RepLenCoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _LZMA_SIZE_OPT
|
||||||
{
|
{
|
||||||
unsigned limit, offset;
|
unsigned limit, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
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);
|
TREE_DECODE(probLen, limit, len);
|
||||||
len += offset;
|
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)
|
if (state >= kNumStates)
|
||||||
{
|
{
|
||||||
@@ -332,7 +371,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
if (distance >= kStartPosModelIndex)
|
if (distance >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
unsigned posSlot = (unsigned)distance;
|
unsigned posSlot = (unsigned)distance;
|
||||||
int numDirectBits = (int)(((distance >> 1) - 1));
|
unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
|
||||||
distance = (2 | (distance & 1));
|
distance = (2 | (distance & 1));
|
||||||
if (posSlot < kEndPosModelIndex)
|
if (posSlot < kEndPosModelIndex)
|
||||||
{
|
{
|
||||||
@@ -391,6 +430,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rep3 = rep2;
|
rep3 = rep2;
|
||||||
rep2 = rep1;
|
rep2 = rep1;
|
||||||
rep1 = rep0;
|
rep1 = rep0;
|
||||||
@@ -407,17 +447,21 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
|
|
||||||
len += kMatchMinLen;
|
len += kMatchMinLen;
|
||||||
|
|
||||||
if (limit == dicPos)
|
|
||||||
return SZ_ERROR_DATA;
|
|
||||||
{
|
{
|
||||||
SizeT rem = limit - dicPos;
|
SizeT rem;
|
||||||
unsigned curLen = ((rem < len) ? (unsigned)rem : len);
|
unsigned curLen;
|
||||||
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
|
SizeT pos;
|
||||||
|
|
||||||
|
if ((rem = limit - dicPos) == 0)
|
||||||
|
return SZ_ERROR_DATA;
|
||||||
|
|
||||||
|
curLen = ((rem < len) ? (unsigned)rem : len);
|
||||||
|
pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
|
||||||
|
|
||||||
processedPos += curLen;
|
processedPos += curLen;
|
||||||
|
|
||||||
len -= curLen;
|
len -= curLen;
|
||||||
if (pos + curLen <= dicBufSize)
|
if (curLen <= dicBufSize - pos)
|
||||||
{
|
{
|
||||||
Byte *dest = dic + dicPos;
|
Byte *dest = dic + dicPos;
|
||||||
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
|
||||||
@@ -441,7 +485,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (dicPos < limit && buf < bufLimit);
|
while (dicPos < limit && buf < bufLimit);
|
||||||
|
|
||||||
NORMALIZE;
|
NORMALIZE;
|
||||||
|
|
||||||
p->buf = buf;
|
p->buf = buf;
|
||||||
p->range = range;
|
p->range = range;
|
||||||
p->code = code;
|
p->code = code;
|
||||||
@@ -465,9 +511,10 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
|||||||
SizeT dicPos = p->dicPos;
|
SizeT dicPos = p->dicPos;
|
||||||
SizeT dicBufSize = p->dicBufSize;
|
SizeT dicBufSize = p->dicBufSize;
|
||||||
unsigned len = p->remainLen;
|
unsigned len = p->remainLen;
|
||||||
UInt32 rep0 = p->reps[0];
|
SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
|
||||||
if (limit - dicPos < len)
|
SizeT rem = limit - dicPos;
|
||||||
len = (unsigned)(limit - dicPos);
|
if (rem < len)
|
||||||
|
len = (unsigned)(rem);
|
||||||
|
|
||||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
|
||||||
p->checkDicSize = p->prop.dicSize;
|
p->checkDicSize = p->prop.dicSize;
|
||||||
@@ -477,7 +524,7 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
|
|||||||
while (len != 0)
|
while (len != 0)
|
||||||
{
|
{
|
||||||
len--;
|
len--;
|
||||||
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
|
||||||
dicPos++;
|
dicPos++;
|
||||||
}
|
}
|
||||||
p->dicPos = dicPos;
|
p->dicPos = dicPos;
|
||||||
@@ -495,17 +542,19 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
|
|||||||
if (limit - p->dicPos > rem)
|
if (limit - p->dicPos > rem)
|
||||||
limit2 = p->dicPos + rem;
|
limit2 = p->dicPos + rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
|
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;
|
p->checkDicSize = p->prop.dicSize;
|
||||||
|
|
||||||
LzmaDec_WriteRem(p, limit);
|
LzmaDec_WriteRem(p, limit);
|
||||||
}
|
}
|
||||||
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
|
||||||
|
|
||||||
if (p->remainLen > kMatchSpecLenStart)
|
if (p->remainLen > kMatchSpecLenStart)
|
||||||
{
|
|
||||||
p->remainLen = kMatchSpecLenStart;
|
p->remainLen = kMatchSpecLenStart;
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,12 +571,12 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
UInt32 range = p->range;
|
UInt32 range = p->range;
|
||||||
UInt32 code = p->code;
|
UInt32 code = p->code;
|
||||||
const Byte *bufLimit = buf + inSize;
|
const Byte *bufLimit = buf + inSize;
|
||||||
CLzmaProb *probs = p->probs;
|
const CLzmaProb *probs = p->probs;
|
||||||
unsigned state = p->state;
|
unsigned state = p->state;
|
||||||
ELzmaDummy res;
|
ELzmaDummy res;
|
||||||
|
|
||||||
{
|
{
|
||||||
CLzmaProb *prob;
|
const CLzmaProb *prob;
|
||||||
UInt32 bound;
|
UInt32 bound;
|
||||||
unsigned ttt;
|
unsigned ttt;
|
||||||
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
|
||||||
@@ -541,7 +590,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
|
|
||||||
prob = probs + Literal;
|
prob = probs + Literal;
|
||||||
if (p->checkDicSize != 0 || p->processedPos != 0)
|
if (p->checkDicSize != 0 || p->processedPos != 0)
|
||||||
prob += (LZMA_LIT_SIZE *
|
prob += ((UInt32)LZMA_LIT_SIZE *
|
||||||
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
|
||||||
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
|
||||||
|
|
||||||
@@ -553,13 +602,13 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
|
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 offs = 0x100;
|
||||||
unsigned symbol = 1;
|
unsigned symbol = 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned bit;
|
unsigned bit;
|
||||||
CLzmaProb *probLit;
|
const CLzmaProb *probLit;
|
||||||
matchByte <<= 1;
|
matchByte <<= 1;
|
||||||
bit = (matchByte & offs);
|
bit = (matchByte & offs);
|
||||||
probLit = prob + offs + bit + symbol;
|
probLit = prob + offs + bit + symbol;
|
||||||
@@ -629,7 +678,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
unsigned limit, offset;
|
unsigned limit, offset;
|
||||||
CLzmaProb *probLen = prob + LenChoice;
|
const CLzmaProb *probLen = prob + LenChoice;
|
||||||
IF_BIT_0_CHECK(probLen)
|
IF_BIT_0_CHECK(probLen)
|
||||||
{
|
{
|
||||||
UPDATE_0_CHECK;
|
UPDATE_0_CHECK;
|
||||||
@@ -669,7 +718,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
|
||||||
if (posSlot >= kStartPosModelIndex)
|
if (posSlot >= kStartPosModelIndex)
|
||||||
{
|
{
|
||||||
int numDirectBits = ((posSlot >> 1) - 1);
|
unsigned numDirectBits = ((posSlot >> 1) - 1);
|
||||||
|
|
||||||
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
/* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
|
||||||
|
|
||||||
@@ -708,13 +757,6 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
|
|
||||||
{
|
|
||||||
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
|
|
||||||
p->range = 0xFFFFFFFF;
|
|
||||||
p->needFlush = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||||
{
|
{
|
||||||
p->needFlush = 1;
|
p->needFlush = 1;
|
||||||
@@ -739,8 +781,8 @@ void LzmaDec_Init(CLzmaDec *p)
|
|||||||
|
|
||||||
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
static void LzmaDec_InitStateReal(CLzmaDec *p)
|
||||||
{
|
{
|
||||||
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
|
SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
|
||||||
UInt32 i;
|
SizeT i;
|
||||||
CLzmaProb *probs = p->probs;
|
CLzmaProb *probs = p->probs;
|
||||||
for (i = 0; i < numProbs; i++)
|
for (i = 0; i < numProbs; i++)
|
||||||
probs[i] = kBitModelTotal >> 1;
|
probs[i] = kBitModelTotal >> 1;
|
||||||
@@ -762,7 +804,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||||||
{
|
{
|
||||||
int checkEndMarkNow;
|
int checkEndMarkNow;
|
||||||
|
|
||||||
if (p->needFlush != 0)
|
if (p->needFlush)
|
||||||
{
|
{
|
||||||
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
|
||||||
p->tempBuf[p->tempBufSize++] = *src++;
|
p->tempBuf[p->tempBufSize++] = *src++;
|
||||||
@@ -773,8 +815,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||||||
}
|
}
|
||||||
if (p->tempBuf[0] != 0)
|
if (p->tempBuf[0] != 0)
|
||||||
return SZ_ERROR_DATA;
|
return SZ_ERROR_DATA;
|
||||||
|
p->code =
|
||||||
LzmaDec_InitRc(p, p->tempBuf);
|
((UInt32)p->tempBuf[1] << 24)
|
||||||
|
| ((UInt32)p->tempBuf[2] << 16)
|
||||||
|
| ((UInt32)p->tempBuf[3] << 8)
|
||||||
|
| ((UInt32)p->tempBuf[4]);
|
||||||
|
p->range = 0xFFFFFFFF;
|
||||||
|
p->needFlush = 0;
|
||||||
p->tempBufSize = 0;
|
p->tempBufSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,7 +905,16 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||||||
p->buf = p->tempBuf;
|
p->buf = p->tempBuf;
|
||||||
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
|
||||||
return SZ_ERROR_DATA;
|
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;
|
(*srcLen) += lookAhead;
|
||||||
src += lookAhead;
|
src += lookAhead;
|
||||||
inSize -= lookAhead;
|
inSize -= lookAhead;
|
||||||
@@ -913,13 +969,13 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
|
|||||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->probs);
|
alloc->Free(alloc, p->probs);
|
||||||
p->probs = 0;
|
p->probs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, p->dic);
|
alloc->Free(alloc, p->dic);
|
||||||
p->dic = 0;
|
p->dic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||||
@@ -957,12 +1013,12 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
|||||||
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
|
||||||
if (p->probs == 0 || numProbs != p->numProbs)
|
if (!p->probs || numProbs != p->numProbs)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
|
||||||
p->numProbs = numProbs;
|
p->numProbs = numProbs;
|
||||||
if (p->probs == 0)
|
if (!p->probs)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
@@ -983,12 +1039,22 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll
|
|||||||
SizeT dicBufSize;
|
SizeT dicBufSize;
|
||||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||||
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
|
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);
|
LzmaDec_FreeDict(p, alloc);
|
||||||
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
|
||||||
if (p->dic == 0)
|
if (!p->dic)
|
||||||
{
|
{
|
||||||
LzmaDec_FreeProbs(p, alloc);
|
LzmaDec_FreeProbs(p, alloc);
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|||||||
237
C/LzmaEnc.c
237
C/LzmaEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* LzmaEnc.c -- LZMA Encoder
|
/* LzmaEnc.c -- LZMA Encoder
|
||||||
2014-12-29 : Igor Pavlov : Public domain */
|
2015-05-15 Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -23,6 +23,9 @@
|
|||||||
static unsigned g_STAT_OFFSET = 0;
|
static unsigned g_STAT_OFFSET = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define kMaxHistorySize ((UInt32)3 << 29)
|
||||||
|
/* #define kMaxHistorySize ((UInt32)7 << 29) */
|
||||||
|
|
||||||
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
|
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
|
||||||
|
|
||||||
#define kBlockSize (9 << 10)
|
#define kBlockSize (9 << 10)
|
||||||
@@ -58,6 +61,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
|||||||
int level = p->level;
|
int level = p->level;
|
||||||
if (level < 0) level = 5;
|
if (level < 0) level = 5;
|
||||||
p->level = level;
|
p->level = level;
|
||||||
|
|
||||||
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
|
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
|
||||||
if (p->dictSize > p->reduceSize)
|
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 ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->lc < 0) p->lc = 3;
|
if (p->lc < 0) p->lc = 3;
|
||||||
if (p->lp < 0) p->lp = 0;
|
if (p->lp < 0) p->lp = 0;
|
||||||
if (p->pb < 0) p->pb = 2;
|
if (p->pb < 0) p->pb = 2;
|
||||||
|
|
||||||
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
|
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
|
||||||
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
|
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
|
||||||
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
|
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
|
||||||
if (p->numHashBytes < 0) p->numHashBytes = 4;
|
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)
|
if (p->numThreads < 0)
|
||||||
p->numThreads =
|
p->numThreads =
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
@@ -92,17 +99,18 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
|
|||||||
return props.dictSize;
|
return props.dictSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (_MSC_VER >= 1400)
|
||||||
|
/* BSR code is fast for some new CPUs */
|
||||||
/* #define LZMA_LOG_BSR */
|
/* #define LZMA_LOG_BSR */
|
||||||
/* Define it for Intel's CPU */
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef LZMA_LOG_BSR
|
#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); }
|
#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;
|
UInt32 res;
|
||||||
BSR2_RET(pos, res);
|
BSR2_RET(pos, res);
|
||||||
@@ -113,27 +121,44 @@ UInt32 GetPosSlot1(UInt32 pos)
|
|||||||
|
|
||||||
#else
|
#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)
|
#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[0] = 0;
|
||||||
g_FastPos[1] = 1;
|
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));
|
size_t k = ((size_t)1 << ((slot >> 1) - 1));
|
||||||
UInt32 j;
|
size_t j;
|
||||||
for (j = 0; j < k; j++, c++)
|
for (j = 0; j < k; j++)
|
||||||
g_FastPos[c] = (Byte)slotFast;
|
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) & \
|
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
|
||||||
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
|
||||||
res = p->g_FastPos[pos >> i] + (i * 2); }
|
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))) ? \
|
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
|
||||||
p->g_FastPos[pos >> 6] + 12 : \
|
p->g_FastPos[pos >> 6] + 12 : \
|
||||||
@@ -213,6 +238,7 @@ typedef struct
|
|||||||
|
|
||||||
#define kNumStates 12
|
#define kNumStates 12
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLzmaProb choice;
|
CLzmaProb choice;
|
||||||
@@ -222,14 +248,16 @@ typedef struct
|
|||||||
CLzmaProb high[kLenNumHighSymbols];
|
CLzmaProb high[kLenNumHighSymbols];
|
||||||
} CLenEnc;
|
} CLenEnc;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLenEnc p;
|
CLenEnc p;
|
||||||
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
|
|
||||||
UInt32 tableSize;
|
UInt32 tableSize;
|
||||||
|
UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
|
||||||
UInt32 counters[LZMA_NUM_PB_STATES_MAX];
|
UInt32 counters[LZMA_NUM_PB_STATES_MAX];
|
||||||
} CLenPriceEnc;
|
} CLenPriceEnc;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UInt32 range;
|
UInt32 range;
|
||||||
@@ -244,10 +272,14 @@ typedef struct
|
|||||||
SRes res;
|
SRes res;
|
||||||
} CRangeEnc;
|
} CRangeEnc;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CLzmaProb *litProbs;
|
CLzmaProb *litProbs;
|
||||||
|
|
||||||
|
UInt32 state;
|
||||||
|
UInt32 reps[LZMA_NUM_REPS];
|
||||||
|
|
||||||
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
||||||
CLzmaProb isRep[kNumStates];
|
CLzmaProb isRep[kNumStates];
|
||||||
CLzmaProb isRepG0[kNumStates];
|
CLzmaProb isRepG0[kNumStates];
|
||||||
@@ -261,15 +293,49 @@ typedef struct
|
|||||||
|
|
||||||
CLenPriceEnc lenEnc;
|
CLenPriceEnc lenEnc;
|
||||||
CLenPriceEnc repLenEnc;
|
CLenPriceEnc repLenEnc;
|
||||||
|
|
||||||
UInt32 reps[LZMA_NUM_REPS];
|
|
||||||
UInt32 state;
|
|
||||||
} CSaveState;
|
} CSaveState;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
IMatchFinder matchFinder;
|
|
||||||
void *matchFinderObj;
|
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
|
#ifndef _7ZIP_ST
|
||||||
Bool mtMode;
|
Bool mtMode;
|
||||||
@@ -282,12 +348,6 @@ typedef struct
|
|||||||
Byte pad[128];
|
Byte pad[128];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UInt32 optimumEndIndex;
|
|
||||||
UInt32 optimumCurrentIndex;
|
|
||||||
|
|
||||||
UInt32 longestMatchLength;
|
|
||||||
UInt32 numPairs;
|
|
||||||
UInt32 numAvail;
|
|
||||||
COptimal opt[kNumOpts];
|
COptimal opt[kNumOpts];
|
||||||
|
|
||||||
#ifndef LZMA_LOG_BSR
|
#ifndef LZMA_LOG_BSR
|
||||||
@@ -296,22 +356,10 @@ typedef struct
|
|||||||
|
|
||||||
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
||||||
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
|
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 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
|
||||||
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
|
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
|
||||||
UInt32 alignPrices[kAlignTableSize];
|
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 isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
|
||||||
CLzmaProb isRep[kNumStates];
|
CLzmaProb isRep[kNumStates];
|
||||||
@@ -327,26 +375,14 @@ typedef struct
|
|||||||
CLenPriceEnc lenEnc;
|
CLenPriceEnc lenEnc;
|
||||||
CLenPriceEnc repLenEnc;
|
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;
|
CSaveState saveState;
|
||||||
|
|
||||||
|
#ifndef _7ZIP_ST
|
||||||
|
Byte pad2[128];
|
||||||
|
#endif
|
||||||
} CLzmaEnc;
|
} CLzmaEnc;
|
||||||
|
|
||||||
|
|
||||||
void LzmaEnc_SaveState(CLzmaEncHandle pp)
|
void LzmaEnc_SaveState(CLzmaEncHandle pp)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
@@ -370,7 +406,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp)
|
|||||||
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
|
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
|
||||||
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
|
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
|
||||||
memcpy(dest->reps, p->reps, sizeof(p->reps));
|
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)
|
void LzmaEnc_RestoreState(CLzmaEncHandle pp)
|
||||||
@@ -396,7 +432,7 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp)
|
|||||||
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
|
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
|
||||||
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
|
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
|
||||||
memcpy(dest->reps, p->reps, sizeof(p->reps));
|
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)
|
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
||||||
@@ -405,9 +441,13 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||||||
CLzmaEncProps props = *props2;
|
CLzmaEncProps props = *props2;
|
||||||
LzmaEncProps_Normalize(&props);
|
LzmaEncProps_Normalize(&props);
|
||||||
|
|
||||||
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
|
if (props.lc > LZMA_LC_MAX
|
||||||
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
|
|| props.lp > LZMA_LP_MAX
|
||||||
|
|| props.pb > LZMA_PB_MAX
|
||||||
|
|| props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress)
|
||||||
|
|| props.dictSize > kMaxHistorySize)
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
|
|
||||||
p->dictSize = props.dictSize;
|
p->dictSize = props.dictSize;
|
||||||
{
|
{
|
||||||
unsigned fb = props.fb;
|
unsigned fb = props.fb;
|
||||||
@@ -421,7 +461,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||||||
p->lp = props.lp;
|
p->lp = props.lp;
|
||||||
p->pb = props.pb;
|
p->pb = props.pb;
|
||||||
p->fastMode = (props.algo == 0);
|
p->fastMode = (props.algo == 0);
|
||||||
p->matchFinderBase.btMode = props.btMode;
|
p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0);
|
||||||
{
|
{
|
||||||
UInt32 numHashBytes = 4;
|
UInt32 numHashBytes = 4;
|
||||||
if (props.btMode)
|
if (props.btMode)
|
||||||
@@ -607,7 +647,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol,
|
|||||||
while (symbol < 0x10000);
|
while (symbol < 0x10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
|
static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
|
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_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
|
||||||
#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> 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;
|
UInt32 price = 0;
|
||||||
symbol |= 0x100;
|
symbol |= 0x100;
|
||||||
@@ -656,7 +696,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro
|
|||||||
return price;
|
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 price = 0;
|
||||||
UInt32 offs = 0x100;
|
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;
|
UInt32 price = 0;
|
||||||
symbol |= (1 << numBitLevels);
|
symbol |= (1 << numBitLevels);
|
||||||
@@ -712,7 +752,7 @@ static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 s
|
|||||||
return price;
|
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 price = 0;
|
||||||
UInt32 m = 1;
|
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 a0 = GET_PRICE_0a(p->choice);
|
||||||
UInt32 a1 = GET_PRICE_1a(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);
|
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);
|
LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
|
||||||
p->counters[posState] = p->tableSize;
|
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;
|
UInt32 posState;
|
||||||
for (posState = 0; posState < numPosStates; posState++)
|
for (posState = 0; posState < numPosStates; posState++)
|
||||||
LenPriceEnc_UpdateTable(p, posState, ProbPrices);
|
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);
|
LenEnc_Encode(&p->p, rc, symbol, posState);
|
||||||
if (updatePrice)
|
if (updatePrice)
|
||||||
@@ -845,14 +885,16 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
|
|||||||
lenRes = p->matches[numPairs - 2];
|
lenRes = p->matches[numPairs - 2];
|
||||||
if (lenRes == p->numFastBytes)
|
if (lenRes == p->numFastBytes)
|
||||||
{
|
{
|
||||||
const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
|
||||||
UInt32 distance = p->matches[numPairs - 1] + 1;
|
|
||||||
UInt32 numAvail = p->numAvail;
|
UInt32 numAvail = p->numAvail;
|
||||||
if (numAvail > LZMA_MATCH_LEN_MAX)
|
if (numAvail > LZMA_MATCH_LEN_MAX)
|
||||||
numAvail = LZMA_MATCH_LEN_MAX;
|
numAvail = LZMA_MATCH_LEN_MAX;
|
||||||
{
|
{
|
||||||
const Byte *pby2 = pby - distance;
|
const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
|
||||||
for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
|
const Byte *pby = pbyCur + lenRes;
|
||||||
|
ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1];
|
||||||
|
const Byte *pbyLim = pbyCur + numAvail;
|
||||||
|
for (; pby != pbyLim && *pby == pby[dif]; pby++);
|
||||||
|
lenRes = (UInt32)(pby - pbyCur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -937,7 +979,7 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
|
|||||||
return p->optimumCurrentIndex;
|
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)
|
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
||||||
{
|
{
|
||||||
@@ -981,7 +1023,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
UInt32 lenTest;
|
UInt32 lenTest;
|
||||||
const Byte *data2;
|
const Byte *data2;
|
||||||
reps[i] = p->reps[i];
|
reps[i] = p->reps[i];
|
||||||
data2 = data - (reps[i] + 1);
|
data2 = data - reps[i] - 1;
|
||||||
if (data[0] != data2[0] || data[1] != data2[1])
|
if (data[0] != data2[0] || data[1] != data2[1])
|
||||||
{
|
{
|
||||||
repLens[i] = 0;
|
repLens[i] = 0;
|
||||||
@@ -1282,7 +1324,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
/* try Literal + rep0 */
|
/* try Literal + rep0 */
|
||||||
UInt32 temp;
|
UInt32 temp;
|
||||||
UInt32 lenTest2;
|
UInt32 lenTest2;
|
||||||
const Byte *data2 = data - (reps[0] + 1);
|
const Byte *data2 = data - reps[0] - 1;
|
||||||
UInt32 limit = p->numFastBytes + 1;
|
UInt32 limit = p->numFastBytes + 1;
|
||||||
if (limit > numAvailFull)
|
if (limit > numAvailFull)
|
||||||
limit = numAvailFull;
|
limit = numAvailFull;
|
||||||
@@ -1325,7 +1367,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
UInt32 lenTest;
|
UInt32 lenTest;
|
||||||
UInt32 lenTestTemp;
|
UInt32 lenTestTemp;
|
||||||
UInt32 price;
|
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])
|
if (data[0] != data2[0] || data[1] != data2[1])
|
||||||
continue;
|
continue;
|
||||||
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
|
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
|
||||||
@@ -1442,7 +1484,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
|
|||||||
if (/*_maxMode && */lenTest == matches[offs])
|
if (/*_maxMode && */lenTest == matches[offs])
|
||||||
{
|
{
|
||||||
/* Try Match + Literal + Rep0 */
|
/* Try Match + Literal + Rep0 */
|
||||||
const Byte *data2 = data - (curBack + 1);
|
const Byte *data2 = data - curBack - 1;
|
||||||
UInt32 lenTest2 = lenTest + 1;
|
UInt32 lenTest2 = lenTest + 1;
|
||||||
UInt32 limit = lenTest2 + p->numFastBytes;
|
UInt32 limit = lenTest2 + p->numFastBytes;
|
||||||
UInt32 nextRepMatchPrice;
|
UInt32 nextRepMatchPrice;
|
||||||
@@ -1525,7 +1567,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
|
|||||||
for (i = 0; i < LZMA_NUM_REPS; i++)
|
for (i = 0; i < LZMA_NUM_REPS; i++)
|
||||||
{
|
{
|
||||||
UInt32 len;
|
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])
|
if (data[0] != data2[0] || data[1] != data2[1])
|
||||||
continue;
|
continue;
|
||||||
for (len = 2; len < numAvail && data[len] == data2[len]; len++);
|
for (len = 2; len < numAvail && data[len] == data2[len]; len++);
|
||||||
@@ -1594,7 +1636,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
|
|||||||
for (i = 0; i < LZMA_NUM_REPS; i++)
|
for (i = 0; i < LZMA_NUM_REPS; i++)
|
||||||
{
|
{
|
||||||
UInt32 len, limit;
|
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])
|
if (data[0] != data2[0] || data[1] != data2[1])
|
||||||
continue;
|
continue;
|
||||||
limit = mainLen - 1;
|
limit = mainLen - 1;
|
||||||
@@ -1690,6 +1732,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
|
|||||||
{
|
{
|
||||||
RangeEnc_Construct(&p->rc);
|
RangeEnc_Construct(&p->rc);
|
||||||
MatchFinder_Construct(&p->matchFinderBase);
|
MatchFinder_Construct(&p->matchFinderBase);
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
MatchFinderMt_Construct(&p->matchFinderMt);
|
MatchFinderMt_Construct(&p->matchFinderMt);
|
||||||
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
|
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
|
||||||
@@ -1732,6 +1775,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
|||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
|
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MatchFinder_Free(&p->matchFinderBase, allocBig);
|
MatchFinder_Free(&p->matchFinderBase, allocBig);
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
RangeEnc_Free(&p->rc, alloc);
|
RangeEnc_Free(&p->rc, alloc);
|
||||||
@@ -1768,7 +1812,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
|||||||
ReadMatchDistances(p, &numPairs);
|
ReadMatchDistances(p, &numPairs);
|
||||||
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
|
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
|
||||||
p->state = kLiteralNextStates[p->state];
|
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);
|
LitEnc_Encode(&p->rc, p->litProbs, curByte);
|
||||||
p->additionalOffset--;
|
p->additionalOffset--;
|
||||||
nowPos32++;
|
nowPos32++;
|
||||||
@@ -1894,7 +1938,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
|
|||||||
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
|
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (processed >= (1 << 15))
|
else if (processed >= (1 << 17))
|
||||||
{
|
{
|
||||||
p->nowPos64 += nowPos32 - startPos32;
|
p->nowPos64 += nowPos32 - startPos32;
|
||||||
return CheckErrors(p);
|
return CheckErrors(p);
|
||||||
@@ -1912,6 +1956,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
UInt32 beforeSize = kNumOpts;
|
UInt32 beforeSize = kNumOpts;
|
||||||
if (!RangeEnc_Alloc(&p->rc, alloc))
|
if (!RangeEnc_Alloc(&p->rc, alloc))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
|
p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0));
|
||||||
#endif
|
#endif
|
||||||
@@ -1921,8 +1966,8 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
|
if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
|
||||||
{
|
{
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
|
p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
||||||
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
|
p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb));
|
||||||
if (p->litProbs == 0 || p->saveState.litProbs == 0)
|
if (p->litProbs == 0 || p->saveState.litProbs == 0)
|
||||||
{
|
{
|
||||||
LzmaEnc_FreeLits(p, alloc);
|
LzmaEnc_FreeLits(p, alloc);
|
||||||
@@ -1932,7 +1977,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
|
p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
|
||||||
|
|
||||||
if (beforeSize + p->dictSize < keepWindowSize)
|
if (beforeSize + p->dictSize < keepWindowSize)
|
||||||
beforeSize = keepWindowSize - p->dictSize;
|
beforeSize = keepWindowSize - p->dictSize;
|
||||||
@@ -1952,6 +1997,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||||||
p->matchFinderObj = &p->matchFinderBase;
|
p->matchFinderObj = &p->matchFinderBase;
|
||||||
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
|
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1980,9 +2026,10 @@ void LzmaEnc_Init(CLzmaEnc *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt32 num = 0x300 << (p->lp + p->lc);
|
UInt32 num = (UInt32)0x300 << (p->lp + p->lc);
|
||||||
|
CLzmaProb *probs = p->litProbs;
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
p->litProbs[i] = kProbInitValue;
|
probs[i] = kProbInitValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -2089,7 +2136,7 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
|
|||||||
if (p->mtMode)
|
if (p->mtMode)
|
||||||
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
|
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
|
||||||
#else
|
#else
|
||||||
pp = pp;
|
UNUSED_VAR(pp);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2201,25 +2248,23 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
|
|||||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
||||||
{
|
{
|
||||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||||
int i;
|
unsigned i;
|
||||||
UInt32 dictSize = p->dictSize;
|
UInt32 dictSize = p->dictSize;
|
||||||
if (*size < LZMA_PROPS_SIZE)
|
if (*size < LZMA_PROPS_SIZE)
|
||||||
return SZ_ERROR_PARAM;
|
return SZ_ERROR_PARAM;
|
||||||
*size = LZMA_PROPS_SIZE;
|
*size = LZMA_PROPS_SIZE;
|
||||||
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
|
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))
|
UInt32 kDictMask = ((UInt32)1 << 20) - 1;
|
||||||
{
|
if (dictSize < (UInt32)0xFFFFFFFF - kDictMask)
|
||||||
dictSize = (2 << i);
|
dictSize = (dictSize + kDictMask) & ~kDictMask;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (dictSize <= ((UInt32)3 << i))
|
else for (i = 11; i <= 30; i++)
|
||||||
{
|
{
|
||||||
dictSize = (3 << i);
|
if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; }
|
||||||
break;
|
if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
|
|||||||
12
C/LzmaLib.c
12
C/LzmaLib.c
@@ -1,17 +1,11 @@
|
|||||||
/* LzmaLib.c -- LZMA library wrapper
|
/* LzmaLib.c -- LZMA library wrapper
|
||||||
2008-08-05
|
2015-06-13 : Igor Pavlov : Public domain */
|
||||||
Igor Pavlov
|
|
||||||
Public domain */
|
|
||||||
|
|
||||||
#include "LzmaEnc.h"
|
|
||||||
#include "LzmaDec.h"
|
|
||||||
#include "Alloc.h"
|
#include "Alloc.h"
|
||||||
|
#include "LzmaDec.h"
|
||||||
|
#include "LzmaEnc.h"
|
||||||
#include "LzmaLib.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,
|
unsigned char *outProps, size_t *outPropsSize,
|
||||||
int level, /* 0 <= level <= 9, default = 5 */
|
int level, /* 0 <= level <= 9, default = 5 */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* RotateDefs.h -- Rotate functions
|
/* RotateDefs.h -- Rotate functions
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2015-03-25 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __ROTATE_DEFS_H
|
#ifndef __ROTATE_DEFS_H
|
||||||
#define __ROTATE_DEFS_H
|
#define __ROTATE_DEFS_H
|
||||||
@@ -8,16 +8,20 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#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(_rotl)
|
||||||
#pragma intrinsic(_rotr)
|
#pragma intrinsic(_rotr)
|
||||||
// #endif
|
/* #endif */
|
||||||
|
|
||||||
#define rotlFixed(x, n) _rotl((x), (n))
|
#define rotlFixed(x, n) _rotl((x), (n))
|
||||||
#define rotrFixed(x, n) _rotr((x), (n))
|
#define rotrFixed(x, n) _rotr((x), (n))
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
/* new compilers can translate these macros to fast commands. */
|
||||||
|
|
||||||
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
|
||||||
#define rotrFixed(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
|
||||||
151
C/Sha256.c
151
C/Sha256.c
@@ -1,14 +1,21 @@
|
|||||||
/* Crypto/Sha256.c -- SHA-256 Hash
|
/* 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. */
|
This code is based on public domain code from Wei Dai's Crypto++ library. */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "CpuArch.h"
|
||||||
#include "RotateDefs.h"
|
#include "RotateDefs.h"
|
||||||
#include "Sha256.h"
|
#include "Sha256.h"
|
||||||
|
|
||||||
/* define it for speed optimization */
|
/* define it for speed optimization */
|
||||||
/* #define _SHA256_UNROLL */
|
#ifndef _SFX
|
||||||
|
#define _SHA256_UNROLL
|
||||||
|
#define _SHA256_UNROLL2
|
||||||
|
#endif
|
||||||
|
|
||||||
/* #define _SHA256_UNROLL2 */
|
/* #define _SHA256_UNROLL2 */
|
||||||
|
|
||||||
void Sha256_Init(CSha256 *p)
|
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 s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3))
|
||||||
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
|
#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10))
|
||||||
|
|
||||||
#define blk0(i) (W[i] = data[i])
|
#define blk0(i) (W[i])
|
||||||
#define blk2(i) (W[i&15] += s1(W[(i-2)&15]) + W[(i-7)&15] + s0(W[(i-15)&15]))
|
#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 Ch(x,y,z) (z^(x&(y^z)))
|
||||||
#define Maj(x,y,z) ((x&y)|(z&(x|y)))
|
#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
|
#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));\
|
#define R(a,b,c,d,e,f,g,h, i) \
|
||||||
d += h; h += S0(a) + Maj(a, b, c)
|
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) \
|
#define RX_8(i) \
|
||||||
R(a,b,c,d,e,f,g,h, 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(c,d,e,f,g,h,a,b, i+6); \
|
||||||
R(b,c,d,e,f,g,h,a, i+7)
|
R(b,c,d,e,f,g,h,a, i+7)
|
||||||
|
|
||||||
|
#define RX_16 RX_8(0); RX_8(8);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define R(i) h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j?blk2(i):blk0(i));\
|
#define a(i) T[(0-(i))&7]
|
||||||
d(i) += h(i); h(i) += S0(a(i)) + Maj(a(i), b(i), c(i))
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
@@ -92,10 +109,12 @@ static const UInt32 K[64] = {
|
|||||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||||
};
|
};
|
||||||
|
|
||||||
static void Sha256_Transform(UInt32 *state, const UInt32 *data)
|
static void Sha256_WriteByteBlock(CSha256 *p)
|
||||||
{
|
{
|
||||||
UInt32 W[16];
|
UInt32 W[16];
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
UInt32 *state = p->state;
|
||||||
|
|
||||||
#ifdef _SHA256_UNROLL2
|
#ifdef _SHA256_UNROLL2
|
||||||
UInt32 a,b,c,d,e,f,g,h;
|
UInt32 a,b,c,d,e,f,g,h;
|
||||||
a = state[0];
|
a = state[0];
|
||||||
@@ -112,14 +131,15 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
|
|||||||
T[j] = state[j];
|
T[j] = state[j];
|
||||||
#endif
|
#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)
|
for (j = 0; j < 64; j += 16)
|
||||||
{
|
{
|
||||||
#if defined(_SHA256_UNROLL) || defined(_SHA256_UNROLL2)
|
RX_16
|
||||||
RX_8(0); RX_8(8);
|
|
||||||
#else
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < 16; i++) { R(i); }
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _SHA256_UNROLL2
|
#ifdef _SHA256_UNROLL2
|
||||||
@@ -146,61 +166,72 @@ static void Sha256_Transform(UInt32 *state, const UInt32 *data)
|
|||||||
#undef s0
|
#undef s0
|
||||||
#undef s1
|
#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)
|
void Sha256_Update(CSha256 *p, const Byte *data, size_t size)
|
||||||
{
|
{
|
||||||
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
|
if (size == 0)
|
||||||
while (size > 0)
|
return;
|
||||||
|
|
||||||
{
|
{
|
||||||
p->buffer[curBufferPos++] = *data++;
|
unsigned pos = (unsigned)p->count & 0x3F;
|
||||||
p->count++;
|
unsigned num;
|
||||||
size--;
|
|
||||||
if (curBufferPos == 64)
|
p->count += size;
|
||||||
|
|
||||||
|
num = 64 - pos;
|
||||||
|
if (num > size)
|
||||||
|
{
|
||||||
|
memcpy(p->buffer + pos, data, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size -= num;
|
||||||
|
memcpy(p->buffer + pos, data, num);
|
||||||
|
data += num;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
curBufferPos = 0;
|
|
||||||
Sha256_WriteByteBlock(p);
|
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)
|
void Sha256_Final(CSha256 *p, Byte *digest)
|
||||||
{
|
{
|
||||||
UInt64 lenInBits = (p->count << 3);
|
unsigned pos = (unsigned)p->count & 0x3F;
|
||||||
UInt32 curBufferPos = (UInt32)p->count & 0x3F;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
p->buffer[curBufferPos++] = 0x80;
|
|
||||||
while (curBufferPos != (64 - 8))
|
p->buffer[pos++] = 0x80;
|
||||||
|
|
||||||
|
while (pos != (64 - 8))
|
||||||
{
|
{
|
||||||
curBufferPos &= 0x3F;
|
pos &= 0x3F;
|
||||||
if (curBufferPos == 0)
|
if (pos == 0)
|
||||||
Sha256_WriteByteBlock(p);
|
Sha256_WriteByteBlock(p);
|
||||||
p->buffer[curBufferPos++] = 0;
|
p->buffer[pos++] = 0;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
{
|
||||||
p->buffer[curBufferPos++] = (Byte)(lenInBits >> 56);
|
UInt64 numBits = (p->count << 3);
|
||||||
lenInBits <<= 8;
|
SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32));
|
||||||
|
SetBe32(p->buffer + 64 - 4, (UInt32)(numBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
Sha256_WriteByteBlock(p);
|
Sha256_WriteByteBlock(p);
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
*digest++ = (Byte)(p->state[i] >> 24);
|
UInt32 v = p->state[i];
|
||||||
*digest++ = (Byte)(p->state[i] >> 16);
|
SetBe32(digest, v);
|
||||||
*digest++ = (Byte)(p->state[i] >> 8);
|
digest += 4;
|
||||||
*digest++ = (Byte)(p->state[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Sha256_Init(p);
|
Sha256_Init(p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* Threads.c -- multithreading library
|
/* Threads.c -- multithreading library
|
||||||
2013-11-12 : Igor Pavlov : Public domain */
|
2014-09-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#ifndef _WIN32_WCE
|
#ifndef UNDER_CE
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
# 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 BASE RSC /l 0x419 /d "NDEBUG"
|
||||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
@@ -165,6 +165,10 @@ SOURCE=..\..\Bra86.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\BraIA64.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\CpuArch.c
|
SOURCE=..\..\CpuArch.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -173,6 +177,14 @@ SOURCE=..\..\CpuArch.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* 7zMain.c - Test application for 7z Decoder
|
/* 7zMain.c - Test application for 7z Decoder
|
||||||
2015-01-02 : Igor Pavlov : Public domain */
|
2015-05-11 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -34,75 +34,117 @@ static int Buf_EnsureSize(CBuf *dest, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#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 (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
unsigned numAdds;
|
UInt32 val;
|
||||||
UInt32 value;
|
if (src == srcLim)
|
||||||
if (srcPos == srcLen)
|
return size;
|
||||||
|
|
||||||
|
size++;
|
||||||
|
val = *src++;
|
||||||
|
|
||||||
|
if (val < 0x80)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (val < _UTF8_RANGE(1))
|
||||||
{
|
{
|
||||||
*destLen = destPos;
|
size++;
|
||||||
return True;
|
|
||||||
}
|
|
||||||
value = src[srcPos++];
|
|
||||||
if (value < 0x80)
|
|
||||||
{
|
|
||||||
if (dest)
|
|
||||||
dest[destPos] = (char)value;
|
|
||||||
destPos++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (value >= 0xD800 && value < 0xE000)
|
|
||||||
|
if (val >= 0xD800 && val < 0xDC00 && src != srcLim)
|
||||||
{
|
{
|
||||||
UInt32 c2;
|
UInt32 c2 = *src;
|
||||||
if (value >= 0xDC00 || srcPos == srcLen)
|
if (c2 >= 0xDC00 && c2 < 0xE000)
|
||||||
break;
|
|
||||||
c2 = src[srcPos++];
|
|
||||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
|
||||||
break;
|
|
||||||
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
|
||||||
}
|
|
||||||
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--;
|
src++;
|
||||||
if (dest)
|
size += 3;
|
||||||
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
continue;
|
||||||
destPos++;
|
|
||||||
}
|
}
|
||||||
while (numAdds != 0);
|
|
||||||
}
|
}
|
||||||
*destLen = destPos;
|
|
||||||
return False;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
static SRes Utf16_To_Utf8Buf(CBuf *dest, const UInt16 *src, size_t srcLen)
|
||||||
{
|
{
|
||||||
size_t destLen = 0;
|
size_t destLen = Utf16_To_Utf8_Calc(src, src + srcLen);
|
||||||
Bool res;
|
|
||||||
Utf16_To_Utf8(NULL, &destLen, src, srcLen);
|
|
||||||
destLen += 1;
|
destLen += 1;
|
||||||
if (!Buf_EnsureSize(dest, destLen))
|
if (!Buf_EnsureSize(dest, destLen))
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
res = Utf16_To_Utf8(dest->data, &destLen, src, srcLen);
|
*Utf16_To_Utf8(dest->data, src, src + srcLen) = 0;
|
||||||
dest->data[destLen] = 0;
|
return SZ_OK;
|
||||||
return res ? SZ_OK : SZ_ERROR_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
|
static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
|
||||||
#ifdef _WIN32
|
#ifndef _USE_UTF8
|
||||||
, UINT codePage
|
, UINT codePage
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
@@ -110,7 +152,7 @@ static SRes Utf16_To_Char(CBuf *buf, const UInt16 *s
|
|||||||
unsigned len = 0;
|
unsigned len = 0;
|
||||||
for (len = 0; s[len] != 0; len++);
|
for (len = 0; s[len] != 0; len++);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifndef _USE_UTF8
|
||||||
{
|
{
|
||||||
unsigned size = len * 3 + 100;
|
unsigned size = len * 3 + 100;
|
||||||
if (!Buf_EnsureSize(buf, size))
|
if (!Buf_EnsureSize(buf, size))
|
||||||
@@ -191,7 +233,7 @@ static SRes PrintString(const UInt16 *s)
|
|||||||
SRes res;
|
SRes res;
|
||||||
Buf_Init(&buf);
|
Buf_Init(&buf);
|
||||||
res = Utf16_To_Char(&buf, s
|
res = Utf16_To_Char(&buf, s
|
||||||
#ifdef _WIN32
|
#ifndef _USE_UTF8
|
||||||
, CP_OEMCP
|
, CP_OEMCP
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
@@ -281,7 +323,7 @@ static void ConvertFileTimeToString(const CNtfsFileTime *nt, char *s)
|
|||||||
UIntToStr_2(s, sec); s[2] = 0;
|
UIntToStr_2(s, sec); s[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintError(const char *sz)
|
void PrintError(char *sz)
|
||||||
{
|
{
|
||||||
printf("\nERROR: %s\n", sz);
|
printf("\nERROR: %s\n", sz);
|
||||||
}
|
}
|
||||||
@@ -318,6 +360,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
// UInt32 parents[NUM_PARENTS_MAX];
|
// UInt32 parents[NUM_PARENTS_MAX];
|
||||||
|
|
||||||
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
|
printf("\n7z ANSI-C Decoder " MY_VERSION_COPYRIGHT_DATE "\n\n");
|
||||||
|
|
||||||
if (numargs == 1)
|
if (numargs == 1)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
@@ -329,6 +372,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
" x: eXtract files with full paths\n");
|
" x: eXtract files with full paths\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numargs < 3)
|
if (numargs < 3)
|
||||||
{
|
{
|
||||||
PrintError("incorrect command");
|
PrintError("incorrect command");
|
||||||
@@ -364,11 +408,14 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
CrcGenerateTable();
|
CrcGenerateTable();
|
||||||
|
|
||||||
SzArEx_Init(&db);
|
SzArEx_Init(&db);
|
||||||
|
|
||||||
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
char *command = args[1];
|
char *command = args[1];
|
||||||
int listCommand = 0, testCommand = 0, fullPaths = 0;
|
int listCommand = 0, testCommand = 0, fullPaths = 0;
|
||||||
|
|
||||||
if (strcmp(command, "l") == 0) listCommand = 1;
|
if (strcmp(command, "l") == 0) listCommand = 1;
|
||||||
else if (strcmp(command, "t") == 0) testCommand = 1;
|
else if (strcmp(command, "t") == 0) testCommand = 1;
|
||||||
else if (strcmp(command, "e") == 0) { }
|
else if (strcmp(command, "e") == 0) { }
|
||||||
@@ -397,7 +444,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
size_t outSizeProcessed = 0;
|
size_t outSizeProcessed = 0;
|
||||||
// const CSzFileItem *f = db.Files + i;
|
// const CSzFileItem *f = db.Files + i;
|
||||||
size_t len;
|
size_t len;
|
||||||
int isDir = SzArEx_IsDir(&db, i);
|
unsigned isDir = SzArEx_IsDir(&db, i);
|
||||||
if (listCommand == 0 && isDir && !fullPaths)
|
if (listCommand == 0 && isDir && !fullPaths)
|
||||||
continue;
|
continue;
|
||||||
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
len = SzArEx_GetFileNameUtf16(&db, i, NULL);
|
||||||
@@ -433,6 +480,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
|
|
||||||
fileSize = SzArEx_GetFileSize(&db, i);
|
fileSize = SzArEx_GetFileSize(&db, i);
|
||||||
UInt64ToStr(fileSize, s);
|
UInt64ToStr(fileSize, s);
|
||||||
|
|
||||||
if (SzBitWithVals_Check(&db.MTime, i))
|
if (SzBitWithVals_Check(&db.MTime, i))
|
||||||
ConvertFileTimeToString(&db.MTime.Vals[i], t);
|
ConvertFileTimeToString(&db.MTime.Vals[i], t);
|
||||||
else
|
else
|
||||||
@@ -452,6 +500,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(testCommand ?
|
fputs(testCommand ?
|
||||||
"Testing ":
|
"Testing ":
|
||||||
"Extracting ",
|
"Extracting ",
|
||||||
@@ -459,6 +508,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
res = PrintString(temp);
|
res = PrintString(temp);
|
||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
printf("/");
|
printf("/");
|
||||||
else
|
else
|
||||||
@@ -470,6 +520,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
if (res != SZ_OK)
|
if (res != SZ_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!testCommand)
|
if (!testCommand)
|
||||||
{
|
{
|
||||||
CSzFile outFile;
|
CSzFile outFile;
|
||||||
@@ -477,6 +528,7 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
size_t j;
|
size_t j;
|
||||||
UInt16 *name = (UInt16 *)temp;
|
UInt16 *name = (UInt16 *)temp;
|
||||||
const UInt16 *destPath = (const UInt16 *)name;
|
const UInt16 *destPath = (const UInt16 *)name;
|
||||||
|
|
||||||
for (j = 0; name[j] != 0; j++)
|
for (j = 0; name[j] != 0; j++)
|
||||||
if (name[j] == '/')
|
if (name[j] == '/')
|
||||||
{
|
{
|
||||||
@@ -502,19 +554,23 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
processedSize = outSizeProcessed;
|
processedSize = outSizeProcessed;
|
||||||
|
|
||||||
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
|
if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 || processedSize != outSizeProcessed)
|
||||||
{
|
{
|
||||||
PrintError("can not write output file");
|
PrintError("can not write output file");
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (File_Close(&outFile))
|
if (File_Close(&outFile))
|
||||||
{
|
{
|
||||||
PrintError("can not close output file");
|
PrintError("can not close output file");
|
||||||
res = SZ_ERROR_FAIL;
|
res = SZ_ERROR_FAIL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_FILE
|
#ifdef USE_WINDOWS_FILE
|
||||||
if (SzBitWithVals_Check(&db.Attribs, i))
|
if (SzBitWithVals_Check(&db.Attribs, i))
|
||||||
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
|
SetFileAttributesW(destPath, db.Attribs.Vals[i]);
|
||||||
@@ -525,15 +581,18 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
IAlloc_Free(&allocImp, outBuffer);
|
IAlloc_Free(&allocImp, outBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SzArEx_Free(&db, &allocImp);
|
SzArEx_Free(&db, &allocImp);
|
||||||
SzFree(NULL, temp);
|
SzFree(NULL, temp);
|
||||||
|
|
||||||
File_Close(&archiveStream.file);
|
File_Close(&archiveStream.file);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
printf("\nEverything is Ok\n");
|
printf("\nEverything is Ok\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == SZ_ERROR_UNSUPPORTED)
|
if (res == SZ_ERROR_UNSUPPORTED)
|
||||||
PrintError("decoder doesn't support this archive");
|
PrintError("decoder doesn't support this archive");
|
||||||
else if (res == SZ_ERROR_MEM)
|
else if (res == SZ_ERROR_MEM)
|
||||||
@@ -542,5 +601,6 @@ int MY_CDECL main(int numargs, char *args[])
|
|||||||
PrintError("CRC error");
|
PrintError("CRC error");
|
||||||
else
|
else
|
||||||
printf("\nERROR #%d\n", res);
|
printf("\nERROR #%d\n", res);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# MY_STATIC_LINK=1
|
|
||||||
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
|
CFLAGS = $(CFLAGS) -D_7ZIP_PPMD_SUPPPORT
|
||||||
|
|
||||||
PROG = 7zDec.exe
|
PROG = 7zDec.exe
|
||||||
@@ -15,7 +14,9 @@ C_OBJS = \
|
|||||||
$O\Bcj2.obj \
|
$O\Bcj2.obj \
|
||||||
$O\Bra.obj \
|
$O\Bra.obj \
|
||||||
$O\Bra86.obj \
|
$O\Bra86.obj \
|
||||||
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
|
$O\Delta.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
$O\Ppmd7.obj \
|
$O\Ppmd7.obj \
|
||||||
|
|||||||
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 |
1452
C/Util/7zipInstall/7zipInstall.c
Normal file
1452
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
|
/* LzmaUtil.c -- Test application for LZMA compression
|
||||||
2014-12-31 : Igor Pavlov : Public domain */
|
2015-06-13 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "../../Precomp.h"
|
#include "../../Precomp.h"
|
||||||
|
|
||||||
@@ -18,10 +18,6 @@ const char *kCantWriteMessage = "Can not write output file";
|
|||||||
const char *kCantAllocateMessage = "Can not allocate memory";
|
const char *kCantAllocateMessage = "Can not allocate memory";
|
||||||
const char *kDataErrorMessage = "Data error";
|
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)
|
void PrintHelp(char *buffer)
|
||||||
{
|
{
|
||||||
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
|
strcat(buffer, "\nLZMA Utility " MY_VERSION_COPYRIGHT_DATE "\n"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* SfxSetup.c - 7z SFX Setup
|
/* SfxSetup.c - 7z SFX Setup
|
||||||
2014-12-07 : Igor Pavlov : Public domain */
|
2015-03-25 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#define k_EXE_ExtIndex 2
|
#define k_EXE_ExtIndex 2
|
||||||
|
|
||||||
static const char *kExts[] =
|
static const char * const kExts[] =
|
||||||
{
|
{
|
||||||
"bat"
|
"bat"
|
||||||
, "cmd"
|
, "cmd"
|
||||||
@@ -37,7 +37,7 @@ static const char *kExts[] =
|
|||||||
, "htm"
|
, "htm"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *kNames[] =
|
static const char * const kNames[] =
|
||||||
{
|
{
|
||||||
"setup"
|
"setup"
|
||||||
, "install"
|
, "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)))
|
#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;
|
unsigned i;
|
||||||
for (i = 0; i < num; 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;
|
continue;
|
||||||
for (j = 0; j < len; j++)
|
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])
|
if (c != s[j] && MAKE_CHAR_UPPER(c) != s[j])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -182,6 +182,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
|
|||||||
path[len] = L'\0';
|
path[len] = L'\0';
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (wcscmp(fd.cFileName, L".") != 0 &&
|
if (wcscmp(fd.cFileName, L".") != 0 &&
|
||||||
@@ -199,9 +200,11 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
|
|||||||
if (DeleteFileW(path) == 0)
|
if (DeleteFileW(path) == 0)
|
||||||
res = GetLastError();
|
res = GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res != 0)
|
if (res != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FindNextFileW(handle, &fd))
|
if (!FindNextFileW(handle, &fd))
|
||||||
{
|
{
|
||||||
res = GetLastError();
|
res = GetLastError();
|
||||||
@@ -210,6 +213,7 @@ static WRes RemoveDirWithSubItems(WCHAR *path)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
path[len] = L'\0';
|
path[len] = L'\0';
|
||||||
FindClose(handle);
|
FindClose(handle);
|
||||||
if (res == 0)
|
if (res == 0)
|
||||||
@@ -248,6 +252,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
const wchar_t *cmdLineParams;
|
const wchar_t *cmdLineParams;
|
||||||
const char *errorMessage = NULL;
|
const char *errorMessage = NULL;
|
||||||
Bool useShellExecute = True;
|
Bool useShellExecute = True;
|
||||||
|
DWORD exitCode = 0;
|
||||||
|
|
||||||
#ifdef _CONSOLE
|
#ifdef _CONSOLE
|
||||||
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
|
||||||
@@ -315,7 +320,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
{
|
{
|
||||||
unsigned t = value & 0xF;
|
unsigned t = value & 0xF;
|
||||||
value >>= 4;
|
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';
|
s[k] = '\0';
|
||||||
}
|
}
|
||||||
@@ -584,6 +589,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
if (hProcess != 0)
|
if (hProcess != 0)
|
||||||
{
|
{
|
||||||
WaitForSingleObject(hProcess, INFINITE);
|
WaitForSingleObject(hProcess, INFINITE);
|
||||||
|
if (!GetExitCodeProcess(hProcess, &exitCode))
|
||||||
|
exitCode = 1;
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,7 +603,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
RemoveDirWithSubItems(path);
|
RemoveDirWithSubItems(path);
|
||||||
|
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
return 0;
|
return (int)exitCode;
|
||||||
|
|
||||||
{
|
{
|
||||||
if (res == SZ_ERROR_UNSUPPORTED)
|
if (res == SZ_ERROR_UNSUPPORTED)
|
||||||
@@ -610,6 +617,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
if (!errorMessage)
|
if (!errorMessage)
|
||||||
errorMessage = "ERROR";
|
errorMessage = "ERROR";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMessage)
|
if (errorMessage)
|
||||||
PrintErrorMessage(errorMessage);
|
PrintErrorMessage(errorMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,6 +167,10 @@ SOURCE=..\..\Bra86.c
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=..\..\BraIA64.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=..\..\CpuArch.c
|
SOURCE=..\..\CpuArch.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -175,6 +179,14 @@ SOURCE=..\..\CpuArch.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=..\..\Lzma2Dec.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ C_OBJS = \
|
|||||||
$O\Bcj2.obj \
|
$O\Bcj2.obj \
|
||||||
$O\Bra.obj \
|
$O\Bra.obj \
|
||||||
$O\Bra86.obj \
|
$O\Bra86.obj \
|
||||||
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
|
$O\Delta.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ C_OBJS = \
|
|||||||
$O\Bcj2.obj \
|
$O\Bcj2.obj \
|
||||||
$O\Bra.obj \
|
$O\Bra.obj \
|
||||||
$O\Bra86.obj \
|
$O\Bra86.obj \
|
||||||
|
$O\BraIA64.obj \
|
||||||
$O\CpuArch.obj \
|
$O\CpuArch.obj \
|
||||||
|
$O\Delta.obj \
|
||||||
$O\Lzma2Dec.obj \
|
$O\Lzma2Dec.obj \
|
||||||
$O\LzmaDec.obj \
|
$O\LzmaDec.obj \
|
||||||
|
|
||||||
|
|||||||
10
C/Xz.c
10
C/Xz.c
@@ -1,5 +1,5 @@
|
|||||||
/* Xz.c - Xz
|
/* Xz.c - Xz
|
||||||
2009-04-15 : Igor Pavlov : Public domain */
|
2015-05-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
#include "Xz.h"
|
#include "Xz.h"
|
||||||
#include "XzCrc64.h"
|
#include "XzCrc64.h"
|
||||||
|
|
||||||
Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 };
|
const 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_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' };
|
||||||
|
|
||||||
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
|
unsigned Xz_WriteVarInt(Byte *buf, UInt64 v)
|
||||||
{
|
{
|
||||||
@@ -40,11 +40,11 @@ void Xz_Free(CXzStream *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
|
unsigned XzFlags_GetCheckSize(CXzStreamFlags f)
|
||||||
{
|
{
|
||||||
int t = XzFlags_GetCheckType(f);
|
unsigned t = XzFlags_GetCheckType(f);
|
||||||
return (t == 0) ? 0 : (4 << ((t - 1) / 3));
|
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;
|
p->mode = mode;
|
||||||
switch (mode)
|
switch (mode)
|
||||||
|
|||||||
14
C/Xz.h
14
C/Xz.h
@@ -1,5 +1,5 @@
|
|||||||
/* Xz.h - Xz interface
|
/* Xz.h - Xz interface
|
||||||
2014-12-30 : Igor Pavlov : Public domain */
|
2015-05-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#ifndef __XZ_H
|
#ifndef __XZ_H
|
||||||
#define __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_SIG_SIZE 6
|
||||||
#define XZ_FOOTER_SIG_SIZE 2
|
#define XZ_FOOTER_SIG_SIZE 2
|
||||||
|
|
||||||
extern Byte XZ_SIG[XZ_SIG_SIZE];
|
extern const Byte XZ_SIG[XZ_SIG_SIZE];
|
||||||
extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
|
extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
|
||||||
|
|
||||||
#define XZ_STREAM_FLAGS_SIZE 2
|
#define XZ_STREAM_FLAGS_SIZE 2
|
||||||
#define XZ_STREAM_CRC_SIZE 4
|
#define XZ_STREAM_CRC_SIZE 4
|
||||||
@@ -76,13 +76,13 @@ extern Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE];
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int mode;
|
unsigned mode;
|
||||||
UInt32 crc;
|
UInt32 crc;
|
||||||
UInt64 crc64;
|
UInt64 crc64;
|
||||||
CSha256 sha;
|
CSha256 sha;
|
||||||
} CXzCheck;
|
} 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);
|
void XzCheck_Update(CXzCheck *p, const void *data, size_t size);
|
||||||
int XzCheck_Final(CXzCheck *p, Byte *digest);
|
int XzCheck_Final(CXzCheck *p, Byte *digest);
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
ISzAlloc *alloc;
|
ISzAlloc *alloc;
|
||||||
Byte *buf;
|
Byte *buf;
|
||||||
int numCoders;
|
unsigned numCoders;
|
||||||
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
|
int finished[MIXCODER_NUM_FILTERS_MAX - 1];
|
||||||
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
|
size_t pos[MIXCODER_NUM_FILTERS_MAX - 1];
|
||||||
size_t size[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_Construct(CMixCoder *p, ISzAlloc *alloc);
|
||||||
void MixCoder_Free(CMixCoder *p);
|
void MixCoder_Free(CMixCoder *p);
|
||||||
void MixCoder_Init(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,
|
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
||||||
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
const Byte *src, SizeT *srcLen, int srcWasFinished,
|
||||||
ECoderFinishMode finishMode, ECoderStatus *status);
|
ECoderFinishMode finishMode, ECoderStatus *status);
|
||||||
|
|||||||
24
C/XzCrc64.c
24
C/XzCrc64.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzCrc64.c -- CRC64 calculation
|
/* XzCrc64.c -- CRC64 calculation
|
||||||
2011-06-28 : Igor Pavlov : Public domain */
|
2015-03-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -13,14 +13,15 @@
|
|||||||
#else
|
#else
|
||||||
#define CRC_NUM_TABLES 5
|
#define CRC_NUM_TABLES 5
|
||||||
#define CRC_UINT64_SWAP(v) \
|
#define CRC_UINT64_SWAP(v) \
|
||||||
((v >> 56) | \
|
((v >> 56) \
|
||||||
((v >> 40) & ((UInt64)0xFF << 8)) | \
|
| ((v >> 40) & ((UInt64)0xFF << 8)) \
|
||||||
((v >> 24) & ((UInt64)0xFF << 16)) | \
|
| ((v >> 24) & ((UInt64)0xFF << 16)) \
|
||||||
((v >> 8) & ((UInt64)0xFF << 24)) | \
|
| ((v >> 8) & ((UInt64)0xFF << 24)) \
|
||||||
((v << 8) & ((UInt64)0xFF << 32)) | \
|
| ((v << 8) & ((UInt64)0xFF << 32)) \
|
||||||
((v << 24) & ((UInt64)0xFF << 40)) | \
|
| ((v << 24) & ((UInt64)0xFF << 40)) \
|
||||||
((v << 40) & ((UInt64)0xFF << 48)) | \
|
| ((v << 40) & ((UInt64)0xFF << 48)) \
|
||||||
(v << 56))
|
| ((v << 56)))
|
||||||
|
|
||||||
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
|
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -64,11 +65,6 @@ void MY_FAST_CALL Crc64GenerateTable()
|
|||||||
|
|
||||||
g_Crc64Update = XzCrc64UpdateT4;
|
g_Crc64Update = XzCrc64UpdateT4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
#ifndef MY_CPU_BE
|
#ifndef MY_CPU_BE
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
/* XzCrc64Opt.c -- CRC64 calculation
|
/* XzCrc64Opt.c -- CRC64 calculation
|
||||||
2011-06-28 : Igor Pavlov : Public domain */
|
2015-03-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
#include "CpuArch.h"
|
#include "CpuArch.h"
|
||||||
|
|
||||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
|
||||||
|
|
||||||
#ifndef MY_CPU_BE
|
#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)
|
UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
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)
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
{
|
{
|
||||||
UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
|
UInt32 d = (UInt32)v ^ *(const UInt32 *)p;
|
||||||
v = (v >> 32) ^
|
v = (v >> 32)
|
||||||
table[0x300 + ((d ) & 0xFF)] ^
|
^ table[0x300 + ((d ) & 0xFF)]
|
||||||
table[0x200 + ((d >> 8) & 0xFF)] ^
|
^ table[0x200 + ((d >> 8) & 0xFF)]
|
||||||
table[0x100 + ((d >> 16) & 0xFF)] ^
|
^ table[0x100 + ((d >> 16) & 0xFF)]
|
||||||
table[0x000 + ((d >> 24))];
|
^ table[0x000 + ((d >> 24))];
|
||||||
}
|
}
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *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
|
#ifndef MY_CPU_LE
|
||||||
|
|
||||||
#define CRC_UINT64_SWAP(v) \
|
#define CRC_UINT64_SWAP(v) \
|
||||||
((v >> 56) | \
|
((v >> 56) \
|
||||||
((v >> 40) & ((UInt64)0xFF << 8)) | \
|
| ((v >> 40) & ((UInt64)0xFF << 8)) \
|
||||||
((v >> 24) & ((UInt64)0xFF << 16)) | \
|
| ((v >> 24) & ((UInt64)0xFF << 16)) \
|
||||||
((v >> 8) & ((UInt64)0xFF << 24)) | \
|
| ((v >> 8) & ((UInt64)0xFF << 24)) \
|
||||||
((v << 8) & ((UInt64)0xFF << 32)) | \
|
| ((v << 8) & ((UInt64)0xFF << 32)) \
|
||||||
((v << 24) & ((UInt64)0xFF << 40)) | \
|
| ((v << 24) & ((UInt64)0xFF << 40)) \
|
||||||
((v << 40) & ((UInt64)0xFF << 48)) | \
|
| ((v << 40) & ((UInt64)0xFF << 48)) \
|
||||||
(v << 56))
|
| ((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)
|
UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table)
|
||||||
{
|
{
|
||||||
const Byte *p = (const Byte *)data;
|
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;
|
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)
|
for (; size >= 4; size -= 4, p += 4)
|
||||||
{
|
{
|
||||||
UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
|
UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)p;
|
||||||
v = (v << 32) ^
|
v = (v << 32)
|
||||||
table[0x000 + ((d ) & 0xFF)] ^
|
^ table[0x000 + ((d ) & 0xFF)]
|
||||||
table[0x100 + ((d >> 8) & 0xFF)] ^
|
^ table[0x100 + ((d >> 8) & 0xFF)]
|
||||||
table[0x200 + ((d >> 16) & 0xFF)] ^
|
^ table[0x200 + ((d >> 16) & 0xFF)]
|
||||||
table[0x300 + ((d >> 24))];
|
^ table[0x300 + ((d >> 24))];
|
||||||
}
|
}
|
||||||
table -= 0x100;
|
|
||||||
v = CRC_UINT64_SWAP(v);
|
|
||||||
for (; size > 0; size--, p++)
|
for (; size > 0; size--, p++)
|
||||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
v = CRC_UPDATE_BYTE_2_BE(v, *p);
|
||||||
return v;
|
return CRC_UINT64_SWAP(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
54
C/XzDec.c
54
C/XzDec.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzDec.c -- Xz Decode
|
/* XzDec.c -- Xz Decode
|
||||||
2014-12-30 : Igor Pavlov : Public domain */
|
2015-05-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -32,9 +32,9 @@
|
|||||||
|
|
||||||
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
|
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
|
||||||
{
|
{
|
||||||
int i, limit;
|
unsigned i, limit;
|
||||||
*value = 0;
|
*value = 0;
|
||||||
limit = (maxSize > 9) ? 9 : (int)maxSize;
|
limit = (maxSize > 9) ? 9 : (unsigned)maxSize;
|
||||||
|
|
||||||
for (i = 0; i < limit;)
|
for (i = 0; i < limit;)
|
||||||
{
|
{
|
||||||
@@ -66,12 +66,12 @@ typedef struct
|
|||||||
Byte buf[BRA_BUF_SIZE];
|
Byte buf[BRA_BUF_SIZE];
|
||||||
} CBraState;
|
} CBraState;
|
||||||
|
|
||||||
void BraState_Free(void *pp, ISzAlloc *alloc)
|
static void BraState_Free(void *pp, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
alloc->Free(alloc, pp);
|
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);
|
CBraState *p = ((CBraState *)pp);
|
||||||
alloc = alloc;
|
alloc = alloc;
|
||||||
@@ -87,7 +87,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
|
|||||||
if (propSize == 4)
|
if (propSize == 4)
|
||||||
{
|
{
|
||||||
UInt32 v = GetUi32(props);
|
UInt32 v = GetUi32(props);
|
||||||
switch(p->methodId)
|
switch (p->methodId)
|
||||||
{
|
{
|
||||||
case XZ_ID_PPC:
|
case XZ_ID_PPC:
|
||||||
case XZ_ID_ARM:
|
case XZ_ID_ARM:
|
||||||
@@ -112,7 +112,7 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
|
|||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BraState_Init(void *pp)
|
static void BraState_Init(void *pp)
|
||||||
{
|
{
|
||||||
CBraState *p = ((CBraState *)pp);
|
CBraState *p = ((CBraState *)pp);
|
||||||
p->bufPos = p->bufConv = p->bufTotal = 0;
|
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)
|
if (p->bufTotal == 0)
|
||||||
break;
|
break;
|
||||||
switch(p->methodId)
|
switch (p->methodId)
|
||||||
{
|
{
|
||||||
case XZ_ID_Delta:
|
case XZ_ID_Delta:
|
||||||
if (p->encodeMode)
|
if (p->encodeMode)
|
||||||
@@ -235,7 +235,7 @@ static void SbState_Free(void *pp, ISzAlloc *alloc)
|
|||||||
|
|
||||||
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
pp = pp;
|
UNUSED_VAR(pp);
|
||||||
props = props;
|
props = props;
|
||||||
alloc = alloc;
|
alloc = alloc;
|
||||||
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
|
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
|
||||||
@@ -330,9 +330,9 @@ static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
|
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
p->alloc = alloc;
|
p->alloc = alloc;
|
||||||
p->buf = 0;
|
p->buf = NULL;
|
||||||
p->numCoders = 0;
|
p->numCoders = 0;
|
||||||
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
|
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
|
||||||
p->coders[i].p = NULL;
|
p->coders[i].p = NULL;
|
||||||
@@ -340,7 +340,7 @@ void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
|
|||||||
|
|
||||||
void MixCoder_Free(CMixCoder *p)
|
void MixCoder_Free(CMixCoder *p)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
for (i = 0; i < p->numCoders; i++)
|
for (i = 0; i < p->numCoders; i++)
|
||||||
{
|
{
|
||||||
IStateCoder *sc = &p->coders[i];
|
IStateCoder *sc = &p->coders[i];
|
||||||
@@ -351,14 +351,14 @@ void MixCoder_Free(CMixCoder *p)
|
|||||||
if (p->buf)
|
if (p->buf)
|
||||||
{
|
{
|
||||||
p->alloc->Free(p->alloc, 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)
|
void MixCoder_Init(CMixCoder *p)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
for (i = 0; i < p->numCoders - 1; i++)
|
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++)
|
||||||
{
|
{
|
||||||
p->size[i] = 0;
|
p->size[i] = 0;
|
||||||
p->pos[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];
|
IStateCoder *sc = &p->coders[coderIndex];
|
||||||
p->ids[coderIndex] = methodId;
|
p->ids[coderIndex] = methodId;
|
||||||
switch(methodId)
|
switch (methodId)
|
||||||
{
|
{
|
||||||
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
|
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
|
||||||
#ifdef USE_SUBBLOCK
|
#ifdef USE_SUBBLOCK
|
||||||
@@ -398,10 +398,10 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
*srcLen = 0;
|
*srcLen = 0;
|
||||||
*status = CODER_STATUS_NOT_FINISHED;
|
*status = CODER_STATUS_NOT_FINISHED;
|
||||||
|
|
||||||
if (p->buf == 0)
|
if (!p->buf)
|
||||||
{
|
{
|
||||||
p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
|
||||||
if (p->buf == 0)
|
if (!p->buf)
|
||||||
return SZ_ERROR_MEM;
|
return SZ_ERROR_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
Bool processed = False;
|
Bool processed = False;
|
||||||
int i;
|
unsigned i;
|
||||||
/*
|
/*
|
||||||
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
|
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
|
||||||
break;
|
break;
|
||||||
@@ -520,8 +520,8 @@ static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *b
|
|||||||
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
||||||
{
|
{
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
int numFilters, i;
|
unsigned numFilters, i;
|
||||||
UInt32 headerSize = (UInt32)header[0] << 2;
|
unsigned headerSize = (unsigned)header[0] << 2;
|
||||||
|
|
||||||
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
|
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
@@ -557,7 +557,7 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
|
|||||||
#ifdef XZ_DUMP
|
#ifdef XZ_DUMP
|
||||||
printf("\nf[%d] = %2X: ", i, filter->id);
|
printf("\nf[%d] = %2X: ", i, filter->id);
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
printf(" %2X", filter->props[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)
|
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned i;
|
||||||
Bool needReInit = True;
|
Bool needReInit = True;
|
||||||
int numFilters = XzBlock_GetNumFilters(block);
|
unsigned numFilters = XzBlock_GetNumFilters(block);
|
||||||
|
|
||||||
if (numFilters == p->numCoders)
|
if (numFilters == p->numCoders)
|
||||||
{
|
{
|
||||||
for (i = 0; i < numFilters; i++)
|
for (i = 0; i < numFilters; i++)
|
||||||
@@ -582,6 +583,7 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
|
|||||||
break;
|
break;
|
||||||
needReInit = (i != numFilters);
|
needReInit = (i != numFilters);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needReInit)
|
if (needReInit)
|
||||||
{
|
{
|
||||||
MixCoder_Free(p);
|
MixCoder_Free(p);
|
||||||
@@ -592,12 +594,14 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
|
|||||||
RINOK(MixCoder_SetFromMethod(p, i, f->id));
|
RINOK(MixCoder_SetFromMethod(p, i, f->id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numFilters; i++)
|
for (i = 0; i < numFilters; i++)
|
||||||
{
|
{
|
||||||
const CXzFilter *f = &block->filters[numFilters - 1 - i];
|
const CXzFilter *f = &block->filters[numFilters - 1 - i];
|
||||||
IStateCoder *sc = &p->coders[i];
|
IStateCoder *sc = &p->coders[i];
|
||||||
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
|
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
|
||||||
}
|
}
|
||||||
|
|
||||||
MixCoder_Init(p);
|
MixCoder_Init(p);
|
||||||
return SZ_OK;
|
return SZ_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
23
C/XzEnc.c
23
C/XzEnc.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzEnc.c -- Xz Encode
|
/* XzEnc.c -- Xz Encode
|
||||||
2014-12-30 : Igor Pavlov : Public domain */
|
2015-05-01 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -18,14 +18,6 @@
|
|||||||
|
|
||||||
#include "XzEnc.h"
|
#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_ClearFlags(p) (p)->flags = 0;
|
||||||
#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);
|
#define XzBlock_SetNumFilters(p, n) (p)->flags |= ((n) - 1);
|
||||||
#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE;
|
#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE;
|
||||||
@@ -59,12 +51,13 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
|||||||
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
|
Byte header[XZ_BLOCK_HEADER_SIZE_MAX];
|
||||||
|
|
||||||
unsigned pos = 1;
|
unsigned pos = 1;
|
||||||
int numFilters, i;
|
unsigned numFilters, i;
|
||||||
header[pos++] = p->flags;
|
header[pos++] = p->flags;
|
||||||
|
|
||||||
if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
|
if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize);
|
||||||
if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
|
if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize);
|
||||||
numFilters = XzBlock_GetNumFilters(p);
|
numFilters = XzBlock_GetNumFilters(p);
|
||||||
|
|
||||||
for (i = 0; i < numFilters; i++)
|
for (i = 0; i < numFilters; i++)
|
||||||
{
|
{
|
||||||
const CXzFilter *f = &p->filters[i];
|
const CXzFilter *f = &p->filters[i];
|
||||||
@@ -73,8 +66,10 @@ SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStream *s)
|
|||||||
memcpy(header + pos, f->props, f->propsSize);
|
memcpy(header + pos, f->props, f->propsSize);
|
||||||
pos += f->propsSize;
|
pos += f->propsSize;
|
||||||
}
|
}
|
||||||
while((pos & 3) != 0)
|
|
||||||
|
while ((pos & 3) != 0)
|
||||||
header[pos++] = 0;
|
header[pos++] = 0;
|
||||||
|
|
||||||
header[0] = (Byte)(pos >> 2);
|
header[0] = (Byte)(pos >> 2);
|
||||||
SetUi32(header + pos, CrcCalc(header, pos));
|
SetUi32(header + pos, CrcCalc(header, pos));
|
||||||
return WriteBytes(s, header, pos + 4);
|
return WriteBytes(s, header, pos + 4);
|
||||||
@@ -163,13 +158,13 @@ typedef struct
|
|||||||
CXzCheck check;
|
CXzCheck check;
|
||||||
} CSeqCheckInStream;
|
} CSeqCheckInStream;
|
||||||
|
|
||||||
void SeqCheckInStream_Init(CSeqCheckInStream *p, int mode)
|
static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned mode)
|
||||||
{
|
{
|
||||||
p->processed = 0;
|
p->processed = 0;
|
||||||
XzCheck_Init(&p->check, mode);
|
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);
|
XzCheck_Final(&p->check, digest);
|
||||||
}
|
}
|
||||||
@@ -408,7 +403,7 @@ static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
|
|||||||
CSeqCheckInStream checkInStream;
|
CSeqCheckInStream checkInStream;
|
||||||
CSeqSizeOutStream seqSizeOutStream;
|
CSeqSizeOutStream seqSizeOutStream;
|
||||||
CXzBlock block;
|
CXzBlock block;
|
||||||
int filterIndex = 0;
|
unsigned filterIndex = 0;
|
||||||
CXzFilter *filter = NULL;
|
CXzFilter *filter = NULL;
|
||||||
const CXzFilterProps *fp = props->filterProps;
|
const CXzFilterProps *fp = props->filterProps;
|
||||||
|
|
||||||
|
|||||||
67
C/XzIn.c
67
C/XzIn.c
@@ -1,5 +1,5 @@
|
|||||||
/* XzIn.c - Xz input
|
/* XzIn.c - Xz input
|
||||||
2014-12-30 : Igor Pavlov : Public domain */
|
2015-04-21 : Igor Pavlov : Public domain */
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
|
|
||||||
@@ -134,55 +134,58 @@ static SRes Xz_ReadIndex(CXzStream *p, ILookInStream *stream, UInt64 indexSize,
|
|||||||
return res;
|
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)
|
static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOffset, ISzAlloc *alloc)
|
||||||
{
|
{
|
||||||
UInt64 indexSize;
|
UInt64 indexSize;
|
||||||
Byte buf[XZ_STREAM_FOOTER_SIZE];
|
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;
|
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)
|
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
||||||
{
|
{
|
||||||
UInt32 total = 0;
|
UInt32 total = 0;
|
||||||
*startOffset += XZ_STREAM_FOOTER_SIZE;
|
pos += XZ_STREAM_FOOTER_SIZE;
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
#define TEMP_BUF_SIZE (1 << 10)
|
#define TEMP_BUF_SIZE (1 << 10)
|
||||||
Byte tempBuf[TEMP_BUF_SIZE];
|
Byte temp[TEMP_BUF_SIZE];
|
||||||
if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
|
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos;
|
||||||
i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
|
pos -= i;
|
||||||
|
RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i));
|
||||||
total += (UInt32)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--)
|
for (; i != 0; i--)
|
||||||
if (tempBuf[i - 1] != 0)
|
if (temp[i - 1] != 0)
|
||||||
break;
|
break;
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
if ((i & 3) != 0)
|
if ((i & 3) != 0)
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
*startOffset += i;
|
pos += i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
|
||||||
if (*startOffset < XZ_STREAM_FOOTER_SIZE)
|
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
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));
|
if (pos < XZ_STREAM_FOOTER_SIZE)
|
||||||
|
return 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)
|
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
|
||||||
return SZ_ERROR_NO_ARCHIVE;
|
return SZ_ERROR_NO_ARCHIVE;
|
||||||
}
|
}
|
||||||
@@ -197,20 +200,22 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
|
|||||||
|
|
||||||
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
|
indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2;
|
||||||
|
|
||||||
*startOffset = -(Int64)(indexSize + XZ_STREAM_FOOTER_SIZE);
|
if (pos < indexSize)
|
||||||
RINOK(SeekFromCur(stream, startOffset));
|
return SZ_ERROR_ARCHIVE;
|
||||||
|
|
||||||
|
pos -= indexSize;
|
||||||
|
RINOK(LookInStream_SeekTo(stream, pos));
|
||||||
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
|
RINOK(Xz_ReadIndex(p, stream, indexSize, alloc));
|
||||||
|
|
||||||
{
|
{
|
||||||
UInt64 totalSize = Xz_GetPackSize(p);
|
UInt64 totalSize = Xz_GetPackSize(p);
|
||||||
UInt64 sum = XZ_STREAM_HEADER_SIZE + totalSize + indexSize;
|
if (totalSize == XZ_SIZE_OVERFLOW
|
||||||
if (totalSize == XZ_SIZE_OVERFLOW ||
|
|| totalSize >= ((UInt64)1 << 63)
|
||||||
sum >= ((UInt64)1 << 63) ||
|
|| pos < totalSize + XZ_STREAM_HEADER_SIZE)
|
||||||
totalSize >= ((UInt64)1 << 63))
|
|
||||||
return SZ_ERROR_ARCHIVE;
|
return SZ_ERROR_ARCHIVE;
|
||||||
*startOffset = -(Int64)sum;
|
pos -= (totalSize + XZ_STREAM_HEADER_SIZE);
|
||||||
RINOK(SeekFromCur(stream, startOffset));
|
RINOK(LookInStream_SeekTo(stream, pos));
|
||||||
|
*startOffset = pos;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CXzStreamFlags headerFlags;
|
CXzStreamFlags headerFlags;
|
||||||
@@ -299,7 +304,7 @@ SRes Xzs_ReadBackward(CXzs *p, ILookInStream *stream, Int64 *startOffset, ICompr
|
|||||||
p->streams[p->num++] = st;
|
p->streams[p->num++] = st;
|
||||||
if (*startOffset == 0)
|
if (*startOffset == 0)
|
||||||
break;
|
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)
|
if (progress && progress->Progress(progress, endOffset - *startOffset, (UInt64)(Int64)-1) != SZ_OK)
|
||||||
return SZ_ERROR_PROGRESS;
|
return SZ_ERROR_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -350,14 +350,6 @@ SOURCE=..\Common\CoderMixer2.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin 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
|
SOURCE=..\Common\CrossThreadProgress.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|||||||
@@ -9,37 +9,62 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
struct CMethodFull: public CProps
|
struct CMethodFull: public CMethodProps
|
||||||
{
|
{
|
||||||
CMethodId Id;
|
CMethodId Id;
|
||||||
UInt32 NumInStreams;
|
UInt32 NumStreams;
|
||||||
UInt32 NumOutStreams;
|
|
||||||
|
|
||||||
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 OutCoder;
|
||||||
UInt32 OutStream;
|
UInt32 OutStream;
|
||||||
|
UInt32 InCoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CCompressionMethodMode
|
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;
|
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
|
#ifndef _7ZIP_ST
|
||||||
UInt32 NumThreads;
|
UInt32 NumThreads;
|
||||||
|
bool MultiThreadMixer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool PasswordIsDefined;
|
bool PasswordIsDefined;
|
||||||
UString Password;
|
UString Password;
|
||||||
|
|
||||||
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
|
||||||
CCompressionMethodMode(): PasswordIsDefined(false)
|
CCompressionMethodMode():
|
||||||
|
DefaultMethod_was_Inserted(false),
|
||||||
|
Filter_was_Inserted(false),
|
||||||
|
PasswordIsDefined(false)
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, NumThreads(1)
|
, NumThreads(1)
|
||||||
|
, MultiThreadMixer(true)
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
#include "../../Common/LimitedStreams.h"
|
#include "../../Common/LimitedStreams.h"
|
||||||
#include "../../Common/LockedStream.h"
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
#include "../../Common/ProgressUtils.h"
|
||||||
#include "../../Common/StreamObjects.h"
|
#include "../../Common/StreamObjects.h"
|
||||||
|
|
||||||
@@ -12,50 +11,70 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static void ConvertFolderItemInfoToBindInfo(const CFolder &folder,
|
class CDecProgress:
|
||||||
CBindInfoEx &bindInfo)
|
public ICompressProgressInfo,
|
||||||
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
bindInfo.Clear();
|
CMyComPtr<ICompressProgressInfo> _progress;
|
||||||
bindInfo.BindPairs.ClearAndSetSize(folder.BindPairs.Size());
|
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;
|
unsigned i;
|
||||||
for (i = 0; i < folder.BindPairs.Size(); i++)
|
for (i = 0; i < folder.Bonds.Size(); i++)
|
||||||
{
|
{
|
||||||
NCoderMixer::CBindPair &bindPair = bindInfo.BindPairs[i];
|
NCoderMixer2::CBond &bond = bi.Bonds[i];
|
||||||
bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex;
|
const N7z::CBond &folderBond = folder.Bonds[i];
|
||||||
bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex;
|
bond.PackIndex = folderBond.PackIndex;
|
||||||
|
bond.UnpackIndex = folderBond.UnpackIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bindInfo.Coders.ClearAndSetSize(folder.Coders.Size());
|
bi.Coders.ClearAndSetSize(folder.Coders.Size());
|
||||||
bindInfo.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size());
|
bi.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size());
|
||||||
|
|
||||||
UInt32 outStreamIndex = 0;
|
|
||||||
for (i = 0; i < folder.Coders.Size(); i++)
|
for (i = 0; i < folder.Coders.Size(); i++)
|
||||||
{
|
{
|
||||||
NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
|
|
||||||
const CCoderInfo &coderInfo = folder.Coders[i];
|
const CCoderInfo &coderInfo = folder.Coders[i];
|
||||||
coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams;
|
bi.Coders[i].NumStreams = coderInfo.NumStreams;
|
||||||
coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams;
|
bi.CoderMethodIDs[i] = coderInfo.MethodID;
|
||||||
bindInfo.CoderMethodIDs[i] = coderInfo.MethodID;
|
|
||||||
for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++)
|
|
||||||
if (folder.FindBindPairForOutStream(outStreamIndex) < 0)
|
|
||||||
bindInfo.OutStreams.Add(outStreamIndex);
|
|
||||||
}
|
}
|
||||||
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++)
|
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,
|
static inline bool AreCodersEqual(
|
||||||
const NCoderMixer::CCoderStreamsInfo &a2)
|
const NCoderMixer2::CCoderStreamsInfo &a1,
|
||||||
|
const NCoderMixer2::CCoderStreamsInfo &a2)
|
||||||
{
|
{
|
||||||
return (a1.NumInStreams == a2.NumInStreams) &&
|
return (a1.NumStreams == a2.NumStreams);
|
||||||
(a1.NumOutStreams == a2.NumOutStreams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) &&
|
return
|
||||||
(a1.OutIndex == a2.OutIndex);
|
(a1.PackIndex == a2.PackIndex) &&
|
||||||
|
(a1.UnpackIndex == a2.UnpackIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
||||||
@@ -66,186 +85,284 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2)
|
|||||||
for (i = 0; i < a1.Coders.Size(); i++)
|
for (i = 0; i < a1.Coders.Size(); i++)
|
||||||
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
|
if (!AreCodersEqual(a1.Coders[i], a2.Coders[i]))
|
||||||
return false;
|
return false;
|
||||||
if (a1.BindPairs.Size() != a2.BindPairs.Size())
|
|
||||||
|
if (a1.Bonds.Size() != a2.Bonds.Size())
|
||||||
return false;
|
return false;
|
||||||
for (i = 0; i < a1.BindPairs.Size(); i++)
|
for (i = 0; i < a1.Bonds.Size(); i++)
|
||||||
if (!AreBindPairsEqual(a1.BindPairs[i], a2.BindPairs[i]))
|
if (!AreBondsEqual(a1.Bonds[i], a2.Bonds[i]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
|
for (i = 0; i < a1.CoderMethodIDs.Size(); i++)
|
||||||
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
|
if (a1.CoderMethodIDs[i] != a2.CoderMethodIDs[i])
|
||||||
return false;
|
return false;
|
||||||
if (a1.InStreams.Size() != a2.InStreams.Size())
|
|
||||||
|
if (a1.PackStreams.Size() != a2.PackStreams.Size())
|
||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (a1.UnpackCoder != a2.UnpackCoder)
|
||||||
|
return false;
|
||||||
|
*/
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDecoder::CDecoder(bool multiThread)
|
CDecoder::CDecoder(bool useMixerMT):
|
||||||
|
_bindInfoPrev_Defined(false),
|
||||||
|
_useMixerMT(useMixerMT)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
struct CLockedInStream:
|
||||||
|
public IUnknown,
|
||||||
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
#ifndef _ST_MODE
|
CMyComPtr<IInStream> Stream;
|
||||||
multiThread = true;
|
UInt64 Pos;
|
||||||
|
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
|
||||||
|
#ifdef USE_MIXER_MT
|
||||||
|
NWindows::NSynchronization::CCriticalSection CriticalSection;
|
||||||
#endif
|
#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(
|
HRESULT CDecoder::Decode(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
UInt64 startPos,
|
UInt64 startPos,
|
||||||
const CFolders &folders, int folderIndex,
|
const CFolders &folders, unsigned folderIndex,
|
||||||
ISequentialOutStream *outStream,
|
const UInt64 *unpackSize
|
||||||
ICompressProgressInfo *compressProgress
|
|
||||||
|
, ISequentialOutStream *outStream
|
||||||
|
, ICompressProgressInfo *compressProgress
|
||||||
|
, ISequentialInStream **
|
||||||
|
|
||||||
|
#ifdef USE_MIXER_ST
|
||||||
|
inStreamMainRes
|
||||||
|
#endif
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||||
|
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
, bool mtMode, UInt32 numThreads
|
, bool mtMode, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
|
const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]];
|
||||||
CFolder folderInfo;
|
CFolderEx folderInfo;
|
||||||
folders.ParseFolderInfo(folderIndex, folderInfo);
|
folders.ParseFolderEx(folderIndex, folderInfo);
|
||||||
|
|
||||||
if (!folderInfo.CheckStructure(folders.GetNumFolderUnpackSizes(folderIndex)))
|
if (!folderInfo.IsDecodingSupported())
|
||||||
return E_NOTIMPL;
|
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 don't need to init isEncrypted and passwordIsDefined
|
||||||
We must upgrade them only
|
We must upgrade them only
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
isEncrypted = false;
|
isEncrypted = false;
|
||||||
passwordIsDefined = false;
|
passwordIsDefined = false;
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CObjectVector< CMyComPtr<ISequentialInStream> > inStreams;
|
if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev))
|
||||||
|
|
||||||
CLockedInStream lockedInStream;
|
|
||||||
lockedInStream.Init(inStream);
|
|
||||||
|
|
||||||
for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
|
|
||||||
{
|
{
|
||||||
CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp;
|
_mixerRef.Release();
|
||||||
CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec;
|
|
||||||
lockedStreamImpSpec->Init(&lockedInStream, startPos + packPositions[j]);
|
#ifdef USE_MIXER_MT
|
||||||
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
|
#ifdef USE_MIXER_ST
|
||||||
CMyComPtr<ISequentialInStream> inStream = streamSpec;
|
if (_useMixerMT)
|
||||||
streamSpec->SetStream(lockedStreamImp);
|
#endif
|
||||||
streamSpec->Init(packPositions[j + 1] - packPositions[j]);
|
{
|
||||||
inStreams.Add(inStream);
|
_mixerMT = new NCoderMixer2::CMixerMT(false);
|
||||||
|
_mixerRef = _mixerMT;
|
||||||
|
_mixer = _mixerMT;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_MIXER_ST
|
||||||
unsigned numCoders = folderInfo.Coders.Size();
|
|
||||||
|
|
||||||
CBindInfoEx bindInfo;
|
|
||||||
ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo);
|
|
||||||
bool createNewCoders;
|
|
||||||
if (!_bindInfoExPrevIsDefined)
|
|
||||||
createNewCoders = true;
|
|
||||||
else
|
else
|
||||||
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
|
#endif
|
||||||
if (createNewCoders)
|
#endif
|
||||||
{
|
{
|
||||||
unsigned i;
|
#ifdef USE_MIXER_ST
|
||||||
_decoders.Clear();
|
_mixerST = new NCoderMixer2::CMixerST(false);
|
||||||
// _decoders2.Clear();
|
_mixerRef = _mixerST;
|
||||||
|
_mixer = _mixerST;
|
||||||
_mixerCoder.Release();
|
|
||||||
|
|
||||||
if (_multiThread)
|
|
||||||
{
|
|
||||||
_mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT;
|
|
||||||
_mixerCoder = _mixerCoderMTSpec;
|
|
||||||
_mixerCoderCommon = _mixerCoderMTSpec;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
_mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST;
|
|
||||||
_mixerCoder = _mixerCoderSTSpec;
|
|
||||||
_mixerCoderCommon = _mixerCoderSTSpec;
|
|
||||||
#endif
|
#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];
|
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||||
|
|
||||||
|
CCreatedCoder cod;
|
||||||
CMyComPtr<ICompressCoder> decoder;
|
|
||||||
CMyComPtr<ICompressCoder2> decoder2;
|
|
||||||
RINOK(CreateCoder(
|
RINOK(CreateCoder(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
coderInfo.MethodID, decoder, decoder2, false));
|
coderInfo.MethodID, false, cod));
|
||||||
CMyComPtr<IUnknown> decoderUnknown;
|
|
||||||
if (coderInfo.IsSimpleCoder())
|
if (coderInfo.IsSimpleCoder())
|
||||||
{
|
{
|
||||||
if (decoder == 0)
|
if (!cod.Coder)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
// CMethodId m = coderInfo.MethodID;
|
||||||
decoderUnknown = (IUnknown *)decoder;
|
// isFilter = (IsFilterMethod(m) || m == k_AES);
|
||||||
|
|
||||||
if (_multiThread)
|
|
||||||
_mixerCoderMTSpec->AddCoder(decoder);
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
else
|
|
||||||
_mixerCoderSTSpec->AddCoder(decoder, false);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (decoder2 == 0)
|
if (!cod.Coder2 || cod.NumStreams != coderInfo.NumStreams)
|
||||||
return E_NOTIMPL;
|
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
|
#ifdef EXTERNAL_CODECS
|
||||||
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
||||||
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
|
decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
|
||||||
if (setCompressCodecsInfo)
|
if (setCompressCodecsInfo)
|
||||||
{
|
{
|
||||||
|
// we must use g_ExternalCodecs also
|
||||||
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
|
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
_bindInfoExPrev = bindInfo;
|
|
||||||
_bindInfoExPrevIsDefined = true;
|
_bindInfoPrev = bindInfo;
|
||||||
|
_bindInfoPrev_Defined = true;
|
||||||
}
|
}
|
||||||
unsigned i;
|
|
||||||
_mixerCoderCommon->ReInit();
|
_mixer->ReInit();
|
||||||
|
|
||||||
UInt32 packStreamIndex = 0;
|
UInt32 packStreamIndex = 0;
|
||||||
UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
|
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];
|
const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
||||||
CMyComPtr<IUnknown> &decoder = _decoders[coderIndex];
|
IUnknown *decoder = _mixer->GetCoder(i).GetUnknown();
|
||||||
|
|
||||||
{
|
{
|
||||||
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
|
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
|
||||||
decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
|
decoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
|
||||||
if (setDecoderProperties)
|
if (setDecoderProperties)
|
||||||
{
|
{
|
||||||
const CByteBuffer &props = coderInfo.Props;
|
const CByteBuffer &props = coderInfo.Props;
|
||||||
size_t size = props.Size();
|
size_t size = props.Size();
|
||||||
if (size > 0xFFFFFFFF)
|
if (size > 0xFFFFFFFF)
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
// if (size > 0)
|
HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size);
|
||||||
{
|
if (res == E_INVALIDARG)
|
||||||
RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size));
|
res = E_NOTIMPL;
|
||||||
}
|
RINOK(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,7 +370,7 @@ HRESULT CDecoder::Decode(
|
|||||||
if (mtMode)
|
if (mtMode)
|
||||||
{
|
{
|
||||||
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
CMyComPtr<ICompressSetCoderMt> setCoderMt;
|
||||||
decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
|
decoder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
|
||||||
if (setCoderMt)
|
if (setCoderMt)
|
||||||
{
|
{
|
||||||
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
|
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
|
||||||
@@ -264,7 +381,7 @@ HRESULT CDecoder::Decode(
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
{
|
{
|
||||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||||
decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
decoder->QueryInterface(IID_ICryptoSetPassword, (void **)&cryptoSetPassword);
|
||||||
if (cryptoSetPassword)
|
if (cryptoSetPassword)
|
||||||
{
|
{
|
||||||
isEncrypted = true;
|
isEncrypted = true;
|
||||||
@@ -273,9 +390,13 @@ HRESULT CDecoder::Decode(
|
|||||||
CMyComBSTR passwordBSTR;
|
CMyComBSTR passwordBSTR;
|
||||||
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
|
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
|
||||||
passwordIsDefined = true;
|
passwordIsDefined = true;
|
||||||
|
password.Empty();
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if (passwordBSTR)
|
if (passwordBSTR)
|
||||||
len = MyStringLen((BSTR)passwordBSTR);
|
{
|
||||||
|
password = passwordBSTR;
|
||||||
|
len = password.Len();
|
||||||
|
}
|
||||||
CByteBuffer buffer(len * 2);
|
CByteBuffer buffer(len * 2);
|
||||||
for (size_t i = 0; i < len; i++)
|
for (size_t i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
@@ -288,56 +409,129 @@ HRESULT CDecoder::Decode(
|
|||||||
}
|
}
|
||||||
#endif
|
#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);
|
CMyComPtr<ICompressSetFinishMode> setFinishMode;
|
||||||
if (bindPairIndex >= 0)
|
decoder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
|
||||||
packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + (UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex];
|
if (setFinishMode)
|
||||||
|
{
|
||||||
|
RINOK(setFinishMode->SetFinishMode(BoolToInt(fullUnpack)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex);
|
int index = folderInfo.Find_in_PackStreams(packStreamIndex);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
return S_FALSE; // check it
|
return E_NOTIMPL;
|
||||||
packSizes[j] = packPositions[index + 1] - packPositions[index];
|
packSizes[j] = packPositions[(unsigned)index + 1] - packPositions[(unsigned)index];
|
||||||
packSizesPointers[j] = &packSizes[j];
|
packSizesPointers[j] = &packSizes[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_mixerCoderCommon->SetCoderInfo(i, packSizesPointers, unpackSizesPointers);
|
const UInt64 *unpackSizesPointer =
|
||||||
|
(unpackSize && i == bindInfo.UnpackCoder) ?
|
||||||
|
unpackSize :
|
||||||
|
&folders.CoderUnpackSizes[unpackStreamIndexStart + i];
|
||||||
|
|
||||||
|
_mixer->SetCoderInfo(i, unpackSizesPointer, packSizesPointers);
|
||||||
}
|
}
|
||||||
UInt32 mainCoder, temp;
|
|
||||||
bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp);
|
|
||||||
|
|
||||||
if (_multiThread)
|
if (outStream)
|
||||||
_mixerCoderMTSpec->SetProgressCoderIndex(mainCoder);
|
{
|
||||||
/*
|
_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
|
else
|
||||||
_mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);;
|
{
|
||||||
*/
|
#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();
|
unsigned num = inStreams.Size();
|
||||||
CObjArray<ISequentialInStream *> inStreamPointers(num);
|
CObjArray<ISequentialInStream *> inStreamPointers(num);
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
inStreamPointers[i] = inStreams[i];
|
inStreamPointers[i] = inStreams[i];
|
||||||
|
|
||||||
|
if (outStream)
|
||||||
|
{
|
||||||
|
CMyComPtr<ICompressProgressInfo> progress2;
|
||||||
|
if (compressProgress && !_mixer->Is_PackSize_Correct_for_Coder(_mixer->MainCoderIndex))
|
||||||
|
progress2 = new CDecProgress(compressProgress);
|
||||||
|
|
||||||
ISequentialOutStream *outStreamPointer = outStream;
|
ISequentialOutStream *outStreamPointer = outStream;
|
||||||
return _mixerCoder->Code(
|
return _mixer->Code(inStreamPointers, &outStreamPointer, progress2 ? (ICompressProgressInfo *)progress2 : compressProgress);
|
||||||
inStreamPointers, NULL, num,
|
}
|
||||||
&outStreamPointer, NULL, 1,
|
|
||||||
compressProgress);
|
#ifdef USE_MIXER_ST
|
||||||
|
return _mixerST->GetMainUnpackStream(inStreamPointers, inStreamMainRes);
|
||||||
|
#else
|
||||||
|
return E_FAIL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -3,25 +3,17 @@
|
|||||||
#ifndef __7Z_DECODE_H
|
#ifndef __7Z_DECODE_H
|
||||||
#define __7Z_DECODE_H
|
#define __7Z_DECODE_H
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../../IPassword.h"
|
|
||||||
|
|
||||||
#include "../Common/CoderMixer2.h"
|
#include "../Common/CoderMixer2.h"
|
||||||
#include "../Common/CoderMixer2MT.h"
|
|
||||||
#ifdef _ST_MODE
|
|
||||||
#include "../Common/CoderMixer2ST.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../../Common/CreateCoder.h"
|
|
||||||
|
|
||||||
#include "7zIn.h"
|
#include "7zIn.h"
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
struct CBindInfoEx: public NCoderMixer::CBindInfo
|
struct CBindInfoEx: public NCoderMixer2::CBindInfo
|
||||||
{
|
{
|
||||||
CRecordVector<CMethodId> CoderMethodIDs;
|
CRecordVector<CMethodId> CoderMethodIDs;
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
CBindInfo::Clear();
|
CBindInfo::Clear();
|
||||||
@@ -31,29 +23,40 @@ struct CBindInfoEx: public NCoderMixer::CBindInfo
|
|||||||
|
|
||||||
class CDecoder
|
class CDecoder
|
||||||
{
|
{
|
||||||
bool _bindInfoExPrevIsDefined;
|
bool _bindInfoPrev_Defined;
|
||||||
CBindInfoEx _bindInfoExPrev;
|
CBindInfoEx _bindInfoPrev;
|
||||||
|
|
||||||
bool _multiThread;
|
bool _useMixerMT;
|
||||||
#ifdef _ST_MODE
|
|
||||||
NCoderMixer::CCoderMixer2ST *_mixerCoderSTSpec;
|
#ifdef USE_MIXER_ST
|
||||||
|
NCoderMixer2::CMixerST *_mixerST;
|
||||||
#endif
|
#endif
|
||||||
NCoderMixer::CCoderMixer2MT *_mixerCoderMTSpec;
|
|
||||||
NCoderMixer::CCoderMixer2 *_mixerCoderCommon;
|
|
||||||
|
|
||||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
#ifdef USE_MIXER_MT
|
||||||
CObjectVector<CMyComPtr<IUnknown> > _decoders;
|
NCoderMixer2::CMixerMT *_mixerMT;
|
||||||
// CObjectVector<CMyComPtr<ICompressCoder2> > _decoders2;
|
#endif
|
||||||
|
|
||||||
|
NCoderMixer2::CMixer *_mixer;
|
||||||
|
CMyComPtr<IUnknown> _mixerRef;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDecoder(bool multiThread);
|
|
||||||
|
CDecoder(bool useMixerMT);
|
||||||
|
|
||||||
HRESULT Decode(
|
HRESULT Decode(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
IInStream *inStream,
|
IInStream *inStream,
|
||||||
UInt64 startPos,
|
UInt64 startPos,
|
||||||
const CFolders &folders, int folderIndex,
|
const CFolders &folders, unsigned folderIndex,
|
||||||
ISequentialOutStream *outStream,
|
const UInt64 *unpackSize // if (!unpackSize), then full folder is required
|
||||||
ICompressProgressInfo *compressProgress
|
// if (unpackSize), then only *unpackSize bytes from folder are required
|
||||||
|
|
||||||
|
, ISequentialOutStream *outStream
|
||||||
|
, ICompressProgressInfo *compressProgress
|
||||||
|
, ISequentialInStream **inStreamMainRes
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||||
|
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
, bool mtMode, UInt32 numThreads
|
, bool mtMode, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,43 +12,80 @@
|
|||||||
#include "7zEncode.h"
|
#include "7zEncode.h"
|
||||||
#include "7zSpecStream.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 NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindInfo,
|
void CEncoder::InitBindConv()
|
||||||
const CRecordVector<CMethodId> decompressionMethods,
|
|
||||||
CFolder &folder)
|
|
||||||
{
|
{
|
||||||
// bindInfo.CoderMethodIDs.Clear();
|
unsigned numIn = _bindInfo.Coders.Size();
|
||||||
// folder.OutStreams.Clear();
|
|
||||||
folder.BindPairs.SetSize(bindInfo.BindPairs.Size());
|
_SrcIn_to_DestOut.ClearAndSetSize(numIn);
|
||||||
unsigned i;
|
_DestOut_to_SrcIn.ClearAndSetSize(numIn);
|
||||||
for (i = 0; i < bindInfo.BindPairs.Size(); i++)
|
|
||||||
|
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];
|
i--;
|
||||||
const NCoderMixer::CBindPair &mixerBp = bindInfo.BindPairs[i];
|
|
||||||
bp.InIndex = mixerBp.InIndex;
|
const NCoderMixer2::CCoderStreamsInfo &coder = _bindInfo.Coders[i];
|
||||||
bp.OutIndex = mixerBp.OutIndex;
|
|
||||||
|
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];
|
CCoderInfo &coderInfo = folder.Coders[i];
|
||||||
const NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i];
|
const NCoderMixer2::CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[_bindInfo.Coders.Size() - 1 - i];
|
||||||
coderInfo.NumInStreams = coderStreamsInfo.NumInStreams;
|
|
||||||
coderInfo.NumOutStreams = coderStreamsInfo.NumOutStreams;
|
coderInfo.NumStreams = coderStreamsInfo.NumStreams;
|
||||||
coderInfo.MethodID = decompressionMethods[i];
|
coderInfo.MethodID = _decompressionMethods[i];
|
||||||
// coderInfo.Props can be nonFree;
|
// 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.SetSize(_bindInfo.PackStreams.Size());
|
||||||
folder.PackStreams[i] = bindInfo.InStreams[i];
|
|
||||||
|
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)
|
static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
|
||||||
{
|
{
|
||||||
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
|
||||||
@@ -58,30 +95,75 @@ static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce,
|
|||||||
return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
|
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(
|
HRESULT CEncoder::CreateMixerCoder(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
const UInt64 *inSizeForReduce)
|
const UInt64 *inSizeForReduce)
|
||||||
{
|
{
|
||||||
_mixerCoderSpec = new NCoderMixer::CCoderMixer2MT;
|
#ifdef USE_MIXER_MT
|
||||||
_mixerCoder = _mixerCoderSpec;
|
#ifdef USE_MIXER_ST
|
||||||
RINOK(_mixerCoderSpec->SetBindInfo(_bindInfo));
|
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)
|
FOR_VECTOR (i, _options.Methods)
|
||||||
{
|
{
|
||||||
const CMethodFull &methodFull = _options.Methods[i];
|
const CMethodFull &methodFull = _options.Methods[i];
|
||||||
CCoderInfo &encodingInfo = _codersInfo.AddNew();
|
|
||||||
encodingInfo.MethodID = methodFull.Id;
|
|
||||||
CMyComPtr<ICompressCoder> encoder;
|
|
||||||
CMyComPtr<ICompressCoder2> encoder2;
|
|
||||||
|
|
||||||
|
CCreatedCoder cod;
|
||||||
|
|
||||||
RINOK(CreateCoder(
|
RINOK(CreateCoder(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
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;
|
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
|
#ifndef _7ZIP_ST
|
||||||
{
|
{
|
||||||
@@ -105,21 +187,25 @@ HRESULT CEncoder::CreateMixerCoder(
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// now there is no codec that uses another external codec
|
||||||
|
/*
|
||||||
#ifdef EXTERNAL_CODECS
|
#ifdef EXTERNAL_CODECS
|
||||||
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
|
||||||
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
|
encoderCommon.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
|
||||||
if (setCompressCodecsInfo)
|
if (setCompressCodecsInfo)
|
||||||
{
|
{
|
||||||
|
// we must use g_ExternalCodecs also
|
||||||
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
|
RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
|
||||||
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
encoderCommon.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword);
|
||||||
|
|
||||||
if (cryptoSetPassword)
|
if (cryptoSetPassword)
|
||||||
{
|
{
|
||||||
const UInt32 sizeInBytes = _options.Password.Len() * 2;
|
const unsigned sizeInBytes = _options.Password.Len() * 2;
|
||||||
CByteBuffer buffer(sizeInBytes);
|
CByteBuffer buffer(sizeInBytes);
|
||||||
for (unsigned i = 0; i < _options.Password.Len(); i++)
|
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] = (Byte)c;
|
||||||
((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
|
((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)
|
_mixer->AddCoder(cod);
|
||||||
_mixerCoderSpec->AddCoder(encoder);
|
|
||||||
else
|
|
||||||
_mixerCoderSpec->AddCoder2(encoder2);
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
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(
|
HRESULT CEncoder::Encode(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
ISequentialInStream *inStream,
|
ISequentialInStream *inStream,
|
||||||
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
|
// const UInt64 *inStreamSize,
|
||||||
|
const UInt64 *inSizeForReduce,
|
||||||
CFolder &folderItem,
|
CFolder &folderItem,
|
||||||
CRecordVector<UInt64> &coderUnpackSizes,
|
CRecordVector<UInt64> &coderUnpackSizes,
|
||||||
UInt64 &unpackSize,
|
UInt64 &unpackSize,
|
||||||
@@ -151,27 +295,37 @@ HRESULT CEncoder::Encode(
|
|||||||
{
|
{
|
||||||
RINOK(EncoderConstr());
|
RINOK(EncoderConstr());
|
||||||
|
|
||||||
if (!_mixerCoderSpec)
|
if (!_mixerRef)
|
||||||
{
|
{
|
||||||
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
|
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<CInOutTempBuffer> inOutTempBuffers;
|
||||||
CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;
|
CObjectVector<CSequentialOutTempBufferImp2 *> tempBufferSpecs;
|
||||||
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
|
CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;
|
||||||
|
|
||||||
unsigned numMethods = _bindInfo.Coders.Size();
|
unsigned numMethods = _bindInfo.Coders.Size();
|
||||||
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
|
||||||
|
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
|
||||||
{
|
{
|
||||||
CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
|
CInOutTempBuffer &iotb = inOutTempBuffers.AddNew();
|
||||||
iotb.Create();
|
iotb.Create();
|
||||||
iotb.InitWriting();
|
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;
|
CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;
|
||||||
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
tempBufferSpec->Init(&inOutTempBuffers[i - 1]);
|
||||||
tempBuffers.Add(tempBuffer);
|
tempBuffers.Add(tempBuffer);
|
||||||
@@ -179,94 +333,111 @@ HRESULT CEncoder::Encode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < numMethods; i++)
|
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)
|
if (inStreamSize)
|
||||||
{
|
_mixer->SetCoderInfo(_bindInfo.UnpackCoder, inStreamSize, NULL);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UInt64 outStreamStartPos;
|
|
||||||
// RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));
|
|
||||||
|
|
||||||
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
|
CSequentialInStreamSizeCount2 *inStreamSizeCountSpec = new CSequentialInStreamSizeCount2;
|
||||||
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;
|
||||||
|
|
||||||
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
|
CSequentialOutStreamSizeCount *outStreamSizeCountSpec = NULL;
|
||||||
CMyComPtr<ISequentialOutStream> outStreamSizeCount;
|
CMyComPtr<ISequentialOutStream> outStreamSizeCount;
|
||||||
|
|
||||||
inStreamSizeCountSpec->Init(inStream);
|
inStreamSizeCountSpec->Init(inStream);
|
||||||
|
|
||||||
CRecordVector<ISequentialInStream *> inStreamPointers;
|
ISequentialInStream *inStreamPointer = inStreamSizeCount;
|
||||||
CRecordVector<ISequentialOutStream *> outStreamPointers;
|
CRecordVector<ISequentialOutStream *> outStreamPointers;
|
||||||
inStreamPointers.Add(inStreamSizeCount);
|
|
||||||
|
|
||||||
if (_bindInfo.OutStreams.Size() != 0)
|
SetFolder(folderItem);
|
||||||
|
|
||||||
|
for (i = 0; i < numMethods; i++)
|
||||||
{
|
{
|
||||||
outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
|
IUnknown *coder = _mixer->GetCoder(i).GetUnknown();
|
||||||
outStreamSizeCount = outStreamSizeCountSpec;
|
|
||||||
outStreamSizeCountSpec->SetStream(outStream);
|
|
||||||
outStreamSizeCountSpec->Init();
|
|
||||||
outStreamPointers.Add(outStreamSizeCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < _bindInfo.OutStreams.Size(); i++)
|
|
||||||
outStreamPointers.Add(tempBuffers[i - 1]);
|
|
||||||
|
|
||||||
for (i = 0; i < _codersInfo.Size(); i++)
|
|
||||||
{
|
|
||||||
CCoderInfo &encodingInfo = _codersInfo[i];
|
|
||||||
|
|
||||||
CMyComPtr<ICryptoResetInitVector> resetInitVector;
|
CMyComPtr<ICryptoResetInitVector> resetInitVector;
|
||||||
_mixerCoderSpec->_coders[i].QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
|
coder->QueryInterface(IID_ICryptoResetInitVector, (void **)&resetInitVector);
|
||||||
if (resetInitVector)
|
if (resetInitVector)
|
||||||
{
|
{
|
||||||
resetInitVector->ResetInitVector();
|
resetInitVector->ResetInitVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
|
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)
|
if (writeCoderProperties)
|
||||||
{
|
{
|
||||||
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
|
CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
|
CMyComPtr<ISequentialOutStream> dynOutStream(outStreamSpec);
|
||||||
outStreamSpec->Init();
|
outStreamSpec->Init();
|
||||||
writeCoderProperties->WriteCoderProperties(outStream);
|
writeCoderProperties->WriteCoderProperties(dynOutStream);
|
||||||
outStreamSpec->CopyToBuffer(encodingInfo.Props);
|
outStreamSpec->CopyToBuffer(props);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
props.Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 progressIndex = mainCoderIndex;
|
_mixer->SelectMainCoder(false);
|
||||||
|
UInt32 mainCoder = _mixer->MainCoderIndex;
|
||||||
|
|
||||||
for (i = 0; i + 1 < _codersInfo.Size(); i++)
|
bool useMtProgress = false;
|
||||||
|
if (!_mixer->Is_PackSize_Correct_for_Coder(mainCoder))
|
||||||
{
|
{
|
||||||
UInt64 m = _codersInfo[i].MethodID;
|
#ifdef _7ZIP_ST
|
||||||
if (m == k_Delta || m == k_BCJ || m == k_BCJ2)
|
if (!_mixer->IsThere_ExternalCoder_in_PackTree(mainCoder))
|
||||||
progressIndex = i + 1;
|
#endif
|
||||||
|
useMtProgress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_mixerCoderSpec->SetProgressCoderIndex(progressIndex);
|
if (useMtProgress)
|
||||||
|
{
|
||||||
|
mtProgressSpec = new CMtEncMultiProgress;
|
||||||
|
mtProgress = mtProgressSpec;
|
||||||
|
mtProgressSpec->Init(compressProgress);
|
||||||
|
|
||||||
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
|
mtOutStreamNotifySpec = new CSequentialOutMtNotify;
|
||||||
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));
|
mtOutStreamNotify = mtOutStreamNotifySpec;
|
||||||
|
mtOutStreamNotifySpec->_stream = outStream;
|
||||||
|
mtOutStreamNotifySpec->_mtProgresSpec = mtProgressSpec;
|
||||||
|
|
||||||
ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods, folderItem);
|
FOR_VECTOR(i, tempBufferSpecs)
|
||||||
|
{
|
||||||
|
tempBufferSpecs[i]->_mtProgresSpec = mtProgressSpec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_bindInfo.OutStreams.Size() != 0)
|
|
||||||
|
if (_bindInfo.PackStreams.Size() != 0)
|
||||||
|
{
|
||||||
|
outStreamSizeCountSpec = new CSequentialOutStreamSizeCount;
|
||||||
|
outStreamSizeCount = outStreamSizeCountSpec;
|
||||||
|
outStreamSizeCountSpec->SetStream(mtOutStreamNotify ? (ISequentialOutStream *)mtOutStreamNotify : outStream);
|
||||||
|
outStreamSizeCountSpec->Init();
|
||||||
|
outStreamPointers.Add(outStreamSizeCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i < _bindInfo.PackStreams.Size(); i++)
|
||||||
|
outStreamPointers.Add(tempBuffers[i - 1]);
|
||||||
|
|
||||||
|
RINOK(_mixer->Code(
|
||||||
|
&inStreamPointer,
|
||||||
|
&outStreamPointers.Front(),
|
||||||
|
mtProgress ? (ICompressProgressInfo *)mtProgress : compressProgress));
|
||||||
|
|
||||||
|
if (_bindInfo.PackStreams.Size() != 0)
|
||||||
packSizes.Add(outStreamSizeCountSpec->GetSize());
|
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];
|
CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];
|
||||||
RINOK(inOutTempBuffer.WriteToStream(outStream));
|
RINOK(inOutTempBuffer.WriteToStream(outStream));
|
||||||
@@ -274,37 +445,45 @@ HRESULT CEncoder::Encode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unpackSize = 0;
|
unpackSize = 0;
|
||||||
for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)
|
|
||||||
|
for (i = 0; i < _bindInfo.Coders.Size(); i++)
|
||||||
{
|
{
|
||||||
int binder = _bindInfo.FindBinderForInStream(
|
int bond = _bindInfo.FindBond_for_UnpackStream(_DestOut_to_SrcIn[i]);
|
||||||
_bindReverseConverter->DestOutToSrcInMap[i]);
|
|
||||||
UInt64 streamSize;
|
UInt64 streamSize;
|
||||||
if (binder < 0)
|
if (bond < 0)
|
||||||
{
|
{
|
||||||
streamSize = inStreamSizeCountSpec->GetSize();
|
streamSize = inStreamSizeCountSpec->GetSize();
|
||||||
unpackSize = streamSize;
|
unpackSize = streamSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);
|
streamSize = _mixer->GetBondStreamSize(bond);
|
||||||
coderUnpackSizes.Add(streamSize);
|
coderUnpackSizes.Add(streamSize);
|
||||||
}
|
}
|
||||||
for (i = 0; i < numMethods; i++)
|
|
||||||
folderItem.Coders[numMethods - 1 - i].Props = _codersInfo[i].Props;
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CEncoder::CEncoder(const CCompressionMethodMode &options):
|
CEncoder::CEncoder(const CCompressionMethodMode &options):
|
||||||
_bindReverseConverter(0),
|
|
||||||
_constructed(false)
|
_constructed(false)
|
||||||
{
|
{
|
||||||
if (options.IsEmpty())
|
if (options.IsEmpty())
|
||||||
throw 1;
|
throw 1;
|
||||||
|
|
||||||
_options = options;
|
_options = options;
|
||||||
_mixerCoderSpec = NULL;
|
|
||||||
|
#ifdef USE_MIXER_ST
|
||||||
|
_mixerST = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_MIXER_MT
|
||||||
|
_mixerMT = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_mixer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRESULT CEncoder::EncoderConstr()
|
HRESULT CEncoder::EncoderConstr()
|
||||||
{
|
{
|
||||||
if (_constructed)
|
if (_constructed)
|
||||||
@@ -314,112 +493,125 @@ HRESULT CEncoder::EncoderConstr()
|
|||||||
// it has only password method;
|
// it has only password method;
|
||||||
if (!_options.PasswordIsDefined)
|
if (!_options.PasswordIsDefined)
|
||||||
throw 1;
|
throw 1;
|
||||||
if (!_options.Binds.IsEmpty())
|
if (!_options.Bonds.IsEmpty())
|
||||||
throw 1;
|
throw 1;
|
||||||
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
|
|
||||||
CMethodFull method;
|
CMethodFull method;
|
||||||
|
|
||||||
method.NumInStreams = 1;
|
|
||||||
method.NumOutStreams = 1;
|
|
||||||
coderStreamsInfo.NumInStreams = 1;
|
|
||||||
coderStreamsInfo.NumOutStreams = 1;
|
|
||||||
method.Id = k_AES;
|
method.Id = k_AES;
|
||||||
|
method.NumStreams = 1;
|
||||||
_options.Methods.Add(method);
|
_options.Methods.Add(method);
|
||||||
|
|
||||||
|
NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;
|
||||||
|
coderStreamsInfo.NumStreams = 1;
|
||||||
_bindInfo.Coders.Add(coderStreamsInfo);
|
_bindInfo.Coders.Add(coderStreamsInfo);
|
||||||
|
|
||||||
_bindInfo.InStreams.Add(0);
|
_bindInfo.PackStreams.Add(0);
|
||||||
_bindInfo.OutStreams.Add(0);
|
_bindInfo.UnpackCoder = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
UInt32 numInStreams = 0, numOutStreams = 0;
|
UInt32 numOutStreams = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < _options.Methods.Size(); i++)
|
for (i = 0; i < _options.Methods.Size(); i++)
|
||||||
{
|
{
|
||||||
const CMethodFull &methodFull = _options.Methods[i];
|
const CMethodFull &methodFull = _options.Methods[i];
|
||||||
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
|
NCoderMixer2::CCoderStreamsInfo cod;
|
||||||
coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;
|
|
||||||
coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;
|
cod.NumStreams = methodFull.NumStreams;
|
||||||
if (_options.Binds.IsEmpty())
|
|
||||||
|
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;
|
NCoderMixer2::CBond bond;
|
||||||
bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;
|
bond.PackIndex = numOutStreams;
|
||||||
bindPair.OutIndex = numOutStreams;
|
bond.UnpackIndex = i + 1; // it's next coder
|
||||||
_bindInfo.BindPairs.Add(bindPair);
|
_bindInfo.Bonds.Add(bond);
|
||||||
}
|
}
|
||||||
else if (coderStreamsInfo.NumOutStreams != 0)
|
else if (cod.NumStreams != 0)
|
||||||
_bindInfo.OutStreams.Insert(0, numOutStreams);
|
_bindInfo.PackStreams.Insert(0, numOutStreams);
|
||||||
for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)
|
|
||||||
_bindInfo.OutStreams.Add(numOutStreams + j);
|
for (UInt32 j = 1; j < cod.NumStreams; j++)
|
||||||
|
_bindInfo.PackStreams.Add(numOutStreams + j);
|
||||||
}
|
}
|
||||||
|
|
||||||
numInStreams += coderStreamsInfo.NumInStreams;
|
numOutStreams += cod.NumStreams;
|
||||||
numOutStreams += coderStreamsInfo.NumOutStreams;
|
|
||||||
|
|
||||||
_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;
|
NCoderMixer2::CBond mixerBond;
|
||||||
const CBind &bind = _options.Binds[i];
|
const CBond2 &bond = _options.Bonds[i];
|
||||||
bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;
|
if (bond.InCoder >= _bindInfo.Coders.Size()
|
||||||
bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;
|
|| bond.OutCoder >= _bindInfo.Coders.Size()
|
||||||
_bindInfo.BindPairs.Add(bindPair);
|
|| bond.OutStream >= _bindInfo.Coders[bond.OutCoder].NumStreams)
|
||||||
}
|
return E_INVALIDARG;
|
||||||
for (i = 0; i < (int)numOutStreams; i++)
|
mixerBond.PackIndex = _bindInfo.GetStream_for_Coder(bond.OutCoder) + bond.OutStream;
|
||||||
if (_bindInfo.FindBinderForOutStream(i) == -1)
|
mixerBond.UnpackIndex = bond.InCoder;
|
||||||
_bindInfo.OutStreams.Add(i);
|
_bindInfo.Bonds.Add(mixerBond);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < (int)numInStreams; i++)
|
for (i = 0; i < numOutStreams; i++)
|
||||||
if (_bindInfo.FindBinderForInStream(i) == -1)
|
if (_bindInfo.FindBond_for_PackStream(i) == -1)
|
||||||
_bindInfo.InStreams.Add(i);
|
_bindInfo.PackStreams.Add(i);
|
||||||
|
}
|
||||||
|
|
||||||
if (_bindInfo.InStreams.IsEmpty())
|
if (!_bindInfo.SetUnpackCoder())
|
||||||
throw 1; // this is error
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!_bindInfo.CalcMapsAndCheck())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (_bindInfo.PackStreams.Size() != 1)
|
||||||
|
{
|
||||||
|
/* 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;
|
||||||
|
|
||||||
// Make main stream first in list
|
|
||||||
int inIndex = _bindInfo.InStreams[0];
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt32 coderIndex, coderStreamIndex;
|
if (_bindInfo.Coders[ci].NumStreams == 0)
|
||||||
_bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);
|
break;
|
||||||
UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
|
|
||||||
int binder = _bindInfo.FindBinderForOutStream(outIndex);
|
UInt32 outIndex = _bindInfo.Coder_to_Stream[ci];
|
||||||
if (binder >= 0)
|
int bond = _bindInfo.FindBond_for_PackStream(outIndex);
|
||||||
|
if (bond >= 0)
|
||||||
{
|
{
|
||||||
inIndex = _bindInfo.BindPairs[binder].InIndex;
|
ci = _bindInfo.Bonds[bond].UnpackIndex;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
|
||||||
if (_bindInfo.OutStreams[i] == outIndex)
|
int i = _bindInfo.FindStream_in_PackStreams(outIndex);
|
||||||
{
|
if (i >= 0)
|
||||||
_bindInfo.OutStreams.Delete(i);
|
_bindInfo.PackStreams.MoveToFront(i);
|
||||||
_bindInfo.OutStreams.Insert(0, outIndex);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_options.PasswordIsDefined)
|
if (_options.PasswordIsDefined)
|
||||||
{
|
{
|
||||||
unsigned numCryptoStreams = _bindInfo.OutStreams.Size();
|
unsigned numCryptoStreams = _bindInfo.PackStreams.Size();
|
||||||
|
|
||||||
|
unsigned numInStreams = _bindInfo.Coders.Size();
|
||||||
|
|
||||||
for (i = 0; i < numCryptoStreams; i++)
|
for (i = 0; i < numCryptoStreams; i++)
|
||||||
{
|
{
|
||||||
NCoderMixer::CBindPair bindPair;
|
NCoderMixer2::CBond bond;
|
||||||
bindPair.InIndex = numInStreams + i;
|
bond.UnpackIndex = numInStreams + i;
|
||||||
bindPair.OutIndex = _bindInfo.OutStreams[i];
|
bond.PackIndex = _bindInfo.PackStreams[i];
|
||||||
_bindInfo.BindPairs.Add(bindPair);
|
_bindInfo.Bonds.Add(bond);
|
||||||
}
|
}
|
||||||
_bindInfo.OutStreams.Clear();
|
_bindInfo.PackStreams.Clear();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (numCryptoStreams == 0)
|
if (numCryptoStreams == 0)
|
||||||
@@ -428,37 +620,37 @@ HRESULT CEncoder::EncoderConstr()
|
|||||||
|
|
||||||
for (i = 0; i < numCryptoStreams; i++)
|
for (i = 0; i < numCryptoStreams; i++)
|
||||||
{
|
{
|
||||||
NCoderMixer::CCoderStreamsInfo coderStreamsInfo;
|
|
||||||
CMethodFull method;
|
CMethodFull method;
|
||||||
method.NumInStreams = 1;
|
method.NumStreams = 1;
|
||||||
method.NumOutStreams = 1;
|
|
||||||
coderStreamsInfo.NumInStreams = method.NumOutStreams;
|
|
||||||
coderStreamsInfo.NumOutStreams = method.NumInStreams;
|
|
||||||
method.Id = k_AES;
|
method.Id = k_AES;
|
||||||
|
|
||||||
_options.Methods.Add(method);
|
_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--)
|
for (unsigned i = _options.Methods.Size(); i != 0;)
|
||||||
{
|
_decompressionMethods.Add(_options.Methods[--i].Id);
|
||||||
const CMethodFull &methodFull = _options.Methods[i];
|
|
||||||
_decompressionMethods.Add(methodFull.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
_bindReverseConverter = new NCoderMixer::CBindReverseConverter(_bindInfo);
|
if (_bindInfo.Coders.Size() > 16)
|
||||||
_bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);
|
return E_INVALIDARG;
|
||||||
|
if (_bindInfo.GetNum_Bonds_and_PackStreams() > 16)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!_bindInfo.CalcMapsAndCheck())
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
InitBindConv();
|
||||||
_constructed = true;
|
_constructed = true;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CEncoder::~CEncoder()
|
CEncoder::~CEncoder() {}
|
||||||
{
|
|
||||||
delete _bindReverseConverter;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -3,47 +3,82 @@
|
|||||||
#ifndef __7Z_ENCODE_H
|
#ifndef __7Z_ENCODE_H
|
||||||
#define __7Z_ENCODE_H
|
#define __7Z_ENCODE_H
|
||||||
|
|
||||||
// #include "../../Common/StreamObjects.h"
|
|
||||||
|
|
||||||
#include "7zCompressionMode.h"
|
#include "7zCompressionMode.h"
|
||||||
|
|
||||||
#include "../Common/CoderMixer2.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 NArchive {
|
||||||
namespace N7z {
|
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
|
class CEncoder
|
||||||
{
|
{
|
||||||
NCoderMixer::CCoderMixer2MT *_mixerCoderSpec;
|
#ifdef USE_MIXER_ST
|
||||||
CMyComPtr<ICompressCoder2> _mixerCoder;
|
NCoderMixer2::CMixerST *_mixerST;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_MIXER_MT
|
||||||
|
NCoderMixer2::CMixerMT *_mixerMT;
|
||||||
|
#endif
|
||||||
|
|
||||||
CObjectVector<CCoderInfo> _codersInfo;
|
NCoderMixer2::CMixer *_mixer;
|
||||||
|
CMyComPtr<IUnknown> _mixerRef;
|
||||||
|
|
||||||
CCompressionMethodMode _options;
|
CCompressionMethodMode _options;
|
||||||
NCoderMixer::CBindInfo _bindInfo;
|
NCoderMixer2::CBindInfo _bindInfo;
|
||||||
NCoderMixer::CBindInfo _decompressBindInfo;
|
|
||||||
NCoderMixer::CBindReverseConverter *_bindReverseConverter;
|
|
||||||
CRecordVector<CMethodId> _decompressionMethods;
|
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
|
HRESULT CreateMixerCoder(DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
const UInt64 *inSizeForReduce);
|
const UInt64 *inSizeForReduce);
|
||||||
|
|
||||||
bool _constructed;
|
bool _constructed;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CEncoder(const CCompressionMethodMode &options);
|
CEncoder(const CCompressionMethodMode &options);
|
||||||
~CEncoder();
|
~CEncoder();
|
||||||
HRESULT EncoderConstr();
|
HRESULT EncoderConstr();
|
||||||
HRESULT Encode(
|
HRESULT Encode(
|
||||||
DECL_EXTERNAL_CODECS_LOC_VARS
|
DECL_EXTERNAL_CODECS_LOC_VARS
|
||||||
ISequentialInStream *inStream,
|
ISequentialInStream *inStream,
|
||||||
const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,
|
// const UInt64 *inStreamSize,
|
||||||
|
const UInt64 *inSizeForReduce,
|
||||||
CFolder &folderItem,
|
CFolder &folderItem,
|
||||||
CRecordVector<UInt64> &coderUnpackSizes,
|
CRecordVector<UInt64> &coderUnpackSizes,
|
||||||
UInt64 &unpackSize,
|
UInt64 &unpackSize,
|
||||||
|
|||||||
@@ -2,205 +2,327 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
#include "../../../../C/7zCrc.h"
|
||||||
|
|
||||||
#include "../../../Common/ComTry.h"
|
#include "../../../Common/ComTry.h"
|
||||||
|
|
||||||
#include "../../Common/ProgressUtils.h"
|
#include "../../Common/ProgressUtils.h"
|
||||||
|
|
||||||
#include "7zDecode.h"
|
#include "7zDecode.h"
|
||||||
// #include "7z1Decode.h"
|
|
||||||
#include "7zFolderOutStream.h"
|
|
||||||
#include "7zHandler.h"
|
#include "7zHandler.h"
|
||||||
|
|
||||||
|
// EXTERN_g_ExternalCodecs
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
struct CExtractFolderInfo
|
class CFolderOutStream:
|
||||||
|
public ISequentialOutStream,
|
||||||
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
#ifdef _7Z_VOL
|
CMyComPtr<ISequentialOutStream> _stream;
|
||||||
int VolumeIndex;
|
public:
|
||||||
#endif
|
bool TestMode;
|
||||||
CNum FileIndex;
|
bool CheckCrc;
|
||||||
CNum FolderIndex;
|
private:
|
||||||
CBoolVector ExtractStatuses;
|
bool _fileIsOpen;
|
||||||
UInt64 UnpackSize;
|
bool _calcCrc;
|
||||||
CExtractFolderInfo(
|
UInt32 _crc;
|
||||||
#ifdef _7Z_VOL
|
UInt64 _rem;
|
||||||
int volumeIndex,
|
|
||||||
#endif
|
const UInt32 *_indexes;
|
||||||
CNum fileIndex, CNum folderIndex):
|
unsigned _numFiles;
|
||||||
#ifdef _7Z_VOL
|
unsigned _fileIndex;
|
||||||
VolumeIndex(volumeIndex),
|
|
||||||
#endif
|
HRESULT OpenFile(bool isCorrupted = false);
|
||||||
FileIndex(fileIndex),
|
HRESULT CloseFile_and_SetResult(Int32 res);
|
||||||
FolderIndex(folderIndex),
|
HRESULT CloseFile();
|
||||||
UnpackSize(0)
|
HRESULT ProcessEmptyFiles();
|
||||||
{
|
|
||||||
if (fileIndex != kNumNoIndex)
|
public:
|
||||||
{
|
MY_UNKNOWN_IMP1(ISequentialOutStream)
|
||||||
ExtractStatuses.ClearAndSetSize(1);
|
|
||||||
ExtractStatuses[0] = true;
|
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,
|
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||||
{
|
{
|
||||||
COM_TRY_BEGIN
|
COM_TRY_BEGIN
|
||||||
bool testMode = (testModeSpec != 0);
|
|
||||||
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
|
||||||
|
|
||||||
UInt64 importantTotalUnpacked = 0;
|
UInt64 importantTotalUnpacked = 0;
|
||||||
|
|
||||||
|
// numItems = (UInt32)(Int32)-1;
|
||||||
|
|
||||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||||
if (allFilesMode)
|
if (allFilesMode)
|
||||||
numItems =
|
numItems = _db.Files.Size();
|
||||||
#ifdef _7Z_VOL
|
|
||||||
_refs.Size();
|
|
||||||
#else
|
|
||||||
_db.Files.Size();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(numItems == 0)
|
if (numItems == 0)
|
||||||
return S_OK;
|
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];
|
CNum prevFolder = kNumNoIndex;
|
||||||
UInt32 ref2Index = allFilesMode ? ii : indices[ii];
|
UInt32 nextFile = 0;
|
||||||
// const CRef2 &ref2 = _refs[ref2Index];
|
|
||||||
|
|
||||||
// for (UInt32 ri = 0; ri < ref2.Refs.Size(); ri++)
|
UInt32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < numItems; i++)
|
||||||
{
|
{
|
||||||
#ifdef _7Z_VOL
|
UInt32 fileIndex = allFilesMode ? i : indices[i];
|
||||||
// const CRef &ref = ref2.Refs[ri];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
|
||||||
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];
|
|
||||||
if (folderIndex == kNumNoIndex)
|
if (folderIndex == kNumNoIndex)
|
||||||
{
|
|
||||||
extractFolderInfoVector.Add(CExtractFolderInfo(
|
|
||||||
#ifdef _7Z_VOL
|
|
||||||
volumeIndex,
|
|
||||||
#endif
|
|
||||||
fileIndex, kNumNoIndex));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (folderIndex != prevFolder || fileIndex < nextFile)
|
||||||
if (extractFolderInfoVector.IsEmpty() ||
|
nextFile = _db.FolderStartFileIndex[folderIndex];
|
||||||
folderIndex != extractFolderInfoVector.Back().FolderIndex
|
for (CNum index = nextFile; index <= fileIndex; index++)
|
||||||
#ifdef _7Z_VOL
|
importantTotalUnpacked += _db.Files[index].Size;
|
||||||
|| volumeIndex != extractFolderInfoVector.Back().VolumeIndex
|
nextFile = fileIndex + 1;
|
||||||
#endif
|
prevFolder = folderIndex;
|
||||||
)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
|
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;
|
CLocalProgress *lps = new CLocalProgress;
|
||||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||||
lps->Init(extractCallback, false);
|
lps->Init(extractCallback, false);
|
||||||
|
|
||||||
for (unsigned i = 0;; i++, totalUnpacked += curUnpacked, totalPacked += curPacked)
|
CDecoder decoder(
|
||||||
{
|
#ifndef USE_MIXER_ST
|
||||||
lps->OutSize = totalUnpacked;
|
false
|
||||||
lps->InSize = totalPacked;
|
#else
|
||||||
RINOK(lps->SetCur());
|
_useMultiThreadMixer
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
if (i >= extractFolderInfoVector.Size())
|
UInt64 curPacked, curUnpacked;
|
||||||
break;
|
|
||||||
|
|
||||||
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
|
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
|
||||||
curUnpacked = efi.UnpackSize;
|
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
|
||||||
curPacked = 0;
|
|
||||||
|
|
||||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||||
|
|
||||||
#ifdef _7Z_VOL
|
folderOutStream->_db = &_db;
|
||||||
const CVolume &volume = _volumes[efi.VolumeIndex];
|
folderOutStream->ExtractCallback = extractCallback;
|
||||||
const CDbEx &db = volume.Database;
|
folderOutStream->TestMode = (testModeSpec != 0);
|
||||||
#else
|
folderOutStream->CheckCrc = (_crcSize != 0);
|
||||||
const CDbEx &db = _db;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CNum startIndex;
|
for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
|
||||||
if (efi.FileIndex != kNumNoIndex)
|
{
|
||||||
startIndex = efi.FileIndex;
|
RINOK(lps->SetCur());
|
||||||
else
|
|
||||||
startIndex = db.FolderStartFileIndex[efi.FolderIndex];
|
|
||||||
|
|
||||||
HRESULT result = folderOutStream->Init(&db,
|
if (i >= numItems)
|
||||||
#ifdef _7Z_VOL
|
break;
|
||||||
volume.StartRef2Index,
|
|
||||||
#else
|
curUnpacked = 0;
|
||||||
0,
|
curPacked = 0;
|
||||||
#endif
|
|
||||||
startIndex,
|
UInt32 fileIndex = allFilesMode ? i : indices[i];
|
||||||
&efi.ExtractStatuses, extractCallback, testMode, _crcSize != 0);
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
|
||||||
|
|
||||||
|
UInt32 numSolidFiles = 1;
|
||||||
|
|
||||||
|
if (folderIndex != kNumNoIndex)
|
||||||
|
{
|
||||||
|
curPacked = _db.GetFolderFullPackSize(folderIndex);
|
||||||
|
UInt32 nextFile = fileIndex + 1;
|
||||||
|
fileIndex = _db.FolderStartFileIndex[folderIndex];
|
||||||
|
UInt32 k;
|
||||||
|
|
||||||
|
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);
|
RINOK(result);
|
||||||
|
|
||||||
if (efi.FileIndex != kNumNoIndex)
|
// to test solid block with zero unpacked size we disable that code
|
||||||
|
if (folderOutStream->WasWritingFinished())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CNum folderIndex = efi.FolderIndex;
|
|
||||||
curPacked = _db.GetFolderFullPackSize(folderIndex);
|
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||||
if (extractCallback)
|
if (extractCallback)
|
||||||
@@ -212,50 +334,64 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
bool isEncrypted = false;
|
bool isEncrypted = false;
|
||||||
bool passwordIsDefined = false;
|
bool passwordIsDefined = false;
|
||||||
|
UString password;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
HRESULT result = decoder.Decode(
|
HRESULT result = decoder.Decode(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
#ifdef _7Z_VOL
|
|
||||||
volume.Stream,
|
|
||||||
#else
|
|
||||||
_inStream,
|
_inStream,
|
||||||
#endif
|
_db.ArcInfo.DataStartPosition,
|
||||||
db.ArcInfo.DataStartPosition,
|
_db, folderIndex,
|
||||||
db, folderIndex,
|
&curUnpacked,
|
||||||
|
|
||||||
outStream,
|
outStream,
|
||||||
progress
|
progress,
|
||||||
|
NULL // *inStreamMainRes
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS
|
_7Z_DECODER_CRYPRO_VARS
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
, true, _numThreads
|
, true, _numThreads
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result == S_FALSE)
|
if (result == S_FALSE || result == E_NOTIMPL)
|
||||||
{
|
{
|
||||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
bool wasFinished = folderOutStream->WasWritingFinished();
|
||||||
continue;
|
|
||||||
}
|
int resOp = (result == S_FALSE ?
|
||||||
if (result == E_NOTIMPL)
|
NExtract::NOperationResult::kDataError :
|
||||||
{
|
NExtract::NOperationResult::kUnsupportedMethod);
|
||||||
RINOK(folderOutStream->FlushCorrupted(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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != S_OK)
|
if (result != S_OK)
|
||||||
return result;
|
return result;
|
||||||
if (folderOutStream->WasWritingFinished() != S_OK)
|
|
||||||
{
|
|
||||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||||
continue;
|
// continue;
|
||||||
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,96 +7,103 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
CFolderInStream::CFolderInStream()
|
|
||||||
{
|
|
||||||
_inStreamWithHashSpec = new CSequentialInStreamWithCRC;
|
|
||||||
_inStreamWithHash = _inStreamWithHashSpec;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
void CFolderInStream::Init(IArchiveUpdateCallback *updateCallback,
|
||||||
const UInt32 *fileIndices, UInt32 numFiles)
|
const UInt32 *indexes, unsigned numFiles)
|
||||||
{
|
{
|
||||||
_updateCallback = updateCallback;
|
_updateCallback = updateCallback;
|
||||||
|
_indexes = indexes;
|
||||||
_numFiles = numFiles;
|
_numFiles = numFiles;
|
||||||
_fileIndex = 0;
|
_index = 0;
|
||||||
_fileIndices = fileIndices;
|
|
||||||
Processed.Clear();
|
Processed.ClearAndReserve(numFiles);
|
||||||
CRCs.Clear();
|
CRCs.ClearAndReserve(numFiles);
|
||||||
Sizes.Clear();
|
Sizes.ClearAndReserve(numFiles);
|
||||||
_fileIsOpen = false;
|
|
||||||
_currentSizeIsDefined = false;
|
_pos = 0;
|
||||||
|
_crc = CRC_INIT_VAL;
|
||||||
|
_size_Defined = false;
|
||||||
|
_size = 0;
|
||||||
|
|
||||||
|
_stream.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CFolderInStream::OpenStream()
|
HRESULT CFolderInStream::OpenStream()
|
||||||
{
|
{
|
||||||
_filePos = 0;
|
_pos = 0;
|
||||||
while (_fileIndex < _numFiles)
|
_crc = CRC_INIT_VAL;
|
||||||
|
_size_Defined = false;
|
||||||
|
_size = 0;
|
||||||
|
|
||||||
|
while (_index < _numFiles)
|
||||||
{
|
{
|
||||||
CMyComPtr<ISequentialInStream> stream;
|
CMyComPtr<ISequentialInStream> stream;
|
||||||
HRESULT result = _updateCallback->GetStream(_fileIndices[_fileIndex], &stream);
|
HRESULT result = _updateCallback->GetStream(_indexes[_index], &stream);
|
||||||
if (result != S_OK && result != S_FALSE)
|
if (result != S_OK)
|
||||||
|
{
|
||||||
|
if (result != S_FALSE)
|
||||||
return result;
|
return result;
|
||||||
_fileIndex++;
|
}
|
||||||
_inStreamWithHashSpec->SetStream(stream);
|
|
||||||
_inStreamWithHashSpec->Init();
|
_stream = stream;
|
||||||
|
|
||||||
if (stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
_fileIsOpen = true;
|
|
||||||
CMyComPtr<IStreamGetSize> streamGetSize;
|
CMyComPtr<IStreamGetSize> streamGetSize;
|
||||||
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
|
stream.QueryInterface(IID_IStreamGetSize, &streamGetSize);
|
||||||
if (streamGetSize)
|
if (streamGetSize)
|
||||||
{
|
{
|
||||||
RINOK(streamGetSize->GetSize(&_currentSize));
|
if (streamGetSize->GetSize(&_size) == S_OK)
|
||||||
_currentSizeIsDefined = true;
|
_size_Defined = true;
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_index++;
|
||||||
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
Sizes.Add(0);
|
AddFileInfo(result == S_OK);
|
||||||
Processed.Add(result == S_OK);
|
|
||||||
AddDigest();
|
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFolderInStream::AddDigest()
|
void CFolderInStream::AddFileInfo(bool isProcessed)
|
||||||
{
|
{
|
||||||
CRCs.Add(_inStreamWithHashSpec->GetCRC());
|
Processed.Add(isProcessed);
|
||||||
}
|
Sizes.Add(_pos);
|
||||||
|
CRCs.Add(CRC_GET_DIGEST(_crc));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||||
{
|
{
|
||||||
if (processedSize != 0)
|
if (processedSize)
|
||||||
*processedSize = 0;
|
*processedSize = 0;
|
||||||
while (size > 0)
|
while (size != 0)
|
||||||
{
|
{
|
||||||
if (_fileIsOpen)
|
if (_stream)
|
||||||
{
|
{
|
||||||
UInt32 processed2;
|
UInt32 processed2;
|
||||||
RINOK(_inStreamWithHash->Read(data, size, &processed2));
|
RINOK(_stream->Read(data, size, &processed2));
|
||||||
if (processed2 == 0)
|
if (processed2 != 0)
|
||||||
{
|
{
|
||||||
RINOK(CloseStream());
|
_crc = CrcUpdate(_crc, data, processed2);
|
||||||
continue;
|
_pos += processed2;
|
||||||
}
|
if (processedSize)
|
||||||
if (processedSize != 0)
|
|
||||||
*processedSize = processed2;
|
*processedSize = processed2;
|
||||||
_filePos += processed2;
|
return S_OK;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (_fileIndex >= _numFiles)
|
|
||||||
|
_stream.Release();
|
||||||
|
_index++;
|
||||||
|
AddFileInfo(true);
|
||||||
|
|
||||||
|
_pos = 0;
|
||||||
|
_crc = CRC_INIT_VAL;
|
||||||
|
_size_Defined = false;
|
||||||
|
_size = 0;
|
||||||
|
|
||||||
|
RINOK(_updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_index >= _numFiles)
|
||||||
break;
|
break;
|
||||||
RINOK(OpenStream());
|
RINOK(OpenStream());
|
||||||
}
|
}
|
||||||
@@ -106,17 +113,23 @@ STDMETHODIMP CFolderInStream::Read(void *data, UInt32 size, UInt32 *processedSiz
|
|||||||
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
STDMETHODIMP CFolderInStream::GetSubStreamSize(UInt64 subStream, UInt64 *value)
|
||||||
{
|
{
|
||||||
*value = 0;
|
*value = 0;
|
||||||
unsigned index2 = (unsigned)subStream;
|
|
||||||
if (subStream > Sizes.Size())
|
if (subStream > Sizes.Size())
|
||||||
return E_FAIL;
|
return S_FALSE; // E_FAIL;
|
||||||
if (index2 < Sizes.Size())
|
|
||||||
|
unsigned index = (unsigned)subStream;
|
||||||
|
if (index < Sizes.Size())
|
||||||
{
|
{
|
||||||
*value = Sizes[index2];
|
*value = Sizes[index];
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
if (!_currentSizeIsDefined)
|
|
||||||
|
if (!_size_Defined)
|
||||||
|
{
|
||||||
|
*value = _pos;
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
*value = _currentSize;
|
}
|
||||||
|
|
||||||
|
*value = (_pos > _size ? _pos : _size);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,13 @@
|
|||||||
#ifndef __7Z_FOLDER_IN_STREAM_H
|
#ifndef __7Z_FOLDER_IN_STREAM_H
|
||||||
#define __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 "../../ICoder.h"
|
||||||
#include "../IArchive.h"
|
#include "../IArchive.h"
|
||||||
#include "../Common/InStreamWithCRC.h"
|
|
||||||
|
|
||||||
#include "7zItem.h"
|
|
||||||
|
|
||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
@@ -17,33 +19,34 @@ class CFolderInStream:
|
|||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
public CMyUnknownImp
|
public CMyUnknownImp
|
||||||
{
|
{
|
||||||
CSequentialInStreamWithCRC *_inStreamWithHashSpec;
|
CMyComPtr<ISequentialInStream> _stream;
|
||||||
CMyComPtr<ISequentialInStream> _inStreamWithHash;
|
UInt64 _pos;
|
||||||
|
UInt32 _crc;
|
||||||
|
bool _size_Defined;
|
||||||
|
UInt64 _size;
|
||||||
|
|
||||||
|
const UInt32 *_indexes;
|
||||||
|
unsigned _numFiles;
|
||||||
|
unsigned _index;
|
||||||
|
|
||||||
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
CMyComPtr<IArchiveUpdateCallback> _updateCallback;
|
||||||
|
|
||||||
bool _currentSizeIsDefined;
|
|
||||||
bool _fileIsOpen;
|
|
||||||
UInt64 _currentSize;
|
|
||||||
UInt64 _filePos;
|
|
||||||
const UInt32 *_fileIndices;
|
|
||||||
UInt32 _numFiles;
|
|
||||||
UInt32 _fileIndex;
|
|
||||||
|
|
||||||
HRESULT OpenStream();
|
HRESULT OpenStream();
|
||||||
HRESULT CloseStream();
|
void AddFileInfo(bool isProcessed);
|
||||||
void AddDigest();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRecordVector<bool> Processed;
|
CRecordVector<bool> Processed;
|
||||||
CRecordVector<UInt32> CRCs;
|
CRecordVector<UInt32> CRCs;
|
||||||
CRecordVector<UInt64> Sizes;
|
CRecordVector<UInt64> Sizes;
|
||||||
|
|
||||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
STDMETHOD(GetSubStreamSize)(UInt64 subStream, UInt64 *value);
|
||||||
|
|
||||||
CFolderInStream();
|
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *indexes, unsigned numFiles);
|
||||||
void Init(IArchiveUpdateCallback *updateCallback, const UInt32 *fileIndices, UInt32 numFiles);
|
|
||||||
|
bool WasFinished() const { return _index == _numFiles; }
|
||||||
|
|
||||||
UInt64 GetFullSize() const
|
UInt64 GetFullSize() const
|
||||||
{
|
{
|
||||||
UInt64 size = 0;
|
UInt64 size = 0;
|
||||||
|
|||||||
@@ -1,149 +1,3 @@
|
|||||||
// 7zFolderOutStream.cpp
|
// 7zFolderOutStream.cpp
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#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
|
#ifndef __7Z_FOLDER_OUT_STREAM_H
|
||||||
#define __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
|
#endif
|
||||||
|
|||||||
@@ -150,22 +150,12 @@ static char *AddProp32(char *s, const char *name, UInt32 v)
|
|||||||
|
|
||||||
void CHandler::AddMethodName(AString &s, UInt64 id)
|
void CHandler::AddMethodName(AString &s, UInt64 id)
|
||||||
{
|
{
|
||||||
UString methodName;
|
AString name;
|
||||||
FindMethod(EXTERNAL_CODECS_VARS id, methodName);
|
FindMethod(EXTERNAL_CODECS_VARS id, name);
|
||||||
if (methodName.IsEmpty())
|
if (name.IsEmpty())
|
||||||
{
|
|
||||||
for (unsigned i = 0; i < methodName.Len(); i++)
|
|
||||||
if (methodName[i] >= 0x80)
|
|
||||||
{
|
|
||||||
methodName.Empty();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (methodName.IsEmpty())
|
|
||||||
ConvertMethodIdToString(s, id);
|
ConvertMethodIdToString(s, id);
|
||||||
else
|
else
|
||||||
for (unsigned i = 0; i < methodName.Len(); i++)
|
s += name;
|
||||||
s += (char)methodName[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -186,8 +176,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
FOR_VECTOR (i, pm.IDs)
|
FOR_VECTOR (i, pm.IDs)
|
||||||
{
|
{
|
||||||
UInt64 id = pm.IDs[i];
|
UInt64 id = pm.IDs[i];
|
||||||
if (!s.IsEmpty())
|
s.Add_Space_if_NotEmpty();
|
||||||
s += ' ';
|
|
||||||
char temp[16];
|
char temp[16];
|
||||||
if (id == k_LZMA2)
|
if (id == k_LZMA2)
|
||||||
{
|
{
|
||||||
@@ -376,6 +365,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
|||||||
// numCoders == 0 ???
|
// numCoders == 0 ???
|
||||||
CNum numCoders = inByte.ReadNum();
|
CNum numCoders = inByte.ReadNum();
|
||||||
bool needSpace = false;
|
bool needSpace = false;
|
||||||
|
|
||||||
for (; numCoders != 0; numCoders--, needSpace = true)
|
for (; numCoders != 0; numCoders--, needSpace = true)
|
||||||
{
|
{
|
||||||
if (pos < 32) // max size of property
|
if (pos < 32) // max size of property
|
||||||
@@ -500,17 +490,8 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UString methodName;
|
AString methodName;
|
||||||
FindMethod(EXTERNAL_CODECS_VARS id64, 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)
|
if (needSpace)
|
||||||
temp[--pos] = ' ';
|
temp[--pos] = ' ';
|
||||||
if (methodName.IsEmpty())
|
if (methodName.IsEmpty())
|
||||||
@@ -522,10 +503,11 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
|||||||
break;
|
break;
|
||||||
pos -= len;
|
pos -= len;
|
||||||
for (unsigned i = 0; i < len; i++)
|
for (unsigned i = 0; i < len; i++)
|
||||||
temp[pos + i] = (char)methodName[i];
|
temp[pos + i] = methodName[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numCoders != 0 && pos >= 4)
|
if (numCoders != 0 && pos >= 4)
|
||||||
{
|
{
|
||||||
temp[--pos] = ' ';
|
temp[--pos] = ' ';
|
||||||
@@ -533,6 +515,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
|
|||||||
temp[--pos] = '.';
|
temp[--pos] = '.';
|
||||||
temp[--pos] = '.';
|
temp[--pos] = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return PropVarEm_Set_Str(prop, 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];
|
const CFileItem &item = _db.Files[index];
|
||||||
UInt32 index2 = index;
|
UInt32 index2 = index;
|
||||||
|
|
||||||
switch(propID)
|
switch (propID)
|
||||||
{
|
{
|
||||||
case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break;
|
case kpidIsDir: PropVarEm_Set_Bool(value, item.IsDir); break;
|
||||||
case kpidSize:
|
case kpidSize:
|
||||||
@@ -608,7 +591,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
case kpidPath: return _db.GetPath_Prop(index, value);
|
case kpidPath: return _db.GetPath_Prop(index, value);
|
||||||
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
|
|
||||||
case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
|
case kpidMethod: return SetMethodToProp(_db.FileIndexToFolderIndexMap[index2], value);
|
||||||
case kpidBlock:
|
case kpidBlock:
|
||||||
{
|
{
|
||||||
@@ -617,30 +602,29 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
|
PropVarEm_Set_UInt32(value, (UInt32)folderIndex);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
case kpidPackedSize0:
|
case kpidPackedSize0:
|
||||||
case kpidPackedSize1:
|
case kpidPackedSize1:
|
||||||
case kpidPackedSize2:
|
case kpidPackedSize2:
|
||||||
case kpidPackedSize3:
|
case kpidPackedSize3:
|
||||||
case kpidPackedSize4:
|
case kpidPackedSize4:
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
||||||
if (folderIndex != kNumNoIndex)
|
if (folderIndex != kNumNoIndex)
|
||||||
{
|
{
|
||||||
const CFolder &folderInfo = _db.Folders[folderIndex];
|
|
||||||
if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
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
|
else
|
||||||
prop = (UInt64)0;
|
PropVarEm_Set_UInt64(value, 0);
|
||||||
}
|
|
||||||
else
|
|
||||||
prop = (UInt64)0;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// prop.Detach(value);
|
// prop.Detach(value);
|
||||||
@@ -668,7 +652,13 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
|
openArchiveCallbackTemp.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CInArchive archive;
|
CInArchive archive(
|
||||||
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
|
_useMultiThreadMixer
|
||||||
|
#else
|
||||||
|
true
|
||||||
|
#endif
|
||||||
|
);
|
||||||
_db.IsArc = false;
|
_db.IsArc = false;
|
||||||
RINOK(archive.Open(stream, maxCheckStartPosition));
|
RINOK(archive.Open(stream, maxCheckStartPosition));
|
||||||
_db.IsArc = true;
|
_db.IsArc = true;
|
||||||
@@ -677,7 +667,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
_db
|
_db
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
, getTextPassword, _isEncrypted, _passwordIsDefined
|
, getTextPassword, _isEncrypted, _passwordIsDefined, _password
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
@@ -688,8 +678,9 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
|
|||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
// return E_INVALIDARG;
|
// return E_INVALIDARG;
|
||||||
|
// return S_FALSE;
|
||||||
// we must return out_of_memory here
|
// we must return out_of_memory here
|
||||||
return S_FALSE;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
// _inStream = stream;
|
// _inStream = stream;
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
@@ -707,6 +698,7 @@ STDMETHODIMP CHandler::Close()
|
|||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
_isEncrypted = false;
|
_isEncrypted = false;
|
||||||
_passwordIsDefined = false;
|
_passwordIsDefined = false;
|
||||||
|
_password.Empty();
|
||||||
#endif
|
#endif
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
@@ -715,11 +707,12 @@ STDMETHODIMP CHandler::Close()
|
|||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
#ifdef EXTRACT_ONLY
|
#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
|
COM_TRY_BEGIN
|
||||||
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
||||||
_numThreads = numProcessors;
|
_numThreads = numProcessors;
|
||||||
|
_useMultiThreadMixer = true;
|
||||||
|
|
||||||
for (UInt32 i = 0; i < numProps; i++)
|
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);
|
int index = ParseStringToUInt32(name, number);
|
||||||
if (index == 0)
|
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));
|
RINOK(ParseMtProp(name.Ptr(2), value, numProcessors, _numThreads));
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -18,16 +18,6 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
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
|
#ifndef __7Z_SET_PROPERTIES
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
@@ -64,7 +54,9 @@ public:
|
|||||||
CBoolPair Write_ATime;
|
CBoolPair Write_ATime;
|
||||||
CBoolPair Write_MTime;
|
CBoolPair Write_MTime;
|
||||||
|
|
||||||
bool _volumeMode;
|
bool _useMultiThreadMixer;
|
||||||
|
|
||||||
|
// bool _volumeMode;
|
||||||
|
|
||||||
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
|
void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
|
||||||
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
|
void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
|
||||||
@@ -117,7 +109,7 @@ public:
|
|||||||
INTERFACE_IArchiveGetRawProps(;)
|
INTERFACE_IArchiveGetRawProps(;)
|
||||||
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef EXTRACT_ONLY
|
#ifndef EXTRACT_ONLY
|
||||||
@@ -131,28 +123,29 @@ public:
|
|||||||
private:
|
private:
|
||||||
CMyComPtr<IInStream> _inStream;
|
CMyComPtr<IInStream> _inStream;
|
||||||
NArchive::N7z::CDbEx _db;
|
NArchive::N7z::CDbEx _db;
|
||||||
|
|
||||||
#ifndef _NO_CRYPTO
|
#ifndef _NO_CRYPTO
|
||||||
bool _isEncrypted;
|
bool _isEncrypted;
|
||||||
bool _passwordIsDefined;
|
bool _passwordIsDefined;
|
||||||
|
UString _password;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef EXTRACT_ONLY
|
#ifdef EXTRACT_ONLY
|
||||||
|
|
||||||
#ifdef __7Z_SET_PROPERTIES
|
#ifdef __7Z_SET_PROPERTIES
|
||||||
UInt32 _numThreads;
|
UInt32 _numThreads;
|
||||||
|
bool _useMultiThreadMixer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UInt32 _crcSize;
|
UInt32 _crcSize;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
CRecordVector<CBind> _binds;
|
CRecordVector<CBond2> _bonds;
|
||||||
|
|
||||||
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
|
HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
|
||||||
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
|
HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
|
||||||
void AddDefaultMethod();
|
HRESULT SetMainMethod(CCompressionMethodMode &method
|
||||||
HRESULT SetMainMethod(CCompressionMethodMode &method,
|
|
||||||
CObjectVector<COneMethodInfo> &methodsInfo
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, UInt32 numThreads
|
, UInt32 numThreads
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ using namespace NWindows;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static const wchar_t *k_LZMA_Name = L"LZMA";
|
static const char *k_LZMA_Name = "LZMA";
|
||||||
static const wchar_t *kDefaultMethodName = L"LZMA2";
|
static const char *kDefaultMethodName = "LZMA2";
|
||||||
static const wchar_t *k_Copy_Name = L"Copy";
|
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_NumFastBytes_ForHeaders = 273;
|
||||||
static const UInt32 k_Level_ForHeaders = 5;
|
static const UInt32 k_Level_ForHeaders = 5;
|
||||||
static const UInt32 k_Dictionary_ForHeaders =
|
static const UInt32 k_Dictionary_ForHeaders =
|
||||||
@@ -42,7 +42,7 @@ HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodI
|
|||||||
{
|
{
|
||||||
if (!FindMethod(
|
if (!FindMethod(
|
||||||
EXTERNAL_CODECS_VARS
|
EXTERNAL_CODECS_VARS
|
||||||
m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
|
m.MethodName, dest.Id, dest.NumStreams))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
(CProps &)dest = (CProps &)m;
|
(CProps &)dest = (CProps &)m;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -54,48 +54,62 @@ HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
COneMethodInfo m;
|
COneMethodInfo m;
|
||||||
m.MethodName = k_LZMA_Name;
|
m.MethodName = k_LZMA_Name;
|
||||||
m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
|
m.AddProp_Ascii(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
|
||||||
m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
|
m.AddProp_Level(k_Level_ForHeaders);
|
||||||
m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
|
m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
|
||||||
m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
|
m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
|
||||||
m.AddNumThreadsProp(1);
|
m.AddProp_NumThreads(1);
|
||||||
|
|
||||||
CMethodFull methodFull;
|
CMethodFull &methodFull = headerMethod.Methods.AddNew();
|
||||||
RINOK(PropsMethod_To_FullMethod(methodFull, m));
|
return 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CHandler::SetMainMethod(
|
HRESULT CHandler::SetMainMethod(
|
||||||
CCompressionMethodMode &methodMode,
|
CCompressionMethodMode &methodMode
|
||||||
CObjectVector<COneMethodInfo> &methods
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, UInt32 numThreads
|
, UInt32 numThreads
|
||||||
#endif
|
#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_Min = (1 << 24);
|
||||||
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
|
const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
|
||||||
|
|
||||||
bool needSolid = false;
|
bool needSolid = false;
|
||||||
|
|
||||||
FOR_VECTOR (i, methods)
|
FOR_VECTOR (i, methods)
|
||||||
{
|
{
|
||||||
COneMethodInfo &oneMethodInfo = methods[i];
|
COneMethodInfo &oneMethodInfo = methods[i];
|
||||||
@@ -105,9 +119,8 @@ HRESULT CHandler::SetMainMethod(
|
|||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
CMethodFull methodFull;
|
CMethodFull &methodFull = methodMode.Methods.AddNew();
|
||||||
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
|
||||||
methodMode.Methods.Add(methodFull);
|
|
||||||
|
|
||||||
if (methodFull.Id != k_Copy)
|
if (methodFull.Id != k_Copy)
|
||||||
needSolid = true;
|
needSolid = true;
|
||||||
@@ -125,6 +138,7 @@ HRESULT CHandler::SetMainMethod(
|
|||||||
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
|
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
|
||||||
default: continue;
|
default: continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_numSolidBytes = (UInt64)dicSize << 7;
|
_numSolidBytes = (UInt64)dicSize << 7;
|
||||||
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
|
if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
|
||||||
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
|
if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
|
||||||
@@ -517,18 +531,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
CCompressionMethodMode methodMode, headerMethod;
|
CCompressionMethodMode methodMode, headerMethod;
|
||||||
|
|
||||||
HRESULT res = SetMainMethod(methodMode, _methods
|
HRESULT res = SetMainMethod(methodMode
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
, _numThreads
|
, _numThreads
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
methodMode.Binds = _binds;
|
|
||||||
|
|
||||||
RINOK(SetHeaderMethod(headerMethod));
|
RINOK(SetHeaderMethod(headerMethod));
|
||||||
|
|
||||||
#ifndef _7ZIP_ST
|
#ifndef _7ZIP_ST
|
||||||
methodMode.NumThreads = _numThreads;
|
methodMode.NumThreads = _numThreads;
|
||||||
|
methodMode.MultiThreadMixer = _useMultiThreadMixer;
|
||||||
headerMethod.NumThreads = 1;
|
headerMethod.NumThreads = 1;
|
||||||
|
headerMethod.MultiThreadMixer = _useMultiThreadMixer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CMyComPtr<ICryptoGetTextPassword2> getPassword2;
|
CMyComPtr<ICryptoGetTextPassword2> getPassword2;
|
||||||
@@ -542,7 +558,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
Int32 passwordIsDefined;
|
Int32 passwordIsDefined;
|
||||||
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
|
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
|
||||||
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
|
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
|
||||||
if (methodMode.PasswordIsDefined && (BSTR)password)
|
if (methodMode.PasswordIsDefined && password)
|
||||||
methodMode.Password = password;
|
methodMode.Password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,6 +566,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
|
|
||||||
bool encryptHeaders = false;
|
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 (methodMode.PasswordIsDefined)
|
||||||
{
|
{
|
||||||
if (_encryptHeadersSpecified)
|
if (_encryptHeadersSpecified)
|
||||||
@@ -569,12 +594,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
if (numItems < 2)
|
if (numItems < 2)
|
||||||
compressMainHeader = false;
|
compressMainHeader = false;
|
||||||
|
|
||||||
|
int level = GetLevel();
|
||||||
|
|
||||||
CUpdateOptions options;
|
CUpdateOptions options;
|
||||||
options.Method = &methodMode;
|
options.Method = &methodMode;
|
||||||
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
|
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : NULL;
|
||||||
int level = GetLevel();
|
options.UseFilters = (level != 0 && _autoFilter && !methodMode.Filter_was_Inserted);
|
||||||
options.UseFilters = level != 0 && _autoFilter;
|
options.MaxFilter = (level >= 8);
|
||||||
options.MaxFilter = level >= 8;
|
options.AnalysisLevel = GetAnalysisLevel();
|
||||||
|
|
||||||
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
options.HeaderOptions.CompressMainHeader = compressMainHeader;
|
||||||
/*
|
/*
|
||||||
@@ -587,7 +614,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
options.NumSolidBytes = _numSolidBytes;
|
options.NumSolidBytes = _numSolidBytes;
|
||||||
options.SolidExtension = _solidExtension;
|
options.SolidExtension = _solidExtension;
|
||||||
options.RemoveSfxBlock = _removeSfxBlock;
|
options.RemoveSfxBlock = _removeSfxBlock;
|
||||||
options.VolumeMode = _volumeMode;
|
// options.VolumeMode = _volumeMode;
|
||||||
|
|
||||||
|
options.MultiThreadMixer = _useMultiThreadMixer;
|
||||||
|
|
||||||
COutArchive archive;
|
COutArchive archive;
|
||||||
CArchiveDatabaseOut newDatabase;
|
CArchiveDatabaseOut newDatabase;
|
||||||
@@ -635,20 +664,20 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
|
static HRESULT ParseBond(UString &srcString, UInt32 &coder, UInt32 &stream)
|
||||||
{
|
{
|
||||||
stream = 0;
|
stream = 0;
|
||||||
int index = ParseStringToUInt32(srcString, coder);
|
int index = ParseStringToUInt32(srcString, coder);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
srcString.Delete(0, index);
|
srcString.DeleteFrontal(index);
|
||||||
if (srcString[0] == 's')
|
if (srcString[0] == 's')
|
||||||
{
|
{
|
||||||
srcString.Delete(0);
|
srcString.Delete(0);
|
||||||
int index = ParseStringToUInt32(srcString, stream);
|
int index = ParseStringToUInt32(srcString, stream);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
srcString.Delete(0, index);
|
srcString.DeleteFrontal(index);
|
||||||
}
|
}
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
@@ -667,7 +696,10 @@ void COutHandler::InitProps()
|
|||||||
Write_ATime.Init();
|
Write_ATime.Init();
|
||||||
Write_MTime.Init();
|
Write_MTime.Init();
|
||||||
|
|
||||||
_volumeMode = false;
|
_useMultiThreadMixer = true;
|
||||||
|
|
||||||
|
// _volumeMode = false;
|
||||||
|
|
||||||
InitSolid();
|
InitSolid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,7 +794,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
|||||||
|
|
||||||
UInt32 number;
|
UInt32 number;
|
||||||
int index = ParseStringToUInt32(name, number);
|
int index = ParseStringToUInt32(name, number);
|
||||||
UString realName = name.Ptr(index);
|
// UString realName = name.Ptr(index);
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
|
if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
|
||||||
@@ -787,15 +819,17 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
|
|||||||
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
|
if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
|
||||||
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
|
if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
|
||||||
|
|
||||||
if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
|
if (name.IsEqualTo("mtf")) return PROPVARIANT_to_bool(value, _useMultiThreadMixer);
|
||||||
|
|
||||||
|
// if (name.IsEqualTo("v")) return PROPVARIANT_to_bool(value, _volumeMode);
|
||||||
}
|
}
|
||||||
return CMultiMethodProps::SetProperty(name, value);
|
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
|
COM_TRY_BEGIN
|
||||||
_binds.Clear();
|
_bonds.Clear();
|
||||||
InitProps();
|
InitProps();
|
||||||
|
|
||||||
for (UInt32 i = 0; i < numProps; i++)
|
for (UInt32 i = 0; i < numProps; i++)
|
||||||
@@ -812,15 +846,19 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
if (value.vt != VT_EMPTY)
|
if (value.vt != VT_EMPTY)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
name.Delete(0);
|
name.Delete(0);
|
||||||
CBind bind;
|
|
||||||
RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
|
CBond2 bond;
|
||||||
|
RINOK(ParseBond(name, bond.OutCoder, bond.OutStream));
|
||||||
if (name[0] != ':')
|
if (name[0] != ':')
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
name.Delete(0);
|
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())
|
if (!name.IsEmpty())
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
_binds.Add(bind);
|
_bonds.Add(bond);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -831,40 +869,27 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
|
|||||||
if (numEmptyMethods > 0)
|
if (numEmptyMethods > 0)
|
||||||
{
|
{
|
||||||
unsigned k;
|
unsigned k;
|
||||||
for (k = 0; k < _binds.Size(); k++)
|
for (k = 0; k < _bonds.Size(); k++)
|
||||||
{
|
{
|
||||||
const CBind &bind = _binds[k];
|
const CBond2 &bond = _bonds[k];
|
||||||
if (bind.InCoder < (UInt32)numEmptyMethods ||
|
if (bond.InCoder < (UInt32)numEmptyMethods ||
|
||||||
bind.OutCoder < (UInt32)numEmptyMethods)
|
bond.OutCoder < (UInt32)numEmptyMethods)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
for (k = 0; k < _binds.Size(); k++)
|
for (k = 0; k < _bonds.Size(); k++)
|
||||||
{
|
{
|
||||||
CBind &bind = _binds[k];
|
CBond2 &bond = _bonds[k];
|
||||||
bind.InCoder -= (UInt32)numEmptyMethods;
|
bond.InCoder -= (UInt32)numEmptyMethods;
|
||||||
bind.OutCoder -= (UInt32)numEmptyMethods;
|
bond.OutCoder -= (UInt32)numEmptyMethods;
|
||||||
}
|
}
|
||||||
_methods.DeleteFrontal(numEmptyMethods);
|
_methods.DeleteFrontal(numEmptyMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddDefaultMethod();
|
FOR_VECTOR (k, _bonds)
|
||||||
|
|
||||||
if (!_filterMethod.MethodName.IsEmpty())
|
|
||||||
{
|
{
|
||||||
FOR_VECTOR (k, _binds)
|
const CBond2 &bond = _bonds[k];
|
||||||
{
|
if (bond.InCoder >= (UInt32)_methods.Size() ||
|
||||||
CBind &bind = _binds[k];
|
bond.OutCoder >= (UInt32)_methods.Size())
|
||||||
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())
|
|
||||||
return E_INVALIDARG;
|
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
|
#endif
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ using namespace NCOM;
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
static const UInt32 k_LZMA2 = 0x21;
|
|
||||||
static const UInt32 k_LZMA = 0x030101;
|
|
||||||
|
|
||||||
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
||||||
{
|
{
|
||||||
v.ClearAndSetSize(size);
|
v.ClearAndSetSize(size);
|
||||||
@@ -43,78 +40,6 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
|
|||||||
p[i] = false;
|
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 CInArchiveException {};
|
||||||
class CUnsupportedFeatureException: public CInArchiveException {};
|
class CUnsupportedFeatureException: public CInArchiveException {};
|
||||||
|
|
||||||
@@ -193,6 +118,8 @@ Byte CInByte2::ReadByte()
|
|||||||
|
|
||||||
void CInByte2::ReadBytes(Byte *data, size_t size)
|
void CInByte2::ReadBytes(Byte *data, size_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
if (size > _size - _pos)
|
if (size > _size - _pos)
|
||||||
ThrowEndOfData();
|
ThrowEndOfData();
|
||||||
memcpy(data, _buffer + _pos, size);
|
memcpy(data, _buffer + _pos, size);
|
||||||
@@ -218,41 +145,48 @@ static UInt64 ReadNumberSpec(const Byte *p, size_t size, size_t &processed)
|
|||||||
processed = 0;
|
processed = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Byte firstByte = *p++;
|
|
||||||
|
unsigned b = *p++;
|
||||||
size--;
|
size--;
|
||||||
if ((firstByte & 0x80) == 0)
|
|
||||||
|
if ((b & 0x80) == 0)
|
||||||
{
|
{
|
||||||
processed = 1;
|
processed = 1;
|
||||||
return firstByte;
|
return b;
|
||||||
}
|
}
|
||||||
Byte mask = 0x40;
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
processed = 0;
|
processed = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 value = (UInt64)*p;
|
UInt64 value = (UInt64)*p;
|
||||||
p++;
|
p++;
|
||||||
size--;
|
size--;
|
||||||
|
|
||||||
for (unsigned i = 1; i < 8; i++)
|
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);
|
UInt64 high = b & (mask - 1);
|
||||||
value += (highPart << (i * 8));
|
value |= (high << (i * 8));
|
||||||
processed = i + 1;
|
processed = i + 1;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
processed = 0;
|
processed = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
value |= ((UInt64)*p << (i * 8));
|
value |= ((UInt64)*p << (i * 8));
|
||||||
p++;
|
p++;
|
||||||
size--;
|
size--;
|
||||||
mask >>= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
processed = 9;
|
processed = 9;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -344,6 +278,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
UInt32 readSize = kBufSize - kHeaderSize;
|
UInt32 readSize = kBufSize - kHeaderSize;
|
||||||
|
if (searchHeaderSizeLimit)
|
||||||
{
|
{
|
||||||
UInt64 rem = *searchHeaderSizeLimit - offset;
|
UInt64 rem = *searchHeaderSizeLimit - offset;
|
||||||
if (readSize > rem)
|
if (readSize > rem)
|
||||||
@@ -351,10 +286,12 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
|||||||
if (readSize == 0)
|
if (readSize == 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt32 processed = 0;
|
UInt32 processed = 0;
|
||||||
RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
|
RINOK(stream->Read(buf + kHeaderSize, readSize, &processed));
|
||||||
if (processed == 0)
|
if (processed == 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
for (UInt32 pos = 0;;)
|
for (UInt32 pos = 0;;)
|
||||||
{
|
{
|
||||||
const Byte *p = buf + pos + 1;
|
const Byte *p = buf + pos + 1;
|
||||||
@@ -376,6 +313,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
|
|||||||
return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
|
return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += processed;
|
offset += processed;
|
||||||
memmove(buf, buf + processed, kHeaderSize);
|
memmove(buf, buf + processed, kHeaderSize);
|
||||||
}
|
}
|
||||||
@@ -415,13 +353,15 @@ void CInArchive::ReadArchiveProperties(CInArchiveInfo & /* archiveInfo */)
|
|||||||
|
|
||||||
void CInByte2::ParseFolder(CFolder &folder)
|
void CInByte2::ParseFolder(CFolder &folder)
|
||||||
{
|
{
|
||||||
CNum numCoders = ReadNum();
|
UInt32 numCoders = ReadNum();
|
||||||
|
|
||||||
|
if (numCoders == 0)
|
||||||
|
ThrowUnsupported();
|
||||||
|
|
||||||
folder.Coders.SetSize(numCoders);
|
folder.Coders.SetSize(numCoders);
|
||||||
|
|
||||||
CNum numInStreams = 0;
|
UInt32 numInStreams = 0;
|
||||||
CNum numOutStreams = 0;
|
UInt32 i;
|
||||||
CNum i;
|
|
||||||
for (i = 0; i < numCoders; i++)
|
for (i = 0; i < numCoders; i++)
|
||||||
{
|
{
|
||||||
CCoderInfo &coder = folder.Coders[i];
|
CCoderInfo &coder = folder.Coders[i];
|
||||||
@@ -441,14 +381,14 @@ void CInByte2::ParseFolder(CFolder &folder)
|
|||||||
|
|
||||||
if ((mainByte & 0x10) != 0)
|
if ((mainByte & 0x10) != 0)
|
||||||
{
|
{
|
||||||
coder.NumInStreams = ReadNum();
|
coder.NumStreams = ReadNum();
|
||||||
coder.NumOutStreams = ReadNum();
|
/* numOutStreams = */ ReadNum();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
coder.NumInStreams = 1;
|
coder.NumStreams = 1;
|
||||||
coder.NumOutStreams = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mainByte & 0x20) != 0)
|
if ((mainByte & 0x20) != 0)
|
||||||
{
|
{
|
||||||
CNum propsSize = ReadNum();
|
CNum propsSize = ReadNum();
|
||||||
@@ -458,27 +398,27 @@ void CInByte2::ParseFolder(CFolder &folder)
|
|||||||
else
|
else
|
||||||
coder.Props.Free();
|
coder.Props.Free();
|
||||||
}
|
}
|
||||||
numInStreams += coder.NumInStreams;
|
numInStreams += coder.NumStreams;
|
||||||
numOutStreams += coder.NumOutStreams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CNum numBindPairs = numOutStreams - 1;
|
UInt32 numBonds = numCoders - 1;
|
||||||
folder.BindPairs.SetSize(numBindPairs);
|
folder.Bonds.SetSize(numBonds);
|
||||||
for (i = 0; i < numBindPairs; i++)
|
for (i = 0; i < numBonds; i++)
|
||||||
{
|
{
|
||||||
CBindPair &bp = folder.BindPairs[i];
|
CBond &bp = folder.Bonds[i];
|
||||||
bp.InIndex = ReadNum();
|
bp.PackIndex = ReadNum();
|
||||||
bp.OutIndex = ReadNum();
|
bp.UnpackIndex = ReadNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numInStreams < numBindPairs)
|
if (numInStreams < numBonds)
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
CNum numPackStreams = numInStreams - numBindPairs;
|
UInt32 numPackStreams = numInStreams - numBonds;
|
||||||
folder.PackStreams.SetSize(numPackStreams);
|
folder.PackStreams.SetSize(numPackStreams);
|
||||||
|
|
||||||
if (numPackStreams == 1)
|
if (numPackStreams == 1)
|
||||||
{
|
{
|
||||||
for (i = 0; i < numInStreams; i++)
|
for (i = 0; i < numInStreams; i++)
|
||||||
if (folder.FindBindPairForInStream(i) < 0)
|
if (folder.FindBond_for_PackStream(i) < 0)
|
||||||
{
|
{
|
||||||
folder.PackStreams[0] = i;
|
folder.PackStreams[0] = i;
|
||||||
break;
|
break;
|
||||||
@@ -509,12 +449,12 @@ void CDatabase::GetPath(unsigned index, UString &path) const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
size_t offset = NameOffsets[index];
|
size_t offset = NameOffsets[index];
|
||||||
size_t size = NameOffsets[index + 1] - offset - 1;
|
size_t size = NameOffsets[index + 1] - offset;
|
||||||
|
|
||||||
if (size >= (1 << 20))
|
if (size >= (1 << 28))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wchar_t *s = path.GetBuffer((unsigned)size);
|
wchar_t *s = path.GetBuf((unsigned)size - 1);
|
||||||
|
|
||||||
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
|
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
|
||||||
|
|
||||||
@@ -533,7 +473,7 @@ void CDatabase::GetPath(unsigned index, UString &path) const
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
path.ReleaseBuffer((unsigned)size);
|
path.ReleaseBuf_SetLen((unsigned)size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
||||||
@@ -592,7 +532,7 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
|||||||
{
|
{
|
||||||
unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1);
|
unsigned len = (unsigned)(NameOffsets[cur + 1] - NameOffsets[cur] - 1);
|
||||||
const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2;
|
const Byte *p = (const Byte *)NamesBuf + (NameOffsets[cur + 1] * 2) - 2;
|
||||||
do
|
for (; len != 0; len--)
|
||||||
{
|
{
|
||||||
p -= 2;
|
p -= 2;
|
||||||
--s;
|
--s;
|
||||||
@@ -601,7 +541,7 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
|
|||||||
c = WCHAR_PATH_SEPARATOR;
|
c = WCHAR_PATH_SEPARATOR;
|
||||||
*s = c;
|
*s = c;
|
||||||
}
|
}
|
||||||
while (--len);
|
|
||||||
const CFileItem &file = Files[cur];
|
const CFileItem &file = Files[cur];
|
||||||
cur = file.Parent;
|
cur = file.Parent;
|
||||||
if (cur < 0)
|
if (cur < 0)
|
||||||
@@ -639,6 +579,9 @@ void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define k_Scan_NumCoders_MAX 64
|
||||||
|
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
|
||||||
|
|
||||||
void CInArchive::ReadPackInfo(CFolders &f)
|
void CInArchive::ReadPackInfo(CFolders &f)
|
||||||
{
|
{
|
||||||
CNum numPackStreams = ReadNum();
|
CNum numPackStreams = ReadNum();
|
||||||
@@ -692,27 +635,31 @@ void CInArchive::ReadUnpackInfo(
|
|||||||
folders.FoCodersDataOffset.Alloc(numFolders + 1);
|
folders.FoCodersDataOffset.Alloc(numFolders + 1);
|
||||||
folders.FoToCoderUnpackSizes.Alloc(numFolders + 1);
|
folders.FoToCoderUnpackSizes.Alloc(numFolders + 1);
|
||||||
|
|
||||||
CRecordVector<bool> InStreamUsed;
|
CBoolVector StreamUsed;
|
||||||
CRecordVector<bool> OutStreamUsed;
|
CBoolVector CoderUsed;
|
||||||
|
|
||||||
CNum packStreamIndex = 0;
|
CNum packStreamIndex = 0;
|
||||||
CNum fo;
|
CNum fo;
|
||||||
CInByte2 *inByte = _inByteBack;
|
CInByte2 *inByte = _inByteBack;
|
||||||
|
|
||||||
for (fo = 0; fo < numFolders; fo++)
|
for (fo = 0; fo < numFolders; fo++)
|
||||||
{
|
{
|
||||||
UInt32 numOutStreams = 0;
|
|
||||||
UInt32 indexOfMainStream = 0;
|
UInt32 indexOfMainStream = 0;
|
||||||
UInt32 numPackStreams = 0;
|
UInt32 numPackStreams = 0;
|
||||||
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
|
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
|
||||||
|
|
||||||
numOutStreams = 0;
|
|
||||||
CNum numInStreams = 0;
|
CNum numInStreams = 0;
|
||||||
CNum numCoders = inByte->ReadNum();
|
CNum numCoders = inByte->ReadNum();
|
||||||
|
|
||||||
|
if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
|
||||||
|
ThrowUnsupported();
|
||||||
|
|
||||||
for (CNum ci = 0; ci < numCoders; ci++)
|
for (CNum ci = 0; ci < numCoders; ci++)
|
||||||
{
|
{
|
||||||
Byte mainByte = inByte->ReadByte();
|
Byte mainByte = inByte->ReadByte();
|
||||||
if ((mainByte & 0xC0) != 0)
|
if ((mainByte & 0xC0) != 0)
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
|
|
||||||
unsigned idSize = (mainByte & 0xF);
|
unsigned idSize = (mainByte & 0xF);
|
||||||
if (idSize > 8)
|
if (idSize > 8)
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
@@ -725,19 +672,21 @@ void CInArchive::ReadUnpackInfo(
|
|||||||
inByte->SkipDataNoCheck(idSize);
|
inByte->SkipDataNoCheck(idSize);
|
||||||
if (folders.ParsedMethods.IDs.Size() < 128)
|
if (folders.ParsedMethods.IDs.Size() < 128)
|
||||||
folders.ParsedMethods.IDs.AddToUniqueSorted(id);
|
folders.ParsedMethods.IDs.AddToUniqueSorted(id);
|
||||||
|
|
||||||
CNum coderInStreams = 1;
|
CNum coderInStreams = 1;
|
||||||
CNum coderOutStreams = 1;
|
|
||||||
if ((mainByte & 0x10) != 0)
|
if ((mainByte & 0x10) != 0)
|
||||||
{
|
{
|
||||||
coderInStreams = inByte->ReadNum();
|
coderInStreams = inByte->ReadNum();
|
||||||
coderOutStreams = inByte->ReadNum();
|
if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
|
||||||
|
ThrowUnsupported();
|
||||||
|
if (inByte->ReadNum() != 1)
|
||||||
|
ThrowUnsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
numInStreams += coderInStreams;
|
numInStreams += coderInStreams;
|
||||||
if (numInStreams < coderInStreams)
|
if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
|
||||||
ThrowUnsupported();
|
|
||||||
numOutStreams += coderOutStreams;
|
|
||||||
if (numOutStreams < coderOutStreams)
|
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
|
|
||||||
if ((mainByte & 0x20) != 0)
|
if ((mainByte & 0x20) != 0)
|
||||||
{
|
{
|
||||||
CNum propsSize = inByte->ReadNum();
|
CNum propsSize = inByte->ReadNum();
|
||||||
@@ -759,7 +708,7 @@ void CInArchive::ReadUnpackInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numOutStreams == 1 && numInStreams == 1)
|
if (numCoders == 1 && numInStreams == 1)
|
||||||
{
|
{
|
||||||
indexOfMainStream = 0;
|
indexOfMainStream = 0;
|
||||||
numPackStreams = 1;
|
numPackStreams = 1;
|
||||||
@@ -767,55 +716,55 @@ void CInArchive::ReadUnpackInfo(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
if (numOutStreams == 0)
|
CNum numBonds = numCoders - 1;
|
||||||
ThrowUnsupported();
|
if (numInStreams < numBonds)
|
||||||
CNum numBindPairs = numOutStreams - 1;
|
|
||||||
if (numInStreams < numBindPairs)
|
|
||||||
ThrowUnsupported();
|
|
||||||
if (numInStreams >= 256 || numOutStreams >= 256)
|
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
|
|
||||||
InStreamUsed.ClearAndSetSize(numInStreams);
|
BoolVector_Fill_False(StreamUsed, numInStreams);
|
||||||
for (i = 0; i < numInStreams; i++)
|
BoolVector_Fill_False(CoderUsed, numCoders);
|
||||||
InStreamUsed[i] = false;
|
|
||||||
|
|
||||||
OutStreamUsed.ClearAndSetSize(numOutStreams);
|
for (i = 0; i < numBonds; i++)
|
||||||
for (i = 0; i < numOutStreams; i++)
|
|
||||||
OutStreamUsed[i] = false;
|
|
||||||
|
|
||||||
for (i = 0; i < numBindPairs; i++)
|
|
||||||
{
|
{
|
||||||
CNum index = ReadNum();
|
CNum index = ReadNum();
|
||||||
if (index >= numInStreams || InStreamUsed[index])
|
if (index >= numInStreams || StreamUsed[index])
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
InStreamUsed[index] = true;
|
StreamUsed[index] = true;
|
||||||
|
|
||||||
index = ReadNum();
|
index = ReadNum();
|
||||||
if (index >= numOutStreams || OutStreamUsed[index])
|
if (index >= numCoders || CoderUsed[index])
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
OutStreamUsed[index] = true;
|
CoderUsed[index] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
numPackStreams = numInStreams - numBindPairs;
|
numPackStreams = numInStreams - numBonds;
|
||||||
|
|
||||||
if (numPackStreams != 1)
|
if (numPackStreams != 1)
|
||||||
for (i = 0; i < numPackStreams; i++)
|
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++)
|
for (i = 0; i < numCoders; i++)
|
||||||
if (!OutStreamUsed[i])
|
if (!CoderUsed[i])
|
||||||
{
|
{
|
||||||
indexOfMainStream = i;
|
indexOfMainStream = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i == numOutStreams)
|
|
||||||
|
if (i == numCoders)
|
||||||
ThrowUnsupported();
|
ThrowUnsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
||||||
numCodersOutStreams += numOutStreams;
|
numCodersOutStreams += numCoders;
|
||||||
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||||
packStreamIndex += numPackStreams;
|
packStreamIndex += numPackStreams;
|
||||||
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
|
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
|
size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
|
||||||
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
|
||||||
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
|
||||||
@@ -1105,13 +1054,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
unpackSizes,
|
unpackSizes,
|
||||||
digests);
|
digests);
|
||||||
|
|
||||||
CDecoder decoder(
|
CDecoder decoder(_useMixerMT);
|
||||||
#ifdef _ST_MODE
|
|
||||||
false
|
|
||||||
#else
|
|
||||||
true
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
for (CNum i = 0; i < folders.NumFolders; i++)
|
for (CNum i = 0; i < folders.NumFolders; i++)
|
||||||
{
|
{
|
||||||
@@ -1130,10 +1073,16 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
|
|||||||
EXTERNAL_CODECS_LOC_VARS
|
EXTERNAL_CODECS_LOC_VARS
|
||||||
_stream, baseOffset + dataOffset,
|
_stream, baseOffset + dataOffset,
|
||||||
folders, i,
|
folders, i,
|
||||||
outStream, NULL
|
NULL, // *unpackSize
|
||||||
|
|
||||||
|
outStream,
|
||||||
|
NULL, // *compressProgress
|
||||||
|
NULL // **inStreamMainRes
|
||||||
|
|
||||||
_7Z_DECODER_CRYPRO_VARS
|
_7Z_DECODER_CRYPRO_VARS
|
||||||
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
#if !defined(_7ZIP_ST) && !defined(_SFX)
|
||||||
, false, 1
|
, false // mtMode
|
||||||
|
, 1 // numThreads
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
RINOK(result);
|
RINOK(result);
|
||||||
@@ -1396,6 +1345,9 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
|
|
||||||
type = ReadID(); // Read (NID::kEnd) end of headers
|
type = ReadID(); // Read (NID::kEnd) end of headers
|
||||||
|
|
||||||
|
if (numFiles - numEmptyStreams != unpackSizes.Size())
|
||||||
|
ThrowUnsupported();
|
||||||
|
|
||||||
CNum emptyFileIndex = 0;
|
CNum emptyFileIndex = 0;
|
||||||
CNum sizeIndex = 0;
|
CNum sizeIndex = 0;
|
||||||
|
|
||||||
@@ -1444,13 +1396,13 @@ HRESULT CInArchive::ReadHeader(
|
|||||||
|
|
||||||
void CDbEx::FillLinks()
|
void CDbEx::FillLinks()
|
||||||
{
|
{
|
||||||
FolderStartFileIndex.ClearAndSetSize(NumFolders);
|
FolderStartFileIndex.Alloc(NumFolders);
|
||||||
|
FileIndexToFolderIndexMap.Alloc(Files.Size());
|
||||||
FileIndexToFolderIndexMap.ClearAndSetSize(Files.Size());
|
|
||||||
|
|
||||||
CNum folderIndex = 0;
|
CNum folderIndex = 0;
|
||||||
CNum indexInFolder = 0;
|
CNum indexInFolder = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < Files.Size(); i++)
|
for (i = 0; i < Files.Size(); i++)
|
||||||
{
|
{
|
||||||
bool emptyStream = !Files[i].HasStream;
|
bool emptyStream = !Files[i].HasStream;
|
||||||
@@ -1489,6 +1441,7 @@ void CDbEx::FillLinks()
|
|||||||
if (indexInFolder != 0)
|
if (indexInFolder != 0)
|
||||||
ThrowIncorrect();
|
ThrowIncorrect();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (folderIndex >= NumFolders)
|
if (folderIndex >= NumFolders)
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ namespace N7z {
|
|||||||
#define _7Z_DECODER_CRYPRO_VARS_DECL
|
#define _7Z_DECODER_CRYPRO_VARS_DECL
|
||||||
#define _7Z_DECODER_CRYPRO_VARS
|
#define _7Z_DECODER_CRYPRO_VARS
|
||||||
#else
|
#else
|
||||||
#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined
|
#define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
|
||||||
#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined
|
#define _7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct CParsedMethods
|
struct CParsedMethods
|
||||||
@@ -39,6 +39,11 @@ struct CParsedMethods
|
|||||||
CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
|
CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CFolderEx: public CFolder
|
||||||
|
{
|
||||||
|
unsigned UnpackCoder;
|
||||||
|
};
|
||||||
|
|
||||||
struct CFolders
|
struct CFolders
|
||||||
{
|
{
|
||||||
CNum NumPackStreams;
|
CNum NumPackStreams;
|
||||||
@@ -50,7 +55,7 @@ struct CFolders
|
|||||||
CUInt32DefVector FolderCRCs; // NumFolders
|
CUInt32DefVector FolderCRCs; // NumFolders
|
||||||
CObjArray<CNum> NumUnpackStreamsVector; // 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> FoToCoderUnpackSizes; // NumFolders + 1
|
||||||
CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
|
CObjArray<CNum> FoStartPackStreamIndex; // NumFolders + 1
|
||||||
CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
|
CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
|
||||||
@@ -61,10 +66,15 @@ struct CFolders
|
|||||||
CParsedMethods ParsedMethods;
|
CParsedMethods ParsedMethods;
|
||||||
|
|
||||||
void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
|
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
|
unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
|
||||||
{
|
{
|
||||||
return FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex];
|
return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetFolderUnpackSize(unsigned folderIndex) const
|
UInt64 GetFolderUnpackSize(unsigned folderIndex) const
|
||||||
@@ -103,9 +113,9 @@ struct CDatabase: public CFolders
|
|||||||
CUInt64DefVector ATime;
|
CUInt64DefVector ATime;
|
||||||
CUInt64DefVector MTime;
|
CUInt64DefVector MTime;
|
||||||
CUInt64DefVector StartPos;
|
CUInt64DefVector StartPos;
|
||||||
CRecordVector<bool> IsAnti;
|
CBoolVector IsAnti;
|
||||||
/*
|
/*
|
||||||
CRecordVector<bool> IsAux;
|
CBoolVector IsAux;
|
||||||
CByteBuffer SecureBuf;
|
CByteBuffer SecureBuf;
|
||||||
CRecordVector<UInt32> SecureIDs;
|
CRecordVector<UInt32> SecureIDs;
|
||||||
*/
|
*/
|
||||||
@@ -148,13 +158,14 @@ struct CDatabase: public CFolders
|
|||||||
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
|
||||||
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
|
// bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
|
||||||
|
|
||||||
const void * GetName(unsigned index) const
|
/*
|
||||||
|
const void* GetName(unsigned index) const
|
||||||
{
|
{
|
||||||
if (!NameOffsets || !NamesBuf)
|
if (!NameOffsets || !NamesBuf)
|
||||||
return NULL;
|
return NULL;
|
||||||
return (const void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
|
return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
void GetPath(unsigned index, UString &path) const;
|
void GetPath(unsigned index, UString &path) const;
|
||||||
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
|
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
|
||||||
};
|
};
|
||||||
@@ -181,8 +192,9 @@ struct CInArchiveInfo
|
|||||||
struct CDbEx: public CDatabase
|
struct CDbEx: public CDatabase
|
||||||
{
|
{
|
||||||
CInArchiveInfo ArcInfo;
|
CInArchiveInfo ArcInfo;
|
||||||
CRecordVector<CNum> FolderStartFileIndex;
|
|
||||||
CRecordVector<CNum> FileIndexToFolderIndexMap;
|
CObjArray<CNum> FolderStartFileIndex;
|
||||||
|
CObjArray<CNum> FileIndexToFolderIndexMap;
|
||||||
|
|
||||||
UInt64 HeadersSize;
|
UInt64 HeadersSize;
|
||||||
UInt64 PhySize;
|
UInt64 PhySize;
|
||||||
@@ -234,8 +246,8 @@ struct CDbEx: public CDatabase
|
|||||||
|
|
||||||
// SecureOffsets.Clear();
|
// SecureOffsets.Clear();
|
||||||
ArcInfo.Clear();
|
ArcInfo.Clear();
|
||||||
FolderStartFileIndex.Clear();
|
FolderStartFileIndex.Free();
|
||||||
FileIndexToFolderIndexMap.Clear();
|
FileIndexToFolderIndexMap.Free();
|
||||||
|
|
||||||
HeadersSize = 0;
|
HeadersSize = 0;
|
||||||
PhySize = 0;
|
PhySize = 0;
|
||||||
@@ -243,22 +255,22 @@ struct CDbEx: public CDatabase
|
|||||||
|
|
||||||
void FillLinks();
|
void FillLinks();
|
||||||
|
|
||||||
UInt64 GetFolderStreamPos(unsigned folderIndex, unsigned indexInFolder) const
|
UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const
|
||||||
{
|
{
|
||||||
return ArcInfo.DataStartPosition +
|
return ArcInfo.DataStartPosition +
|
||||||
PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
|
PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
|
||||||
}
|
}
|
||||||
|
|
||||||
UInt64 GetFolderFullPackSize(unsigned folderIndex) const
|
UInt64 GetFolderFullPackSize(CNum folderIndex) const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
|
PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
|
||||||
PackPositions[FoStartPackStreamIndex[folderIndex]];
|
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];
|
return PackPositions[i + 1] - PackPositions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +339,8 @@ class CInArchive
|
|||||||
|
|
||||||
UInt64 HeadersSize;
|
UInt64 HeadersSize;
|
||||||
|
|
||||||
|
bool _useMixerMT;
|
||||||
|
|
||||||
void AddByteStream(const Byte *buffer, size_t size);
|
void AddByteStream(const Byte *buffer, size_t size);
|
||||||
|
|
||||||
void DeleteByteStream(bool needUpdatePos)
|
void DeleteByteStream(bool needUpdatePos)
|
||||||
@@ -340,7 +354,6 @@ class CInArchive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
|
HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
|
||||||
|
|
||||||
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
|
void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
|
||||||
@@ -396,7 +409,11 @@ private:
|
|||||||
_7Z_DECODER_CRYPRO_VARS_DECL
|
_7Z_DECODER_CRYPRO_VARS_DECL
|
||||||
);
|
);
|
||||||
public:
|
public:
|
||||||
CInArchive(): _numInByteBufs(0) { }
|
CInArchive(bool useMixerMT):
|
||||||
|
_numInByteBufs(0),
|
||||||
|
_useMixerMT(useMixerMT)
|
||||||
|
{}
|
||||||
|
|
||||||
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,6 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
const UInt64 k_AES = 0x06F10701;
|
|
||||||
|
|
||||||
typedef UInt32 CNum;
|
typedef UInt32 CNum;
|
||||||
const CNum kNumMax = 0x7FFFFFFF;
|
const CNum kNumMax = 0x7FFFFFFF;
|
||||||
const CNum kNumNoIndex = 0xFFFFFFFF;
|
const CNum kNumNoIndex = 0xFFFFFFFF;
|
||||||
@@ -23,71 +21,70 @@ struct CCoderInfo
|
|||||||
{
|
{
|
||||||
CMethodId MethodID;
|
CMethodId MethodID;
|
||||||
CByteBuffer Props;
|
CByteBuffer Props;
|
||||||
CNum NumInStreams;
|
UInt32 NumStreams;
|
||||||
CNum NumOutStreams;
|
|
||||||
|
|
||||||
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
|
bool IsSimpleCoder() const { return NumStreams == 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CBindPair
|
struct CBond
|
||||||
{
|
{
|
||||||
CNum InIndex;
|
UInt32 PackIndex;
|
||||||
CNum OutIndex;
|
UInt32 UnpackIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CFolder
|
struct CFolder
|
||||||
{
|
{
|
||||||
|
CLASS_NO_COPY(CFolder)
|
||||||
|
public:
|
||||||
CObjArray2<CCoderInfo> Coders;
|
CObjArray2<CCoderInfo> Coders;
|
||||||
CObjArray2<CBindPair> BindPairs;
|
CObjArray2<CBond> Bonds;
|
||||||
CObjArray2<CNum> PackStreams;
|
CObjArray2<UInt32> PackStreams;
|
||||||
|
|
||||||
CNum GetNumOutStreams() const
|
CFolder() {}
|
||||||
{
|
|
||||||
CNum result = 0;
|
|
||||||
FOR_VECTOR(i, Coders)
|
|
||||||
result += Coders[i].NumOutStreams;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindBindPairForInStream(CNum inStreamIndex) const
|
bool IsDecodingSupported() const { return Coders.Size() <= 32; }
|
||||||
{
|
|
||||||
FOR_VECTOR(i, BindPairs)
|
int Find_in_PackStreams(UInt32 packStream) const
|
||||||
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
|
|
||||||
{
|
{
|
||||||
FOR_VECTOR(i, PackStreams)
|
FOR_VECTOR(i, PackStreams)
|
||||||
if (PackStreams[i] == inStreamIndex)
|
if (PackStreams[i] == packStream)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetIndexOfMainOutStream() const
|
int FindBond_for_PackStream(UInt32 packStream) const
|
||||||
{
|
{
|
||||||
for (int i = (int)GetNumOutStreams() - 1; i >= 0; i--)
|
FOR_VECTOR(i, Bonds)
|
||||||
if (FindBindPairForOutStream(i) < 0)
|
if (Bonds[i].PackIndex == packStream)
|
||||||
return i;
|
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
|
bool IsEncrypted() const
|
||||||
{
|
{
|
||||||
for (int i = Coders.Size() - 1; i >= 0; i--)
|
FOR_VECTOR(i, Coders)
|
||||||
if (Coders[i].MethodID == k_AES)
|
if (Coders[i].MethodID == k_AES)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckStructure(unsigned numUnpackSizes) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CUInt32DefVector
|
struct CUInt32DefVector
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ void COutArchive::WriteNumber(UInt64 value)
|
|||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
}
|
}
|
||||||
WriteByte(firstByte);
|
WriteByte(firstByte);
|
||||||
for (;i > 0; i--)
|
for (; i > 0; i--)
|
||||||
{
|
{
|
||||||
WriteByte((Byte)value);
|
WriteByte((Byte)value);
|
||||||
value >>= 8;
|
value >>= 8;
|
||||||
@@ -254,31 +254,33 @@ void COutArchive::WriteFolder(const CFolder &folder)
|
|||||||
{
|
{
|
||||||
WriteNumber(folder.Coders.Size());
|
WriteNumber(folder.Coders.Size());
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < folder.Coders.Size(); i++)
|
for (i = 0; i < folder.Coders.Size(); i++)
|
||||||
{
|
{
|
||||||
const CCoderInfo &coder = folder.Coders[i];
|
const CCoderInfo &coder = folder.Coders[i];
|
||||||
{
|
{
|
||||||
size_t propsSize = coder.Props.Size();
|
|
||||||
|
|
||||||
UInt64 id = coder.MethodID;
|
UInt64 id = coder.MethodID;
|
||||||
int idSize;
|
unsigned idSize;
|
||||||
for (idSize = 1; idSize < sizeof(id); idSize++)
|
for (idSize = 1; idSize < sizeof(id); idSize++)
|
||||||
if ((id >> (8 * idSize)) == 0)
|
if ((id >> (8 * idSize)) == 0)
|
||||||
break;
|
break;
|
||||||
Byte longID[15];
|
idSize &= 0xF;
|
||||||
for (int t = idSize - 1; t >= 0 ; t--, id >>= 8)
|
Byte temp[16];
|
||||||
longID[t] = (Byte)(id & 0xFF);
|
for (unsigned t = idSize; t != 0; t--, id >>= 8)
|
||||||
Byte b;
|
temp[t] = (Byte)(id & 0xFF);
|
||||||
b = (Byte)(idSize & 0xF);
|
|
||||||
|
Byte b = (Byte)(idSize);
|
||||||
bool isComplex = !coder.IsSimpleCoder();
|
bool isComplex = !coder.IsSimpleCoder();
|
||||||
b |= (isComplex ? 0x10 : 0);
|
b |= (isComplex ? 0x10 : 0);
|
||||||
b |= ((propsSize != 0) ? 0x20 : 0 );
|
|
||||||
WriteByte(b);
|
size_t propsSize = coder.Props.Size();
|
||||||
WriteBytes(longID, idSize);
|
b |= ((propsSize != 0) ? 0x20 : 0);
|
||||||
|
temp[0] = b;
|
||||||
|
WriteBytes(temp, idSize + 1);
|
||||||
if (isComplex)
|
if (isComplex)
|
||||||
{
|
{
|
||||||
WriteNumber(coder.NumInStreams);
|
WriteNumber(coder.NumStreams);
|
||||||
WriteNumber(coder.NumOutStreams);
|
WriteNumber(1); // NumOutStreams;
|
||||||
}
|
}
|
||||||
if (propsSize == 0)
|
if (propsSize == 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -286,17 +288,17 @@ void COutArchive::WriteFolder(const CFolder &folder)
|
|||||||
WriteBytes(coder.Props, propsSize);
|
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];
|
const CBond &bond = folder.Bonds[i];
|
||||||
WriteNumber(bindPair.InIndex);
|
WriteNumber(bond.PackIndex);
|
||||||
WriteNumber(bindPair.OutIndex);
|
WriteNumber(bond.UnpackIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (folder.PackStreams.Size() > 1)
|
if (folder.PackStreams.Size() > 1)
|
||||||
for (i = 0; i < folder.PackStreams.Size(); i++)
|
for (i = 0; i < folder.PackStreams.Size(); i++)
|
||||||
{
|
|
||||||
WriteNumber(folder.PackStreams[i]);
|
WriteNumber(folder.PackStreams[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
|
void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
|
||||||
@@ -521,7 +523,10 @@ HRESULT COutArchive::EncodeStream(
|
|||||||
UInt64 unpackSize;
|
UInt64 unpackSize;
|
||||||
RINOK(encoder.Encode(
|
RINOK(encoder.Encode(
|
||||||
EXTERNAL_CODECS_LOC_VARS
|
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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ public:
|
|||||||
}
|
}
|
||||||
void WriteBytes(const void *data, size_t size)
|
void WriteBytes(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
if (size > _size - _pos)
|
if (size > _size - _pos)
|
||||||
throw 1;
|
throw 1;
|
||||||
memcpy(_data + _pos, data, size);
|
memcpy(_data + _pos, data, size);
|
||||||
@@ -92,7 +94,7 @@ struct COutFolders
|
|||||||
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
|
CUInt32DefVector FolderUnpackCRCs; // Now we use it for headers only.
|
||||||
|
|
||||||
CRecordVector<CNum> NumUnpackStreamsVector;
|
CRecordVector<CNum> NumUnpackStreamsVector;
|
||||||
CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bind coders
|
CRecordVector<UInt64> CoderUnpackSizes; // including unpack sizes of bond coders
|
||||||
|
|
||||||
void OutFoldersClear()
|
void OutFoldersClear()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace N7z {
|
|||||||
|
|
||||||
struct CPropMap
|
struct CPropMap
|
||||||
{
|
{
|
||||||
UInt64 FilePropID;
|
UInt32 FilePropID;
|
||||||
STATPROPSTG StatPROPSTG;
|
STATPROPSTG StatPROPSTG;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ static const CPropMap kPropMap[] =
|
|||||||
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
|
{ NID::kMTime, { NULL, kpidMTime, VT_FILETIME } },
|
||||||
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
|
{ NID::kATime, { NULL, kpidATime, VT_FILETIME } },
|
||||||
{ NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
|
{ NID::kWinAttrib, { NULL, kpidAttrib, VT_UI4 } },
|
||||||
{ NID::kStartPos, { NULL, kpidPosition, VT_UI4 } },
|
{ NID::kStartPos, { NULL, kpidPosition, VT_UI8 } },
|
||||||
|
|
||||||
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
|
{ NID::kCRC, { NULL, kpidCRC, VT_UI4 } },
|
||||||
|
|
||||||
@@ -44,20 +44,12 @@ static const CPropMap kPropMap[] =
|
|||||||
|
|
||||||
#ifndef _SFX
|
#ifndef _SFX
|
||||||
,
|
,
|
||||||
{ 97, { NULL,kpidEncrypted, VT_BOOL } },
|
{ 97, { NULL, kpidEncrypted, VT_BOOL } },
|
||||||
{ 98, { NULL,kpidMethod, VT_BSTR } },
|
{ 98, { NULL, kpidMethod, VT_BSTR } },
|
||||||
{ 99, { NULL,kpidBlock, VT_UI4 } }
|
{ 99, { NULL, kpidBlock, VT_UI4 } }
|
||||||
#endif
|
#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,
|
static void CopyOneItem(CRecordVector<UInt64> &src,
|
||||||
CRecordVector<UInt64> &dest, UInt32 item)
|
CRecordVector<UInt64> &dest, UInt32 item)
|
||||||
{
|
{
|
||||||
@@ -131,6 +123,7 @@ void CHandler::FillPopIDs()
|
|||||||
_fileInfoPopIDs.Add(98);
|
_fileInfoPopIDs.Add(98);
|
||||||
_fileInfoPopIDs.Add(99);
|
_fileInfoPopIDs.Add(99);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MULTI_PACK
|
#ifdef _MULTI_PACK
|
||||||
_fileInfoPopIDs.Add(100);
|
_fileInfoPopIDs.Add(100);
|
||||||
_fileInfoPopIDs.Add(101);
|
_fileInfoPopIDs.Add(101);
|
||||||
@@ -155,16 +148,27 @@ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps)
|
|||||||
|
|
||||||
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType)
|
||||||
{
|
{
|
||||||
if ((int)index >= _fileInfoPopIDs.Size())
|
if (index >= _fileInfoPopIDs.Size())
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
int indexInMap = FindPropInMap(_fileInfoPopIDs[index]);
|
UInt64 id = _fileInfoPopIDs[index];
|
||||||
if (indexInMap == -1)
|
for (unsigned i = 0; i < ARRAY_SIZE(kPropMap); i++)
|
||||||
return E_INVALIDARG;
|
{
|
||||||
const STATPROPSTG &srcItem = kPropMap[indexInMap].StatPROPSTG;
|
const CPropMap &pr = kPropMap[i];
|
||||||
*propID = srcItem.propid;
|
if (pr.FilePropID == id)
|
||||||
*varType = srcItem.vt;
|
{
|
||||||
*name = 0;
|
const STATPROPSTG &st = pr.StatPROPSTG;
|
||||||
|
*propID = st.propid;
|
||||||
|
*varType = st.vt;
|
||||||
|
/*
|
||||||
|
if (st.lpwstrName)
|
||||||
|
*name = ::SysAllocString(st.lpwstrName);
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
*name = NULL;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -9,17 +9,13 @@
|
|||||||
namespace NArchive {
|
namespace NArchive {
|
||||||
namespace N7z {
|
namespace N7z {
|
||||||
|
|
||||||
IMP_CreateArcIn
|
static Byte k_Signature_Dec[kSignatureSize] = {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||||
IMP_CreateArcOut
|
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
REGISTER_ARC_IO_DECREMENT_SIG(
|
||||||
{ "7z", "7z", 0, 7,
|
"7z", "7z", NULL, 7,
|
||||||
6, {'7' + 1, 'z', 0xBC, 0xAF, 0x27, 0x1C},
|
k_Signature_Dec,
|
||||||
0,
|
0,
|
||||||
NArcInfoFlags::kFindSignature,
|
NArcInfoFlags::kFindSignature,
|
||||||
REF_CreateArc_Pair };
|
NULL);
|
||||||
|
|
||||||
REGISTER_ARC_DEC_SIG(7z)
|
|
||||||
// REGISTER_ARC(7z)
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
#ifndef __7Z_SPEC_STREAM_H
|
#ifndef __7Z_SPEC_STREAM_H
|
||||||
#define __7Z_SPEC_STREAM_H
|
#define __7Z_SPEC_STREAM_H
|
||||||
|
|
||||||
#include "../../IStream.h"
|
|
||||||
#include "../../ICoder.h"
|
|
||||||
#include "../../../Common/MyCom.h"
|
#include "../../../Common/MyCom.h"
|
||||||
|
|
||||||
|
#include "../../ICoder.h"
|
||||||
|
|
||||||
class CSequentialInStreamSizeCount2:
|
class CSequentialInStreamSizeCount2:
|
||||||
public ISequentialInStream,
|
public ISequentialInStream,
|
||||||
public ICompressGetSubStreamSize,
|
public ICompressGetSubStreamSize,
|
||||||
@@ -18,14 +18,14 @@ class CSequentialInStreamSizeCount2:
|
|||||||
public:
|
public:
|
||||||
void Init(ISequentialInStream *stream)
|
void Init(ISequentialInStream *stream)
|
||||||
{
|
{
|
||||||
_stream = stream;
|
|
||||||
_getSubStreamSize = 0;
|
|
||||||
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
|
|
||||||
_size = 0;
|
_size = 0;
|
||||||
|
_getSubStreamSize.Release();
|
||||||
|
_stream = stream;
|
||||||
|
_stream.QueryInterface(IID_ICompressGetSubStreamSize, &_getSubStreamSize);
|
||||||
}
|
}
|
||||||
UInt64 GetSize() const { return _size; }
|
UInt64 GetSize() const { return _size; }
|
||||||
|
|
||||||
MY_UNKNOWN_IMP1(ICompressGetSubStreamSize)
|
MY_UNKNOWN_IMP2(ISequentialInStream, ICompressGetSubStreamSize)
|
||||||
|
|
||||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -65,6 +65,7 @@ struct CUpdateItem
|
|||||||
// int SecureIndex; // 0 means (no_security)
|
// int SecureIndex; // 0 means (no_security)
|
||||||
|
|
||||||
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
|
bool HasStream() const { return !IsDir && !IsAnti && Size != 0; }
|
||||||
|
// bool HasStream() const { return !IsDir && !IsAnti /* && Size != 0 */; } // for test purposes
|
||||||
|
|
||||||
CUpdateItem():
|
CUpdateItem():
|
||||||
// ParentSortIndex(-1),
|
// ParentSortIndex(-1),
|
||||||
@@ -77,18 +78,19 @@ struct CUpdateItem
|
|||||||
MTimeDefined(false)
|
MTimeDefined(false)
|
||||||
// SecureIndex(0)
|
// SecureIndex(0)
|
||||||
{}
|
{}
|
||||||
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); };
|
void SetDirStatusFromAttrib() { IsDir = ((Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0); }
|
||||||
|
|
||||||
int GetExtensionPos() const;
|
// unsigned GetExtensionPos() const;
|
||||||
UString GetExtension() const;
|
// UString GetExtension() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CUpdateOptions
|
struct CUpdateOptions
|
||||||
{
|
{
|
||||||
const CCompressionMethodMode *Method;
|
const CCompressionMethodMode *Method;
|
||||||
const CCompressionMethodMode *HeaderMethod;
|
const CCompressionMethodMode *HeaderMethod;
|
||||||
bool UseFilters;
|
bool UseFilters; // use additional filters for some files
|
||||||
bool MaxFilter;
|
bool MaxFilter; // use BCJ2 filter instead of BCJ
|
||||||
|
int AnalysisLevel;
|
||||||
|
|
||||||
CHeaderOptions HeaderOptions;
|
CHeaderOptions HeaderOptions;
|
||||||
|
|
||||||
@@ -96,7 +98,20 @@ struct CUpdateOptions
|
|||||||
UInt64 NumSolidBytes;
|
UInt64 NumSolidBytes;
|
||||||
bool SolidExtension;
|
bool SolidExtension;
|
||||||
bool RemoveSfxBlock;
|
bool RemoveSfxBlock;
|
||||||
bool VolumeMode;
|
bool MultiThreadMixer;
|
||||||
|
|
||||||
|
CUpdateOptions():
|
||||||
|
Method(NULL),
|
||||||
|
HeaderMethod(NULL),
|
||||||
|
UseFilters(false),
|
||||||
|
MaxFilter(false),
|
||||||
|
AnalysisLevel(-1),
|
||||||
|
NumSolidFiles((UInt64)(Int64)(-1)),
|
||||||
|
NumSolidBytes((UInt64)(Int64)(-1)),
|
||||||
|
SolidExtension(false),
|
||||||
|
RemoveSfxBlock(false),
|
||||||
|
MultiThreadMixer(true)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT Update(
|
HRESULT Update(
|
||||||
|
|||||||
@@ -376,15 +376,13 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
IMP_CreateArcIn
|
static const Byte k_Signature[] = { kSig0, kSig1 };
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
REGISTER_ARC_I(
|
||||||
{ "APM", "apm", 0, 0xD4,
|
"APM", "apm", 0, 0xD4,
|
||||||
2, { kSig0, kSig1 },
|
k_Signature,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
CreateArc, NULL, IsArc_Apm };
|
IsArc_Apm)
|
||||||
|
|
||||||
REGISTER_ARC(Apm)
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ enum EType
|
|||||||
kType_Lib
|
kType_Lib
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *k_TypeExtionsions[] =
|
static const char * const k_TypeExtionsions[] =
|
||||||
{
|
{
|
||||||
"ar"
|
"ar"
|
||||||
, "a"
|
, "a"
|
||||||
@@ -121,7 +121,7 @@ struct CItem
|
|||||||
int SameNameIndex;
|
int SameNameIndex;
|
||||||
|
|
||||||
CItem(): TextFileIndex(-1), SameNameIndex(-1) {}
|
CItem(): TextFileIndex(-1), SameNameIndex(-1) {}
|
||||||
UInt64 GetDataPos() const { return HeaderPos + HeaderSize; };
|
UInt64 GetDataPos() const { return HeaderPos + HeaderSize; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CInArchive
|
class CInArchive
|
||||||
@@ -257,10 +257,9 @@ HRESULT CInArchive::GetNextItem(CItem &item, bool &filled)
|
|||||||
{
|
{
|
||||||
SubType = kSubType_BSD;
|
SubType = kSubType_BSD;
|
||||||
size_t processedSize = longNameLen;
|
size_t processedSize = longNameLen;
|
||||||
char *s = item.Name.GetBuffer(longNameLen);
|
char *s = item.Name.GetBuf(longNameLen);
|
||||||
HRESULT res = ReadStream(m_Stream, s, &processedSize);
|
HRESULT res = ReadStream(m_Stream, s, &processedSize);
|
||||||
s[longNameLen] = 0;
|
item.Name.ReleaseBuf_CalcLen(longNameLen);
|
||||||
item.Name.ReleaseBuffer();
|
|
||||||
RINOK(res);
|
RINOK(res);
|
||||||
if (processedSize != longNameLen)
|
if (processedSize != longNameLen)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@@ -683,11 +682,11 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
|||||||
{
|
{
|
||||||
case kpidPhySize: prop = _phySize; break;
|
case kpidPhySize: prop = _phySize; break;
|
||||||
case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break;
|
case kpidMainSubfile: if (_mainSubfile >= 0) prop = (UInt32)_mainSubfile; break;
|
||||||
case kpidExtension: prop = k_TypeExtionsions[_type]; break;
|
case kpidExtension: prop = k_TypeExtionsions[(unsigned)_type]; break;
|
||||||
case kpidShortComment:
|
case kpidShortComment:
|
||||||
case kpidSubType:
|
case kpidSubType:
|
||||||
{
|
{
|
||||||
AString s = k_TypeExtionsions[_type];
|
AString s = k_TypeExtionsions[(unsigned)_type];
|
||||||
if (_subType == kSubType_BSD)
|
if (_subType == kSubType_BSD)
|
||||||
s += ":BSD";
|
s += ":BSD";
|
||||||
prop = s;
|
prop = s;
|
||||||
@@ -724,7 +723,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
|||||||
case kpidSize:
|
case kpidSize:
|
||||||
case kpidPackSize:
|
case kpidPackSize:
|
||||||
if (item.TextFileIndex >= 0)
|
if (item.TextFileIndex >= 0)
|
||||||
prop = (UInt64)_libFiles[item.TextFileIndex].Len();
|
prop = (UInt64)_libFiles[(unsigned)item.TextFileIndex].Len();
|
||||||
else
|
else
|
||||||
prop = item.Size;
|
prop = item.Size;
|
||||||
break;
|
break;
|
||||||
@@ -766,7 +765,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
const CItem &item = _items[allFilesMode ? i : indices[i]];
|
const CItem &item = _items[allFilesMode ? i : indices[i]];
|
||||||
totalSize +=
|
totalSize +=
|
||||||
(item.TextFileIndex >= 0) ?
|
(item.TextFileIndex >= 0) ?
|
||||||
(UInt64)_libFiles[item.TextFileIndex].Len() : item.Size;
|
(UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size;
|
||||||
}
|
}
|
||||||
extractCallback->SetTotal(totalSize);
|
extractCallback->SetTotal(totalSize);
|
||||||
|
|
||||||
@@ -795,7 +794,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
const CItem &item = _items[index];
|
const CItem &item = _items[index];
|
||||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||||
currentTotalSize += (item.TextFileIndex >= 0) ?
|
currentTotalSize += (item.TextFileIndex >= 0) ?
|
||||||
(UInt64)_libFiles[item.TextFileIndex].Len() : item.Size;
|
(UInt64)_libFiles[(unsigned)item.TextFileIndex].Len() : item.Size;
|
||||||
|
|
||||||
if (!testMode && !realOutStream)
|
if (!testMode && !realOutStream)
|
||||||
continue;
|
continue;
|
||||||
@@ -808,7 +807,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
bool isOk = true;
|
bool isOk = true;
|
||||||
if (item.TextFileIndex >= 0)
|
if (item.TextFileIndex >= 0)
|
||||||
{
|
{
|
||||||
const AString &f = _libFiles[item.TextFileIndex];
|
const AString &f = _libFiles[(unsigned)item.TextFileIndex];
|
||||||
if (realOutStream)
|
if (realOutStream)
|
||||||
RINOK(WriteStream(realOutStream, f, f.Len()));
|
RINOK(WriteStream(realOutStream, f, f.Len()));
|
||||||
}
|
}
|
||||||
@@ -834,8 +833,8 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|||||||
const CItem &item = _items[index];
|
const CItem &item = _items[index];
|
||||||
if (item.TextFileIndex >= 0)
|
if (item.TextFileIndex >= 0)
|
||||||
{
|
{
|
||||||
const AString &f = _libFiles[item.TextFileIndex];
|
const AString &f = _libFiles[(unsigned)item.TextFileIndex];
|
||||||
Create_BufInStream_WithNewBuf((const void *)(const char *)f, f.Len(), stream);
|
Create_BufInStream_WithNewBuffer((const void *)(const char *)f, f.Len(), stream);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -843,15 +842,11 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
|||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
IMP_CreateArcIn
|
REGISTER_ARC_I(
|
||||||
|
"Ar", "ar a deb lib", 0, 0xEC,
|
||||||
static CArcInfo g_ArcInfo =
|
kSignature,
|
||||||
{ "Ar", "ar a deb lib", 0, 0xEC,
|
|
||||||
kSignatureLen, SIGNATURE,
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
CreateArc };
|
NULL)
|
||||||
|
|
||||||
REGISTER_ARC(Ar)
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
CreateObject PRIVATE
|
CreateObject PRIVATE
|
||||||
|
|
||||||
GetHandlerProperty PRIVATE
|
GetHandlerProperty PRIVATE
|
||||||
GetNumberOfFormats PRIVATE
|
GetNumberOfFormats PRIVATE
|
||||||
GetHandlerProperty2 PRIVATE
|
GetHandlerProperty2 PRIVATE
|
||||||
CreateObject PRIVATE
|
GetIsArc PRIVATE
|
||||||
|
|
||||||
|
SetCodecs PRIVATE
|
||||||
|
|
||||||
|
SetLargePageMode PRIVATE
|
||||||
|
SetCaseSensitive PRIVATE
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
CreateObject PRIVATE
|
CreateObject PRIVATE
|
||||||
|
|
||||||
GetHandlerProperty PRIVATE
|
GetHandlerProperty PRIVATE
|
||||||
GetNumberOfFormats PRIVATE
|
GetNumberOfFormats PRIVATE
|
||||||
GetHandlerProperty2 PRIVATE
|
GetHandlerProperty2 PRIVATE
|
||||||
|
GetIsArc PRIVATE
|
||||||
|
|
||||||
GetNumberOfMethods PRIVATE
|
GetNumberOfMethods PRIVATE
|
||||||
GetMethodProperty PRIVATE
|
GetMethodProperty PRIVATE
|
||||||
|
CreateDecoder PRIVATE
|
||||||
|
CreateEncoder PRIVATE
|
||||||
|
|
||||||
GetHashers PRIVATE
|
GetHashers PRIVATE
|
||||||
|
|
||||||
|
SetCodecs PRIVATE
|
||||||
|
|
||||||
SetLargePageMode PRIVATE
|
SetLargePageMode PRIVATE
|
||||||
SetCaseSensitive PRIVATE
|
SetCaseSensitive PRIVATE
|
||||||
GetIsArc PRIVATE
|
|
||||||
@@ -22,17 +22,19 @@ void RegisterArc(const CArcInfo *arcInfo) throw()
|
|||||||
const char *p = arcInfo->Name;
|
const char *p = arcInfo->Name;
|
||||||
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
|
if (p[0] == '7' && p[1] == 'z' && p[2] == 0)
|
||||||
g_DefaultArcIndex = g_NumArcs;
|
g_DefaultArcIndex = g_NumArcs;
|
||||||
g_Arcs[g_NumArcs] = arcInfo;
|
g_Arcs[g_NumArcs++] = arcInfo;
|
||||||
g_NumArcs++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_CArchiveHandler,
|
DEFINE_GUID(CLSID_CArchiveHandler,
|
||||||
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
k_7zip_GUID_Data1,
|
||||||
|
k_7zip_GUID_Data2,
|
||||||
|
k_7zip_GUID_Data3_Common,
|
||||||
|
0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00);
|
||||||
|
|
||||||
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
|
#define CLS_ARC_ID_ITEM(cls) ((cls).Data4[5])
|
||||||
|
|
||||||
static inline HRESULT SetPropString(const char *s, unsigned size, PROPVARIANT *value)
|
static inline HRESULT SetPropStrFromBin(const char *s, unsigned size, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
|
if ((value->bstrVal = ::SysAllocStringByteLen(s, size)) != 0)
|
||||||
value->vt = VT_BSTR;
|
value->vt = VT_BSTR;
|
||||||
@@ -41,18 +43,18 @@ static inline HRESULT SetPropString(const char *s, unsigned size, PROPVARIANT *v
|
|||||||
|
|
||||||
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
|
static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
|
||||||
{
|
{
|
||||||
return SetPropString((const char *)&guid, sizeof(GUID), value);
|
return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FindFormatCalssId(const GUID *clsID)
|
int FindFormatCalssId(const GUID *clsid)
|
||||||
{
|
{
|
||||||
GUID cls = *clsID;
|
GUID cls = *clsid;
|
||||||
CLS_ARC_ID_ITEM(cls) = 0;
|
CLS_ARC_ID_ITEM(cls) = 0;
|
||||||
if (cls != CLSID_CArchiveHandler)
|
if (cls != CLSID_CArchiveHandler)
|
||||||
return -1;
|
return -1;
|
||||||
Byte id = CLS_ARC_ID_ITEM(*clsID);
|
Byte id = CLS_ARC_ID_ITEM(*clsid);
|
||||||
for (unsigned i = 0; i < g_NumArcs; i++)
|
for (unsigned i = 0; i < g_NumArcs; i++)
|
||||||
if (g_Arcs[i]->ClassId == id)
|
if (g_Arcs[i]->Id == id)
|
||||||
return (int)i;
|
return (int)i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -101,7 +103,7 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
|||||||
case NArchive::NHandlerPropID::kClassID:
|
case NArchive::NHandlerPropID::kClassID:
|
||||||
{
|
{
|
||||||
GUID clsId = CLSID_CArchiveHandler;
|
GUID clsId = CLSID_CArchiveHandler;
|
||||||
CLS_ARC_ID_ITEM(clsId) = arc.ClassId;
|
CLS_ARC_ID_ITEM(clsId) = arc.Id;
|
||||||
return SetPropGUID(clsId, value);
|
return SetPropGUID(clsId, value);
|
||||||
}
|
}
|
||||||
case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break;
|
case NArchive::NHandlerPropID::kExtension: if (arc.Ext) prop = arc.Ext; break;
|
||||||
@@ -115,12 +117,12 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
|
|||||||
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
|
// case NArchive::NHandlerPropID::kVersion: prop = (UInt32)MY_VER_MIX; break;
|
||||||
|
|
||||||
case NArchive::NHandlerPropID::kSignature:
|
case NArchive::NHandlerPropID::kSignature:
|
||||||
if (!arc.IsMultiSignature())
|
if (arc.SignatureSize != 0 && !arc.IsMultiSignature())
|
||||||
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
|
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
|
||||||
break;
|
break;
|
||||||
case NArchive::NHandlerPropID::kMultiSignature:
|
case NArchive::NHandlerPropID::kMultiSignature:
|
||||||
if (arc.IsMultiSignature())
|
if (arc.SignatureSize != 0 && arc.IsMultiSignature())
|
||||||
return SetPropString((const char *)arc.Signature, arc.SignatureSize, value);
|
return SetPropStrFromBin((const char *)arc.Signature, arc.SignatureSize, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prop.Detach(value);
|
prop.Detach(value);
|
||||||
|
|||||||
@@ -17,13 +17,180 @@
|
|||||||
#include "../Common/StreamObjects.h"
|
#include "../Common/StreamObjects.h"
|
||||||
#include "../Common/StreamUtils.h"
|
#include "../Common/StreamUtils.h"
|
||||||
|
|
||||||
#include "../Compress/ArjDecoder1.h"
|
|
||||||
#include "../Compress/ArjDecoder2.h"
|
|
||||||
#include "../Compress/CopyCoder.h"
|
#include "../Compress/CopyCoder.h"
|
||||||
|
#include "../Compress/LzhDecoder.h"
|
||||||
|
|
||||||
#include "Common/ItemNameUtils.h"
|
#include "Common/ItemNameUtils.h"
|
||||||
#include "Common/OutStreamWithCRC.h"
|
#include "Common/OutStreamWithCRC.h"
|
||||||
|
|
||||||
|
namespace NCompress {
|
||||||
|
namespace NArj {
|
||||||
|
namespace NDecoder {
|
||||||
|
|
||||||
|
static const unsigned kMatchMinLen = 3;
|
||||||
|
|
||||||
|
static const UInt32 kWindowSize = 1 << 15; // must be >= (1 << 14)
|
||||||
|
|
||||||
|
class CCoder:
|
||||||
|
public ICompressCoder,
|
||||||
|
public CMyUnknownImp
|
||||||
|
{
|
||||||
|
CLzOutWindow _outWindow;
|
||||||
|
NBitm::CDecoder<CInBuffer> _inBitStream;
|
||||||
|
|
||||||
|
class CCoderReleaser
|
||||||
|
{
|
||||||
|
CCoder *_coder;
|
||||||
|
public:
|
||||||
|
CCoderReleaser(CCoder *coder): _coder(coder) {}
|
||||||
|
void Disable() { _coder = NULL; }
|
||||||
|
~CCoderReleaser() { if (_coder) _coder->_outWindow.Flush(); }
|
||||||
|
};
|
||||||
|
friend class CCoderReleaser;
|
||||||
|
|
||||||
|
HRESULT CodeReal(UInt64 outSize, ICompressProgressInfo *progress);
|
||||||
|
public:
|
||||||
|
MY_UNKNOWN_IMP
|
||||||
|
|
||||||
|
bool FinishMode;
|
||||||
|
CCoder(): FinishMode(false) {}
|
||||||
|
|
||||||
|
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||||
|
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
||||||
|
UInt64 GetInputProcessedSize() const { return _inBitStream.GetProcessedSize(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT CCoder::CodeReal(UInt64 rem, ICompressProgressInfo *progress)
|
||||||
|
{
|
||||||
|
const UInt32 kStep = 1 << 20;
|
||||||
|
UInt64 next = 0;
|
||||||
|
if (rem > kStep && progress)
|
||||||
|
next = rem - kStep;
|
||||||
|
|
||||||
|
while (rem != 0)
|
||||||
|
{
|
||||||
|
if (rem <= next)
|
||||||
|
{
|
||||||
|
if (_inBitStream.ExtraBitsWereRead())
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
UInt64 packSize = _inBitStream.GetProcessedSize();
|
||||||
|
UInt64 pos = _outWindow.GetProcessedSize();
|
||||||
|
RINOK(progress->SetRatioInfo(&packSize, &pos));
|
||||||
|
next = 0;
|
||||||
|
if (rem > kStep)
|
||||||
|
next = rem - kStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 len;
|
||||||
|
|
||||||
|
{
|
||||||
|
const unsigned kNumBits = 7 + 7;
|
||||||
|
UInt32 val = _inBitStream.GetValue(kNumBits);
|
||||||
|
|
||||||
|
if ((val & (1 << (kNumBits - 1))) == 0)
|
||||||
|
{
|
||||||
|
_outWindow.PutByte((Byte)(val >> 5));
|
||||||
|
_inBitStream.MovePos(1 + 8);
|
||||||
|
rem--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt32 mask = 1 << (kNumBits - 2);
|
||||||
|
unsigned w;
|
||||||
|
|
||||||
|
for (w = 1; w < 7; w++, mask >>= 1)
|
||||||
|
if ((val & mask) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
unsigned readBits = (w != 7 ? 1 : 0);
|
||||||
|
readBits += w + w;
|
||||||
|
len = (1 << w) - 1 + kMatchMinLen - 1 +
|
||||||
|
(((val >> (kNumBits - readBits)) & ((1 << w) - 1)));
|
||||||
|
_inBitStream.MovePos(readBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const unsigned kNumBits = 4 + 13;
|
||||||
|
UInt32 val = _inBitStream.GetValue(kNumBits);
|
||||||
|
|
||||||
|
unsigned readBits = 1;
|
||||||
|
unsigned w;
|
||||||
|
|
||||||
|
if ((val & ((UInt32)1 << 16)) == 0) w = 9;
|
||||||
|
else if ((val & ((UInt32)1 << 15)) == 0) w = 10;
|
||||||
|
else if ((val & ((UInt32)1 << 14)) == 0) w = 11;
|
||||||
|
else if ((val & ((UInt32)1 << 13)) == 0) w = 12;
|
||||||
|
else { w = 13; readBits = 0; }
|
||||||
|
|
||||||
|
readBits += w + w - 9;
|
||||||
|
|
||||||
|
UInt32 dist = ((UInt32)1 << w) - (1 << 9) +
|
||||||
|
(((val >> (kNumBits - readBits)) & ((1 << w) - 1)));
|
||||||
|
_inBitStream.MovePos(readBits);
|
||||||
|
|
||||||
|
if (len > rem)
|
||||||
|
len = (UInt32)rem;
|
||||||
|
|
||||||
|
if (!_outWindow.CopyBlock(dist, len))
|
||||||
|
return S_FALSE;
|
||||||
|
rem -= len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FinishMode)
|
||||||
|
{
|
||||||
|
if (_inBitStream.ReadAlignBits() != 0)
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_inBitStream.ExtraBitsWereRead())
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
STDMETHODIMP CCoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
||||||
|
const UInt64 * /* inSize */, const UInt64 *outSize, ICompressProgressInfo *progress)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!outSize)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (!_outWindow.Create(kWindowSize))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
if (!_inBitStream.Create(1 << 17))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
_outWindow.SetStream(outStream);
|
||||||
|
_outWindow.Init(false);
|
||||||
|
_inBitStream.SetStream(inStream);
|
||||||
|
_inBitStream.Init();
|
||||||
|
|
||||||
|
CCoderReleaser coderReleaser(this);
|
||||||
|
HRESULT res;
|
||||||
|
{
|
||||||
|
res = CodeReal(*outSize, progress);
|
||||||
|
if (res != S_OK)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
coderReleaser.Disable();
|
||||||
|
return _outWindow.Flush();
|
||||||
|
}
|
||||||
|
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||||
|
catch(const CLzOutWindowException &e) { return e.ErrorCode; }
|
||||||
|
catch(...) { return S_FALSE; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using namespace NWindows;
|
using namespace NWindows;
|
||||||
|
|
||||||
#define Get16(p) GetUi16(p)
|
#define Get16(p) GetUi16(p)
|
||||||
@@ -95,7 +262,7 @@ namespace NHostOS
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *kHostOS[] =
|
static const char * const kHostOS[] =
|
||||||
{
|
{
|
||||||
"MSDOS"
|
"MSDOS"
|
||||||
, "PRIMOS"
|
, "PRIMOS"
|
||||||
@@ -164,10 +331,10 @@ API_FUNC_static_IsArc IsArc_Arj(const Byte *p, size_t size)
|
|||||||
|
|
||||||
static HRESULT ReadString(const Byte *p, unsigned &size, AString &res)
|
static HRESULT ReadString(const Byte *p, unsigned &size, AString &res)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < size;)
|
unsigned num = size;
|
||||||
|
for (unsigned i = 0; i < num;)
|
||||||
{
|
{
|
||||||
char c = (char)p[i++];
|
if (p[i++] == 0)
|
||||||
if (c == 0)
|
|
||||||
{
|
{
|
||||||
size = i;
|
size = i;
|
||||||
res = (const char *)p;
|
res = (const char *)p;
|
||||||
@@ -656,15 +823,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
{
|
{
|
||||||
const CItem &item = _items[allFilesMode ? i : indices[i]];
|
const CItem &item = _items[allFilesMode ? i : indices[i]];
|
||||||
totalUnpacked += item.Size;
|
totalUnpacked += item.Size;
|
||||||
totalPacked += item.PackSize;
|
// totalPacked += item.PackSize;
|
||||||
}
|
}
|
||||||
extractCallback->SetTotal(totalUnpacked);
|
extractCallback->SetTotal(totalUnpacked);
|
||||||
|
|
||||||
totalUnpacked = totalPacked = 0;
|
totalUnpacked = totalPacked = 0;
|
||||||
UInt64 curUnpacked, curPacked;
|
UInt64 curUnpacked, curPacked;
|
||||||
|
|
||||||
CMyComPtr<ICompressCoder> arj1Decoder;
|
NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = NULL;
|
||||||
CMyComPtr<ICompressCoder> arj2Decoder;
|
CMyComPtr<ICompressCoder> lzhDecoder;
|
||||||
|
|
||||||
|
NCompress::NArj::NDecoder::CCoder *arjDecoderSpec = NULL;
|
||||||
|
CMyComPtr<ICompressCoder> arjDecoder;
|
||||||
|
|
||||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||||
|
|
||||||
@@ -741,22 +912,37 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
case NCompressionMethod::kCompressed1b:
|
case NCompressionMethod::kCompressed1b:
|
||||||
case NCompressionMethod::kCompressed1c:
|
case NCompressionMethod::kCompressed1c:
|
||||||
{
|
{
|
||||||
if (!arj1Decoder)
|
if (!lzhDecoder)
|
||||||
arj1Decoder = new NCompress::NArj::NDecoder1::CCoder;
|
{
|
||||||
result = arj1Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder;
|
||||||
|
lzhDecoder = lzhDecoderSpec;
|
||||||
|
}
|
||||||
|
lzhDecoderSpec->FinishMode = true;
|
||||||
|
const UInt32 kHistorySize = 26624;
|
||||||
|
lzhDecoderSpec->SetDictSize(kHistorySize);
|
||||||
|
result = lzhDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
||||||
|
if (result == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize)
|
||||||
|
result = S_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NCompressionMethod::kCompressed2:
|
case NCompressionMethod::kCompressed2:
|
||||||
{
|
{
|
||||||
if (!arj2Decoder)
|
if (!arjDecoder)
|
||||||
arj2Decoder = new NCompress::NArj::NDecoder2::CCoder;
|
{
|
||||||
result = arj2Decoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
arjDecoderSpec = new NCompress::NArj::NDecoder::CCoder;
|
||||||
|
arjDecoder = arjDecoderSpec;
|
||||||
|
}
|
||||||
|
arjDecoderSpec->FinishMode = true;
|
||||||
|
result = arjDecoder->Code(inStream, outStream, NULL, &curUnpacked, progress);
|
||||||
|
if (result == S_OK && arjDecoderSpec->GetInputProcessedSize() != item.PackSize)
|
||||||
|
result = S_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
opRes = NExtract::NOperationResult::kUnsupportedMethod;
|
opRes = NExtract::NOperationResult::kUnsupportedMethod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opRes == NExtract::NOperationResult::kOK)
|
if (opRes == NExtract::NOperationResult::kOK)
|
||||||
{
|
{
|
||||||
if (result == S_FALSE)
|
if (result == S_FALSE)
|
||||||
@@ -769,23 +955,23 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
|||||||
NExtract::NOperationResult::kCRCError;
|
NExtract::NOperationResult::kCRCError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outStream.Release();
|
outStream.Release();
|
||||||
RINOK(extractCallback->SetOperationResult(opRes));
|
RINOK(extractCallback->SetOperationResult(opRes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
COM_TRY_END
|
COM_TRY_END
|
||||||
}
|
}
|
||||||
|
|
||||||
IMP_CreateArcIn
|
static const Byte k_Signature[] = { kSig0, kSig1 };
|
||||||
|
|
||||||
static CArcInfo g_ArcInfo =
|
REGISTER_ARC_I(
|
||||||
{ "Arj", "arj", 0, 4,
|
"Arj", "arj", 0, 4,
|
||||||
2, { kSig0, kSig1 },
|
k_Signature,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
CreateArc, NULL, IsArc_Arj };
|
IsArc_Arj)
|
||||||
|
|
||||||
REGISTER_ARC(Arj)
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user