LZMA2 support for file_extractor by Kode54
This commit is contained in:
parent
81862972a9
commit
40af766b05
|
@ -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,7 +1,6 @@
|
|||
/* 7zAlloc.c -- Allocation functions
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2010-10-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "7zAlloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
/* 7zAlloc.h -- Allocation functions
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
2010-10-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_ALLOC_H
|
||||
#define __7Z_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
void *SzAlloc(void *p, size_t size);
|
||||
void SzFree(void *p, void *address);
|
||||
|
@ -16,8 +12,4 @@ void SzFree(void *p, void *address);
|
|||
void *SzAllocTemp(void *p, size_t size);
|
||||
void SzFreeTemp(void *p, void *address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#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,32 +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"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
|
@ -1,17 +1,128 @@
|
|||
/* 7zDecode.c -- Decoding from 7z folder
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
/* 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 "7zDecode.h"
|
||||
#include "Lzma2Dec.h"
|
||||
#ifdef _7ZIP_PPMD_SUPPPORT
|
||||
#include "Ppmd7.h"
|
||||
#endif
|
||||
|
||||
#define k_Copy 0
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_BCJ2 0x0303011B
|
||||
#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)
|
||||
|
@ -31,7 +142,7 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
|
|||
size_t lookahead = (1 << 18);
|
||||
if (lookahead > inSize)
|
||||
lookahead = (size_t)inSize;
|
||||
res = inStream->Look((void *)inStream, (void **)&inBuf, &lookahead);
|
||||
res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead);
|
||||
if (res != SZ_OK)
|
||||
break;
|
||||
|
||||
|
@ -61,6 +172,55 @@ static SRes SzDecodeLzma(CSzCoderInfo *coder, UInt64 inSize, ILookInStream *inSt
|
|||
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)
|
||||
|
@ -69,7 +229,7 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
|
|||
size_t curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)inSize;
|
||||
RINOK(inStream->Look((void *)inStream, (void **)&inBuf, &curSize));
|
||||
RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize));
|
||||
if (curSize == 0)
|
||||
return SZ_ERROR_INPUT_EOF;
|
||||
memcpy(outBuffer, inBuf, curSize);
|
||||
|
@ -80,17 +240,37 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer
|
|||
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)
|
||||
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
|
||||
SRes CheckSupportedFolder(const CSzFolder *f)
|
||||
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_UNSUPPORTED_CODER(f->Coders[0]))
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[0]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
|
@ -100,18 +280,31 @@ SRes CheckSupportedFolder(const CSzFolder *f)
|
|||
}
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
if (IS_NO_BCJ(f->Coders[1]) ||
|
||||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
|
||||
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)
|
||||
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_UNSUPPORTED_CODER(f->Coders[1]) ||
|
||||
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
|
||||
IS_NO_BCJ2(f->Coders[3]))
|
||||
if (!IS_SUPPORTED_CODER(&f->Coders[1]) ||
|
||||
!IS_SUPPORTED_CODER(&f->Coders[2]) ||
|
||||
!IS_BCJ2(&f->Coders[3]))
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
if (f->NumPackStreams != 4 ||
|
||||
f->PackStreams[0] != 2 ||
|
||||
|
@ -128,8 +321,7 @@ SRes CheckSupportedFolder(const CSzFolder *f)
|
|||
return SZ_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static
|
||||
UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
static UInt64 GetSum(const UInt64 *values, UInt32 index)
|
||||
{
|
||||
UInt64 sum = 0;
|
||||
UInt32 i;
|
||||
|
@ -138,8 +330,9 @@ UInt64 GetSum(const UInt64 *values, UInt32 index)
|
|||
return sum;
|
||||
}
|
||||
|
||||
static
|
||||
SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
#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[])
|
||||
|
@ -155,7 +348,7 @@ SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
|||
{
|
||||
CSzCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
|
||||
if (IS_MAIN_METHOD((UInt32)coder->MethodID))
|
||||
{
|
||||
UInt32 si = 0;
|
||||
UInt64 offset;
|
||||
|
@ -199,18 +392,22 @@ SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
|||
return SZ_ERROR_DATA;
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
}
|
||||
else
|
||||
else if (coder->MethodID == k_LZMA)
|
||||
{
|
||||
RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ)
|
||||
{
|
||||
UInt32 state;
|
||||
if (ci != 1)
|
||||
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;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
|
@ -238,18 +435,34 @@ SRes SzDecode2(const UInt64 *packSizes, const CSzFolder *folder,
|
|||
RINOK(res)
|
||||
}
|
||||
else
|
||||
return SZ_ERROR_UNSUPPORTED;
|
||||
{
|
||||
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 SzDecode(const UInt64 *packSizes, const CSzFolder *folder,
|
||||
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 = SzDecode2(packSizes, folder, inStream, startPos,
|
||||
SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos,
|
||||
outBuffer, (SizeT)outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
IAlloc_Free(allocMain, tempBuf[i]);
|
||||
|
|
378
fex/7z_C/7zIn.c
378
fex/7z_C/7zIn.c
|
@ -1,17 +1,134 @@
|
|||
/* 7zIn.c -- 7z Input functions
|
||||
2008-12-31 : Igor Pavlov : Public domain */
|
||||
2010-10-29 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "7z.h"
|
||||
#include "7zCrc.h"
|
||||
#include "CpuArch.h"
|
||||
|
||||
#include "7zDecode.h"
|
||||
#include "7zIn.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(
|
||||
|
@ -869,23 +949,23 @@ static SRes SzReadHeader2(
|
|||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp)
|
||||
{
|
||||
UInt64 htype;
|
||||
UInt64 type;
|
||||
UInt32 numUnpackStreams = 0;
|
||||
UInt32 numFiles = 0;
|
||||
CSzFileItem *files = 0;
|
||||
UInt32 numEmptyStreams = 0;
|
||||
UInt32 i;
|
||||
|
||||
RINOK(SzReadID(sd, &htype));
|
||||
RINOK(SzReadID(sd, &type));
|
||||
|
||||
if (htype == k7zIdArchiveProperties)
|
||||
if (type == k7zIdArchiveProperties)
|
||||
{
|
||||
RINOK(SzReadArchiveProperties(sd));
|
||||
RINOK(SzReadID(sd, &htype));
|
||||
RINOK(SzReadID(sd, &type));
|
||||
}
|
||||
|
||||
|
||||
if (htype == k7zIdMainStreamsInfo)
|
||||
if (type == k7zIdMainStreamsInfo)
|
||||
{
|
||||
RINOK(SzReadStreamsInfo(sd,
|
||||
&p->dataPos,
|
||||
|
@ -895,12 +975,12 @@ static SRes SzReadHeader2(
|
|||
digestsDefined,
|
||||
digests, allocMain, allocTemp));
|
||||
p->dataPos += p->startPosAfterHeader;
|
||||
RINOK(SzReadID(sd, &htype));
|
||||
RINOK(SzReadID(sd, &type));
|
||||
}
|
||||
|
||||
if (htype == k7zIdEnd)
|
||||
if (type == k7zIdEnd)
|
||||
return SZ_OK;
|
||||
if (htype != k7zIdFilesInfo)
|
||||
if (type != k7zIdFilesInfo)
|
||||
return SZ_ERROR_ARCHIVE;
|
||||
|
||||
RINOK(SzReadNumber32(sd, &numFiles));
|
||||
|
@ -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,11 +1,10 @@
|
|||
/* 7zStream.c -- 7z Stream functions
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
2010-03-11 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#if NEVER_CALLED
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
|
@ -31,7 +30,6 @@ SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
|||
RINOK(stream->Read(stream, buf, &processed));
|
||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||
}
|
||||
#endif
|
||||
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
||||
{
|
||||
|
@ -39,17 +37,15 @@ SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
|||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||
}
|
||||
|
||||
#if NEVER_CALLED
|
||||
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));
|
||||
memcpy(buf, lookBuf, *size);
|
||||
return stream->Skip(stream, *size);
|
||||
}
|
||||
#endif
|
||||
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
|
@ -70,14 +66,9 @@ 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;
|
||||
#if !NEVER_CALLED
|
||||
(void)pp;
|
||||
(void)buf;
|
||||
(void)size;
|
||||
#else
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
|
@ -90,11 +81,10 @@ static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
|
|||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
#endif
|
||||
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;
|
||||
|
@ -143,9 +133,6 @@ static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
|||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
||||
{
|
||||
#if !NEVER_CALLED
|
||||
lookahead = 0;
|
||||
#endif
|
||||
p->s.Look = lookahead ?
|
||||
LookToRead_Look_Lookahead :
|
||||
LookToRead_Look_Exact;
|
||||
|
@ -159,7 +146,6 @@ void LookToRead_Init(CLookToRead *p)
|
|||
p->pos = p->size = 0;
|
||||
}
|
||||
|
||||
#if NEVER_CALLED
|
||||
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToLook *p = (CSecToLook *)pp;
|
||||
|
@ -181,4 +167,3 @@ void SecToRead_CreateVTable(CSecToRead *p)
|
|||
{
|
||||
p->s.Read = SecToRead_Read;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,11 +43,11 @@ int Bcj2_Decode(
|
|||
const Byte *buffer, *bufferLim;
|
||||
UInt32 range, code;
|
||||
Byte prevByte = 0;
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||
p[i] = kBitModelTotal >> 1;
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
|
||||
p[i] = kBitModelTotal >> 1;
|
||||
|
||||
buffer = buf3;
|
||||
bufferLim = buffer + size3;
|
||||
RC_INIT2
|
||||
|
@ -67,12 +67,12 @@ int Bcj2_Decode(
|
|||
limit = outSize - outPos;
|
||||
while (limit != 0)
|
||||
{
|
||||
Byte bb = buf0[inPos];
|
||||
outBuf[outPos++] = bb;
|
||||
if (IsJ(prevByte, bb))
|
||||
Byte b = buf0[inPos];
|
||||
outBuf[outPos++] = b;
|
||||
if (IsJ(prevByte, b))
|
||||
break;
|
||||
inPos++;
|
||||
prevByte = bb;
|
||||
prevByte = b;
|
||||
limit--;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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,15 +81,23 @@ 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)
|
||||
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
|
@ -66,4 +118,38 @@ about these properties of platform.
|
|||
|
||||
#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
|
||||
|
|
|
@ -0,0 +1,371 @@
|
|||
/* 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;
|
||||
}
|
||||
|
||||
static
|
||||
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
{
|
||||
p->needFlush = 1;
|
||||
p->remainLen = 0;
|
||||
p->tempBufSize = 0;
|
||||
|
||||
if (initDic)
|
||||
{
|
||||
p->processedPos = 0;
|
||||
p->checkDicSize = 0;
|
||||
p->needInitState = 1;
|
||||
}
|
||||
if (initState)
|
||||
p->needInitState = 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -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
|
||||
|
@ -266,14 +259,14 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||
prob = probs + RepLenCoder;
|
||||
}
|
||||
{
|
||||
unsigned limit2, offset;
|
||||
unsigned limit, offset;
|
||||
CLzmaProb *probLen = prob + LenChoice;
|
||||
IF_BIT_0(probLen)
|
||||
{
|
||||
UPDATE_0(probLen);
|
||||
probLen = prob + LenLow + (posState << kLenNumLowBits);
|
||||
offset = 0;
|
||||
limit2 = (1 << kLenNumLowBits);
|
||||
limit = (1 << kLenNumLowBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -284,17 +277,17 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
|
|||
UPDATE_0(probLen);
|
||||
probLen = prob + LenMid + (posState << kLenNumMidBits);
|
||||
offset = kLenNumLowSymbols;
|
||||
limit2 = (1 << kLenNumMidBits);
|
||||
limit = (1 << kLenNumMidBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPDATE_1(probLen);
|
||||
probLen = prob + LenHigh;
|
||||
offset = kLenNumLowSymbols + kLenNumMidSymbols;
|
||||
limit2 = (1 << kLenNumHighBits);
|
||||
limit = (1 << kLenNumHighBits);
|
||||
}
|
||||
}
|
||||
TREE_DECODE(probLen, limit2, len);
|
||||
TREE_DECODE(probLen, limit, len);
|
||||
len += offset;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -846,7 +838,6 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
|
|||
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
||||
}
|
||||
|
||||
#if NEVER_CALLED
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen;
|
||||
|
@ -886,7 +877,6 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
|
|||
return SZ_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
@ -220,4 +224,8 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
|||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#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 @@
|
|||
|
||||
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
|
||||
|
@ -59,9 +77,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
|
||||
|
@ -77,6 +97,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
|
||||
|
@ -86,13 +112,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
|
||||
|
@ -100,6 +124,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);
|
||||
|
@ -134,7 +168,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 */
|
||||
|
@ -199,8 +233,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
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "File_Extractor", "File_Extractor2010.vcxproj", "{7AEC599C-7C82-4F00-AA60-411E0A359CB0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7AEC599C-7C82-4F00-AA60-411E0A359CB0}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
Binary file not shown.
|
@ -79,6 +79,7 @@
|
|||
<ClCompile Include="7z_C\7zAlloc.c" />
|
||||
<ClCompile Include="7z_C\7zBuf.c" />
|
||||
<ClCompile Include="7z_C\7zCrc.c" />
|
||||
<ClCompile Include="7z_C\7zCrcOpt.c" />
|
||||
<ClCompile Include="7z_C\7zDecode.c" />
|
||||
<ClCompile Include="7z_C\7zExtract.c" />
|
||||
<ClCompile Include="7z_C\7zHeader.c" />
|
||||
|
@ -86,7 +87,10 @@
|
|||
<ClCompile Include="7z_C\7zItem.c" />
|
||||
<ClCompile Include="7z_C\7zStream.c" />
|
||||
<ClCompile Include="7z_C\Bcj2.c" />
|
||||
<ClCompile Include="7z_C\Bra.c" />
|
||||
<ClCompile Include="7z_C\Bra86.c" />
|
||||
<ClCompile Include="7z_C\CpuArch.c" />
|
||||
<ClCompile Include="7z_C\Lzma2Dec.c" />
|
||||
<ClCompile Include="7z_C\LzmaDec.c" />
|
||||
<ClCompile Include="fex\Binary_Extractor.cpp" />
|
||||
<ClCompile Include="fex\blargg_common.cpp" />
|
||||
|
@ -105,7 +109,6 @@
|
|||
<ClInclude Include="7z_C\7zAlloc.h" />
|
||||
<ClInclude Include="7z_C\7zBuf.h" />
|
||||
<ClInclude Include="7z_C\7zCrc.h" />
|
||||
<ClInclude Include="7z_C\7zDecode.h" />
|
||||
<ClInclude Include="7z_C\7zExtract.h" />
|
||||
<ClInclude Include="7z_C\7zHeader.h" />
|
||||
<ClInclude Include="7z_C\7zIn.h" />
|
||||
|
@ -113,6 +116,7 @@
|
|||
<ClInclude Include="7z_C\Bcj2.h" />
|
||||
<ClInclude Include="7z_C\Bra.h" />
|
||||
<ClInclude Include="7z_C\CpuArch.h" />
|
||||
<ClInclude Include="7z_C\Lzma2Dec.h" />
|
||||
<ClInclude Include="7z_C\LzmaDec.h" />
|
||||
<ClInclude Include="7z_C\Types.h" />
|
||||
<ClInclude Include="fex\Binary_Extractor.h" />
|
||||
|
@ -134,7 +138,6 @@
|
|||
<ItemGroup>
|
||||
<None Include="7z_C\7zC.txt" />
|
||||
<None Include="7z_C\lzma.txt" />
|
||||
<None Include="7z_C\readme.txt" />
|
||||
<None Include="changes.txt" />
|
||||
<None Include="fex.txt" />
|
||||
<None Include="internals.txt" />
|
||||
|
|
|
@ -9,42 +9,6 @@
|
|||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="7z_C\7zAlloc.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zBuf.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zCrc.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zDecode.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zExtract.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zHeader.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zIn.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zItem.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zStream.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\Bcj2.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\Bra86.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\LzmaDec.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fex\Binary_Extractor.cpp">
|
||||
<Filter>fex</Filter>
|
||||
</ClCompile>
|
||||
|
@ -72,56 +36,65 @@
|
|||
<ClCompile Include="fex\Rar_Extractor.cpp">
|
||||
<Filter>fex</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fex\Zip7_Extractor.cpp">
|
||||
<ClCompile Include="fex\Zip_Extractor.cpp">
|
||||
<Filter>fex</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fex\Zip_Extractor.cpp">
|
||||
<ClCompile Include="fex\Zip7_Extractor.cpp">
|
||||
<Filter>fex</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fex\Zlib_Inflater.cpp">
|
||||
<Filter>fex</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zAlloc.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zBuf.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zCrc.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zExtract.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zHeader.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zIn.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zItem.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zStream.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\Bcj2.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\Bra86.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\LzmaDec.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\CpuArch.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zCrcOpt.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\Lzma2Dec.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\Bra.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="7z_C\7zDecode.c">
|
||||
<Filter>7z</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="7z_C\7zAlloc.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zBuf.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zCrc.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zDecode.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zExtract.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zHeader.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zIn.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zItem.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Bcj2.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Bra.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\CpuArch.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\LzmaDec.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Types.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fex\Binary_Extractor.h">
|
||||
<Filter>fex</Filter>
|
||||
</ClInclude>
|
||||
|
@ -158,30 +131,66 @@
|
|||
<ClInclude Include="fex\Rar_Extractor.h">
|
||||
<Filter>fex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fex\Zip7_Extractor.h">
|
||||
<ClInclude Include="fex\Zip_Extractor.h">
|
||||
<Filter>fex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fex\Zip_Extractor.h">
|
||||
<ClInclude Include="fex\Zip7_Extractor.h">
|
||||
<Filter>fex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fex\Zlib_Inflater.h">
|
||||
<Filter>fex</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zAlloc.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zBuf.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zCrc.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zExtract.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zHeader.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zIn.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\7zItem.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Bcj2.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Bra.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\CpuArch.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\LzmaDec.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Types.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="7z_C\Lzma2Dec.h">
|
||||
<Filter>7z</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="changes.txt" />
|
||||
<None Include="fex.txt" />
|
||||
<None Include="internals.txt" />
|
||||
<None Include="license.txt" />
|
||||
<None Include="readme.txt" />
|
||||
<None Include="7z_C\7zC.txt">
|
||||
<Filter>7z</Filter>
|
||||
</None>
|
||||
<None Include="7z_C\lzma.txt">
|
||||
<Filter>7z</Filter>
|
||||
</None>
|
||||
<None Include="7z_C\readme.txt">
|
||||
<Filter>7z</Filter>
|
||||
</None>
|
||||
<None Include="changes.txt" />
|
||||
<None Include="fex.txt" />
|
||||
<None Include="internals.txt" />
|
||||
<None Include="license.txt" />
|
||||
<None Include="readme.txt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -230,12 +230,178 @@ blargg_err_t Callback_File_Reader::seek_v( int )
|
|||
return blargg_ok;
|
||||
}
|
||||
|
||||
static const BOOST::uint8_t mask_tab[6]={0x80,0xE0,0xF0,0xF8,0xFC,0xFE};
|
||||
|
||||
// BLARGG_UTF8_PATHS
|
||||
static const BOOST::uint8_t val_tab[6]={0,0xC0,0xE0,0xF0,0xF8,0xFC};
|
||||
|
||||
#if BLARGG_UTF8_PATHS
|
||||
size_t utf8_char_len_from_header( char p_c )
|
||||
{
|
||||
BOOST::uint8_t c = (BOOST::uint8_t)p_c;
|
||||
|
||||
// Thanks to byuu for the idea for BLARGG_UTF8_PATHS and the implementations
|
||||
size_t cnt = 0;
|
||||
for(;;)
|
||||
{
|
||||
if ( ( p_c & mask_tab[cnt] ) == val_tab[cnt] ) break;
|
||||
if ( ++cnt >= 6 ) return 0;
|
||||
}
|
||||
|
||||
return cnt + 1;
|
||||
}
|
||||
|
||||
size_t utf8_decode_char( const char *p_utf8, unsigned & wide, size_t mmax )
|
||||
{
|
||||
const BOOST::uint8_t * utf8 = ( const BOOST::uint8_t* )p_utf8;
|
||||
|
||||
if ( mmax == 0 )
|
||||
{
|
||||
wide = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( utf8[0] < 0x80 )
|
||||
{
|
||||
wide = utf8[0];
|
||||
return utf8[0]>0 ? 1 : 0;
|
||||
}
|
||||
if ( mmax > 6 ) mmax = 6;
|
||||
wide = 0;
|
||||
|
||||
unsigned res=0;
|
||||
unsigned n;
|
||||
unsigned cnt=0;
|
||||
for(;;)
|
||||
{
|
||||
if ( ( *utf8 & mask_tab[cnt] ) == val_tab[cnt] ) break;
|
||||
if ( ++cnt >= mmax ) return 0;
|
||||
}
|
||||
cnt++;
|
||||
|
||||
if ( cnt==2 && !( *utf8 & 0x1E ) ) return 0;
|
||||
|
||||
if ( cnt == 1 )
|
||||
res = *utf8;
|
||||
else
|
||||
res = ( 0xFF >> ( cnt + 1 ) ) & *utf8;
|
||||
|
||||
for ( n = 1; n < cnt; n++ )
|
||||
{
|
||||
if ( ( utf8[n] & 0xC0 ) != 0x80 )
|
||||
return 0;
|
||||
if ( !res && n == 2 && !( ( utf8[n] & 0x7F ) >> ( 7 - cnt ) ) )
|
||||
return 0;
|
||||
|
||||
res = ( res << 6 ) | ( utf8[n] & 0x3F );
|
||||
}
|
||||
|
||||
wide = res;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
size_t utf8_encode_char( unsigned wide, char * target )
|
||||
{
|
||||
size_t count;
|
||||
|
||||
if ( wide < 0x80 )
|
||||
count = 1;
|
||||
else if ( wide < 0x800 )
|
||||
count = 2;
|
||||
else if ( wide < 0x10000 )
|
||||
count = 3;
|
||||
else if ( wide < 0x200000 )
|
||||
count = 4;
|
||||
else if ( wide < 0x4000000 )
|
||||
count = 5;
|
||||
else if ( wide <= 0x7FFFFFFF )
|
||||
count = 6;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if ( target == 0 )
|
||||
return count;
|
||||
|
||||
switch ( count )
|
||||
{
|
||||
case 6:
|
||||
target[5] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x4000000;
|
||||
case 5:
|
||||
target[4] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x200000;
|
||||
case 4:
|
||||
target[3] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x10000;
|
||||
case 3:
|
||||
target[2] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x800;
|
||||
case 2:
|
||||
target[1] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0xC0;
|
||||
case 1:
|
||||
target[0] = wide;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t utf16_encode_char( unsigned cur_wchar, wchar_t * out )
|
||||
{
|
||||
if ( cur_wchar < 0x10000 )
|
||||
{
|
||||
if ( out ) *out = (wchar_t) cur_wchar; return 1;
|
||||
}
|
||||
else if ( cur_wchar < ( 1 << 20 ) )
|
||||
{
|
||||
unsigned c = cur_wchar - 0x10000;
|
||||
//MSDN:
|
||||
//The first (high) surrogate is a 16-bit code value in the range U+D800 to U+DBFF. The second (low) surrogate is a 16-bit code value in the range U+DC00 to U+DFFF. Using surrogates, Unicode can support over one million characters. For more details about surrogates, refer to The Unicode Standard, version 2.0.
|
||||
if ( out )
|
||||
{
|
||||
out[0] = ( wchar_t )( 0xD800 | ( 0x3FF & ( c >> 10 ) ) );
|
||||
out[1] = ( wchar_t )( 0xDC00 | ( 0x3FF & c ) ) ;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( out ) *out = '?'; return 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t utf16_decode_char( const wchar_t * p_source, unsigned * p_out, size_t p_source_length )
|
||||
{
|
||||
if ( p_source_length == 0 ) return 0;
|
||||
else if ( p_source_length == 1 )
|
||||
{
|
||||
*p_out = p_source[0];
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t retval = 0;
|
||||
unsigned decoded = p_source[0];
|
||||
if ( decoded != 0 )
|
||||
{
|
||||
retval = 1;
|
||||
if ( ( decoded & 0xFC00 ) == 0xD800 )
|
||||
{
|
||||
unsigned low = p_source[1];
|
||||
if ( ( low & 0xFC00 ) == 0xDC00 )
|
||||
{
|
||||
decoded = 0x10000 + ( ( ( decoded & 0x3FF ) << 10 ) | ( low & 0x3FF ) );
|
||||
retval = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
*p_out = decoded;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts wide-character path to UTF-8. Free result with free(). Only supported on Windows.
|
||||
char* blargg_to_utf8( const wchar_t* wpath )
|
||||
|
@ -243,15 +409,38 @@ char* blargg_to_utf8( const wchar_t* wpath )
|
|||
if ( wpath == NULL )
|
||||
return NULL;
|
||||
|
||||
int needed = WideCharToMultiByte( CP_UTF8, 0, wpath, -1, NULL, 0, NULL, NULL );
|
||||
size_t needed = 0;
|
||||
size_t mmax = wcslen( wpath );
|
||||
if ( mmax <= 0 )
|
||||
return NULL;
|
||||
|
||||
size_t ptr = 0;
|
||||
while ( ptr < mmax )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf16_decode_char( wpath + ptr, &wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
needed += utf8_encode_char( wide, 0 );
|
||||
}
|
||||
if ( needed <= 0 )
|
||||
return NULL;
|
||||
|
||||
char* path = (char*) malloc( needed );
|
||||
char* path = (char*) calloc( needed + 1, 1 );
|
||||
if ( path == NULL )
|
||||
return NULL;
|
||||
|
||||
int actual = WideCharToMultiByte( CP_UTF8, 0, wpath, -1, path, needed, NULL, NULL );
|
||||
|
||||
ptr = 0;
|
||||
size_t actual = 0;
|
||||
while ( ptr < mmax && actual < needed )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf16_decode_char( wpath + ptr, &wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
actual += utf8_encode_char( wide, path + actual );
|
||||
}
|
||||
|
||||
if ( actual == 0 )
|
||||
{
|
||||
free( path );
|
||||
|
@ -268,15 +457,37 @@ wchar_t* blargg_to_wide( const char* path )
|
|||
if ( path == NULL )
|
||||
return NULL;
|
||||
|
||||
int needed = MultiByteToWideChar( CP_UTF8, 0, path, -1, NULL, 0 );
|
||||
size_t mmax = strlen( path );
|
||||
if ( mmax <= 0 )
|
||||
return NULL;
|
||||
|
||||
size_t needed = 0;
|
||||
size_t ptr = 0;
|
||||
while ( ptr < mmax )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf8_decode_char( path + ptr, wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
needed += utf16_encode_char( wide, 0 );
|
||||
}
|
||||
if ( needed <= 0 )
|
||||
return NULL;
|
||||
|
||||
wchar_t* wpath = (wchar_t*) malloc( needed * sizeof *wpath );
|
||||
wchar_t* wpath = (wchar_t*) calloc( needed + 1, sizeof *wpath );
|
||||
if ( wpath == NULL )
|
||||
return NULL;
|
||||
|
||||
int actual = MultiByteToWideChar( CP_UTF8, 0, path, -1, wpath, needed );
|
||||
|
||||
ptr = 0;
|
||||
size_t actual = 0;
|
||||
while ( ptr < mmax && actual < needed )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf8_decode_char( path + ptr, wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
actual += utf16_encode_char( wide, wpath + actual );
|
||||
}
|
||||
if ( actual == 0 )
|
||||
{
|
||||
free( wpath );
|
||||
|
@ -287,6 +498,8 @@ wchar_t* blargg_to_wide( const char* path )
|
|||
return wpath;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static FILE* blargg_fopen( const char path [], const char mode [] )
|
||||
{
|
||||
FILE* file = NULL;
|
||||
|
|
|
@ -2,9 +2,13 @@
|
|||
|
||||
#include "Zip7_Extractor.h"
|
||||
|
||||
#include "7z_C/7zExtract.h"
|
||||
extern "C" {
|
||||
#include "7z_C/7z.h"
|
||||
#include "7z_C/7zAlloc.h"
|
||||
#include "7z_C/7zCrc.h"
|
||||
}
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/* Copyright (C) 2005-2009 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
|
@ -66,7 +70,7 @@ extern "C"
|
|||
ISeekInStream* stream = STATIC_CAST(ISeekInStream*,vstream);
|
||||
Zip7_Extractor_Impl* impl = STATIC_CAST(Zip7_Extractor_Impl*,stream);
|
||||
|
||||
assert( mode != SZ_SEEK_CUR ); // never used
|
||||
// assert( mode != SZ_SEEK_CUR ); // never used
|
||||
|
||||
if ( mode == SZ_SEEK_END )
|
||||
{
|
||||
|
@ -75,7 +79,7 @@ extern "C"
|
|||
return SZ_OK;
|
||||
}
|
||||
|
||||
assert( mode == SZ_SEEK_SET );
|
||||
// assert( mode == SZ_SEEK_SET );
|
||||
blargg_err_t err = impl->in->seek( *pos );
|
||||
if ( err )
|
||||
{
|
||||
|
@ -204,14 +208,39 @@ blargg_err_t Zip7_Extractor::next_v()
|
|||
CSzFileItem const& item = impl->db.db.Files [index];
|
||||
if ( !item.IsDir )
|
||||
{
|
||||
// TODO: Support date.
|
||||
// NTFS representation, stored as 64-bit value.
|
||||
// Divide by 10000000 (ten million) to get seconds
|
||||
//item.MTime.Low + (.High << 32)
|
||||
// How to convert to DOS style?
|
||||
|
||||
set_name( item.Name );
|
||||
set_info( item.Size, 0, (item.FileCRCDefined ? item.FileCRC : 0) );
|
||||
unsigned long date = 0;
|
||||
if ( item.MTimeDefined )
|
||||
{
|
||||
const UInt64 epoch = ((UInt64)0x019db1de << 32) + 0xd53e8000;
|
||||
/* 0x019db1ded53e8000ULL: 1970-01-01 00:00:00 (UTC) */
|
||||
struct tm tm;
|
||||
|
||||
UInt64 time = ((UInt64)item.MTime.High << 32) + item.MTime.Low - epoch;
|
||||
time /= 1000000;
|
||||
|
||||
time_t _time = time;
|
||||
|
||||
localtime_s( &tm, &_time );
|
||||
|
||||
date = ( tm.tm_sec >> 1 ) & 0x1F |
|
||||
(( tm.tm_min & 0x3F ) << 5 ) |
|
||||
(( tm.tm_hour & 0x1F ) << 11 ) |
|
||||
(( tm.tm_mday & 0x1F ) << 16 ) |
|
||||
(( ( tm.tm_mon + 1 ) & 0x0F ) << 21 ) |
|
||||
(( ( tm.tm_year - 80 ) & 0x7F ) << 25 );
|
||||
}
|
||||
|
||||
size_t name_length = SzArEx_GetFileNameUtf16( &impl->db, index, 0 );
|
||||
name16.resize( name_length );
|
||||
SzArEx_GetFileNameUtf16( &impl->db, index, ( UInt16 * ) name16.begin() );
|
||||
char * temp = blargg_to_utf8( name16.begin() );
|
||||
if ( !temp ) temp = "";
|
||||
size_t utf8_length = strlen( temp );
|
||||
name8.resize( utf8_length + 1 );
|
||||
memcpy( name8.begin(), temp, utf8_length + 1 );
|
||||
free( temp );
|
||||
set_name( name8.begin(), name16.begin() );
|
||||
set_info( item.Size, 0, (item.CrcDefined ? item.Crc : 0) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +271,7 @@ blargg_err_t Zip7_Extractor::data_v( void const** out )
|
|||
impl->in_err = NULL;
|
||||
size_t offset = 0;
|
||||
size_t count = 0;
|
||||
RETURN_ERR( zip7_err( SzAr_Extract( &impl->db, &impl->look.s, index,
|
||||
RETURN_ERR( zip7_err( SzArEx_Extract( &impl->db, &impl->look.s, index,
|
||||
&impl->block_index, &impl->buf, &impl->buf_size,
|
||||
&offset, &count, &zip7_alloc, &zip7_alloc_temp ) ) );
|
||||
assert( count == (size_t) size() );
|
||||
|
|
|
@ -27,6 +27,8 @@ protected:
|
|||
private:
|
||||
Zip7_Extractor_Impl* impl;
|
||||
int index;
|
||||
blargg_vector<char> name8;
|
||||
blargg_vector<wchar_t> name16;
|
||||
|
||||
blargg_err_t zip7_err( int err );
|
||||
};
|
||||
|
|
|
@ -192,11 +192,6 @@ struct blargg_callback
|
|||
void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; }
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
// Not supported on any other platforms
|
||||
#undef BLARGG_UTF8_PATHS
|
||||
#endif
|
||||
|
||||
BLARGG_DEPRECATED( typedef signed int blargg_long; )
|
||||
BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )
|
||||
#if BLARGG_LEGACY
|
||||
|
|
|
@ -235,7 +235,6 @@ BLARGG_EXPORT fex_err_t fex_open( fex_t** fe_out, const char path [] )
|
|||
|
||||
//// Wide paths
|
||||
|
||||
#if BLARGG_UTF8_PATHS
|
||||
char* fex_wide_to_path( const wchar_t* wide )
|
||||
{
|
||||
return blargg_to_utf8( wide );
|
||||
|
@ -245,7 +244,6 @@ void fex_free_path( char* path )
|
|||
{
|
||||
free( path );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//// Errors
|
||||
|
|
|
@ -40,14 +40,12 @@ returns "", since it can open any file. */
|
|||
const char* fex_type_extension( fex_type_t );
|
||||
|
||||
|
||||
/**** Wide-character file paths (Windows only) ****/
|
||||
/**** Wide-character file paths ****/
|
||||
|
||||
/** Converts wide-character path to form suitable for use with fex functions.
|
||||
Only supported when BLARGG_UTF8_PATHS is defined and building on Windows. */
|
||||
/** Converts wide-character path to form suitable for use with fex functions. */
|
||||
char* fex_wide_to_path( const wchar_t* wide );
|
||||
|
||||
/** Frees converted path. OK to pass NULL. Only supported when BLARGG_UTF8_PATHS
|
||||
is defined and building on Windows */
|
||||
/** Frees converted path. OK to pass NULL. */
|
||||
void fex_free_path( char* );
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue