mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
Added support for LZMA2 compression method in .7z archives
Updated LZMA SDK to version 9.20 http://www.7-zip.org/sdk.html http://downloads.sourceforge.net/sevenzip/lzma920.tar.bz2
This commit is contained in:
parent
6b26b710b8
commit
3af7d8a245
46 changed files with 2311 additions and 1793 deletions
203
lzma/C/7z.h
Normal file
203
lzma/C/7z.h
Normal file
|
@ -0,0 +1,203 @@
|
|||
/* 7z.h -- 7z interface
|
||||
2010-03-11 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_H
|
||||
#define __7Z_H
|
||||
|
||||
#include "7zBuf.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define k7zStartHeaderSize 0x20
|
||||
#define k7zSignatureSize 6
|
||||
extern Byte k7zSignature[k7zSignatureSize];
|
||||
#define k7zMajorVersion 0
|
||||
|
||||
enum EIdEnum
|
||||
{
|
||||
k7zIdEnd,
|
||||
k7zIdHeader,
|
||||
k7zIdArchiveProperties,
|
||||
k7zIdAdditionalStreamsInfo,
|
||||
k7zIdMainStreamsInfo,
|
||||
k7zIdFilesInfo,
|
||||
k7zIdPackInfo,
|
||||
k7zIdUnpackInfo,
|
||||
k7zIdSubStreamsInfo,
|
||||
k7zIdSize,
|
||||
k7zIdCRC,
|
||||
k7zIdFolder,
|
||||
k7zIdCodersUnpackSize,
|
||||
k7zIdNumUnpackStream,
|
||||
k7zIdEmptyStream,
|
||||
k7zIdEmptyFile,
|
||||
k7zIdAnti,
|
||||
k7zIdName,
|
||||
k7zIdCTime,
|
||||
k7zIdATime,
|
||||
k7zIdMTime,
|
||||
k7zIdWinAttributes,
|
||||
k7zIdComment,
|
||||
k7zIdEncodedHeader,
|
||||
k7zIdStartPos,
|
||||
k7zIdDummy
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
UInt64 MethodID;
|
||||
CBuf Props;
|
||||
} CSzCoderInfo;
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
} CSzBindPair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzCoderInfo *Coders;
|
||||
CSzBindPair *BindPairs;
|
||||
UInt32 *PackStreams;
|
||||
UInt64 *UnpackSizes;
|
||||
UInt32 NumCoders;
|
||||
UInt32 NumBindPairs;
|
||||
UInt32 NumPackStreams;
|
||||
int UnpackCRCDefined;
|
||||
UInt32 UnpackCRC;
|
||||
|
||||
UInt32 NumUnpackStreams;
|
||||
} CSzFolder;
|
||||
|
||||
void SzFolder_Init(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *stream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
} CNtfsFileTime;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CNtfsFileTime MTime;
|
||||
UInt64 Size;
|
||||
UInt32 Crc;
|
||||
UInt32 Attrib;
|
||||
Byte HasStream;
|
||||
Byte IsDir;
|
||||
Byte IsAnti;
|
||||
Byte CrcDefined;
|
||||
Byte MTimeDefined;
|
||||
Byte AttribDefined;
|
||||
} CSzFileItem;
|
||||
|
||||
void SzFile_Init(CSzFileItem *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt64 *PackSizes;
|
||||
Byte *PackCRCsDefined;
|
||||
UInt32 *PackCRCs;
|
||||
CSzFolder *Folders;
|
||||
CSzFileItem *Files;
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 NumFolders;
|
||||
UInt32 NumFiles;
|
||||
} CSzAr;
|
||||
|
||||
void SzAr_Init(CSzAr *p);
|
||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||
|
||||
|
||||
/*
|
||||
SzExtract extracts file from archive
|
||||
|
||||
*outBuffer must be 0 before first call for each new archive.
|
||||
|
||||
Extracting cache:
|
||||
If you need to decompress more than one file, you can send
|
||||
these values from previous call:
|
||||
*blockIndex,
|
||||
*outBuffer,
|
||||
*outBufferSize
|
||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||
it will increase decompression speed.
|
||||
|
||||
If you use external function, you can declare these 3 cache variables
|
||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||
|
||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzAr db;
|
||||
|
||||
UInt64 startPosAfterHeader;
|
||||
UInt64 dataPos;
|
||||
|
||||
UInt32 *FolderStartPackStreamIndex;
|
||||
UInt64 *PackStreamStartPositions;
|
||||
UInt32 *FolderStartFileIndex;
|
||||
UInt32 *FileIndexToFolderIndexMap;
|
||||
|
||||
size_t *FileNameOffsets; /* in 2-byte steps */
|
||||
CBuf FileNames; /* UTF-16-LE */
|
||||
} CSzArEx;
|
||||
|
||||
void SzArEx_Init(CSzArEx *p);
|
||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||
|
||||
/*
|
||||
if dest == NULL, the return value specifies the required size of the buffer,
|
||||
in 16-bit characters, including the null-terminating character.
|
||||
if dest != NULL, the return value specifies the number of 16-bit characters that
|
||||
are written to the dest, including the null-terminating character. */
|
||||
|
||||
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
|
||||
|
||||
SRes SzArEx_Extract(
|
||||
const CSzArEx *db,
|
||||
ILookInStream *inStream,
|
||||
UInt32 fileIndex, /* index of file */
|
||||
UInt32 *blockIndex, /* index of solid block */
|
||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||
size_t *outBufferSize, /* buffer size for output buffer */
|
||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp);
|
||||
|
||||
|
||||
/*
|
||||
SzArEx_Open Errors:
|
||||
SZ_ERROR_NO_ARCHIVE
|
||||
SZ_ERROR_ARCHIVE
|
||||
SZ_ERROR_UNSUPPORTED
|
||||
SZ_ERROR_MEM
|
||||
SZ_ERROR_CRC
|
||||
SZ_ERROR_INPUT_EOF
|
||||
SZ_ERROR_FAIL
|
||||
*/
|
||||
|
||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
|
@ -1,11 +1,15 @@
|
|||
/* 7zBuf.h -- Byte Buffer
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_BUF_H
|
||||
#define __7Z_BUF_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte *data;
|
||||
|
@ -28,4 +32,8 @@ void DynBuf_SeekToBeg(CDynBuf *p);
|
|||
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAlloc *alloc);
|
||||
void DynBuf_Free(CDynBuf *p, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,35 +1,74 @@
|
|||
/* 7zCrc.c -- CRC32 calculation
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
2009-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zCrc.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
#define kCrcPoly 0xEDB88320
|
||||
UInt32 g_CrcTable[256];
|
||||
|
||||
void MY_FAST_CALL CrcGenerateTable(void)
|
||||
#ifdef MY_CPU_LE
|
||||
#define CRC_NUM_TABLES 8
|
||||
#else
|
||||
#define CRC_NUM_TABLES 1
|
||||
#endif
|
||||
|
||||
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
|
||||
|
||||
static CRC_FUNC g_CrcUpdate;
|
||||
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
|
||||
|
||||
#if CRC_NUM_TABLES == 1
|
||||
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
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
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
return g_CrcUpdate(v, data, size, g_CrcTable);
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||
{
|
||||
return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
|
||||
}
|
||||
|
||||
void MY_FAST_CALL CrcGenerateTable()
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
int j;
|
||||
unsigned j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
g_CrcTable[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 ; size--, p++)
|
||||
v = CRC_UPDATE_BYTE(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
|
||||
{
|
||||
return CrcUpdate(CRC_INIT_VAL, data, size) ^ 0xFFFFFFFF;
|
||||
#if CRC_NUM_TABLES == 1
|
||||
g_CrcUpdate = CrcUpdateT1;
|
||||
#else
|
||||
for (; i < 256 * CRC_NUM_TABLES; i++)
|
||||
{
|
||||
UInt32 r = g_CrcTable[i - 256];
|
||||
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
|
||||
}
|
||||
g_CrcUpdate = CrcUpdateT4;
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
if (!CPU_Is_InOrder())
|
||||
g_CrcUpdate = CrcUpdateT8;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
/* 7zCrc.h -- CRC32 calculation
|
||||
2008-03-13
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
2009-11-21 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_CRC_H
|
||||
#define __7Z_CRC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
extern UInt32 g_CrcTable[];
|
||||
|
||||
/* Call CrcGenerateTable one time before other CRC functions */
|
||||
void MY_FAST_CALL CrcGenerateTable(void);
|
||||
|
||||
#define CRC_INIT_VAL 0xFFFFFFFF
|
||||
#define CRC_GET_DIGEST(crc) ((crc) ^ 0xFFFFFFFF)
|
||||
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
|
||||
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size);
|
||||
UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
|
34
lzma/C/7zCrcOpt.c
Normal file
34
lzma/C/7zCrcOpt.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* 7zCrcOpt.c -- CRC32 calculation : optimized version
|
||||
2009-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "CpuArch.h"
|
||||
|
||||
#ifdef MY_CPU_LE
|
||||
|
||||
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
const Byte *p = (const Byte *)data;
|
||||
for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
for (; size >= 4; size -= 4, p += 4)
|
||||
{
|
||||
v ^= *(const UInt32 *)p;
|
||||
v =
|
||||
table[0x300 + (v & 0xFF)] ^
|
||||
table[0x200 + ((v >> 8) & 0xFF)] ^
|
||||
table[0x100 + ((v >> 16) & 0xFF)] ^
|
||||
table[0x000 + ((v >> 24))];
|
||||
}
|
||||
for (; size > 0; size--, p++)
|
||||
v = CRC_UPDATE_BYTE_2(v, *p);
|
||||
return v;
|
||||
}
|
||||
|
||||
UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
|
||||
{
|
||||
return CrcUpdateT4(v, data, size, table);
|
||||
}
|
||||
|
||||
#endif
|
470
lzma/C/7zDec.c
Normal file
470
lzma/C/7zDec.c
Normal file
|
@ -0,0 +1,470 @@
|
|||
/* 7zDec.c -- Decoding from 7z folder
|
||||
2010-11-02 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* #define _7ZIP_PPMD_SUPPPORT */
|
||||
|
||||
#include "7z.h"
|
||||
|
||||
#include "Bcj2.h"
|
||||
#include "Bra.h"
|
||||
#include "CpuArch.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "Lzma2Dec.h"
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
#include "Ppmd7.h"
|
||||
#endif
|
||||
|
||||
#define k_Copy 0
|
||||
#define k_LZMA2 0x21
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_PPC 0x03030205
|
||||
#define k_ARM 0x03030501
|
||||
#define k_ARMT 0x03030701
|
||||
#define k_SPARC 0x03030805
|
||||
#define k_BCJ2 0x0303011B
|
||||
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
|
||||
#define k_PPMD 0x30401
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IByteIn p;
|
||||
const Byte *cur;
|
||||
const Byte *end;
|
||||
const Byte *begin;
|
||||
UInt64 processed;
|
||||
Bool extra;
|
||||
SRes res;
|
||||
ILookInStream *inStream;
|
||||
} CByteInToLook;
|
||||
|
||||
static Byte ReadByte(void *pp)
|
||||
{
|
||||
CByteInToLook *p = (CByteInToLook *)pp;
|
||||
if (p->cur != p->end)
|
||||
return *p->cur++;
|
||||
if (p->res == SZ_OK)
|
||||
{
|
||||
size_t size = p->cur - p->begin;
|
||||
p->processed += size;
|
||||
p->res = p->inStream->Skip(p->inStream, size);
|
||||
size = (1 << 25);
|
||||
p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
|
||||
p->cur = p->begin;
|
||||
p->end = p->begin + size;
|
||||
if (size != 0)
|
||||
return *p->cur++;;
|
||||
}
|
||||
p->extra = True;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SRes SzDecodePpmd(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CPpmd7 ppmd;
|
||||
CByteInToLook s;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
s.p.Read = ReadByte;
|
||||
s.inStream = inStream;
|
||||
s.begin = s.end = s.cur = NULL;
|
||||
s.extra = False;
|
||||
s.res = SZ_OK;
|
||||
s.processed = 0;
|
||||
|
||||
if (coder->Props.size != 5)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
{
|
||||
unsigned order = coder->Props.data[0];
|
||||
UInt32 memSize = GetUi32(coder->Props.data + 1);
|
||||
if (order < PPMD7_MIN_ORDER ||
|
||||
order > PPMD7_MAX_ORDER ||
|
||||
memSize < PPMD7_MIN_MEM_SIZE ||
|
||||
memSize > PPMD7_MAX_MEM_SIZE)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
Ppmd7_Construct(&ppmd);
|
||||
if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
|
||||
return SZ_ERROR_MEM;
|
||||
Ppmd7_Init(&ppmd, order);
|
||||
}
|
||||
{
|
||||
CPpmd7z_RangeDec rc;
|
||||
Ppmd7z_RangeDec_CreateVTable(&rc);
|
||||
rc.Stream = &s.p;
|
||||
if (!Ppmd7z_RangeDec_Init(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
else if (s.extra)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else
|
||||
{
|
||||
SizeT i;
|
||||
for (i = 0; i < outSize; i++)
|
||||
{
|
||||
int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
|
||||
if (s.extra || sym < 0)
|
||||
break;
|
||||
outBuffer[i] = (Byte)sym;
|
||||
}
|
||||
if (i != outSize)
|
||||
res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
|
||||
else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
|
||||
res = SZ_ERROR_DATA;
|
||||
}
|
||||
}
|
||||
Ppmd7_Free(&ppmd, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzmaDec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
LzmaDec_Construct(&state);
|
||||
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||
state.dic = outBuffer;
|
||||
state.dicBufSize = outSize;
|
||||
LzmaDec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||
{
|
||||
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LzmaDec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeLzma2(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzma2Dec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
Lzma2Dec_Construct(&state);
|
||||
if (coder->Props.size != 1)
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain));
|
||||
state.decoder.dic = outBuffer;
|
||||
state.decoder.dicBufSize = outSize;
|
||||
Lzma2Dec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
|
||||
{
|
||||
if (state.decoder.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Lzma2Dec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static Bool IS_MAIN_METHOD(UInt32 m)
|
||||
{
|
||||
switch(m)
|
||||
{
|
||||
case k_Copy:
|
||||
case k_LZMA:
|
||||
case k_LZMA2:
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
case k_PPMD:
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
|
||||
{
|
||||
return
|
||||
c->NumInStreams == 1 &&
|
||||
c->NumOutStreams == 1 &&
|
||||
c->MethodID <= (UInt32)0xFFFFFFFF &&
|
||||
IS_MAIN_METHOD((UInt32)c->MethodID);
|
||||
}
|
||||
|
||||
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1)
|
||||
|
||||
static SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
{
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
CSzCoderInfo *c = &f->Coders[1];
|
||||
if (c->MethodID > (UInt32)0xFFFFFFFF ||
|
||||
c->NumInStreams != 1 ||
|
||||
c->NumOutStreams != 1 ||
|
||||
f->NumPackStreams != 1 ||
|
||||
f->PackStreams[0] != 0 ||
|
||||
f->NumBindPairs != 1 ||
|
||||
f->BindPairs[0].InIndex != 1 ||
|
||||
f->BindPairs[0].OutIndex != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch ((UInt32)c->MethodID)
|
||||
{
|
||||
case k_BCJ:
|
||||
case k_ARM:
|
||||
break;
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 4)
|
||||
{
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
||||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||
!IS_BCJ2(&f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4 ||
|
||||
f->PackStreams[0] != 2 ||
|
||||
f->PackStreams[1] != 6 ||
|
||||
f->PackStreams[2] != 1 ||
|
||||
f->PackStreams[3] != 0 ||
|
||||
f->NumBindPairs != 3 ||
|
||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
|
||||
|
||||
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
SizeT tempSizes[3] = { 0, 0, 0};
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
|
||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||
{
|
||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||
{
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||
if (temp == 0 && outSizeCur != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA)
|
||||
{
|
||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
else if (coder->MethodID == k_LZMA2)
|
||||
{
|
||||
RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
#else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
UInt64 offset = GetSum(packSizes, 1);
|
||||
UInt64 s3Size = packSizes[1];
|
||||
SRes res;
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
tempSizes[2] = (SizeT)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZ_ERROR_MEM;
|
||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
|
||||
res = Bcj2_Decode(
|
||||
tempBuf3, tempSize3,
|
||||
tempBuf[0], tempSizes[0],
|
||||
tempBuf[1], tempSizes[1],
|
||||
tempBuf[2], tempSizes[2],
|
||||
outBuffer, outSize);
|
||||
RINOK(res)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ci != 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
switch(coder->MethodID)
|
||||
{
|
||||
case k_BCJ:
|
||||
{
|
||||
UInt32 state;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
break;
|
||||
}
|
||||
CASE_BRA_CONV(ARM)
|
||||
default:
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SzFolder_Decode(const CSzFolder *folder, const UInt64 *packSizes,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
return res;
|
||||
}
|
|
@ -1,17 +1,134 @@
|
|||
/* 7zIn.c -- 7z Input functions
|
||||
2008-12-31 : Igor Pavlov : Public domain */
|
||||
2010-10-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "../../7zCrc.h"
|
||||
#include "../../CpuArch.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "7zDecode.h"
|
||||
#include "7zIn.h"
|
||||
#include "7z.h"
|
||||
#include "7zCrc.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
||||
|
||||
#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
|
||||
|
||||
#define NUM_FOLDER_CODERS_MAX 32
|
||||
#define NUM_CODER_STREAMS_MAX 32
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p)
|
||||
{
|
||||
Buf_Init(&p->Props);
|
||||
}
|
||||
|
||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
|
||||
{
|
||||
Buf_Free(&p->Props, alloc);
|
||||
SzCoderInfo_Init(p);
|
||||
}
|
||||
|
||||
void SzFolder_Init(CSzFolder *p)
|
||||
{
|
||||
p->Coders = 0;
|
||||
p->BindPairs = 0;
|
||||
p->PackStreams = 0;
|
||||
p->UnpackSizes = 0;
|
||||
p->NumCoders = 0;
|
||||
p->NumBindPairs = 0;
|
||||
p->NumPackStreams = 0;
|
||||
p->UnpackCRCDefined = 0;
|
||||
p->UnpackCRC = 0;
|
||||
p->NumUnpackStreams = 0;
|
||||
}
|
||||
|
||||
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 i;
|
||||
if (p->Coders)
|
||||
for (i = 0; i < p->NumCoders; i++)
|
||||
SzCoderInfo_Free(&p->Coders[i], alloc);
|
||||
IAlloc_Free(alloc, p->Coders);
|
||||
IAlloc_Free(alloc, p->BindPairs);
|
||||
IAlloc_Free(alloc, p->PackStreams);
|
||||
IAlloc_Free(alloc, p->UnpackSizes);
|
||||
SzFolder_Init(p);
|
||||
}
|
||||
|
||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
|
||||
{
|
||||
UInt32 result = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->NumCoders; i++)
|
||||
result += p->Coders[i].NumOutStreams;
|
||||
return result;
|
||||
}
|
||||
|
||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->NumBindPairs; i++)
|
||||
if (p->BindPairs[i].InIndex == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->NumBindPairs; i++)
|
||||
if (p->BindPairs[i].OutIndex == outStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
|
||||
{
|
||||
int i = (int)SzFolder_GetNumOutStreams(p);
|
||||
if (i == 0)
|
||||
return 0;
|
||||
for (i--; i >= 0; i--)
|
||||
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
||||
return p->UnpackSizes[i];
|
||||
/* throw 1; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SzFile_Init(CSzFileItem *p)
|
||||
{
|
||||
p->HasStream = 1;
|
||||
p->IsDir = 0;
|
||||
p->IsAnti = 0;
|
||||
p->CrcDefined = 0;
|
||||
p->MTimeDefined = 0;
|
||||
}
|
||||
|
||||
void SzAr_Init(CSzAr *p)
|
||||
{
|
||||
p->PackSizes = 0;
|
||||
p->PackCRCsDefined = 0;
|
||||
p->PackCRCs = 0;
|
||||
p->Folders = 0;
|
||||
p->Files = 0;
|
||||
p->NumPackStreams = 0;
|
||||
p->NumFolders = 0;
|
||||
p->NumFiles = 0;
|
||||
}
|
||||
|
||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 i;
|
||||
if (p->Folders)
|
||||
for (i = 0; i < p->NumFolders; i++)
|
||||
SzFolder_Free(&p->Folders[i], alloc);
|
||||
|
||||
IAlloc_Free(alloc, p->PackSizes);
|
||||
IAlloc_Free(alloc, p->PackCRCsDefined);
|
||||
IAlloc_Free(alloc, p->PackCRCs);
|
||||
IAlloc_Free(alloc, p->Folders);
|
||||
IAlloc_Free(alloc, p->Files);
|
||||
SzAr_Init(p);
|
||||
}
|
||||
|
||||
|
||||
void SzArEx_Init(CSzArEx *p)
|
||||
{
|
||||
SzAr_Init(&p->db);
|
||||
|
@ -19,6 +136,8 @@ void SzArEx_Init(CSzArEx *p)
|
|||
p->PackStreamStartPositions = 0;
|
||||
p->FolderStartFileIndex = 0;
|
||||
p->FileIndexToFolderIndexMap = 0;
|
||||
p->FileNameOffsets = 0;
|
||||
Buf_Init(&p->FileNames);
|
||||
}
|
||||
|
||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
||||
|
@ -27,6 +146,10 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
|
|||
IAlloc_Free(alloc, p->PackStreamStartPositions);
|
||||
IAlloc_Free(alloc, p->FolderStartFileIndex);
|
||||
IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
|
||||
|
||||
IAlloc_Free(alloc, p->FileNameOffsets);
|
||||
Buf_Free(&p->FileNames, alloc);
|
||||
|
||||
SzAr_Free(&p->db, alloc);
|
||||
SzArEx_Init(p);
|
||||
}
|
||||
|
@ -488,11 +611,11 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
|
|||
return SZ_ERROR_UNSUPPORTED;
|
||||
|
||||
folder->NumBindPairs = numBindPairs = numOutStreams - 1;
|
||||
MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
|
||||
MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc);
|
||||
|
||||
for (i = 0; i < numBindPairs; i++)
|
||||
{
|
||||
CBindPair *bp = folder->BindPairs + i;
|
||||
CSzBindPair *bp = folder->BindPairs + i;
|
||||
RINOK(SzReadNumber32(sd, &bp->InIndex));
|
||||
RINOK(SzReadNumber32(sd, &bp->OutIndex));
|
||||
}
|
||||
|
@ -780,81 +903,38 @@ static SRes SzReadStreamsInfo(
|
|||
}
|
||||
}
|
||||
|
||||
Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
|
||||
{
|
||||
size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
|
||||
if (dest != 0)
|
||||
{
|
||||
size_t i;
|
||||
const Byte *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2);
|
||||
for (i = 0; i < len; i++)
|
||||
dest[i] = GetUi16(src + i * 2);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, ISzAlloc *alloc)
|
||||
static SRes SzReadFileNames(const Byte *p, size_t size, UInt32 numFiles, size_t *sizes)
|
||||
{
|
||||
UInt32 i;
|
||||
size_t pos = 0;
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
UInt32 len = 0;
|
||||
UInt32 pos = 0;
|
||||
CSzFileItem *file = files + i;
|
||||
while (pos + 2 <= sd->Size)
|
||||
sizes[i] = pos;
|
||||
for (;;)
|
||||
{
|
||||
int numAdds;
|
||||
UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
|
||||
pos += 2;
|
||||
len++;
|
||||
if (value == 0)
|
||||
if (pos >= size)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0)
|
||||
break;
|
||||
if (value < 0x80)
|
||||
continue;
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
UInt32 c2;
|
||||
if (value >= 0xDC00)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if (pos + 2 > sd->Size)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
|
||||
pos += 2;
|
||||
if (c2 < 0xDC00 || c2 >= 0xE000)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
|
||||
}
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
len += numAdds;
|
||||
}
|
||||
|
||||
MY_ALLOC(char, file->Name, (size_t)len, alloc);
|
||||
|
||||
len = 0;
|
||||
while (2 <= sd->Size)
|
||||
{
|
||||
int numAdds;
|
||||
UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
|
||||
SzSkeepDataSize(sd, 2);
|
||||
if (value < 0x80)
|
||||
{
|
||||
file->Name[len++] = (char)value;
|
||||
if (value == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (value >= 0xD800 && value < 0xE000)
|
||||
{
|
||||
UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
|
||||
SzSkeepDataSize(sd, 2);
|
||||
value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
|
||||
}
|
||||
for (numAdds = 1; numAdds < 5; numAdds++)
|
||||
if (value < (((UInt32)1) << (numAdds * 5 + 6)))
|
||||
break;
|
||||
file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
||||
do
|
||||
{
|
||||
numAdds--;
|
||||
file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
||||
}
|
||||
while (numAdds > 0);
|
||||
|
||||
len += numAdds;
|
||||
pos++;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return SZ_OK;
|
||||
sizes[i] = pos;
|
||||
return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
|
||||
}
|
||||
|
||||
static SRes SzReadHeader2(
|
||||
|
@ -920,7 +1000,8 @@ static SRes SzReadHeader2(
|
|||
if (type == k7zIdEnd)
|
||||
break;
|
||||
RINOK(SzReadNumber(sd, &size));
|
||||
|
||||
if (size > sd->Size)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if ((UInt64)(int)type != type)
|
||||
{
|
||||
RINOK(SzSkeepDataSize(sd, size));
|
||||
|
@ -930,8 +1011,17 @@ static SRes SzReadHeader2(
|
|||
{
|
||||
case k7zIdName:
|
||||
{
|
||||
size_t namesSize;
|
||||
RINOK(SzReadSwitch(sd));
|
||||
RINOK(SzReadFileNames(sd, numFiles, files, allocMain))
|
||||
namesSize = (size_t)size - 1;
|
||||
if ((namesSize & 1) != 0)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
if (!Buf_Create(&p->FileNames, namesSize, allocMain))
|
||||
return SZ_ERROR_MEM;
|
||||
MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
|
||||
memcpy(p->FileNames.data, sd->Data, namesSize);
|
||||
RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets))
|
||||
RINOK(SzSkeepDataSize(sd, namesSize));
|
||||
break;
|
||||
}
|
||||
case k7zIdEmptyStream:
|
||||
|
@ -948,6 +1038,25 @@ static SRes SzReadHeader2(
|
|||
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp));
|
||||
break;
|
||||
}
|
||||
case k7zIdWinAttributes:
|
||||
{
|
||||
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
|
||||
RINOK(SzReadSwitch(sd));
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
CSzFileItem *f = &files[i];
|
||||
Byte defined = (*lwtVector)[i];
|
||||
f->AttribDefined = defined;
|
||||
f->Attrib = 0;
|
||||
if (defined)
|
||||
{
|
||||
RINOK(SzReadUInt32(sd, &f->Attrib));
|
||||
}
|
||||
}
|
||||
IAlloc_Free(allocTemp, *lwtVector);
|
||||
*lwtVector = NULL;
|
||||
break;
|
||||
}
|
||||
case k7zIdMTime:
|
||||
{
|
||||
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp));
|
||||
|
@ -964,6 +1073,8 @@ static SRes SzReadHeader2(
|
|||
RINOK(SzReadUInt32(sd, &f->MTime.High));
|
||||
}
|
||||
}
|
||||
IAlloc_Free(allocTemp, *lwtVector);
|
||||
*lwtVector = NULL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -988,8 +1099,8 @@ static SRes SzReadHeader2(
|
|||
{
|
||||
file->IsDir = 0;
|
||||
file->Size = (*unpackSizes)[sizeIndex];
|
||||
file->FileCRC = (*digests)[sizeIndex];
|
||||
file->FileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||
file->Crc = (*digests)[sizeIndex];
|
||||
file->CrcDefined = (Byte)(*digestsDefined)[sizeIndex];
|
||||
sizeIndex++;
|
||||
}
|
||||
else
|
||||
|
@ -1000,7 +1111,8 @@ static SRes SzReadHeader2(
|
|||
file->IsDir = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
|
||||
emptyFileIndex++;
|
||||
file->Size = 0;
|
||||
file->FileCRCDefined = 0;
|
||||
file->Crc = 0;
|
||||
file->CrcDefined = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1066,7 +1178,7 @@ static SRes SzReadAndDecodePackedStreams2(
|
|||
if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
res = SzDecode(p->PackSizes, folder,
|
||||
res = SzFolder_Decode(folder, p->PackSizes,
|
||||
inStream, dataStartPos,
|
||||
outBuffer->data, (size_t)unpackSize, allocTemp);
|
||||
RINOK(res);
|
||||
|
@ -1106,12 +1218,16 @@ static SRes SzArEx_Open2(
|
|||
ISzAlloc *allocTemp)
|
||||
{
|
||||
Byte header[k7zStartHeaderSize];
|
||||
Int64 startArcPos;
|
||||
UInt64 nextHeaderOffset, nextHeaderSize;
|
||||
size_t nextHeaderSizeT;
|
||||
UInt32 nextHeaderCRC;
|
||||
CBuf buffer;
|
||||
SRes res;
|
||||
|
||||
startArcPos = 0;
|
||||
RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
|
||||
|
||||
RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
|
||||
|
||||
if (!TestSignatureCandidate(header))
|
||||
|
@ -1123,7 +1239,7 @@ static SRes SzArEx_Open2(
|
|||
nextHeaderSize = GetUi64(header + 20);
|
||||
nextHeaderCRC = GetUi32(header + 28);
|
||||
|
||||
p->startPosAfterHeader = k7zStartHeaderSize;
|
||||
p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
|
||||
|
||||
if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
|
||||
return SZ_ERROR_CRC;
|
||||
|
@ -1140,13 +1256,13 @@ static SRes SzArEx_Open2(
|
|||
{
|
||||
Int64 pos = 0;
|
||||
RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
|
||||
if ((UInt64)pos < nextHeaderOffset ||
|
||||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
|
||||
(UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
|
||||
if ((UInt64)pos < startArcPos + nextHeaderOffset ||
|
||||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
|
||||
(UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
}
|
||||
|
||||
RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
|
||||
RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
|
||||
|
||||
if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
|
||||
return SZ_ERROR_MEM;
|
||||
|
@ -1202,3 +1318,85 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAl
|
|||
SzArEx_Free(p, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
SRes SzArEx_Extract(
|
||||
const CSzArEx *p,
|
||||
ILookInStream *inStream,
|
||||
UInt32 fileIndex,
|
||||
UInt32 *blockIndex,
|
||||
Byte **outBuffer,
|
||||
size_t *outBufferSize,
|
||||
size_t *offset,
|
||||
size_t *outSizeProcessed,
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp)
|
||||
{
|
||||
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
|
||||
SRes res = SZ_OK;
|
||||
*offset = 0;
|
||||
*outSizeProcessed = 0;
|
||||
if (folderIndex == (UInt32)-1)
|
||||
{
|
||||
IAlloc_Free(allocMain, *outBuffer);
|
||||
*blockIndex = folderIndex;
|
||||
*outBuffer = 0;
|
||||
*outBufferSize = 0;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
||||
{
|
||||
CSzFolder *folder = p->db.Folders + folderIndex;
|
||||
UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
||||
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||
UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
||||
|
||||
if (unpackSize != unpackSizeSpec)
|
||||
return SZ_ERROR_MEM;
|
||||
*blockIndex = folderIndex;
|
||||
IAlloc_Free(allocMain, *outBuffer);
|
||||
*outBuffer = 0;
|
||||
|
||||
RINOK(LookInStream_SeekTo(inStream, startOffset));
|
||||
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
*outBufferSize = unpackSize;
|
||||
if (unpackSize != 0)
|
||||
{
|
||||
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
||||
if (*outBuffer == 0)
|
||||
res = SZ_ERROR_MEM;
|
||||
}
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
res = SzFolder_Decode(folder,
|
||||
p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
|
||||
inStream, startOffset,
|
||||
*outBuffer, unpackSize, allocTemp);
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
if (folder->UnpackCRCDefined)
|
||||
{
|
||||
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
||||
res = SZ_ERROR_CRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
UInt32 i;
|
||||
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
||||
*offset = 0;
|
||||
for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||
*offset += (UInt32)p->db.Files[i].Size;
|
||||
*outSizeProcessed = (size_t)fileItem->Size;
|
||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
||||
return SZ_ERROR_FAIL;
|
||||
if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
|
||||
res = SZ_ERROR_CRC;
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* 7zStream.c -- 7z Stream functions
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
2010-03-11 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -39,7 +39,7 @@ SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
|||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||
{
|
||||
void *lookBuf;
|
||||
const void *lookBuf;
|
||||
if (*size == 0)
|
||||
return SZ_OK;
|
||||
RINOK(stream->Look(stream, &lookBuf, size));
|
||||
|
@ -66,7 +66,7 @@ SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
|||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
|
||||
static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
|
@ -84,7 +84,7 @@ static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
|
|||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
|
||||
static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#define MY_VER_MAJOR 4
|
||||
#define MY_VER_MINOR 65
|
||||
#define MY_VER_MAJOR 9
|
||||
#define MY_VER_MINOR 20
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION "4.65"
|
||||
#define MY_DATE "2009-02-03"
|
||||
#define MY_VERSION "9.20"
|
||||
#define MY_DATE "2010-11-18"
|
||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
||||
|
|
127
lzma/C/Alloc.c
127
lzma/C/Alloc.c
|
@ -1,127 +0,0 @@
|
|||
/* Alloc.c -- Memory allocation functions
|
||||
2008-09-24
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountMid = 0;
|
||||
int g_allocCountBig = 0;
|
||||
#endif
|
||||
|
||||
void *MyAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
{
|
||||
void *p = malloc(size);
|
||||
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void *MidAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void MidFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||
#endif
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#ifndef MEM_LARGE_PAGES
|
||||
#undef _7ZIP_LARGE_PAGES
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T g_LargePageSize = 0;
|
||||
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
||||
#endif
|
||||
|
||||
void SetLargePageSize()
|
||||
{
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T size = 0;
|
||||
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||
if (largePageMinimum == 0)
|
||||
return;
|
||||
size = largePageMinimum();
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
return;
|
||||
g_LargePageSize = size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void *BigAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
||||
{
|
||||
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void BigFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||
#endif
|
||||
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||
/* Alloc.h -- Memory allocation functions
|
||||
2008-03-13
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __COMMON_ALLOC_H
|
||||
#define __COMMON_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void *MyAlloc(size_t size);
|
||||
void MyFree(void *address);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void SetLargePageSize();
|
||||
|
||||
void *MidAlloc(size_t size);
|
||||
void MidFree(void *address);
|
||||
void *BigAlloc(size_t size);
|
||||
void BigFree(void *address);
|
||||
|
||||
#else
|
||||
|
||||
#define MidAlloc(size) MyAlloc(size)
|
||||
#define MidFree(address) MyFree(address)
|
||||
#define BigAlloc(size) MyAlloc(size)
|
||||
#define BigFree(address) MyFree(address)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,254 +0,0 @@
|
|||
/* 7zDecode.c -- Decoding from 7z folder
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../../Bcj2.h"
|
||||
#include "../../Bra.h"
|
||||
#include "../../LzmaDec.h"
|
||||
#include "7zDecode.h"
|
||||
|
||||
#define k_Copy 0
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_BCJ2 0x0303011B
|
||||
|
||||
static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inStream,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
CLzmaDec state;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
LzmaDec_Construct(&state);
|
||||
RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain));
|
||||
state.dic = outBuffer;
|
||||
state.dicBufSize = outSize;
|
||||
LzmaDec_Init(&state);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte *inBuf = NULL;
|
||||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
{
|
||||
SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
|
||||
ELzmaStatus status;
|
||||
res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
|
||||
lookahead -= inProcessed;
|
||||
inSize -= inProcessed;
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
|
||||
{
|
||||
if (state.dicBufSize != outSize || lookahead != 0 ||
|
||||
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
|
||||
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
|
||||
res = SZ_ERROR_DATA;
|
||||
break;
|
||||
}
|
||||
res = inStream->Skip((void *)inStream, inProcessed);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LzmaDec_FreeProbs(&state, allocMain);
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
void *inBuf;
|
||||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
outBuffer += curSize;
|
||||
inSize -= curSize;
|
||||
RINOK(inStream->Skip((void *)inStream, curSize));
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
#define IS_UNSUPPORTED_METHOD(m) ((m) != k_Copy && (m) != k_LZMA)
|
||||
#define IS_UNSUPPORTED_CODER(c) (IS_UNSUPPORTED_METHOD(c.MethodID) || c.NumInStreams != 1 || c.NumOutStreams != 1)
|
||||
#define IS_NO_BCJ(c) (c.MethodID != k_BCJ || c.NumInStreams != 1 || c.NumOutStreams != 1)
|
||||
#define IS_NO_BCJ2(c) (c.MethodID != k_BCJ2 || c.NumInStreams != 4 || c.NumOutStreams != 1)
|
||||
|
||||
SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
{
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (IS_UNSUPPORTED_CODER(f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
if (IS_NO_BCJ(f->Coders[1]) ||
|
||||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
|
||||
f->NumBindPairs != 1 ||
|
||||
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 4)
|
||||
{
|
||||
if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
|
||||
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
|
||||
IS_NO_BCJ2(f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4 ||
|
||||
f->PackStreams[0] != 2 ||
|
||||
f->PackStreams[1] != 6 ||
|
||||
f->PackStreams[2] != 1 ||
|
||||
f->PackStreams[3] != 0 ||
|
||||
f->NumBindPairs != 3 ||
|
||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
SizeT tempSizes[3] = { 0, 0, 0};
|
||||
SizeT tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
|
||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||
{
|
||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
|
||||
{
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
UInt64 inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
SizeT outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
UInt64 unpackSize = folder->UnpackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (SizeT)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZ_ERROR_MEM;
|
||||
temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
|
||||
if (temp == 0 && outSizeCur != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize) /* check it */
|
||||
return SZ_ERROR_PARAM;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (SizeT)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur) /* check it */
|
||||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ)
|
||||
{
|
||||
UInt32 state;
|
||||
if (ci != 1)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
UInt64 offset = GetSum(packSizes, 1);
|
||||
UInt64 s3Size = packSizes[1];
|
||||
SRes res;
|
||||
if (ci != 3)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
RINOK(LookInStream_SeekTo(inStream, startPos + offset));
|
||||
tempSizes[2] = (SizeT)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZ_ERROR_MEM;
|
||||
tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
|
||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||
return SZ_ERROR_MEM;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
|
||||
res = Bcj2_Decode(
|
||||
tempBuf3, tempSize3,
|
||||
tempBuf[0], tempSizes[0],
|
||||
tempBuf[1], tempSizes[1],
|
||||
tempBuf[2], tempSizes[2],
|
||||
outBuffer, outSize);
|
||||
RINOK(res)
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
ILookInStream *inStream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SRes res = SzDecode2(packSizes, folder, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
return res;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
/* 7zDecode.h -- Decoding from 7z folder
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_DECODE_H
|
||||
#define __7Z_DECODE_H
|
||||
|
||||
#include "7zItem.h"
|
||||
|
||||
SRes SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
ILookInStream *stream, UInt64 startPos,
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||
|
||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||
/* 7zExtract.c -- Extracting from 7z archive
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "../../7zCrc.h"
|
||||
#include "7zDecode.h"
|
||||
#include "7zExtract.h"
|
||||
|
||||
SRes SzAr_Extract(
|
||||
const CSzArEx *p,
|
||||
ILookInStream *inStream,
|
||||
UInt32 fileIndex,
|
||||
UInt32 *blockIndex,
|
||||
Byte **outBuffer,
|
||||
size_t *outBufferSize,
|
||||
size_t *offset,
|
||||
size_t *outSizeProcessed,
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp)
|
||||
{
|
||||
UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
|
||||
SRes res = SZ_OK;
|
||||
*offset = 0;
|
||||
*outSizeProcessed = 0;
|
||||
if (folderIndex == (UInt32)-1)
|
||||
{
|
||||
IAlloc_Free(allocMain, *outBuffer);
|
||||
*blockIndex = folderIndex;
|
||||
*outBuffer = 0;
|
||||
*outBufferSize = 0;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
||||
{
|
||||
CSzFolder *folder = p->db.Folders + folderIndex;
|
||||
UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
|
||||
size_t unpackSize = (size_t)unpackSizeSpec;
|
||||
UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);
|
||||
|
||||
if (unpackSize != unpackSizeSpec)
|
||||
return SZ_ERROR_MEM;
|
||||
*blockIndex = folderIndex;
|
||||
IAlloc_Free(allocMain, *outBuffer);
|
||||
*outBuffer = 0;
|
||||
|
||||
RINOK(LookInStream_SeekTo(inStream, startOffset));
|
||||
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
*outBufferSize = unpackSize;
|
||||
if (unpackSize != 0)
|
||||
{
|
||||
*outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
|
||||
if (*outBuffer == 0)
|
||||
res = SZ_ERROR_MEM;
|
||||
}
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
res = SzDecode(p->db.PackSizes +
|
||||
p->FolderStartPackStreamIndex[folderIndex], folder,
|
||||
inStream, startOffset,
|
||||
*outBuffer, unpackSize, allocTemp);
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
if (folder->UnpackCRCDefined)
|
||||
{
|
||||
if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
|
||||
res = SZ_ERROR_CRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
UInt32 i;
|
||||
CSzFileItem *fileItem = p->db.Files + fileIndex;
|
||||
*offset = 0;
|
||||
for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||
*offset += (UInt32)p->db.Files[i].Size;
|
||||
*outSizeProcessed = (size_t)fileItem->Size;
|
||||
if (*offset + *outSizeProcessed > *outBufferSize)
|
||||
return SZ_ERROR_FAIL;
|
||||
{
|
||||
if (fileItem->FileCRCDefined)
|
||||
{
|
||||
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
||||
res = SZ_ERROR_CRC;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/* 7zExtract.h -- Extracting from 7z archive
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_EXTRACT_H
|
||||
#define __7Z_EXTRACT_H
|
||||
|
||||
#include "7zIn.h"
|
||||
|
||||
/*
|
||||
SzExtract extracts file from archive
|
||||
|
||||
*outBuffer must be 0 before first call for each new archive.
|
||||
|
||||
Extracting cache:
|
||||
If you need to decompress more than one file, you can send
|
||||
these values from previous call:
|
||||
*blockIndex,
|
||||
*outBuffer,
|
||||
*outBufferSize
|
||||
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
|
||||
it will increase decompression speed.
|
||||
|
||||
If you use external function, you can declare these 3 cache variables
|
||||
(blockIndex, outBuffer, outBufferSize) as static in that external function.
|
||||
|
||||
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
|
||||
*/
|
||||
|
||||
SRes SzAr_Extract(
|
||||
const CSzArEx *db,
|
||||
ILookInStream *inStream,
|
||||
UInt32 fileIndex, /* index of file */
|
||||
UInt32 *blockIndex, /* index of solid block */
|
||||
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
|
||||
size_t *outBufferSize, /* buffer size for output buffer */
|
||||
size_t *offset, /* offset of stream for required file in *outBuffer */
|
||||
size_t *outSizeProcessed, /* size of file in *outBuffer */
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp);
|
||||
|
||||
#endif
|
|
@ -1,6 +0,0 @@
|
|||
/* 7zHeader.c -- 7z Headers
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zHeader.h"
|
||||
|
||||
Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
|
|
@ -1,57 +0,0 @@
|
|||
/* 7zHeader.h -- 7z Headers
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_HEADER_H
|
||||
#define __7Z_HEADER_H
|
||||
|
||||
#include "../../Types.h"
|
||||
|
||||
#define k7zSignatureSize 6
|
||||
extern Byte k7zSignature[k7zSignatureSize];
|
||||
|
||||
#define k7zMajorVersion 0
|
||||
|
||||
#define k7zStartHeaderSize 0x20
|
||||
|
||||
enum EIdEnum
|
||||
{
|
||||
k7zIdEnd,
|
||||
|
||||
k7zIdHeader,
|
||||
|
||||
k7zIdArchiveProperties,
|
||||
|
||||
k7zIdAdditionalStreamsInfo,
|
||||
k7zIdMainStreamsInfo,
|
||||
k7zIdFilesInfo,
|
||||
|
||||
k7zIdPackInfo,
|
||||
k7zIdUnpackInfo,
|
||||
k7zIdSubStreamsInfo,
|
||||
|
||||
k7zIdSize,
|
||||
k7zIdCRC,
|
||||
|
||||
k7zIdFolder,
|
||||
|
||||
k7zIdCodersUnpackSize,
|
||||
k7zIdNumUnpackStream,
|
||||
|
||||
k7zIdEmptyStream,
|
||||
k7zIdEmptyFile,
|
||||
k7zIdAnti,
|
||||
|
||||
k7zIdName,
|
||||
k7zIdCTime,
|
||||
k7zIdATime,
|
||||
k7zIdMTime,
|
||||
k7zIdWinAttributes,
|
||||
k7zIdComment,
|
||||
|
||||
k7zIdEncodedHeader,
|
||||
|
||||
k7zIdStartPos,
|
||||
k7zIdDummy
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||
/* 7zIn.h -- 7z Input functions
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_IN_H
|
||||
#define __7Z_IN_H
|
||||
|
||||
#include "7zHeader.h"
|
||||
#include "7zItem.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzAr db;
|
||||
|
||||
UInt64 startPosAfterHeader;
|
||||
UInt64 dataPos;
|
||||
|
||||
UInt32 *FolderStartPackStreamIndex;
|
||||
UInt64 *PackStreamStartPositions;
|
||||
UInt32 *FolderStartFileIndex;
|
||||
UInt32 *FileIndexToFolderIndexMap;
|
||||
} CSzArEx;
|
||||
|
||||
void SzArEx_Init(CSzArEx *p);
|
||||
void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
|
||||
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
|
||||
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
|
||||
|
||||
/*
|
||||
Errors:
|
||||
SZ_ERROR_NO_ARCHIVE
|
||||
SZ_ERROR_ARCHIVE
|
||||
SZ_ERROR_UNSUPPORTED
|
||||
SZ_ERROR_MEM
|
||||
SZ_ERROR_CRC
|
||||
SZ_ERROR_INPUT_EOF
|
||||
SZ_ERROR_FAIL
|
||||
*/
|
||||
|
||||
SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp);
|
||||
|
||||
#endif
|
|
@ -1,127 +0,0 @@
|
|||
/* 7zItem.c -- 7z Items
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zItem.h"
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p)
|
||||
{
|
||||
Buf_Init(&p->Props);
|
||||
}
|
||||
|
||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc)
|
||||
{
|
||||
Buf_Free(&p->Props, alloc);
|
||||
SzCoderInfo_Init(p);
|
||||
}
|
||||
|
||||
void SzFolder_Init(CSzFolder *p)
|
||||
{
|
||||
p->Coders = 0;
|
||||
p->BindPairs = 0;
|
||||
p->PackStreams = 0;
|
||||
p->UnpackSizes = 0;
|
||||
p->NumCoders = 0;
|
||||
p->NumBindPairs = 0;
|
||||
p->NumPackStreams = 0;
|
||||
p->UnpackCRCDefined = 0;
|
||||
p->UnpackCRC = 0;
|
||||
p->NumUnpackStreams = 0;
|
||||
}
|
||||
|
||||
void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 i;
|
||||
if (p->Coders)
|
||||
for (i = 0; i < p->NumCoders; i++)
|
||||
SzCoderInfo_Free(&p->Coders[i], alloc);
|
||||
IAlloc_Free(alloc, p->Coders);
|
||||
IAlloc_Free(alloc, p->BindPairs);
|
||||
IAlloc_Free(alloc, p->PackStreams);
|
||||
IAlloc_Free(alloc, p->UnpackSizes);
|
||||
SzFolder_Init(p);
|
||||
}
|
||||
|
||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p)
|
||||
{
|
||||
UInt32 result = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->NumCoders; i++)
|
||||
result += p->Coders[i].NumOutStreams;
|
||||
return result;
|
||||
}
|
||||
|
||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->NumBindPairs; i++)
|
||||
if (p->BindPairs[i].InIndex == inStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int SzFolder_FindBindPairForOutStream(CSzFolder *p, UInt32 outStreamIndex)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->NumBindPairs; i++)
|
||||
if (p->BindPairs[i].OutIndex == outStreamIndex)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p)
|
||||
{
|
||||
int i = (int)SzFolder_GetNumOutStreams(p);
|
||||
if (i == 0)
|
||||
return 0;
|
||||
for (i--; i >= 0; i--)
|
||||
if (SzFolder_FindBindPairForOutStream(p, i) < 0)
|
||||
return p->UnpackSizes[i];
|
||||
/* throw 1; */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SzFile_Init(CSzFileItem *p)
|
||||
{
|
||||
p->HasStream = 1;
|
||||
p->IsDir = 0;
|
||||
p->IsAnti = 0;
|
||||
p->FileCRCDefined = 0;
|
||||
p->MTimeDefined = 0;
|
||||
p->Name = 0;
|
||||
}
|
||||
|
||||
static void SzFile_Free(CSzFileItem *p, ISzAlloc *alloc)
|
||||
{
|
||||
IAlloc_Free(alloc, p->Name);
|
||||
SzFile_Init(p);
|
||||
}
|
||||
|
||||
void SzAr_Init(CSzAr *p)
|
||||
{
|
||||
p->PackSizes = 0;
|
||||
p->PackCRCsDefined = 0;
|
||||
p->PackCRCs = 0;
|
||||
p->Folders = 0;
|
||||
p->Files = 0;
|
||||
p->NumPackStreams = 0;
|
||||
p->NumFolders = 0;
|
||||
p->NumFiles = 0;
|
||||
}
|
||||
|
||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 i;
|
||||
if (p->Folders)
|
||||
for (i = 0; i < p->NumFolders; i++)
|
||||
SzFolder_Free(&p->Folders[i], alloc);
|
||||
if (p->Files)
|
||||
for (i = 0; i < p->NumFiles; i++)
|
||||
SzFile_Free(&p->Files[i], alloc);
|
||||
IAlloc_Free(alloc, p->PackSizes);
|
||||
IAlloc_Free(alloc, p->PackCRCsDefined);
|
||||
IAlloc_Free(alloc, p->PackCRCs);
|
||||
IAlloc_Free(alloc, p->Folders);
|
||||
IAlloc_Free(alloc, p->Files);
|
||||
SzAr_Init(p);
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/* 7zItem.h -- 7z Items
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_ITEM_H
|
||||
#define __7Z_ITEM_H
|
||||
|
||||
#include "../../7zBuf.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 NumInStreams;
|
||||
UInt32 NumOutStreams;
|
||||
UInt64 MethodID;
|
||||
CBuf Props;
|
||||
} CSzCoderInfo;
|
||||
|
||||
void SzCoderInfo_Init(CSzCoderInfo *p);
|
||||
void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 InIndex;
|
||||
UInt32 OutIndex;
|
||||
} CBindPair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CSzCoderInfo *Coders;
|
||||
CBindPair *BindPairs;
|
||||
UInt32 *PackStreams;
|
||||
UInt64 *UnpackSizes;
|
||||
UInt32 NumCoders;
|
||||
UInt32 NumBindPairs;
|
||||
UInt32 NumPackStreams;
|
||||
int UnpackCRCDefined;
|
||||
UInt32 UnpackCRC;
|
||||
|
||||
UInt32 NumUnpackStreams;
|
||||
} CSzFolder;
|
||||
|
||||
void SzFolder_Init(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
int SzFolder_FindBindPairForInStream(CSzFolder *p, UInt32 inStreamIndex);
|
||||
UInt32 SzFolder_GetNumOutStreams(CSzFolder *p);
|
||||
UInt64 SzFolder_GetUnpackSize(CSzFolder *p);
|
||||
|
||||
typedef struct CNtfsFileTime
|
||||
{
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
} CNtfsFileTime;
|
||||
|
||||
typedef struct CSzFileItem
|
||||
{
|
||||
CNtfsFileTime MTime;
|
||||
UInt64 Size;
|
||||
char *Name;
|
||||
UInt32 FileCRC;
|
||||
|
||||
Byte HasStream;
|
||||
Byte IsDir;
|
||||
Byte IsAnti;
|
||||
Byte FileCRCDefined;
|
||||
Byte MTimeDefined;
|
||||
} CSzFileItem;
|
||||
|
||||
void SzFile_Init(CSzFileItem *p);
|
||||
|
||||
typedef struct CSzAr
|
||||
{
|
||||
UInt64 *PackSizes;
|
||||
Byte *PackCRCsDefined;
|
||||
UInt32 *PackCRCs;
|
||||
CSzFolder *Folders;
|
||||
CSzFileItem *Files;
|
||||
UInt32 NumPackStreams;
|
||||
UInt32 NumFolders;
|
||||
UInt32 NumFiles;
|
||||
} CSzAr;
|
||||
|
||||
void SzAr_Init(CSzAr *p);
|
||||
void SzAr_Free(CSzAr *p, ISzAlloc *alloc);
|
||||
|
||||
#endif
|
|
@ -1,11 +1,15 @@
|
|||
/* Bcj2.h -- Converter for x86 code (BCJ2)
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BCJ2_H
|
||||
#define __BCJ2_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
outSize <= FullOutputSize,
|
||||
|
@ -27,4 +31,8 @@ int Bcj2_Decode(
|
|||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
133
lzma/C/Bra.c
Normal file
133
lzma/C/Bra.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* Bra.c -- Converters for RISC code
|
||||
2010-04-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "Bra.h"
|
||||
|
||||
SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 8;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0xEB)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 2;
|
||||
data[i + 2] = (Byte)(dest >> 16);
|
||||
data[i + 1] = (Byte)(dest >> 8);
|
||||
data[i + 0] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
ip += 4;
|
||||
for (i = 0; i <= size; i += 2)
|
||||
{
|
||||
if ((data[i + 1] & 0xF8) == 0xF0 &&
|
||||
(data[i + 3] & 0xF8) == 0xF8)
|
||||
{
|
||||
UInt32 dest;
|
||||
UInt32 src =
|
||||
(((UInt32)data[i + 1] & 0x7) << 19) |
|
||||
((UInt32)data[i + 0] << 11) |
|
||||
(((UInt32)data[i + 3] & 0x7) << 8) |
|
||||
(data[i + 2]);
|
||||
|
||||
src <<= 1;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
dest >>= 1;
|
||||
|
||||
data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
|
||||
data[i + 0] = (Byte)(dest >> 11);
|
||||
data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
|
||||
data[i + 2] = (Byte)dest;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
SizeT i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
|
||||
{
|
||||
UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3] & (~3));
|
||||
|
||||
UInt32 dest;
|
||||
if (encoding)
|
||||
dest = ip + (UInt32)i + src;
|
||||
else
|
||||
dest = src - (ip + (UInt32)i);
|
||||
data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] &= 0x3;
|
||||
data[i + 3] |= dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
|
||||
{
|
||||
UInt32 i;
|
||||
if (size < 4)
|
||||
return 0;
|
||||
size -= 4;
|
||||
for (i = 0; i <= size; i += 4)
|
||||
{
|
||||
if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
|
||||
(data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)data[i + 0] << 24) |
|
||||
((UInt32)data[i + 1] << 16) |
|
||||
((UInt32)data[i + 2] << 8) |
|
||||
((UInt32)data[i + 3]);
|
||||
UInt32 dest;
|
||||
|
||||
src <<= 2;
|
||||
if (encoding)
|
||||
dest = ip + i + src;
|
||||
else
|
||||
dest = src - (ip + i);
|
||||
dest >>= 2;
|
||||
|
||||
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
|
||||
|
||||
data[i + 0] = (Byte)(dest >> 24);
|
||||
data[i + 1] = (Byte)(dest >> 16);
|
||||
data[i + 2] = (Byte)(dest >> 8);
|
||||
data[i + 3] = (Byte)dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
10
lzma/C/Bra.h
10
lzma/C/Bra.h
|
@ -1,11 +1,15 @@
|
|||
/* Bra.h -- Branch converters for executables
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __BRA_H
|
||||
#define __BRA_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
These functions convert relative addresses to absolute addresses
|
||||
in CALL instructions to increase the compression ratio.
|
||||
|
@ -57,4 +61,8 @@ SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
|||
SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
168
lzma/C/CpuArch.c
Normal file
168
lzma/C/CpuArch.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/* CpuArch.c -- CPU specific code
|
||||
2010-10-26: Igor Pavlov : Public domain */
|
||||
|
||||
#include "CpuArch.h"
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
|
||||
#define USE_ASM
|
||||
#endif
|
||||
|
||||
#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
|
||||
static UInt32 CheckFlag(UInt32 flag)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm mov EDX, EAX;
|
||||
__asm xor EAX, flag;
|
||||
__asm push EAX;
|
||||
__asm popfd;
|
||||
__asm pushfd;
|
||||
__asm pop EAX;
|
||||
__asm xor EAX, EDX;
|
||||
__asm push EDX;
|
||||
__asm popfd;
|
||||
__asm and flag, EAX;
|
||||
#else
|
||||
__asm__ __volatile__ (
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"movl %%EAX,%%EDX\n\t"
|
||||
"xorl %0,%%EAX\n\t"
|
||||
"push %%EAX\n\t"
|
||||
"popf\n\t"
|
||||
"pushf\n\t"
|
||||
"pop %%EAX\n\t"
|
||||
"xorl %%EDX,%%EAX\n\t"
|
||||
"push %%EDX\n\t"
|
||||
"popf\n\t"
|
||||
"andl %%EAX, %0\n\t":
|
||||
"=c" (flag) : "c" (flag));
|
||||
#endif
|
||||
return flag;
|
||||
}
|
||||
#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
|
||||
#else
|
||||
#define CHECK_CPUID_IS_SUPPORTED
|
||||
#endif
|
||||
|
||||
static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
|
||||
{
|
||||
#ifdef USE_ASM
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
UInt32 a2, b2, c2, d2;
|
||||
__asm xor EBX, EBX;
|
||||
__asm xor ECX, ECX;
|
||||
__asm xor EDX, EDX;
|
||||
__asm mov EAX, function;
|
||||
__asm cpuid;
|
||||
__asm mov a2, EAX;
|
||||
__asm mov b2, EBX;
|
||||
__asm mov c2, ECX;
|
||||
__asm mov d2, EDX;
|
||||
|
||||
*a = a2;
|
||||
*b = b2;
|
||||
*c = c2;
|
||||
*d = d2;
|
||||
|
||||
#else
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a" (*a) ,
|
||||
"=b" (*b) ,
|
||||
"=c" (*c) ,
|
||||
"=d" (*d)
|
||||
: "0" (function)) ;
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
int CPUInfo[4];
|
||||
__cpuid(CPUInfo, function);
|
||||
*a = CPUInfo[0];
|
||||
*b = CPUInfo[1];
|
||||
*c = CPUInfo[2];
|
||||
*d = CPUInfo[3];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
|
||||
{
|
||||
CHECK_CPUID_IS_SUPPORTED
|
||||
MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
|
||||
MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
|
||||
return True;
|
||||
}
|
||||
|
||||
static UInt32 kVendors[][3] =
|
||||
{
|
||||
{ 0x756E6547, 0x49656E69, 0x6C65746E},
|
||||
{ 0x68747541, 0x69746E65, 0x444D4163},
|
||||
{ 0x746E6543, 0x48727561, 0x736C7561}
|
||||
};
|
||||
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
|
||||
{
|
||||
const UInt32 *v = kVendors[i];
|
||||
if (v[0] == p->vendor[0] &&
|
||||
v[1] == p->vendor[1] &&
|
||||
v[2] == p->vendor[2])
|
||||
return (int)i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Bool CPU_Is_InOrder()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
int firm;
|
||||
UInt32 family, model;
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return True;
|
||||
family = x86cpuid_GetFamily(&p);
|
||||
model = x86cpuid_GetModel(&p);
|
||||
firm = x86cpuid_GetFirm(&p);
|
||||
switch (firm)
|
||||
{
|
||||
case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C));
|
||||
case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
|
||||
case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
#if !defined(MY_CPU_AMD64) && defined(_WIN32)
|
||||
static Bool CPU_Sys_Is_SSE_Supported()
|
||||
{
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (!GetVersionEx(&vi))
|
||||
return False;
|
||||
return (vi.dwMajorVersion >= 5);
|
||||
}
|
||||
#define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
|
||||
#else
|
||||
#define CHECK_SYS_SSE_SUPPORT
|
||||
#endif
|
||||
|
||||
Bool CPU_Is_Aes_Supported()
|
||||
{
|
||||
Cx86cpuid p;
|
||||
CHECK_SYS_SSE_SUPPORT
|
||||
if (!x86cpuid_CheckAndRead(&p))
|
||||
return False;
|
||||
return (p.c >> 25) & 1;
|
||||
}
|
||||
|
||||
#endif
|
118
lzma/C/CpuArch.h
118
lzma/C/CpuArch.h
|
@ -1,29 +1,73 @@
|
|||
/* CpuArch.h
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
/* CpuArch.h -- CPU specific code
|
||||
2010-10-26: Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __CPUARCH_H
|
||||
#define __CPUARCH_H
|
||||
#ifndef __CPU_ARCH_H
|
||||
#define __CPU_ARCH_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
/*
|
||||
LITTLE_ENDIAN_UNALIGN means:
|
||||
1) CPU is LITTLE_ENDIAN
|
||||
2) it's allowed to make unaligned memory accesses
|
||||
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
||||
about these properties of platform.
|
||||
MY_CPU_LE means that CPU is LITTLE ENDIAN.
|
||||
If MY_CPU_LE is not defined, we don't know about that property of platform (it can be LITTLE ENDIAN).
|
||||
|
||||
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
|
||||
If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform.
|
||||
*/
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
|
||||
#define LITTLE_ENDIAN_UNALIGN
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__)
|
||||
#define MY_CPU_AMD64
|
||||
#endif
|
||||
|
||||
#ifdef LITTLE_ENDIAN_UNALIGN
|
||||
#if defined(MY_CPU_AMD64) || defined(_M_IA64)
|
||||
#define MY_CPU_64BIT
|
||||
#endif
|
||||
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
#define MY_CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
|
||||
#define MY_CPU_X86_OR_AMD64
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86) || defined(_M_ARM)
|
||||
#define MY_CPU_32BIT
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_ARM)
|
||||
#define MY_CPU_ARM_LE
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_M_IA64)
|
||||
#define MY_CPU_IA64_LE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64)
|
||||
#define MY_CPU_LE_UNALIGN
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_X86_OR_AMD64) || defined(MY_CPU_ARM_LE) || defined(MY_CPU_IA64_LE) || defined(__ARMEL__) || defined(__MIPSEL__) || defined(__LITTLE_ENDIAN__)
|
||||
#define MY_CPU_LE
|
||||
#endif
|
||||
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
#define MY_CPU_BE
|
||||
#endif
|
||||
|
||||
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
|
||||
Stop_Compiling_Bad_Endian
|
||||
#endif
|
||||
|
||||
#ifdef MY_CPU_LE_UNALIGN
|
||||
|
||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||
#define SetUi16(p, d) *(UInt16 *)(p) = (d);
|
||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||
#define SetUi64(p, d) *(UInt64 *)(p) = (d);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -37,18 +81,24 @@ about these properties of platform.
|
|||
|
||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||
|
||||
#define SetUi16(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); }
|
||||
|
||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||
|
||||
#define SetUi64(p, d) { UInt64 _x64_ = (d); \
|
||||
SetUi32(p, (UInt32)_x64_); \
|
||||
SetUi32(((Byte *)(p)) + 4, (UInt32)(_x64_ >> 32)); }
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||
#if defined(MY_CPU_LE_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||
|
||||
unsigned long _byteswap_ulong(unsigned long);
|
||||
unsigned __int64 _byteswap_uint64(unsigned __int64);
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||
|
@ -68,4 +118,38 @@ unsigned __int64 _byteswap_uint64(unsigned __int64);
|
|||
|
||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||
|
||||
|
||||
#ifdef MY_CPU_X86_OR_AMD64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UInt32 maxFunc;
|
||||
UInt32 vendor[3];
|
||||
UInt32 ver;
|
||||
UInt32 b;
|
||||
UInt32 c;
|
||||
UInt32 d;
|
||||
} Cx86cpuid;
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_FIRM_INTEL,
|
||||
CPU_FIRM_AMD,
|
||||
CPU_FIRM_VIA
|
||||
};
|
||||
|
||||
Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
|
||||
int x86cpuid_GetFirm(const Cx86cpuid *p);
|
||||
|
||||
#define x86cpuid_GetFamily(p) (((p)->ver >> 8) & 0xFF00F)
|
||||
#define x86cpuid_GetModel(p) (((p)->ver >> 4) & 0xF00F)
|
||||
#define x86cpuid_GetStepping(p) ((p)->ver & 0xF)
|
||||
|
||||
Bool CPU_Is_InOrder();
|
||||
Bool CPU_Is_Aes_Supported();
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-04-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -58,6 +58,17 @@ static void MatchFinder_ReadBlock(CMatchFinder *p)
|
|||
{
|
||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||
return;
|
||||
if (p->directInput)
|
||||
{
|
||||
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
|
||||
if (curSize > p->directInputRem)
|
||||
curSize = (UInt32)p->directInputRem;
|
||||
p->directInputRem -= curSize;
|
||||
p->streamPos += curSize;
|
||||
if (p->directInputRem == 0)
|
||||
p->streamEndWasReached = 1;
|
||||
return;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||
|
@ -88,6 +99,8 @@ void MatchFinder_MoveBlock(CMatchFinder *p)
|
|||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||
{
|
||||
if (p->directInput)
|
||||
return 0;
|
||||
/* if (p->streamEndWasReached) return 0; */
|
||||
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
||||
}
|
||||
|
@ -112,8 +125,6 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
|||
p->cutValue = 32;
|
||||
p->btMode = 1;
|
||||
p->numHashBytes = 4;
|
||||
/* p->skipModeBits = 0; */
|
||||
p->directInput = 0;
|
||||
p->bigHash = 0;
|
||||
}
|
||||
|
||||
|
@ -177,7 +188,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||
{
|
||||
UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
|
||||
UInt32 newCyclicBufferSize = historySize + 1;
|
||||
UInt32 hs;
|
||||
p->matchMaxLen = matchMaxLen;
|
||||
{
|
||||
|
@ -192,7 +203,6 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
|||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
/* hs >>= p->skipModeBits; */
|
||||
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||
if (hs > (1 << 24))
|
||||
{
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* LzFind.h -- Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-04-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZFIND_H
|
||||
#define __LZFIND_H
|
||||
#ifndef __LZ_FIND_H
|
||||
#define __LZ_FIND_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef UInt32 CLzRef;
|
||||
|
||||
typedef struct _CMatchFinder
|
||||
|
@ -35,8 +39,8 @@ typedef struct _CMatchFinder
|
|||
|
||||
UInt32 numHashBytes;
|
||||
int directInput;
|
||||
size_t directInputRem;
|
||||
int btMode;
|
||||
/* int skipModeBits; */
|
||||
int bigHash;
|
||||
UInt32 historySize;
|
||||
UInt32 fixedHashSize;
|
||||
|
@ -104,4 +108,8 @@ UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
|||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-09-20 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "LzHash.h"
|
||||
|
||||
|
@ -97,7 +97,7 @@ void MtSync_Destruct(CMtSync *p)
|
|||
|
||||
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||
|
||||
static SRes MtSync_Create2(CMtSync *p, unsigned (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
{
|
||||
if (p->wasCreated)
|
||||
return SZ_OK;
|
||||
|
@ -119,7 +119,7 @@ static SRes MtSync_Create2(CMtSync *p, unsigned (THREAD_FUNC_CALL_TYPE *startAdd
|
|||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes MtSync_Create(CMtSync *p, unsigned (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
{
|
||||
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
|
||||
if (res != SZ_OK)
|
||||
|
@ -143,7 +143,7 @@ DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc;
|
|||
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
|
||||
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
|
||||
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
|
||||
DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask)
|
||||
/* 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)
|
||||
{
|
||||
|
@ -451,8 +451,8 @@ void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
|||
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
|
||||
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
||||
|
||||
static unsigned THREAD_FUNC_CALL_TYPE HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
||||
static unsigned THREAD_FUNC_CALL_TYPE BtThreadFunc2(void *p)
|
||||
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
||||
static unsigned MY_STD_CALL BtThreadFunc2(void *p)
|
||||
{
|
||||
Byte allocaDummy[0x180];
|
||||
int i = 0;
|
||||
|
@ -711,47 +711,47 @@ UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
|||
return len;
|
||||
}
|
||||
|
||||
#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED
|
||||
#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
|
||||
#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
|
||||
#define SKIP_HEADER2_MT do { GET_NEXT_BLOCK_IF_REQUIRED
|
||||
#define SKIP_HEADER_MT(n) SKIP_HEADER2_MT if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
|
||||
#define SKIP_FOOTER_MT } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
|
||||
|
||||
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER2 { p->btNumAvailBytes--;
|
||||
SKIP_FOOTER
|
||||
SKIP_HEADER2_MT { p->btNumAvailBytes--;
|
||||
SKIP_FOOTER_MT
|
||||
}
|
||||
|
||||
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(2)
|
||||
SKIP_HEADER_MT(2)
|
||||
UInt32 hash2Value;
|
||||
MT_HASH2_CALC
|
||||
hash[hash2Value] = p->lzPos;
|
||||
SKIP_FOOTER
|
||||
SKIP_FOOTER_MT
|
||||
}
|
||||
|
||||
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
SKIP_HEADER_MT(3)
|
||||
UInt32 hash2Value, hash3Value;
|
||||
MT_HASH3_CALC
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[ hash2Value] =
|
||||
p->lzPos;
|
||||
SKIP_FOOTER
|
||||
SKIP_FOOTER_MT
|
||||
}
|
||||
|
||||
/*
|
||||
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(4)
|
||||
SKIP_HEADER_MT(4)
|
||||
UInt32 hash2Value, hash3Value, hash4Value;
|
||||
MT_HASH4_CALC
|
||||
hash[kFix4HashSize + hash4Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[ hash2Value] =
|
||||
p->lzPos;
|
||||
SKIP_FOOTER
|
||||
SKIP_FOOTER_MT
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZFINDMT_H
|
||||
#define __LZFINDMT_H
|
||||
#ifndef __LZ_FIND_MT_H
|
||||
#define __LZ_FIND_MT_H
|
||||
|
||||
#include "Threads.h"
|
||||
#include "LzFind.h"
|
||||
#include "Threads.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define kMtHashBlockSize (1 << 13)
|
||||
#define kMtHashNumBlocks (1 << 3)
|
||||
|
@ -94,4 +98,8 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB
|
|||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* LzHash.h -- HASH functions for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZHASH_H
|
||||
#define __LZHASH_H
|
||||
#ifndef __LZ_HASH_H
|
||||
#define __LZ_HASH_H
|
||||
|
||||
#define kHash2Size (1 << 10)
|
||||
#define kHash3Size (1 << 16)
|
||||
|
|
356
lzma/C/Lzma2Dec.c
Normal file
356
lzma/C/Lzma2Dec.c
Normal file
|
@ -0,0 +1,356 @@
|
|||
/* Lzma2Dec.c -- LZMA2 Decoder
|
||||
2009-05-03 : Igor Pavlov : Public domain */
|
||||
|
||||
/* #define SHOW_DEBUG_INFO */
|
||||
|
||||
#ifdef SHOW_DEBUG_INFO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Lzma2Dec.h"
|
||||
|
||||
/*
|
||||
00000000 - EOS
|
||||
00000001 U U - Uncompressed Reset Dic
|
||||
00000010 U U - Uncompressed No Reset
|
||||
100uuuuu U U P P - LZMA no reset
|
||||
101uuuuu U U P P - LZMA reset state
|
||||
110uuuuu U U P P S - LZMA reset state + new prop
|
||||
111uuuuu U U P P S - LZMA reset state + new prop + reset dic
|
||||
|
||||
u, U - Unpack Size
|
||||
P - Pack Size
|
||||
S - Props
|
||||
*/
|
||||
|
||||
#define LZMA2_CONTROL_LZMA (1 << 7)
|
||||
#define LZMA2_CONTROL_COPY_NO_RESET 2
|
||||
#define LZMA2_CONTROL_COPY_RESET_DIC 1
|
||||
#define LZMA2_CONTROL_EOF 0
|
||||
|
||||
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
|
||||
|
||||
#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
|
||||
#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
|
||||
|
||||
#define LZMA2_LCLP_MAX 4
|
||||
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
|
||||
|
||||
#ifdef SHOW_DEBUG_INFO
|
||||
#define PRF(x) x
|
||||
#else
|
||||
#define PRF(x)
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA2_STATE_CONTROL,
|
||||
LZMA2_STATE_UNPACK0,
|
||||
LZMA2_STATE_UNPACK1,
|
||||
LZMA2_STATE_PACK0,
|
||||
LZMA2_STATE_PACK1,
|
||||
LZMA2_STATE_PROP,
|
||||
LZMA2_STATE_DATA,
|
||||
LZMA2_STATE_DATA_CONT,
|
||||
LZMA2_STATE_FINISHED,
|
||||
LZMA2_STATE_ERROR
|
||||
} ELzma2State;
|
||||
|
||||
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
if (prop > 40)
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
|
||||
props[0] = (Byte)LZMA2_LCLP_MAX;
|
||||
props[1] = (Byte)(dicSize);
|
||||
props[2] = (Byte)(dicSize >> 8);
|
||||
props[3] = (Byte)(dicSize >> 16);
|
||||
props[4] = (Byte)(dicSize >> 24);
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||
{
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
|
||||
{
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
|
||||
}
|
||||
|
||||
void Lzma2Dec_Init(CLzma2Dec *p)
|
||||
{
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
p->needInitDic = True;
|
||||
p->needInitState = True;
|
||||
p->needInitProp = True;
|
||||
LzmaDec_Init(&p->decoder);
|
||||
}
|
||||
|
||||
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
|
||||
{
|
||||
switch(p->state)
|
||||
{
|
||||
case LZMA2_STATE_CONTROL:
|
||||
p->control = b;
|
||||
PRF(printf("\n %4X ", p->decoder.dicPos));
|
||||
PRF(printf(" %2X", b));
|
||||
if (p->control == 0)
|
||||
return LZMA2_STATE_FINISHED;
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||
{
|
||||
if ((p->control & 0x7F) > 2)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->unpackSize = 0;
|
||||
}
|
||||
else
|
||||
p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
|
||||
return LZMA2_STATE_UNPACK0;
|
||||
|
||||
case LZMA2_STATE_UNPACK0:
|
||||
p->unpackSize |= (UInt32)b << 8;
|
||||
return LZMA2_STATE_UNPACK1;
|
||||
|
||||
case LZMA2_STATE_UNPACK1:
|
||||
p->unpackSize |= (UInt32)b;
|
||||
p->unpackSize++;
|
||||
PRF(printf(" %8d", p->unpackSize));
|
||||
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
|
||||
|
||||
case LZMA2_STATE_PACK0:
|
||||
p->packSize = (UInt32)b << 8;
|
||||
return LZMA2_STATE_PACK1;
|
||||
|
||||
case LZMA2_STATE_PACK1:
|
||||
p->packSize |= (UInt32)b;
|
||||
p->packSize++;
|
||||
PRF(printf(" %8d", p->packSize));
|
||||
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
|
||||
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
|
||||
|
||||
case LZMA2_STATE_PROP:
|
||||
{
|
||||
int lc, lp;
|
||||
if (b >= (9 * 5 * 5))
|
||||
return LZMA2_STATE_ERROR;
|
||||
lc = b % 9;
|
||||
b /= 9;
|
||||
p->decoder.prop.pb = b / 5;
|
||||
lp = b % 5;
|
||||
if (lc + lp > LZMA2_LCLP_MAX)
|
||||
return LZMA2_STATE_ERROR;
|
||||
p->decoder.prop.lc = lc;
|
||||
p->decoder.prop.lp = lp;
|
||||
p->needInitProp = False;
|
||||
return LZMA2_STATE_DATA;
|
||||
}
|
||||
}
|
||||
return LZMA2_STATE_ERROR;
|
||||
}
|
||||
|
||||
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
|
||||
{
|
||||
memcpy(p->dic + p->dicPos, src, size);
|
||||
p->dicPos += size;
|
||||
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
|
||||
p->checkDicSize = p->prop.dicSize;
|
||||
p->processedPos += (UInt32)size;
|
||||
}
|
||||
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
*srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
|
||||
while (p->state != LZMA2_STATE_FINISHED)
|
||||
{
|
||||
SizeT dicPos = p->decoder.dicPos;
|
||||
if (p->state == LZMA2_STATE_ERROR)
|
||||
return SZ_ERROR_DATA;
|
||||
if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
|
||||
{
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
|
||||
{
|
||||
if (*srcLen == inSize)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
(*srcLen)++;
|
||||
p->state = Lzma2Dec_UpdateState(p, *src++);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
SizeT destSizeCur = dicLimit - dicPos;
|
||||
SizeT srcSizeCur = inSize - *srcLen;
|
||||
ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
|
||||
|
||||
if (p->unpackSize <= destSizeCur)
|
||||
{
|
||||
destSizeCur = (SizeT)p->unpackSize;
|
||||
curFinishMode = LZMA_FINISH_END;
|
||||
}
|
||||
|
||||
if (LZMA2_IS_UNCOMPRESSED_STATE(p))
|
||||
{
|
||||
if (*srcLen == inSize)
|
||||
{
|
||||
*status = LZMA_STATUS_NEEDS_MORE_INPUT;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
|
||||
if (initDic)
|
||||
p->needInitProp = p->needInitState = True;
|
||||
else if (p->needInitDic)
|
||||
return SZ_ERROR_DATA;
|
||||
p->needInitDic = False;
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, False);
|
||||
}
|
||||
|
||||
if (srcSizeCur > destSizeCur)
|
||||
srcSizeCur = destSizeCur;
|
||||
|
||||
if (srcSizeCur == 0)
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->unpackSize -= (UInt32)srcSizeCur;
|
||||
p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
else
|
||||
{
|
||||
SizeT outSizeProcessed;
|
||||
SRes res;
|
||||
|
||||
if (p->state == LZMA2_STATE_DATA)
|
||||
{
|
||||
int mode = LZMA2_GET_LZMA_MODE(p);
|
||||
Bool initDic = (mode == 3);
|
||||
Bool initState = (mode > 0);
|
||||
if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
|
||||
return SZ_ERROR_DATA;
|
||||
|
||||
LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
|
||||
p->needInitDic = False;
|
||||
p->needInitState = False;
|
||||
p->state = LZMA2_STATE_DATA_CONT;
|
||||
}
|
||||
if (srcSizeCur > p->packSize)
|
||||
srcSizeCur = (SizeT)p->packSize;
|
||||
|
||||
res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
|
||||
src += srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
p->packSize -= (UInt32)srcSizeCur;
|
||||
|
||||
outSizeProcessed = p->decoder.dicPos - dicPos;
|
||||
p->unpackSize -= (UInt32)outSizeProcessed;
|
||||
|
||||
RINOK(res);
|
||||
if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
return res;
|
||||
|
||||
if (srcSizeCur == 0 && outSizeProcessed == 0)
|
||||
{
|
||||
if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ||
|
||||
p->unpackSize != 0 || p->packSize != 0)
|
||||
return SZ_ERROR_DATA;
|
||||
p->state = LZMA2_STATE_CONTROL;
|
||||
}
|
||||
if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
|
||||
*status = LZMA_STATUS_NOT_FINISHED;
|
||||
}
|
||||
}
|
||||
}
|
||||
*status = LZMA_STATUS_FINISHED_WITH_MARK;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
*srcLen = *destLen = 0;
|
||||
for (;;)
|
||||
{
|
||||
SizeT srcSizeCur = inSize, outSizeCur, dicPos;
|
||||
ELzmaFinishMode curFinishMode;
|
||||
SRes res;
|
||||
if (p->decoder.dicPos == p->decoder.dicBufSize)
|
||||
p->decoder.dicPos = 0;
|
||||
dicPos = p->decoder.dicPos;
|
||||
if (outSize > p->decoder.dicBufSize - dicPos)
|
||||
{
|
||||
outSizeCur = p->decoder.dicBufSize;
|
||||
curFinishMode = LZMA_FINISH_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
outSizeCur = dicPos + outSize;
|
||||
curFinishMode = finishMode;
|
||||
}
|
||||
|
||||
res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status);
|
||||
src += srcSizeCur;
|
||||
inSize -= srcSizeCur;
|
||||
*srcLen += srcSizeCur;
|
||||
outSizeCur = p->decoder.dicPos - dicPos;
|
||||
memcpy(dest, p->decoder.dic + dicPos, outSizeCur);
|
||||
dest += outSizeCur;
|
||||
outSize -= outSizeCur;
|
||||
*destLen += outSizeCur;
|
||||
if (res != 0)
|
||||
return res;
|
||||
if (outSizeCur == 0 || outSize == 0)
|
||||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
|
||||
{
|
||||
CLzma2Dec decoder;
|
||||
SRes res;
|
||||
SizeT outSize = *destLen, inSize = *srcLen;
|
||||
Byte props[LZMA_PROPS_SIZE];
|
||||
|
||||
Lzma2Dec_Construct(&decoder);
|
||||
|
||||
*destLen = *srcLen = 0;
|
||||
*status = LZMA_STATUS_NOT_SPECIFIED;
|
||||
decoder.decoder.dic = dest;
|
||||
decoder.decoder.dicBufSize = outSize;
|
||||
|
||||
RINOK(Lzma2Dec_GetOldProps(prop, props));
|
||||
RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
|
||||
|
||||
*srcLen = inSize;
|
||||
res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
|
||||
*destLen = decoder.decoder.dicPos;
|
||||
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
|
||||
res = SZ_ERROR_INPUT_EOF;
|
||||
|
||||
LzmaDec_FreeProbs(&decoder.decoder, alloc);
|
||||
return res;
|
||||
}
|
84
lzma/C/Lzma2Dec.h
Normal file
84
lzma/C/Lzma2Dec.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* Lzma2Dec.h -- LZMA2 Decoder
|
||||
2009-05-03 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMA2_DEC_H
|
||||
#define __LZMA2_DEC_H
|
||||
|
||||
#include "LzmaDec.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ---------- State Interface ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaDec decoder;
|
||||
UInt32 packSize;
|
||||
UInt32 unpackSize;
|
||||
int state;
|
||||
Byte control;
|
||||
Bool needInitDic;
|
||||
Bool needInitState;
|
||||
Bool needInitProp;
|
||||
} CLzma2Dec;
|
||||
|
||||
#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
|
||||
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
|
||||
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
|
||||
|
||||
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
|
||||
void Lzma2Dec_Init(CLzma2Dec *p);
|
||||
|
||||
|
||||
/*
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
|
||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/*
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - use smallest number of input bytes
|
||||
LZMA_FINISH_END - read EndOfStream marker after decoding
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/* LzmaDec.c -- LZMA Decoder
|
||||
2008-11-06 : Igor Pavlov : Public domain */
|
||||
2009-09-20 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "LzmaDec.h"
|
||||
|
||||
|
@ -113,12 +113,6 @@
|
|||
StopCompilingDueBUG
|
||||
#endif
|
||||
|
||||
static const Byte kLiteralNextStates[kNumStates * 2] =
|
||||
{
|
||||
0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
|
||||
7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
|
||||
};
|
||||
|
||||
#define LZMA_DIC_MIN (1 << 12)
|
||||
|
||||
/* First LZMA-symbol is always decoded.
|
||||
|
@ -175,6 +169,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||
|
||||
if (state < kNumLitStates)
|
||||
{
|
||||
state -= (state < 4) ? state : 3;
|
||||
symbol = 1;
|
||||
do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
|
||||
}
|
||||
|
@ -182,6 +177,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||
{
|
||||
unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
|
||||
unsigned offs = 0x100;
|
||||
state -= (state < 10) ? 3 : 6;
|
||||
symbol = 1;
|
||||
do
|
||||
{
|
||||
|
@ -196,9 +192,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||
}
|
||||
dic[dicPos++] = (Byte)symbol;
|
||||
processedPos++;
|
||||
|
||||
state = kLiteralNextStates[state];
|
||||
/* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -378,7 +371,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||
else if (distance >= checkDicSize)
|
||||
return SZ_ERROR_DATA;
|
||||
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
|
||||
/* state = kLiteralNextStates[state]; */
|
||||
}
|
||||
|
||||
len += kMatchMinLen;
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* LzmaDec.h -- LZMA Decoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMADEC_H
|
||||
#define __LZMADEC_H
|
||||
#ifndef __LZMA_DEC_H
|
||||
#define __LZMA_DEC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
@ -66,13 +70,7 @@ typedef struct
|
|||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
|
@ -132,11 +130,7 @@ LzmaDec_Allocate* can return:
|
|||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
|
|
103
lzma/C/LzmaEnc.c
103
lzma/C/LzmaEnc.c
|
@ -1,5 +1,5 @@
|
|||
/* LzmaEnc.c -- LZMA Encoder
|
||||
2009-02-02 : Igor Pavlov : Public domain */
|
||||
2010-04-16 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
|||
#include "LzmaEnc.h"
|
||||
|
||||
#include "LzFind.h"
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
#include "LzFindMt.h"
|
||||
#endif
|
||||
|
||||
|
@ -66,7 +66,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
|||
if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
|
||||
if (p->numThreads < 0)
|
||||
p->numThreads =
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
((p->btMode && p->algo) ? 2 : 1);
|
||||
#else
|
||||
1;
|
||||
|
@ -139,7 +139,7 @@ void LzmaEnc_FastPosInit(Byte *g_FastPos)
|
|||
|
||||
typedef unsigned CState;
|
||||
|
||||
typedef struct _COptimal
|
||||
typedef struct
|
||||
{
|
||||
UInt32 price;
|
||||
|
||||
|
@ -172,7 +172,7 @@ typedef struct _COptimal
|
|||
#define kEndPosModelIndex 14
|
||||
#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
|
||||
|
||||
#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
|
||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
|
@ -218,7 +218,7 @@ typedef struct
|
|||
UInt32 counters[LZMA_NUM_PB_STATES_MAX];
|
||||
} CLenPriceEnc;
|
||||
|
||||
typedef struct _CRangeEnc
|
||||
typedef struct
|
||||
{
|
||||
UInt32 range;
|
||||
Byte cache;
|
||||
|
@ -232,26 +232,6 @@ typedef struct _CRangeEnc
|
|||
SRes res;
|
||||
} CRangeEnc;
|
||||
|
||||
typedef struct _CSeqInStreamBuf
|
||||
{
|
||||
ISeqInStream funcTable;
|
||||
const Byte *data;
|
||||
SizeT rem;
|
||||
} CSeqInStreamBuf;
|
||||
|
||||
static SRes MyRead(void *pp, void *data, size_t *size)
|
||||
{
|
||||
size_t curSize = *size;
|
||||
CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
|
||||
if (p->rem < curSize)
|
||||
curSize = p->rem;
|
||||
memcpy(data, p->data, curSize);
|
||||
p->rem -= curSize;
|
||||
p->data += curSize;
|
||||
*size = curSize;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProb *litProbs;
|
||||
|
@ -274,19 +254,19 @@ typedef struct
|
|||
UInt32 state;
|
||||
} CSaveState;
|
||||
|
||||
typedef struct _CLzmaEnc
|
||||
typedef struct
|
||||
{
|
||||
IMatchFinder matchFinder;
|
||||
void *matchFinderObj;
|
||||
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
Bool mtMode;
|
||||
CMatchFinderMt matchFinderMt;
|
||||
#endif
|
||||
|
||||
CMatchFinder matchFinderBase;
|
||||
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
Byte pad[128];
|
||||
#endif
|
||||
|
||||
|
@ -351,8 +331,7 @@ typedef struct _CLzmaEnc
|
|||
UInt32 dictSize;
|
||||
UInt32 matchFinderCycles;
|
||||
|
||||
ISeqInStream *inStream;
|
||||
CSeqInStreamBuf seqBufInStream;
|
||||
int needInit;
|
||||
|
||||
CSaveState saveState;
|
||||
} CLzmaEnc;
|
||||
|
@ -416,7 +395,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||
LzmaEncProps_Normalize(&props);
|
||||
|
||||
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
|
||||
props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
|
||||
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
|
||||
return SZ_ERROR_PARAM;
|
||||
p->dictSize = props.dictSize;
|
||||
p->matchFinderCycles = props.mc;
|
||||
|
@ -449,7 +428,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
|
|||
|
||||
p->writeEndMark = props.writeEndMark;
|
||||
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
/*
|
||||
if (newMultiThread != _multiThread)
|
||||
{
|
||||
|
@ -1698,7 +1677,7 @@ void LzmaEnc_Construct(CLzmaEnc *p)
|
|||
{
|
||||
RangeEnc_Construct(&p->rc);
|
||||
MatchFinder_Construct(&p->matchFinderBase);
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
MatchFinderMt_Construct(&p->matchFinderMt);
|
||||
p->matchFinderMt.MatchFinder = &p->matchFinderBase;
|
||||
#endif
|
||||
|
@ -1737,7 +1716,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
|||
|
||||
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
|
||||
#endif
|
||||
MatchFinder_Free(&p->matchFinderBase, allocBig);
|
||||
|
@ -1754,11 +1733,10 @@ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
|
|||
static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
|
||||
{
|
||||
UInt32 nowPos32, startPos32;
|
||||
if (p->inStream != 0)
|
||||
if (p->needInit)
|
||||
{
|
||||
p->matchFinderBase.stream = p->inStream;
|
||||
p->matchFinder.Init(p->matchFinderObj);
|
||||
p->inStream = 0;
|
||||
p->needInit = 0;
|
||||
}
|
||||
|
||||
if (p->finished)
|
||||
|
@ -1923,7 +1901,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||
if (!RangeEnc_Alloc(&p->rc, alloc))
|
||||
return SZ_ERROR_MEM;
|
||||
btMode = (p->matchFinderBase.btMode != 0);
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
p->mtMode = (p->multiThread && !p->fastMode && btMode);
|
||||
#endif
|
||||
|
||||
|
@ -1948,7 +1926,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I
|
|||
if (beforeSize + p->dictSize < keepWindowSize)
|
||||
beforeSize = keepWindowSize - p->dictSize;
|
||||
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
if (p->mtMode)
|
||||
{
|
||||
RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
|
||||
|
@ -2056,11 +2034,12 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *a
|
|||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
|
||||
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
p->inStream = inStream;
|
||||
p->matchFinderBase.stream = inStream;
|
||||
p->needInit = 1;
|
||||
p->rc.outStream = outStream;
|
||||
return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
|
||||
}
|
||||
|
@ -2070,15 +2049,16 @@ SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
|
|||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
p->inStream = inStream;
|
||||
p->matchFinderBase.stream = inStream;
|
||||
p->needInit = 1;
|
||||
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
|
||||
}
|
||||
|
||||
static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
|
||||
{
|
||||
p->seqBufInStream.funcTable.Read = MyRead;
|
||||
p->seqBufInStream.data = src;
|
||||
p->seqBufInStream.rem = srcLen;
|
||||
p->matchFinderBase.directInput = 1;
|
||||
p->matchFinderBase.bufferBase = (Byte *)src;
|
||||
p->matchFinderBase.directInputRem = srcLen;
|
||||
}
|
||||
|
||||
SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
||||
|
@ -2086,13 +2066,14 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
|
|||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
LzmaEnc_SetInputBuf(p, src, srcLen);
|
||||
p->inStream = &p->seqBufInStream.funcTable;
|
||||
p->needInit = 1;
|
||||
|
||||
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
|
||||
}
|
||||
|
||||
void LzmaEnc_Finish(CLzmaEncHandle pp)
|
||||
{
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
if (p->mtMode)
|
||||
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
|
||||
|
@ -2101,7 +2082,7 @@ void LzmaEnc_Finish(CLzmaEncHandle pp)
|
|||
#endif
|
||||
}
|
||||
|
||||
typedef struct _CSeqOutStreamBuf
|
||||
typedef struct
|
||||
{
|
||||
ISeqOutStream funcTable;
|
||||
Byte *data;
|
||||
|
@ -2170,21 +2151,17 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
|||
return res;
|
||||
}
|
||||
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
SRes res = SZ_OK;
|
||||
|
||||
#ifdef COMPRESS_MF_MT
|
||||
#ifndef _7ZIP_ST
|
||||
Byte allocaDummy[0x300];
|
||||
int i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
allocaDummy[i] = (Byte)i;
|
||||
#endif
|
||||
|
||||
RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
|
||||
|
@ -2200,10 +2177,17 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i
|
|||
}
|
||||
}
|
||||
}
|
||||
LzmaEnc_Finish(pp);
|
||||
LzmaEnc_Finish(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
|
||||
ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
|
||||
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
|
||||
}
|
||||
|
||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
|
@ -2249,8 +2233,11 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte
|
|||
outStream.overflow = False;
|
||||
|
||||
p->writeEndMark = writeEndMark;
|
||||
res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
|
||||
progress, alloc, allocBig);
|
||||
|
||||
p->rc.outStream = &outStream.funcTable;
|
||||
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
|
||||
if (res == SZ_OK)
|
||||
res = LzmaEnc_Encode2(p, progress);
|
||||
|
||||
*destLen -= outStream.rem;
|
||||
if (outStream.overflow)
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
/* LzmaEnc.h -- LZMA Encoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2009-02-07 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMAENC_H
|
||||
#define __LZMAENC_H
|
||||
#ifndef __LZMA_ENC_H
|
||||
#define __LZMA_ENC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaEncProps
|
||||
|
@ -69,4 +73,8 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
|||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/* LzmaLib.c -- LZMA library wrapper
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "LzmaEnc.h"
|
||||
#include "LzmaDec.h"
|
||||
#include "Alloc.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,
|
||||
unsigned char *outProps, size_t *outPropsSize,
|
||||
int level, /* 0 <= level <= 9, default = 5 */
|
||||
unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
|
||||
int lc, /* 0 <= lc <= 8, default = 3 */
|
||||
int lp, /* 0 <= lp <= 4, default = 0 */
|
||||
int pb, /* 0 <= pb <= 4, default = 2 */
|
||||
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||
int numThreads /* 1 or 2, default = 2 */
|
||||
)
|
||||
{
|
||||
CLzmaEncProps props;
|
||||
LzmaEncProps_Init(&props);
|
||||
props.level = level;
|
||||
props.dictSize = dictSize;
|
||||
props.lc = lc;
|
||||
props.lp = lp;
|
||||
props.pb = pb;
|
||||
props.fb = fb;
|
||||
props.numThreads = numThreads;
|
||||
|
||||
return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0,
|
||||
NULL, &g_Alloc, &g_Alloc);
|
||||
}
|
||||
|
||||
|
||||
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
|
||||
const unsigned char *props, size_t propsSize)
|
||||
{
|
||||
ELzmaStatus status;
|
||||
return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc);
|
||||
}
|
135
lzma/C/LzmaLib.h
135
lzma/C/LzmaLib.h
|
@ -1,135 +0,0 @@
|
|||
/* LzmaLib.h -- LZMA library interface
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __LZMALIB_H
|
||||
#define __LZMALIB_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define MY_EXTERN_C extern "C"
|
||||
#else
|
||||
#define MY_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
#define MY_STDAPI MY_EXTERN_C int MY_STD_CALL
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
/*
|
||||
RAM requirements for LZMA:
|
||||
for compression: (dictSize * 11.5 + 6 MB) + state_size
|
||||
for decompression: dictSize + state_size
|
||||
state_size = (4 + (1.5 << (lc + lp))) KB
|
||||
by default (lc=3, lp=0), state_size = 16 KB.
|
||||
|
||||
LZMA properties (5 bytes) format
|
||||
Offset Size Description
|
||||
0 1 lc, lp and pb in encoded form.
|
||||
1 4 dictSize (little endian).
|
||||
*/
|
||||
|
||||
/*
|
||||
LzmaCompress
|
||||
------------
|
||||
|
||||
outPropsSize -
|
||||
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
|
||||
|
||||
LZMA Encoder will use defult values for any parameter, if it is
|
||||
-1 for any from: level, loc, lp, pb, fb, numThreads
|
||||
0 for dictSize
|
||||
|
||||
level - compression level: 0 <= level <= 9;
|
||||
|
||||
level dictSize algo fb
|
||||
0: 16 KB 0 32
|
||||
1: 64 KB 0 32
|
||||
2: 256 KB 0 32
|
||||
3: 1 MB 0 32
|
||||
4: 4 MB 0 32
|
||||
5: 16 MB 1 32
|
||||
6: 32 MB 1 32
|
||||
7+: 64 MB 1 64
|
||||
|
||||
The default value for "level" is 5.
|
||||
|
||||
algo = 0 means fast method
|
||||
algo = 1 means normal method
|
||||
|
||||
dictSize - The dictionary size in bytes. The maximum value is
|
||||
128 MB = (1 << 27) bytes for 32-bit version
|
||||
1 GB = (1 << 30) bytes for 64-bit version
|
||||
The default value is 16 MB = (1 << 24) bytes.
|
||||
It's recommended to use the dictionary that is larger than 4 KB and
|
||||
that can be calculated as (1 << N) or (3 << N) sizes.
|
||||
|
||||
lc - The number of literal context bits (high bits of previous literal).
|
||||
It can be in the range from 0 to 8. The default value is 3.
|
||||
Sometimes lc=4 gives the gain for big files.
|
||||
|
||||
lp - The number of literal pos bits (low bits of current position for literals).
|
||||
It can be in the range from 0 to 4. The default value is 0.
|
||||
The lp switch is intended for periodical data when the period is equal to 2^lp.
|
||||
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
|
||||
better to set lc=0, if you change lp switch.
|
||||
|
||||
pb - The number of pos bits (low bits of current position).
|
||||
It can be in the range from 0 to 4. The default value is 2.
|
||||
The pb switch is intended for periodical data when the period is equal 2^pb.
|
||||
|
||||
fb - Word size (the number of fast bytes).
|
||||
It can be in the range from 5 to 273. The default value is 32.
|
||||
Usually, a big number gives a little bit better compression ratio and
|
||||
slower compression process.
|
||||
|
||||
numThreads - The number of thereads. 1 or 2. The default value is 2.
|
||||
Fast mode (algo = 0) can use only 1 thread.
|
||||
|
||||
Out:
|
||||
destLen - processed output size
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
|
||||
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
|
||||
int level, /* 0 <= level <= 9, default = 5 */
|
||||
unsigned dictSize, /* default = (1 << 24) */
|
||||
int lc, /* 0 <= lc <= 8, default = 3 */
|
||||
int lp, /* 0 <= lp <= 4, default = 0 */
|
||||
int pb, /* 0 <= pb <= 4, default = 2 */
|
||||
int fb, /* 5 <= fb <= 273, default = 32 */
|
||||
int numThreads /* 1 or 2, default = 2 */
|
||||
);
|
||||
|
||||
/*
|
||||
LzmaUncompress
|
||||
--------------
|
||||
In:
|
||||
dest - output data
|
||||
destLen - output data size
|
||||
src - input data
|
||||
srcLen - input data size
|
||||
Out:
|
||||
destLen - processed output size
|
||||
srcLen - processed input size
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation arror
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
|
||||
*/
|
||||
|
||||
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
|
||||
const unsigned char *props, size_t propsSize);
|
||||
|
||||
#endif
|
294
lzma/C/Threads.c
294
lzma/C/Threads.c
|
@ -1,13 +1,12 @@
|
|||
/* Threads.c -- multithreading library
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
2009-09-20 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef _WIN32_WCE
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#include "Threads.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <process.h>
|
||||
|
||||
static WRes GetError()
|
||||
{
|
||||
DWORD res = GetLastError();
|
||||
|
@ -17,276 +16,69 @@ static WRes GetError()
|
|||
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
||||
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
||||
|
||||
static WRes MyCloseHandle(HANDLE *h)
|
||||
WRes HandlePtr_Close(HANDLE *p)
|
||||
{
|
||||
if (*h != NULL)
|
||||
if (!CloseHandle(*h))
|
||||
if (*p != NULL)
|
||||
if (!CloseHandle(*p))
|
||||
return GetError();
|
||||
*h = NULL;
|
||||
*p = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
|
||||
WRes Handle_WaitObject(HANDLE h) { return (WRes)WaitForSingleObject(h, INFINITE); }
|
||||
|
||||
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
|
||||
{
|
||||
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
||||
thread->handle =
|
||||
/* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
|
||||
(HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
|
||||
*p =
|
||||
#ifdef UNDER_CE
|
||||
CreateThread(0, 0, func, param, 0, &threadId);
|
||||
#else
|
||||
(HANDLE)_beginthreadex(NULL, 0, func, param, 0, &threadId);
|
||||
#endif
|
||||
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
||||
return HandleToWRes(thread->handle);
|
||||
return HandleToWRes(*p);
|
||||
}
|
||||
|
||||
WRes WaitObject(HANDLE h)
|
||||
WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
|
||||
{
|
||||
return (WRes)WaitForSingleObject(h, INFINITE);
|
||||
*p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
|
||||
return HandleToWRes(*p);
|
||||
}
|
||||
|
||||
WRes Thread_Wait(CThread *thread)
|
||||
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }
|
||||
WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }
|
||||
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
|
||||
{
|
||||
if (thread->handle == NULL)
|
||||
return 1;
|
||||
return WaitObject(thread->handle);
|
||||
*p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
|
||||
return HandleToWRes(*p);
|
||||
}
|
||||
|
||||
WRes Thread_Close(CThread *thread)
|
||||
{
|
||||
return MyCloseHandle(&thread->handle);
|
||||
}
|
||||
|
||||
WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
|
||||
{
|
||||
p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
|
||||
return HandleToWRes(p->handle);
|
||||
}
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, TRUE, initialSignaled); }
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
|
||||
{ return ManualResetEvent_Create(p, 0); }
|
||||
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, FALSE, initialSignaled); }
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
|
||||
{ return AutoResetEvent_Create(p, 0); }
|
||||
|
||||
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
|
||||
WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); }
|
||||
WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
|
||||
WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
|
||||
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
|
||||
{
|
||||
p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
|
||||
return HandleToWRes(p->handle);
|
||||
}
|
||||
|
||||
WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||
{
|
||||
return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
|
||||
}
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
|
||||
{
|
||||
return Semaphore_Release(p, (LONG)releaseCount, NULL);
|
||||
}
|
||||
WRes Semaphore_Release1(CSemaphore *p)
|
||||
{
|
||||
return Semaphore_ReleaseN(p, 1);
|
||||
}
|
||||
|
||||
WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
|
||||
WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
|
||||
static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||
{ return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)
|
||||
{ return Semaphore_Release(p, (LONG)num, NULL); }
|
||||
WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p)
|
||||
{
|
||||
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
||||
#ifndef __GNUC__
|
||||
#ifdef _MSC_VER
|
||||
__try
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
InitializeCriticalSection(p);
|
||||
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
||||
}
|
||||
#ifndef __GNUC__
|
||||
#ifdef _MSC_VER
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#define PTHREAD_MUTEX_ERRORCHECK PTHREAD_MUTEX_ERRORCHECK_NP
|
||||
#endif
|
||||
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *parameter)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
int ret;
|
||||
|
||||
thread->_created = 0;
|
||||
|
||||
ret = pthread_attr_init(&attr);
|
||||
if (ret) return ret;
|
||||
|
||||
ret = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
|
||||
if (ret) return ret;
|
||||
|
||||
ret = pthread_create(&thread->_tid, &attr, (void * (*)(void *))startAddress, parameter);
|
||||
|
||||
/* ret2 = */ pthread_attr_destroy(&attr);
|
||||
|
||||
if (ret) return ret;
|
||||
|
||||
thread->_created = 1;
|
||||
|
||||
return 0; // SZ_OK;
|
||||
}
|
||||
|
||||
WRes Thread_Wait(CThread *thread)
|
||||
{
|
||||
void *thread_return;
|
||||
int ret;
|
||||
|
||||
if (thread->_created == 0)
|
||||
return EINVAL;
|
||||
|
||||
ret = pthread_join(thread->_tid,&thread_return);
|
||||
thread->_created = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WRes Thread_Close(CThread *thread)
|
||||
{
|
||||
if (!thread->_created) return SZ_OK;
|
||||
|
||||
pthread_detach(thread->_tid);
|
||||
thread->_tid = 0;
|
||||
thread->_created = 0;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
|
||||
{
|
||||
pthread_mutex_init(&p->_mutex,0);
|
||||
pthread_cond_init(&p->_cond,0);
|
||||
p->_manual_reset = manualReset;
|
||||
p->_state = (initialSignaled ? TRUE : FALSE);
|
||||
p->_created = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Event_Set(CEvent *p) {
|
||||
pthread_mutex_lock(&p->_mutex);
|
||||
p->_state = TRUE;
|
||||
pthread_cond_broadcast(&p->_cond);
|
||||
pthread_mutex_unlock(&p->_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Event_Reset(CEvent *p) {
|
||||
pthread_mutex_lock(&p->_mutex);
|
||||
p->_state = FALSE;
|
||||
pthread_mutex_unlock(&p->_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Event_Wait(CEvent *p) {
|
||||
pthread_mutex_lock(&p->_mutex);
|
||||
while (p->_state == FALSE)
|
||||
{
|
||||
pthread_cond_wait(&p->_cond, &p->_mutex);
|
||||
}
|
||||
if (p->_manual_reset == FALSE)
|
||||
{
|
||||
p->_state = FALSE;
|
||||
}
|
||||
pthread_mutex_unlock(&p->_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Event_Close(CEvent *p) {
|
||||
if (p->_created)
|
||||
{
|
||||
p->_created = 0;
|
||||
pthread_mutex_destroy(&p->_mutex);
|
||||
pthread_cond_destroy(&p->_cond);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
|
||||
{
|
||||
pthread_mutex_init(&p->_mutex,0);
|
||||
pthread_cond_init(&p->_cond,0);
|
||||
p->_count = initiallyCount;
|
||||
p->_maxCount = maxCount;
|
||||
p->_created = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
|
||||
{
|
||||
UInt32 newCount;
|
||||
|
||||
if (releaseCount < 1) return EINVAL;
|
||||
|
||||
pthread_mutex_lock(&p->_mutex);
|
||||
|
||||
newCount = p->_count + releaseCount;
|
||||
if (newCount > p->_maxCount)
|
||||
{
|
||||
pthread_mutex_unlock(&p->_mutex);
|
||||
return EINVAL;
|
||||
}
|
||||
p->_count = newCount;
|
||||
pthread_cond_broadcast(&p->_cond);
|
||||
pthread_mutex_unlock(&p->_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Semaphore_Wait(CSemaphore *p) {
|
||||
pthread_mutex_lock(&p->_mutex);
|
||||
while (p->_count < 1)
|
||||
{
|
||||
pthread_cond_wait(&p->_cond, &p->_mutex);
|
||||
}
|
||||
p->_count--;
|
||||
pthread_mutex_unlock(&p->_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Semaphore_Close(CSemaphore *p) {
|
||||
if (p->_created)
|
||||
{
|
||||
p->_created = 0;
|
||||
pthread_mutex_destroy(&p->_mutex);
|
||||
pthread_cond_destroy(&p->_cond);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection * lpCriticalSection)
|
||||
{
|
||||
return pthread_mutex_init(&(lpCriticalSection->_mutex),0);
|
||||
}
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, TRUE, initialSignaled); }
|
||||
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
|
||||
{ return ManualResetEvent_Create(p, 0); }
|
||||
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, FALSE, initialSignaled); }
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
|
||||
{ return AutoResetEvent_Create(p, 0); }
|
||||
|
||||
#endif
|
||||
|
|
162
lzma/C/Threads.h
162
lzma/C/Threads.h
|
@ -1,151 +1,59 @@
|
|||
/* Threads.h -- multithreading library
|
||||
2008-11-22 : Igor Pavlov : Public domain */
|
||||
2009-03-27 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_THRESDS_H
|
||||
#define __7Z_THRESDS_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
typedef DWORD WRes;
|
||||
#ifndef __7Z_THREADS_H
|
||||
#define __7Z_THREADS_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
typedef struct _CThread
|
||||
{
|
||||
HANDLE handle;
|
||||
} CThread;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define Thread_Construct(thread) (thread)->handle = NULL
|
||||
#define Thread_WasCreated(thread) ((thread)->handle != NULL)
|
||||
|
||||
WRes HandlePtr_Close(HANDLE *h);
|
||||
WRes Handle_WaitObject(HANDLE h);
|
||||
|
||||
typedef HANDLE CThread;
|
||||
#define Thread_Construct(p) *(p) = NULL
|
||||
#define Thread_WasCreated(p) (*(p) != NULL)
|
||||
#define Thread_Close(p) HandlePtr_Close(p)
|
||||
#define Thread_Wait(p) Handle_WaitObject(*(p))
|
||||
typedef unsigned THREAD_FUNC_RET_TYPE;
|
||||
#define THREAD_FUNC_CALL_TYPE __stdcall
|
||||
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
|
||||
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
|
||||
typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);
|
||||
WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
|
||||
WRes Thread_Wait(CThread *thread);
|
||||
WRes Thread_Close(CThread *thread);
|
||||
|
||||
typedef struct _CEvent
|
||||
{
|
||||
HANDLE handle;
|
||||
} CEvent;
|
||||
|
||||
typedef HANDLE CEvent;
|
||||
typedef CEvent CAutoResetEvent;
|
||||
typedef CEvent CManualResetEvent;
|
||||
#define Event_Construct(p) *(p) = NULL
|
||||
#define Event_IsCreated(p) (*(p) != NULL)
|
||||
#define Event_Close(p) HandlePtr_Close(p)
|
||||
#define Event_Wait(p) Handle_WaitObject(*(p))
|
||||
WRes Event_Set(CEvent *p);
|
||||
WRes Event_Reset(CEvent *p);
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);
|
||||
|
||||
#define Event_Construct(event) (event)->handle = NULL
|
||||
#define Event_IsCreated(event) ((event)->handle != NULL)
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
|
||||
WRes Event_Set(CEvent *event);
|
||||
WRes Event_Reset(CEvent *event);
|
||||
WRes Event_Wait(CEvent *event);
|
||||
WRes Event_Close(CEvent *event);
|
||||
|
||||
|
||||
typedef struct _CSemaphore
|
||||
{
|
||||
HANDLE handle;
|
||||
} CSemaphore;
|
||||
|
||||
#define Semaphore_Construct(p) (p)->handle = NULL
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
|
||||
typedef HANDLE CSemaphore;
|
||||
#define Semaphore_Construct(p) (*p) = NULL
|
||||
#define Semaphore_Close(p) HandlePtr_Close(p)
|
||||
#define Semaphore_Wait(p) Handle_WaitObject(*(p))
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
||||
WRes Semaphore_Release1(CSemaphore *p);
|
||||
WRes Semaphore_Wait(CSemaphore *p);
|
||||
WRes Semaphore_Close(CSemaphore *p);
|
||||
|
||||
|
||||
typedef CRITICAL_SECTION CCriticalSection;
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p);
|
||||
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
|
||||
#define CriticalSection_Enter(p) EnterCriticalSection(p)
|
||||
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
|
||||
|
||||
#else
|
||||
typedef int WRes;
|
||||
|
||||
#include "Types.h"
|
||||
#include <pthread.h>
|
||||
|
||||
/* #define DEBUG_SYNCHRO 1 */
|
||||
|
||||
typedef struct _CThread
|
||||
{
|
||||
pthread_t _tid;
|
||||
int _created;
|
||||
|
||||
} CThread;
|
||||
|
||||
#define Thread_Construct(thread) (thread)->_created = 0
|
||||
#define Thread_WasCreated(thread) ((thread)->_created != 0)
|
||||
|
||||
typedef unsigned THREAD_FUNC_RET_TYPE;
|
||||
#define THREAD_FUNC_CALL_TYPE
|
||||
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), void *parameter);
|
||||
WRes Thread_Wait(CThread *thread);
|
||||
WRes Thread_Close(CThread *thread);
|
||||
|
||||
typedef struct _CEvent
|
||||
{
|
||||
int _created;
|
||||
int _manual_reset;
|
||||
int _state;
|
||||
pthread_mutex_t _mutex;
|
||||
pthread_cond_t _cond;
|
||||
} CEvent;
|
||||
|
||||
typedef CEvent CAutoResetEvent;
|
||||
typedef CEvent CManualResetEvent;
|
||||
|
||||
#define Event_Construct(event) (event)->_created = 0
|
||||
#define Event_IsCreated(event) ((event)->_created)
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
|
||||
WRes Event_Set(CEvent *event);
|
||||
WRes Event_Reset(CEvent *event);
|
||||
WRes Event_Wait(CEvent *event);
|
||||
WRes Event_Close(CEvent *event);
|
||||
|
||||
|
||||
typedef struct _CSemaphore
|
||||
{
|
||||
int _created;
|
||||
UInt32 _count;
|
||||
UInt32 _maxCount;
|
||||
pthread_mutex_t _mutex;
|
||||
pthread_cond_t _cond;
|
||||
} CSemaphore;
|
||||
|
||||
#define Semaphore_Construct(p) (p)->_created = 0
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
||||
#define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1)
|
||||
WRes Semaphore_Wait(CSemaphore *p);
|
||||
WRes Semaphore_Close(CSemaphore *p);
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t _mutex;
|
||||
} CCriticalSection;
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p);
|
||||
#define CriticalSection_Delete(p) pthread_mutex_destroy(&((p)->_mutex))
|
||||
#define CriticalSection_Enter(p) pthread_mutex_lock(&((p)->_mutex))
|
||||
#define CriticalSection_Leave(p) pthread_mutex_unlock(&((p)->_mutex))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
/* Types.h -- Basic types
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
2010-10-09 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef EXTERN_C_BEGIN
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN_C_BEGIN extern "C" {
|
||||
#define EXTERN_C_END }
|
||||
#else
|
||||
#define EXTERN_C_BEGIN
|
||||
#define EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
|
@ -30,6 +42,12 @@ extern "C" {
|
|||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
@ -37,10 +55,8 @@ typedef int SRes;
|
|||
#if defined(__APPLE__) && !__LP64__
|
||||
#define _LZMA_UINT32_IS_ULONG
|
||||
#endif
|
||||
|
||||
#ifndef ZCONF_H
|
||||
|
||||
typedef unsigned char Byte;
|
||||
#endif
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
|
@ -65,9 +81,11 @@ typedef unsigned long UInt64;
|
|||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#define UINT64_CONST(n) n
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#define UINT64_CONST(n) n ## ULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -83,6 +101,12 @@ typedef int Bool;
|
|||
#define False 0
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define MY_STD_CALL __stdcall
|
||||
#else
|
||||
#define MY_STD_CALL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
|
@ -92,13 +116,11 @@ typedef int Bool;
|
|||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_STD_CALL __stdcall
|
||||
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
||||
#define MY_FAST_CALL __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_CDECL
|
||||
#define MY_STD_CALL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
@ -106,6 +128,16 @@ typedef int Bool;
|
|||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
|
||||
} IByteIn;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*Write)(void *p, Byte b);
|
||||
} IByteOut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
|
@ -140,7 +172,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, void **buf, size_t *size);
|
||||
SRes (*Look)(void *p, const void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
|
@ -205,8 +237,22 @@ typedef struct
|
|||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '\\'
|
||||
#define WCHAR_PATH_SEPARATOR L'\\'
|
||||
#define STRING_PATH_SEPARATOR "\\"
|
||||
#define WSTRING_PATH_SEPARATOR L"\\"
|
||||
|
||||
#else
|
||||
|
||||
#define CHAR_PATH_SEPARATOR '/'
|
||||
#define WCHAR_PATH_SEPARATOR L'/'
|
||||
#define STRING_PATH_SEPARATOR "/"
|
||||
#define WSTRING_PATH_SEPARATOR L"/"
|
||||
|
||||
#endif
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,25 +7,25 @@ if( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL
|
|||
endif( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" )
|
||||
|
||||
set( LZMA_FILES
|
||||
C/Archive/7z/7zDecode.c
|
||||
C/Archive/7z/7zExtract.c
|
||||
C/Archive/7z/7zHeader.c
|
||||
C/Archive/7z/7zIn.c
|
||||
C/Archive/7z/7zItem.c
|
||||
C/7zBuf.c
|
||||
C/7zCrc.c
|
||||
C/7zCrcOpt.c
|
||||
C/7zDec.c
|
||||
C/7zIn.c
|
||||
C/7zStream.c
|
||||
C/Alloc.c
|
||||
C/Bcj2.c
|
||||
C/Bra86.c
|
||||
C/LzFind.c
|
||||
C/LzFindMt.c
|
||||
C/LzmaDec.c
|
||||
C/LzmaEnc.c
|
||||
C/LzmaLib.c )
|
||||
C/Bcj2.c
|
||||
C/Bra.c
|
||||
C/Bra86.c
|
||||
C/CpuArch.c
|
||||
C/LzFind.c
|
||||
C/Lzma2Dec.c
|
||||
C/LzmaDec.c
|
||||
C/LzmaEnc.c )
|
||||
|
||||
if( WIN32 )
|
||||
set( LZMA_FILES ${LZMA_FILES} C/Threads.c )
|
||||
set( LZMA_FILES ${LZMA_FILES} C/LzFindMt.c C/Threads.c )
|
||||
else( WIN32 )
|
||||
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_7ZIP_ST" )
|
||||
endif( WIN32 )
|
||||
|
||||
add_library( lzma ${LZMA_FILES} )
|
||||
|
|
35
lzma/history.txt
Normal file → Executable file
35
lzma/history.txt
Normal file → Executable file
|
@ -1,6 +1,41 @@
|
|||
HISTORY of the LZMA SDK
|
||||
-----------------------
|
||||
|
||||
9.18 beta 2010-11-02
|
||||
-------------------------
|
||||
- New small SFX module for installers (SfxSetup).
|
||||
|
||||
|
||||
9.12 beta 2010-03-24
|
||||
-------------------------
|
||||
- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work,
|
||||
if more than 10 threads were used (or more than 20 threads in some modes).
|
||||
|
||||
|
||||
9.11 beta 2010-03-15
|
||||
-------------------------
|
||||
- PPMd compression method support
|
||||
|
||||
|
||||
9.09 2009-12-12
|
||||
-------------------------
|
||||
- The bug was fixed:
|
||||
Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c
|
||||
incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8.
|
||||
- Some bugs were fixed
|
||||
|
||||
|
||||
9.06 2009-08-17
|
||||
-------------------------
|
||||
- Some changes in ANSI-C 7z Decoder interfaces.
|
||||
|
||||
|
||||
9.04 2009-05-30
|
||||
-------------------------
|
||||
- LZMA2 compression method support
|
||||
- xz format support
|
||||
|
||||
|
||||
4.65 2009-02-03
|
||||
-------------------------
|
||||
- Some minor fixes
|
||||
|
|
34
lzma/lzma.txt
Normal file → Executable file
34
lzma/lzma.txt
Normal file → Executable file
|
@ -1,4 +1,4 @@
|
|||
LZMA SDK 4.65
|
||||
LZMA SDK 9.20
|
||||
-------------
|
||||
|
||||
LZMA SDK provides the documentation, samples, header files, libraries,
|
||||
|
@ -20,6 +20,10 @@ LICENSE
|
|||
|
||||
LZMA SDK is written and placed in the public domain by Igor Pavlov.
|
||||
|
||||
Some code in LZMA SDK is based on public domain code from another developers:
|
||||
1) PPMd var.H (2001): Dmitry Shkarin
|
||||
2) SHA-256: Wei Dai (Crypto++ library)
|
||||
|
||||
|
||||
LZMA SDK Contents
|
||||
-----------------
|
||||
|
@ -33,7 +37,7 @@ LZMA SDK includes:
|
|||
UNIX/Linux version
|
||||
------------------
|
||||
To compile C++ version of file->file LZMA encoding, go to directory
|
||||
C++/7zip/Compress/LZMA_Alone
|
||||
CPP/7zip/Bundles/LzmaCon
|
||||
and call make to recompile it:
|
||||
make -f makefile.gcc clean all
|
||||
|
||||
|
@ -49,6 +53,7 @@ lzma.txt - LZMA SDK description (this file)
|
|||
7zC.txt - 7z ANSI-C Decoder description
|
||||
methods.txt - Compression method IDs for .7z
|
||||
lzma.exe - Compiled file->file LZMA encoder/decoder for Windows
|
||||
7zr.exe - 7-Zip with 7z/lzma/xz support.
|
||||
history.txt - history of the LZMA SDK
|
||||
|
||||
|
||||
|
@ -66,7 +71,7 @@ C/ - C files
|
|||
LzmaEnc.* - LZMA encoding
|
||||
LzmaLib.* - LZMA Library for DLL calling
|
||||
Types.h - Basic types for another .c files
|
||||
Threads.* - The code for multithreading.
|
||||
Threads.* - The code for multithreading.
|
||||
|
||||
LzmaLib - LZMA Library (.DLL for Windows)
|
||||
|
||||
|
@ -86,12 +91,6 @@ CPP/ -- CPP files
|
|||
|
||||
Compress - files related to compression/decompression
|
||||
|
||||
Copy - Copy coder
|
||||
RangeCoder - Range Coder (special code of compression/decompression)
|
||||
LZMA - LZMA compression/decompression on C++
|
||||
LZMA_Alone - file->file LZMA compression/decompression
|
||||
Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code
|
||||
|
||||
Archive - files related to archiving
|
||||
|
||||
Common - common files for archive handling
|
||||
|
@ -100,6 +99,7 @@ CPP/ -- CPP files
|
|||
Bundles - Modules that are bundles of other modules
|
||||
|
||||
Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2
|
||||
LzmaCon - lzma.exe: LZMA compression/decompression
|
||||
Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2
|
||||
Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2.
|
||||
|
||||
|
@ -369,8 +369,8 @@ Interface:
|
|||
propData - LZMA properties (5 bytes)
|
||||
propSize - size of propData buffer (5 bytes)
|
||||
finishMode - It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
You can use LZMA_FINISH_END, when you know that
|
||||
current output buffer covers last bytes of stream.
|
||||
alloc - Memory allocator.
|
||||
|
@ -431,7 +431,7 @@ Memory Requirements:
|
|||
{
|
||||
...
|
||||
int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode);
|
||||
...
|
||||
}
|
||||
|
||||
|
@ -527,7 +527,8 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
|||
LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc);
|
||||
|
||||
|
||||
If callback function return some error code, LzmaEnc_Encode also returns that code.
|
||||
If callback function return some error code, LzmaEnc_Encode also returns that code
|
||||
or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS.
|
||||
|
||||
|
||||
Single-call RAM->RAM Compression
|
||||
|
@ -549,8 +550,8 @@ Return code:
|
|||
|
||||
|
||||
|
||||
LZMA Defines
|
||||
------------
|
||||
Defines
|
||||
-------
|
||||
|
||||
_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code.
|
||||
|
||||
|
@ -562,6 +563,9 @@ _LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is
|
|||
_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type.
|
||||
|
||||
|
||||
_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder.
|
||||
|
||||
|
||||
C++ LZMA Encoder/Decoder
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
C++ LZMA code use COM-like interfaces. So if you want to use it,
|
||||
|
|
|
@ -294,16 +294,28 @@
|
|||
RelativePath=".\C\7zCrc.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\7zCrcOpt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\7zDec.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\7zIn.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\7zStream.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Alloc.c"
|
||||
RelativePath=".\C\Bcj2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Bcj2.c"
|
||||
RelativePath=".\C\Bra.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
@ -318,6 +330,10 @@
|
|||
RelativePath=".\C\LzFindMt.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Lzma2Dec.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\LzmaDec.c"
|
||||
>
|
||||
|
@ -340,6 +356,10 @@
|
|||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\C\7z.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\7zBuf.h"
|
||||
>
|
||||
|
@ -352,10 +372,6 @@
|
|||
RelativePath=".\C\7zVersion.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Alloc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Bcj2.h"
|
||||
>
|
||||
|
@ -380,6 +396,10 @@
|
|||
RelativePath=".\C\LzHash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Lzma2Dec.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\LzmaDec.h"
|
||||
>
|
||||
|
@ -388,10 +408,6 @@
|
|||
RelativePath=".\C\LzmaEnc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\LzmaLib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Threads.h"
|
||||
>
|
||||
|
@ -401,50 +417,6 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="7z"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zDecode.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zDecode.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zExtract.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zExtract.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zHeader.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zHeader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zIn.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zIn.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zItem.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\C\Archive\7z\7zItem.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\CMakeLists.txt"
|
||||
>
|
||||
|
|
|
@ -41,12 +41,8 @@
|
|||
#include "i_system.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
extern "C" {
|
||||
#include "Archive/7z/7zHeader.h"
|
||||
#include "Archive/7z/7zExtract.h"
|
||||
#include "Archive/7z/7zIn.h"
|
||||
#include "7z.h"
|
||||
#include "7zCrc.h"
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -151,7 +147,7 @@ struct C7zArchive
|
|||
SRes Extract(UInt32 file_index, char *buffer)
|
||||
{
|
||||
size_t offset, out_size_processed;
|
||||
SRes res = SzAr_Extract(&DB, &LookStream.s, file_index,
|
||||
SRes res = SzArEx_Extract(&DB, &LookStream.s, file_index,
|
||||
&BlockIndex, &OutBuffer, &OutBufferSize,
|
||||
&offset, &out_size_processed,
|
||||
&g_Alloc, &g_Alloc);
|
||||
|
@ -279,7 +275,27 @@ bool F7ZFile::Open(bool quiet)
|
|||
continue;
|
||||
}
|
||||
|
||||
FString name = file->Name;
|
||||
const size_t nameLength = SzArEx_GetFileNameUtf16(&Archive->DB, i, NULL);
|
||||
|
||||
if (0 == nameLength)
|
||||
{
|
||||
++skipped;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert UTF-16 filename to plain ASCII
|
||||
|
||||
UInt16* const nameUTF16 = static_cast<UInt16*>(alloca(sizeof(UInt16) * nameLength));
|
||||
SzArEx_GetFileNameUtf16(&Archive->DB, i, nameUTF16);
|
||||
|
||||
char* const nameASCII = static_cast<char*>(alloca(nameLength));
|
||||
|
||||
for (size_t c = 0; c < nameLength; ++c)
|
||||
{
|
||||
nameASCII[c] = static_cast<char>(nameUTF16[c]);
|
||||
}
|
||||
|
||||
FString name = nameASCII;
|
||||
FixPathSeperator(name);
|
||||
name.ToLower();
|
||||
|
||||
|
|
Loading…
Reference in a new issue