mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 12:07:03 -06:00
4.48 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
0b33f700a6
commit
fd8b1d78b4
@@ -60,7 +60,6 @@ void MidFree(void *address)
|
||||
}
|
||||
|
||||
#ifndef MEM_LARGE_PAGES
|
||||
wedeed
|
||||
#undef _7ZIP_LARGE_PAGES
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
/* 7zDecode.c */
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
#include "7zDecode.h"
|
||||
#ifdef _SZ_ONE_DIRECTORY
|
||||
#include "LzmaDecode.h"
|
||||
#else
|
||||
#include "../../Compress/Lzma/LzmaDecode.h"
|
||||
#include "../../Compress/Branch/BranchX86.h"
|
||||
#include "../../Compress/Branch/BranchX86_2.h"
|
||||
#endif
|
||||
|
||||
CMethodID k_Copy = { { 0x0 }, 1 };
|
||||
CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
|
||||
#define k_Copy 0
|
||||
#define k_LZMA 0x30101
|
||||
#define k_BCJ 0x03030103
|
||||
#define k_BCJ2 0x0303011B
|
||||
|
||||
#ifdef _LZMA_IN_CB
|
||||
|
||||
@@ -16,7 +22,7 @@ typedef struct _CLzmaInCallbackImp
|
||||
{
|
||||
ILzmaInCallback InCallback;
|
||||
ISzInStream *InStream;
|
||||
size_t Size;
|
||||
CFileSize Size;
|
||||
} CLzmaInCallbackImp;
|
||||
|
||||
int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
|
||||
@@ -24,10 +30,13 @@ int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
|
||||
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
|
||||
size_t processedSize;
|
||||
SZ_RESULT res;
|
||||
size_t curSize = (1 << 20);
|
||||
if (curSize > cb->Size)
|
||||
curSize = (size_t)cb->Size;
|
||||
*size = 0;
|
||||
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
|
||||
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, curSize, &processedSize);
|
||||
*size = (SizeT)processedSize;
|
||||
if (processedSize > cb->Size)
|
||||
if (processedSize > curSize)
|
||||
return (int)SZE_FAIL;
|
||||
cb->Size -= processedSize;
|
||||
if (res == SZ_OK)
|
||||
@@ -37,114 +46,296 @@ int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
|
||||
|
||||
#endif
|
||||
|
||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
||||
SZ_RESULT SzDecodeLzma(CCoderInfo *coder, CFileSize inSize,
|
||||
#ifdef _LZMA_IN_CB
|
||||
ISzInStream *inStream,
|
||||
#else
|
||||
const Byte *inBuffer,
|
||||
#endif
|
||||
Byte *outBuffer, size_t outSize,
|
||||
size_t *outSizeProcessed, ISzAlloc *allocMain)
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
UInt32 si;
|
||||
size_t inSize = 0;
|
||||
CCoderInfo *coder;
|
||||
if (folder->NumPackStreams != 1)
|
||||
return SZE_NOTIMPL;
|
||||
if (folder->NumCoders != 1)
|
||||
return SZE_NOTIMPL;
|
||||
coder = folder->Coders;
|
||||
*outSizeProcessed = 0;
|
||||
|
||||
for (si = 0; si < folder->NumPackStreams; si++)
|
||||
inSize += (size_t)packSizes[si];
|
||||
|
||||
if (AreMethodsEqual(&coder->MethodID, &k_Copy))
|
||||
#ifdef _LZMA_IN_CB
|
||||
CLzmaInCallbackImp lzmaCallback;
|
||||
#else
|
||||
SizeT inProcessed;
|
||||
#endif
|
||||
|
||||
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
|
||||
int result;
|
||||
SizeT outSizeProcessedLoc;
|
||||
|
||||
#ifdef _LZMA_IN_CB
|
||||
lzmaCallback.Size = inSize;
|
||||
lzmaCallback.InStream = inStream;
|
||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
||||
#endif
|
||||
|
||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
||||
(unsigned)coder->Properties.Capacity) != LZMA_RESULT_OK)
|
||||
return SZE_FAIL;
|
||||
|
||||
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
|
||||
if (state.Probs == 0)
|
||||
return SZE_OUTOFMEMORY;
|
||||
|
||||
#ifdef _LZMA_OUT_READ
|
||||
if (state.Properties.DictionarySize == 0)
|
||||
state.Dictionary = 0;
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
if (inSize != outSize)
|
||||
return SZE_DATA_ERROR;
|
||||
#ifdef _LZMA_IN_CB
|
||||
for (i = 0; i < inSize;)
|
||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
||||
if (state.Dictionary == 0)
|
||||
{
|
||||
size_t j;
|
||||
void *inBuffer;
|
||||
size_t bufferSize;
|
||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
|
||||
if (bufferSize == 0)
|
||||
return SZE_DATA_ERROR;
|
||||
if (bufferSize > inSize - i)
|
||||
return SZE_FAIL;
|
||||
*outSizeProcessed += bufferSize;
|
||||
for (j = 0; j < bufferSize && i < inSize; j++, i++)
|
||||
outBuffer[i] = ((const Byte *)inBuffer)[j];
|
||||
allocMain->Free(state.Probs);
|
||||
return SZE_OUTOFMEMORY;
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < inSize; i++)
|
||||
outBuffer[i] = inBuffer[i];
|
||||
*outSizeProcessed = inSize;
|
||||
#endif
|
||||
}
|
||||
LzmaDecoderInit(&state);
|
||||
#endif
|
||||
|
||||
result = LzmaDecode(&state,
|
||||
#ifdef _LZMA_IN_CB
|
||||
&lzmaCallback.InCallback,
|
||||
#else
|
||||
inBuffer, (SizeT)inSize, &inProcessed,
|
||||
#endif
|
||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
|
||||
allocMain->Free(state.Probs);
|
||||
#ifdef _LZMA_OUT_READ
|
||||
allocMain->Free(state.Dictionary);
|
||||
#endif
|
||||
if (result == LZMA_RESULT_DATA_ERROR)
|
||||
return SZE_DATA_ERROR;
|
||||
if (result != LZMA_RESULT_OK)
|
||||
return SZE_FAIL;
|
||||
return (outSizeProcessedLoc == outSize) ? SZ_OK : SZE_DATA_ERROR;
|
||||
}
|
||||
|
||||
#ifdef _LZMA_IN_CB
|
||||
SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer)
|
||||
{
|
||||
while (inSize > 0)
|
||||
{
|
||||
void *inBuffer;
|
||||
size_t processedSize, curSize = (1 << 18);
|
||||
if (curSize > inSize)
|
||||
curSize = (size_t)(inSize);
|
||||
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, curSize, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return SZE_DATA_ERROR;
|
||||
if (processedSize > curSize)
|
||||
return SZE_FAIL;
|
||||
memcpy(outBuffer, inBuffer, processedSize);
|
||||
outBuffer += processedSize;
|
||||
inSize -= processedSize;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
||||
SZ_RESULT CheckSupportedFolder(const CFolder *f)
|
||||
{
|
||||
if (f->NumCoders < 1 || f->NumCoders > 4)
|
||||
return SZE_NOTIMPL;
|
||||
if (IS_UNSUPPORTED_CODER(f->Coders[0]))
|
||||
return SZE_NOTIMPL;
|
||||
if (f->NumCoders == 1)
|
||||
{
|
||||
if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0)
|
||||
return SZE_NOTIMPL;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
if (AreMethodsEqual(&coder->MethodID, &k_LZMA))
|
||||
if (f->NumCoders == 2)
|
||||
{
|
||||
#ifdef _LZMA_IN_CB
|
||||
CLzmaInCallbackImp lzmaCallback;
|
||||
#else
|
||||
SizeT inProcessed;
|
||||
#endif
|
||||
|
||||
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
|
||||
int result;
|
||||
SizeT outSizeProcessedLoc;
|
||||
|
||||
#ifdef _LZMA_IN_CB
|
||||
lzmaCallback.Size = inSize;
|
||||
lzmaCallback.InStream = inStream;
|
||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
||||
#endif
|
||||
|
||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
||||
return SZE_FAIL;
|
||||
|
||||
state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb));
|
||||
if (state.Probs == 0)
|
||||
return SZE_OUTOFMEMORY;
|
||||
|
||||
#ifdef _LZMA_OUT_READ
|
||||
if (state.Properties.DictionarySize == 0)
|
||||
state.Dictionary = 0;
|
||||
else
|
||||
{
|
||||
state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize);
|
||||
if (state.Dictionary == 0)
|
||||
{
|
||||
allocMain->Free(state.Probs);
|
||||
return SZE_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
LzmaDecoderInit(&state);
|
||||
#endif
|
||||
|
||||
result = LzmaDecode(&state,
|
||||
#ifdef _LZMA_IN_CB
|
||||
&lzmaCallback.InCallback,
|
||||
#else
|
||||
inBuffer, (SizeT)inSize, &inProcessed,
|
||||
#endif
|
||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
|
||||
*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
||||
allocMain->Free(state.Probs);
|
||||
#ifdef _LZMA_OUT_READ
|
||||
allocMain->Free(state.Dictionary);
|
||||
#endif
|
||||
if (result == LZMA_RESULT_DATA_ERROR)
|
||||
return SZE_DATA_ERROR;
|
||||
if (result != LZMA_RESULT_OK)
|
||||
return SZE_FAIL;
|
||||
if (IS_NO_BCJ(f->Coders[1]) ||
|
||||
f->NumPackStreams != 1 || f->PackStreams[0] != 0 ||
|
||||
f->NumBindPairs != 1 ||
|
||||
f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0)
|
||||
return SZE_NOTIMPL;
|
||||
return SZ_OK;
|
||||
}
|
||||
if (f->NumCoders == 4)
|
||||
{
|
||||
if (IS_UNSUPPORTED_CODER(f->Coders[1]) ||
|
||||
IS_UNSUPPORTED_CODER(f->Coders[2]) ||
|
||||
IS_NO_BCJ2(f->Coders[3]))
|
||||
return SZE_NOTIMPL;
|
||||
if (f->NumPackStreams != 4 ||
|
||||
f->PackStreams[0] != 2 ||
|
||||
f->PackStreams[1] != 6 ||
|
||||
f->PackStreams[2] != 1 ||
|
||||
f->PackStreams[3] != 0 ||
|
||||
f->NumBindPairs != 3 ||
|
||||
f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 ||
|
||||
f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 ||
|
||||
f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2)
|
||||
return SZE_NOTIMPL;
|
||||
return SZ_OK;
|
||||
}
|
||||
return SZE_NOTIMPL;
|
||||
}
|
||||
|
||||
CFileSize GetSum(const CFileSize *values, UInt32 index)
|
||||
{
|
||||
CFileSize sum = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < index; i++)
|
||||
sum += values[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
||||
#ifdef _LZMA_IN_CB
|
||||
ISzInStream *inStream, CFileSize startPos,
|
||||
#else
|
||||
const Byte *inBuffer,
|
||||
#endif
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
|
||||
Byte *tempBuf[])
|
||||
{
|
||||
UInt32 ci;
|
||||
size_t tempSizes[3] = { 0, 0, 0};
|
||||
size_t tempSize3 = 0;
|
||||
Byte *tempBuf3 = 0;
|
||||
|
||||
RINOK(CheckSupportedFolder(folder));
|
||||
|
||||
for (ci = 0; ci < folder->NumCoders; ci++)
|
||||
{
|
||||
CCoderInfo *coder = &folder->Coders[ci];
|
||||
|
||||
if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA)
|
||||
{
|
||||
UInt32 si = 0;
|
||||
CFileSize offset;
|
||||
CFileSize inSize;
|
||||
Byte *outBufCur = outBuffer;
|
||||
size_t outSizeCur = outSize;
|
||||
if (folder->NumCoders == 4)
|
||||
{
|
||||
UInt32 indices[] = { 3, 2, 0 };
|
||||
CFileSize unpackSize = folder->UnPackSizes[ci];
|
||||
si = indices[ci];
|
||||
if (ci < 2)
|
||||
{
|
||||
Byte *temp;
|
||||
outSizeCur = (size_t)unpackSize;
|
||||
if (outSizeCur != unpackSize)
|
||||
return SZE_OUTOFMEMORY;
|
||||
temp = (Byte *)allocMain->Alloc(outSizeCur);
|
||||
if (temp == 0 && outSizeCur != 0)
|
||||
return SZE_OUTOFMEMORY;
|
||||
outBufCur = tempBuf[1 - ci] = temp;
|
||||
tempSizes[1 - ci] = outSizeCur;
|
||||
}
|
||||
else if (ci == 2)
|
||||
{
|
||||
if (unpackSize > outSize)
|
||||
return SZE_OUTOFMEMORY;
|
||||
tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
|
||||
tempSize3 = outSizeCur = (size_t)unpackSize;
|
||||
}
|
||||
else
|
||||
return SZE_NOTIMPL;
|
||||
}
|
||||
offset = GetSum(packSizes, si);
|
||||
inSize = packSizes[si];
|
||||
#ifdef _LZMA_IN_CB
|
||||
RINOK(inStream->Seek(inStream, startPos + offset));
|
||||
#endif
|
||||
|
||||
if (coder->MethodID == k_Copy)
|
||||
{
|
||||
if (inSize != outSizeCur)
|
||||
return SZE_DATA_ERROR;
|
||||
|
||||
#ifdef _LZMA_IN_CB
|
||||
RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
|
||||
#else
|
||||
memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
SZ_RESULT res = SzDecodeLzma(coder, inSize,
|
||||
#ifdef _LZMA_IN_CB
|
||||
inStream,
|
||||
#else
|
||||
inBuffer + (size_t)offset,
|
||||
#endif
|
||||
outBufCur, outSizeCur, allocMain);
|
||||
RINOK(res)
|
||||
}
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ)
|
||||
{
|
||||
UInt32 state;
|
||||
if (ci != 1)
|
||||
return SZE_NOTIMPL;
|
||||
x86_Convert_Init(state);
|
||||
x86_Convert(outBuffer, outSize, 0, &state, 0);
|
||||
}
|
||||
else if (coder->MethodID == k_BCJ2)
|
||||
{
|
||||
CFileSize offset = GetSum(packSizes, 1);
|
||||
CFileSize s3Size = packSizes[1];
|
||||
SZ_RESULT res;
|
||||
if (ci != 3)
|
||||
return SZE_NOTIMPL;
|
||||
|
||||
#ifdef _LZMA_IN_CB
|
||||
RINOK(inStream->Seek(inStream, startPos + offset));
|
||||
tempSizes[2] = (size_t)s3Size;
|
||||
if (tempSizes[2] != s3Size)
|
||||
return SZE_OUTOFMEMORY;
|
||||
tempBuf[2] = (Byte *)allocMain->Alloc(tempSizes[2]);
|
||||
if (tempBuf[2] == 0 && tempSizes[2] != 0)
|
||||
return SZE_OUTOFMEMORY;
|
||||
res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
|
||||
RINOK(res)
|
||||
#endif
|
||||
|
||||
res = x86_2_Decode(
|
||||
tempBuf3, tempSize3,
|
||||
tempBuf[0], tempSizes[0],
|
||||
tempBuf[1], tempSizes[1],
|
||||
#ifdef _LZMA_IN_CB
|
||||
tempBuf[2], tempSizes[2],
|
||||
#else
|
||||
inBuffer + (size_t)offset, (size_t)s3Size,
|
||||
#endif
|
||||
outBuffer, outSize);
|
||||
RINOK(res)
|
||||
}
|
||||
else
|
||||
return SZE_NOTIMPL;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
||||
#ifdef _LZMA_IN_CB
|
||||
ISzInStream *inStream, CFileSize startPos,
|
||||
#else
|
||||
const Byte *inBuffer,
|
||||
#endif
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain)
|
||||
{
|
||||
Byte *tempBuf[3] = { 0, 0, 0};
|
||||
int i;
|
||||
SZ_RESULT res = SzDecode2(packSizes, folder,
|
||||
#ifdef _LZMA_IN_CB
|
||||
inStream, startPos,
|
||||
#else
|
||||
inBuffer,
|
||||
#endif
|
||||
outBuffer, outSize, allocMain, tempBuf);
|
||||
for (i = 0; i < 3; i++)
|
||||
allocMain->Free(tempBuf[i]);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -11,11 +11,10 @@
|
||||
|
||||
SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
||||
#ifdef _LZMA_IN_CB
|
||||
ISzInStream *stream,
|
||||
ISzInStream *stream, CFileSize startPos,
|
||||
#else
|
||||
const Byte *inBuffer,
|
||||
#endif
|
||||
Byte *outBuffer, size_t outSize,
|
||||
size_t *outSizeProcessed, ISzAlloc *allocMain);
|
||||
Byte *outBuffer, size_t outSize, ISzAlloc *allocMain);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,63 +32,64 @@ SZ_RESULT SzExtract(
|
||||
if (*outBuffer == 0 || *blockIndex != folderIndex)
|
||||
{
|
||||
CFolder *folder = db->Database.Folders + folderIndex;
|
||||
CFileSize unPackSize = SzFolderGetUnPackSize(folder);
|
||||
CFileSize unPackSizeSpec = SzFolderGetUnPackSize(folder);
|
||||
size_t unPackSize = (size_t)unPackSizeSpec;
|
||||
CFileSize startOffset = SzArDbGetFolderStreamPos(db, folderIndex, 0);
|
||||
#ifndef _LZMA_IN_CB
|
||||
CFileSize packSize = SzArDbGetFolderFullPackSize(db, folderIndex);
|
||||
Byte *inBuffer = 0;
|
||||
size_t processedSize;
|
||||
CFileSize packSizeSpec;
|
||||
size_t packSize;
|
||||
RINOK(SzArDbGetFolderFullPackSize(db, folderIndex, &packSizeSpec));
|
||||
packSize = (size_t)packSizeSpec;
|
||||
if (packSize != packSizeSpec)
|
||||
return SZE_OUTOFMEMORY;
|
||||
#endif
|
||||
if (unPackSize != (size_t)unPackSize)
|
||||
if (unPackSize != unPackSizeSpec)
|
||||
return SZE_OUTOFMEMORY;
|
||||
*blockIndex = folderIndex;
|
||||
allocMain->Free(*outBuffer);
|
||||
*outBuffer = 0;
|
||||
|
||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
||||
RINOK(inStream->Seek(inStream, startOffset));
|
||||
|
||||
#ifndef _LZMA_IN_CB
|
||||
if (packSize != 0)
|
||||
{
|
||||
inBuffer = (Byte *)allocTemp->Alloc((size_t)packSize);
|
||||
inBuffer = (Byte *)allocTemp->Alloc(packSize);
|
||||
if (inBuffer == 0)
|
||||
return SZE_OUTOFMEMORY;
|
||||
}
|
||||
res = inStream->Read(inStream, inBuffer, (size_t)packSize, &processedSize);
|
||||
if (res == SZ_OK && processedSize != (size_t)packSize)
|
||||
res = inStream->Read(inStream, inBuffer, packSize, &processedSize);
|
||||
if (res == SZ_OK && processedSize != packSize)
|
||||
res = SZE_FAIL;
|
||||
#endif
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
*outBufferSize = (size_t)unPackSize;
|
||||
*outBufferSize = unPackSize;
|
||||
if (unPackSize != 0)
|
||||
{
|
||||
*outBuffer = (Byte *)allocMain->Alloc((size_t)unPackSize);
|
||||
*outBuffer = (Byte *)allocMain->Alloc(unPackSize);
|
||||
if (*outBuffer == 0)
|
||||
res = SZE_OUTOFMEMORY;
|
||||
}
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
size_t outRealSize;
|
||||
res = SzDecode(db->Database.PackSizes +
|
||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
||||
#ifdef _LZMA_IN_CB
|
||||
inStream,
|
||||
inStream, startOffset,
|
||||
#else
|
||||
inBuffer,
|
||||
#endif
|
||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
|
||||
*outBuffer, unPackSize, allocTemp);
|
||||
if (res == SZ_OK)
|
||||
{
|
||||
if (outRealSize == (size_t)unPackSize)
|
||||
if (folder->UnPackCRCDefined)
|
||||
{
|
||||
if (folder->UnPackCRCDefined)
|
||||
{
|
||||
if (CrcCalc(*outBuffer, (size_t)unPackSize) != folder->UnPackCRC)
|
||||
res = SZE_FAIL;
|
||||
}
|
||||
if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
|
||||
res = SZE_CRC_ERROR;
|
||||
}
|
||||
else
|
||||
res = SZE_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +111,7 @@ SZ_RESULT SzExtract(
|
||||
if (fileItem->IsFileCRCDefined)
|
||||
{
|
||||
if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
|
||||
res = SZE_FAIL;
|
||||
res = SZE_CRC_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,15 +117,21 @@ CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, U
|
||||
db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
|
||||
}
|
||||
|
||||
CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex)
|
||||
int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize)
|
||||
{
|
||||
UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
|
||||
CFolder *folder = db->Database.Folders + folderIndex;
|
||||
CFileSize size = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < folder->NumPackStreams; i++)
|
||||
size += db->Database.PackSizes[packStreamIndex + i];
|
||||
return size;
|
||||
{
|
||||
CFileSize t = size + db->Database.PackSizes[packStreamIndex + i];
|
||||
if (t < size)
|
||||
return SZE_FAIL;
|
||||
size = t;
|
||||
}
|
||||
*resSize = size;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -500,9 +506,17 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
|
||||
Byte mainByte;
|
||||
CCoderInfo *coder = folder->Coders + i;
|
||||
{
|
||||
unsigned idSize, j;
|
||||
Byte longID[15];
|
||||
RINOK(SzReadByte(sd, &mainByte));
|
||||
coder->MethodID.IDSize = (Byte)(mainByte & 0xF);
|
||||
RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize));
|
||||
idSize = (unsigned)(mainByte & 0xF);
|
||||
RINOK(SzReadBytes(sd, longID, idSize));
|
||||
if (idSize > sizeof(coder->MethodID))
|
||||
return SZE_NOTIMPL;
|
||||
coder->MethodID = 0;
|
||||
for (j = 0; j < idSize; j++)
|
||||
coder->MethodID |= (CMethodID)longID[idSize - 1 - j] << (8 * j);
|
||||
|
||||
if ((mainByte & 0x10) != 0)
|
||||
{
|
||||
RINOK(SzReadNumber32(sd, &coder->NumInStreams));
|
||||
@@ -926,6 +940,7 @@ SZ_RESULT SzReadHeader2(
|
||||
UInt32 **digests, /* allocTemp */
|
||||
Byte **emptyStreamVector, /* allocTemp */
|
||||
Byte **emptyFileVector, /* allocTemp */
|
||||
Byte **lwtVector, /* allocTemp */
|
||||
ISzAlloc *allocMain,
|
||||
ISzAlloc *allocTemp)
|
||||
{
|
||||
@@ -1008,6 +1023,24 @@ SZ_RESULT SzReadHeader2(
|
||||
RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
|
||||
break;
|
||||
}
|
||||
case k7zIdLastWriteTime:
|
||||
{
|
||||
RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp->Alloc));
|
||||
RINOK(SzReadSwitch(sd));
|
||||
for (i = 0; i < numFiles; i++)
|
||||
{
|
||||
CFileItem *f = &files[i];
|
||||
Byte defined = (*lwtVector)[i];
|
||||
f->IsLastWriteTimeDefined = defined;
|
||||
f->LastWriteTime.Low = f->LastWriteTime.High = 0;
|
||||
if (defined)
|
||||
{
|
||||
RINOK(SzReadUInt32(sd, &f->LastWriteTime.Low));
|
||||
RINOK(SzReadUInt32(sd, &f->LastWriteTime.High));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RINOK(SzSkeepDataSize(sd, size));
|
||||
@@ -1060,15 +1093,17 @@ SZ_RESULT SzReadHeader(
|
||||
UInt32 *digests = 0;
|
||||
Byte *emptyStreamVector = 0;
|
||||
Byte *emptyFileVector = 0;
|
||||
Byte *lwtVector = 0;
|
||||
SZ_RESULT res = SzReadHeader2(sd, db,
|
||||
&unPackSizes, &digestsDefined, &digests,
|
||||
&emptyStreamVector, &emptyFileVector,
|
||||
&emptyStreamVector, &emptyFileVector, &lwtVector,
|
||||
allocMain, allocTemp);
|
||||
allocTemp->Free(unPackSizes);
|
||||
allocTemp->Free(digestsDefined);
|
||||
allocTemp->Free(digests);
|
||||
allocTemp->Free(emptyStreamVector);
|
||||
allocTemp->Free(emptyFileVector);
|
||||
allocTemp->Free(lwtVector);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1095,7 +1130,6 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
|
||||
UInt32 i = 0;
|
||||
#endif
|
||||
CFileSize unPackSize;
|
||||
size_t outRealSize;
|
||||
SZ_RESULT res;
|
||||
|
||||
RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
|
||||
@@ -1125,15 +1159,12 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
|
||||
|
||||
res = SzDecode(db->PackSizes, folder,
|
||||
#ifdef _LZMA_IN_CB
|
||||
inStream,
|
||||
inStream, dataStartPos,
|
||||
#else
|
||||
*inBuffer,
|
||||
#endif
|
||||
outBuffer->Items, (size_t)unPackSize,
|
||||
&outRealSize, allocTemp);
|
||||
outBuffer->Items, (size_t)unPackSize, allocTemp);
|
||||
RINOK(res)
|
||||
if (outRealSize != (UInt32)unPackSize)
|
||||
return SZE_FAIL;
|
||||
if (folder->UnPackCRCDefined)
|
||||
if (CrcCalc(outBuffer->Items, (size_t)unPackSize) != folder->UnPackCRC)
|
||||
return SZE_FAIL;
|
||||
|
||||
@@ -26,7 +26,7 @@ typedef struct _CArchiveDatabaseEx
|
||||
void SzArDbExInit(CArchiveDatabaseEx *db);
|
||||
void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *));
|
||||
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder);
|
||||
CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex);
|
||||
int SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex, CFileSize *resSize);
|
||||
|
||||
typedef struct _ISzInStream
|
||||
{
|
||||
|
||||
@@ -96,6 +96,7 @@ void SzFileInit(CFileItem *fileItem)
|
||||
fileItem->HasStream = 1;
|
||||
fileItem->IsDirectory = 0;
|
||||
fileItem->IsAnti = 0;
|
||||
fileItem->IsLastWriteTimeDefined = 0;
|
||||
fileItem->Name = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,12 +45,16 @@ int SzFolderFindBindPairForInStream(CFolder *folder, UInt32 inStreamIndex);
|
||||
UInt32 SzFolderGetNumOutStreams(CFolder *folder);
|
||||
CFileSize SzFolderGetUnPackSize(CFolder *folder);
|
||||
|
||||
/* #define CArchiveFileTime UInt64 */
|
||||
typedef struct _CArchiveFileTime
|
||||
{
|
||||
UInt32 Low;
|
||||
UInt32 High;
|
||||
} CArchiveFileTime;
|
||||
|
||||
typedef struct _CFileItem
|
||||
{
|
||||
/*
|
||||
CArchiveFileTime LastWriteTime;
|
||||
/*
|
||||
CFileSize StartPos;
|
||||
UInt32 Attributes;
|
||||
*/
|
||||
@@ -62,6 +66,7 @@ typedef struct _CFileItem
|
||||
Byte HasStream;
|
||||
Byte IsDirectory;
|
||||
Byte IsAnti;
|
||||
Byte IsLastWriteTimeDefined;
|
||||
/*
|
||||
int AreAttributesDefined;
|
||||
int IsLastWriteTimeDefined;
|
||||
|
||||
@@ -44,6 +44,61 @@ void ConvertNumberToString(CFileSize value, char *s)
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
#define PERIOD_4 (4 * 365 + 1)
|
||||
#define PERIOD_100 (PERIOD_4 * 25 - 1)
|
||||
#define PERIOD_400 (PERIOD_100 * 4 + 1)
|
||||
|
||||
void ConvertFileTimeToString(CArchiveFileTime *ft, char *s)
|
||||
{
|
||||
unsigned year, mon, day, hour, min, sec;
|
||||
UInt64 v64 = ft->Low | ((UInt64)ft->High << 32);
|
||||
Byte ms[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
unsigned temp;
|
||||
UInt32 v;
|
||||
v64 /= 10000000;
|
||||
sec = (unsigned)(v64 % 60);
|
||||
v64 /= 60;
|
||||
min = (unsigned)(v64 % 60);
|
||||
v64 /= 60;
|
||||
hour = (unsigned)(v64 % 24);
|
||||
v64 /= 24;
|
||||
|
||||
v = (UInt32)v64;
|
||||
|
||||
year = (unsigned)(1601 + v / PERIOD_400 * 400);
|
||||
v %= PERIOD_400;
|
||||
|
||||
temp = (unsigned)(v / PERIOD_100);
|
||||
if (temp == 4)
|
||||
temp = 3;
|
||||
year += temp * 100;
|
||||
v -= temp * PERIOD_100;
|
||||
|
||||
temp = v / PERIOD_4;
|
||||
if (temp == 25)
|
||||
temp = 24;
|
||||
year += temp * 4;
|
||||
v -= temp * PERIOD_4;
|
||||
|
||||
temp = v / 365;
|
||||
if (temp == 4)
|
||||
temp = 3;
|
||||
year += temp;
|
||||
v -= temp * 365;
|
||||
|
||||
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
|
||||
ms[1] = 29;
|
||||
for (mon = 1; mon <= 12; mon++)
|
||||
{
|
||||
unsigned s = ms[mon - 1];
|
||||
if (v < s)
|
||||
break;
|
||||
v -= s;
|
||||
}
|
||||
day = (unsigned)v + 1;
|
||||
sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_WINDOWS_FUNCTIONS
|
||||
/*
|
||||
@@ -193,7 +248,7 @@ int main(int numargs, char *args[])
|
||||
ISzAlloc allocImp;
|
||||
ISzAlloc allocTempImp;
|
||||
|
||||
printf("\n7z ANSI-C Decoder 4.45 Copyright (c) 1999-2007 Igor Pavlov 2007-03-15\n");
|
||||
printf("\n7z ANSI-C Decoder 4.48 Copyright (c) 1999-2007 Igor Pavlov 2007-06-21\n");
|
||||
if (numargs == 1)
|
||||
{
|
||||
printf(
|
||||
@@ -256,9 +311,14 @@ int main(int numargs, char *args[])
|
||||
for (i = 0; i < db.Database.NumFiles; i++)
|
||||
{
|
||||
CFileItem *f = db.Database.Files + i;
|
||||
char s[32];
|
||||
char s[32], t[32];
|
||||
ConvertNumberToString(f->Size, s);
|
||||
printf("%10s %s\n", s, f->Name);
|
||||
if (f->IsLastWriteTimeDefined)
|
||||
ConvertFileTimeToString(&f->LastWriteTime, t);
|
||||
else
|
||||
strcpy(t, " ");
|
||||
|
||||
printf("%10s %s %s\n", s, t, f->Name);
|
||||
}
|
||||
}
|
||||
else if (testCommand || extractCommand)
|
||||
@@ -300,7 +360,7 @@ int main(int numargs, char *args[])
|
||||
if (!testCommand)
|
||||
{
|
||||
MY_FILE_HANDLE outputHandle;
|
||||
UInt32 processedSize;
|
||||
size_t processedSize;
|
||||
char *fileName = f->Name;
|
||||
size_t nameLen = strlen(f->Name);
|
||||
for (; nameLen > 0; nameLen--)
|
||||
@@ -356,8 +416,12 @@ int main(int numargs, char *args[])
|
||||
printf("\nEverything is Ok\n");
|
||||
return 0;
|
||||
}
|
||||
if (res == (SZ_RESULT)SZE_OUTOFMEMORY)
|
||||
if (res == (SZ_RESULT)SZE_NOTIMPL)
|
||||
PrintError("decoder doesn't support this archive");
|
||||
else if (res == (SZ_RESULT)SZE_OUTOFMEMORY)
|
||||
PrintError("can not allocate memory");
|
||||
else if (res == (SZ_RESULT)SZE_CRC_ERROR)
|
||||
PrintError("CRC error");
|
||||
else
|
||||
printf("\nERROR #%d\n", res);
|
||||
return 1;
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
|
||||
#include "7zMethodID.h"
|
||||
|
||||
/*
|
||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2)
|
||||
{
|
||||
int i;
|
||||
if (a1->IDSize != a2->IDSize)
|
||||
return 0;
|
||||
for (i = 0; i < a1->IDSize; i++)
|
||||
if (a1->ID[i] != a2->ID[i])
|
||||
return 0;
|
||||
return 1;
|
||||
return (*a1 == *a2) ? 1 : 0;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -5,14 +5,6 @@
|
||||
|
||||
#include "../../Types.h"
|
||||
|
||||
#define kMethodIDSize 15
|
||||
|
||||
typedef struct _CMethodID
|
||||
{
|
||||
Byte ID[kMethodIDSize];
|
||||
Byte IDSize;
|
||||
} CMethodID;
|
||||
|
||||
int AreMethodsEqual(CMethodID *a1, CMethodID *a2);
|
||||
typedef UInt64 CMethodID;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,7 +42,7 @@ RSC=rc.exe
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_LZMA_PROB32" /D "_LZMA_IN_CB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x419 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
@@ -50,7 +50,8 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/7zDec.exe" /opt:NOWIN98
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "7z_C - Win32 Debug"
|
||||
|
||||
@@ -114,6 +115,30 @@ SOURCE=..\..\7zCrc.h
|
||||
SOURCE=..\..\Types.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Branch"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Branch\BranchTypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Branch\BranchX86.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Branch\BranchX86.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Branch\BranchX86_2.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Compress\Branch\BranchX86_2.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\7zAlloc.c
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
PROG = 7zDec.exe
|
||||
|
||||
!IFDEF CPU
|
||||
LIBS = $(LIBS) bufferoverflowU.lib
|
||||
CFLAGS = $(CFLAGS) -GS- -Zc:forScope -WX -GS- -Gy -W4
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF O
|
||||
!IFDEF CPU
|
||||
O=$(CPU)
|
||||
@@ -8,7 +13,7 @@ O=O
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -GS- -WX -Gy
|
||||
CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -D_LZMA_IN_CB
|
||||
CFLAGS_O1 = $(CFLAGS) -O1
|
||||
CFLAGS_O2 = $(CFLAGS) -O2
|
||||
|
||||
@@ -38,6 +43,8 @@ C_OBJS = \
|
||||
OBJS = \
|
||||
$(7Z_OBJS) \
|
||||
$O\LzmaDecode.obj \
|
||||
$O\BranchX86.obj \
|
||||
$O\BranchX86_2.obj \
|
||||
$(C_OBJS) \
|
||||
|
||||
all: $(PROGPATH)
|
||||
@@ -56,5 +63,12 @@ $(7Z_OBJS): $(*B).c
|
||||
$(COMPL)
|
||||
$O\LzmaDecode.obj: ../../Compress/Lzma/$(*B).c
|
||||
$(COMPL_O2)
|
||||
|
||||
$O\BranchX86.obj: ../../Compress/Branch/$(*B).c
|
||||
$(COMPL_O2)
|
||||
|
||||
$O\BranchX86_2.obj: ../../Compress/Branch/$(*B).c
|
||||
$(COMPL_O2)
|
||||
|
||||
$(C_OBJS): ../../$(*B).c
|
||||
$(COMPL_O2)
|
||||
|
||||
@@ -2,9 +2,9 @@ PROG = 7zDec
|
||||
CXX = g++
|
||||
LIB =
|
||||
RM = rm -f
|
||||
CFLAGS = -c -O2 -Wall
|
||||
CFLAGS = -c -O2 -Wall -D_LZMA_IN_CB
|
||||
|
||||
OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o
|
||||
OBJS = 7zAlloc.o 7zBuffer.o 7zCrc.o 7zDecode.o 7zExtract.o 7zHeader.o 7zIn.o 7zItem.o 7zMain.o 7zMethodID.o LzmaDecode.o BranchX86.o BranchX86_2.o
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
@@ -44,6 +44,11 @@ $(PROG): $(OBJS)
|
||||
LzmaDecode.o: ../../Compress/Lzma/LzmaDecode.c
|
||||
$(CXX) $(CFLAGS) ../../Compress/Lzma/LzmaDecode.c
|
||||
|
||||
BranchX86.o: ../../Compress/Branch/BranchX86.c
|
||||
$(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86.c
|
||||
|
||||
BranchX86_2.o: ../../Compress/Branch/BranchX86_2.c
|
||||
$(CXX) $(CFLAGS) ../../Compress/Branch/BranchX86_2.c
|
||||
|
||||
clean:
|
||||
-$(RM) $(PROG) $(OBJS)
|
||||
|
||||
@@ -27,7 +27,7 @@ typedef unsigned int UInt32;
|
||||
#ifdef _SZ_NO_INT_64
|
||||
typedef unsigned long UInt64;
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
typedef unsigned long long int UInt64;
|
||||
@@ -35,4 +35,17 @@ typedef unsigned long long int UInt64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* #define _LZMA_NO_SYSTEM_SIZE_T */
|
||||
/* You can use it, if you don't want <stddef.h> */
|
||||
|
||||
#ifndef _7ZIP_SIZET_DEFINED
|
||||
#define _7ZIP_SIZET_DEFINED
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
#include <stddef.h>
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,100 +2,83 @@
|
||||
|
||||
#include "BranchX86.h"
|
||||
|
||||
/*
|
||||
static int inline Test86MSByte(Byte b)
|
||||
{
|
||||
return (b == 0 || b == 0xFF);
|
||||
}
|
||||
*/
|
||||
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
|
||||
|
||||
const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
|
||||
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
|
||||
|
||||
/*
|
||||
void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos)
|
||||
SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding)
|
||||
{
|
||||
*prevMask = 0;
|
||||
*prevPos = (UInt32)(-5);
|
||||
}
|
||||
*/
|
||||
|
||||
UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
|
||||
UInt32 *prevMask, UInt32 *prevPos, int encoding)
|
||||
{
|
||||
UInt32 bufferPos = 0;
|
||||
UInt32 limit;
|
||||
|
||||
SizeT bufferPos = 0, prevPosT;
|
||||
UInt32 prevMask = *prevMaskMix & 0x7;
|
||||
if (endPos < 5)
|
||||
return 0;
|
||||
|
||||
if (nowPos - *prevPos > 5)
|
||||
*prevPos = nowPos - 5;
|
||||
|
||||
limit = endPos - 5;
|
||||
while(bufferPos <= limit)
|
||||
nowPos += 5;
|
||||
prevPosT = (SizeT)0 - 1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Byte b = buffer[bufferPos];
|
||||
UInt32 offset;
|
||||
if (b != 0xE8 && b != 0xE9)
|
||||
{
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
offset = (nowPos + bufferPos - *prevPos);
|
||||
*prevPos = (nowPos + bufferPos);
|
||||
if (offset > 5)
|
||||
*prevMask = 0;
|
||||
Byte *p = buffer + bufferPos;
|
||||
Byte *limit = buffer + endPos - 4;
|
||||
for (; p < limit; p++)
|
||||
if ((*p & 0xFE) == 0xE8)
|
||||
break;
|
||||
bufferPos = (SizeT)(p - buffer);
|
||||
if (p >= limit)
|
||||
break;
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
if (prevPosT > 3)
|
||||
prevMask = 0;
|
||||
else
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < offset; i++)
|
||||
prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
|
||||
if (prevMask != 0)
|
||||
{
|
||||
*prevMask &= 0x77;
|
||||
*prevMask <<= 1;
|
||||
Byte b = p[4 - kMaskToBitNumber[prevMask]];
|
||||
if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
|
||||
{
|
||||
prevPosT = bufferPos;
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
b = buffer[bufferPos + 4];
|
||||
if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
|
||||
(*prevMask >> 1) < 0x10)
|
||||
prevPosT = bufferPos;
|
||||
|
||||
if (Test86MSByte(p[4]))
|
||||
{
|
||||
UInt32 src =
|
||||
((UInt32)(b) << 24) |
|
||||
((UInt32)(buffer[bufferPos + 3]) << 16) |
|
||||
((UInt32)(buffer[bufferPos + 2]) << 8) |
|
||||
(buffer[bufferPos + 1]);
|
||||
|
||||
UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
|
||||
UInt32 dest;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 index;
|
||||
Byte b;
|
||||
int index;
|
||||
if (encoding)
|
||||
dest = (nowPos + bufferPos + 5) + src;
|
||||
dest = (nowPos + (UInt32)bufferPos) + src;
|
||||
else
|
||||
dest = src - (nowPos + bufferPos + 5);
|
||||
if (*prevMask == 0)
|
||||
dest = src - (nowPos + (UInt32)bufferPos);
|
||||
if (prevMask == 0)
|
||||
break;
|
||||
index = kMaskToBitNumber[*prevMask >> 1];
|
||||
b = (Byte)(dest >> (24 - index * 8));
|
||||
index = kMaskToBitNumber[prevMask] * 8;
|
||||
b = (Byte)(dest >> (24 - index));
|
||||
if (!Test86MSByte(b))
|
||||
break;
|
||||
src = dest ^ ((1 << (32 - index * 8)) - 1);
|
||||
src = dest ^ ((1 << (32 - index)) - 1);
|
||||
}
|
||||
buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
buffer[bufferPos + 3] = (Byte)(dest >> 16);
|
||||
buffer[bufferPos + 2] = (Byte)(dest >> 8);
|
||||
buffer[bufferPos + 1] = (Byte)dest;
|
||||
p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
|
||||
p[3] = (Byte)(dest >> 16);
|
||||
p[2] = (Byte)(dest >> 8);
|
||||
p[1] = (Byte)dest;
|
||||
bufferPos += 5;
|
||||
*prevMask = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevMask = ((prevMask << 1) & 0x7) | 1;
|
||||
bufferPos++;
|
||||
*prevMask |= 1;
|
||||
if (Test86MSByte(b))
|
||||
*prevMask |= 0x10;
|
||||
}
|
||||
}
|
||||
prevPosT = bufferPos - prevPosT;
|
||||
*prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
|
||||
return bufferPos;
|
||||
}
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
|
||||
#include "BranchTypes.h"
|
||||
|
||||
#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
|
||||
#define x86_Convert_Init(state) { state = 0; }
|
||||
|
||||
UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
|
||||
UInt32 *prevMask, UInt32 *prevPos, int encoding);
|
||||
SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding);
|
||||
|
||||
#endif
|
||||
|
||||
135
C/Compress/Branch/BranchX86_2.c
Executable file
135
C/Compress/Branch/BranchX86_2.c
Executable file
@@ -0,0 +1,135 @@
|
||||
// BranchX86_2.c
|
||||
|
||||
#include "BranchX86_2.h"
|
||||
|
||||
#include "../../Alloc.h"
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CProb UInt32
|
||||
#else
|
||||
#define CProb UInt16
|
||||
#endif
|
||||
|
||||
#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
|
||||
#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue ((UInt32)1 << kNumTopBits)
|
||||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
#define RC_READ_BYTE (*Buffer++)
|
||||
|
||||
#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
|
||||
{ int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
|
||||
|
||||
#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; }
|
||||
|
||||
#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
|
||||
|
||||
#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
|
||||
|
||||
#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
|
||||
#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
|
||||
#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
|
||||
// #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits));
|
||||
// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits));
|
||||
|
||||
int x86_2_Decode(
|
||||
const Byte *buf0, SizeT size0,
|
||||
const Byte *buf1, SizeT size1,
|
||||
const Byte *buf2, SizeT size2,
|
||||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize)
|
||||
{
|
||||
CProb p[256 + 2];
|
||||
SizeT inPos = 0, outPos = 0;
|
||||
|
||||
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;
|
||||
RC_INIT(buf3, size3);
|
||||
|
||||
if (outSize == 0)
|
||||
return BCJ2_RESULT_OK;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
CProb *prob;
|
||||
UInt32 bound;
|
||||
|
||||
SizeT limit = size0 - inPos;
|
||||
if (outSize - outPos < limit)
|
||||
limit = outSize - outPos;
|
||||
while (limit != 0)
|
||||
{
|
||||
Byte b = buf0[inPos];
|
||||
outBuf[outPos++] = b;
|
||||
if (IsJ(prevByte, b))
|
||||
break;
|
||||
inPos++;
|
||||
prevByte = b;
|
||||
limit--;
|
||||
}
|
||||
|
||||
if (limit == 0 || outPos == outSize)
|
||||
break;
|
||||
|
||||
b = buf0[inPos++];
|
||||
|
||||
if (b == 0xE8)
|
||||
prob = p + prevByte;
|
||||
else if (b == 0xE9)
|
||||
prob = p + 256;
|
||||
else
|
||||
prob = p + 257;
|
||||
|
||||
IfBit0(prob)
|
||||
{
|
||||
UpdateBit0(prob)
|
||||
prevByte = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 dest;
|
||||
const Byte *v;
|
||||
UpdateBit1(prob)
|
||||
if (b == 0xE8)
|
||||
{
|
||||
v = buf1;
|
||||
if (size1 < 4)
|
||||
return BCJ2_RESULT_DATA_ERROR;
|
||||
buf1 += 4;
|
||||
size1 -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = buf2;
|
||||
if (size2 < 4)
|
||||
return BCJ2_RESULT_DATA_ERROR;
|
||||
buf2 += 4;
|
||||
size2 -= 4;
|
||||
}
|
||||
dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
|
||||
((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
|
||||
outBuf[outPos++] = (Byte)dest;
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 8);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = (Byte)(dest >> 16);
|
||||
if (outPos == outSize)
|
||||
break;
|
||||
outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
|
||||
}
|
||||
}
|
||||
return (outPos == outSize) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR;
|
||||
}
|
||||
28
C/Compress/Branch/BranchX86_2.h
Executable file
28
C/Compress/Branch/BranchX86_2.h
Executable file
@@ -0,0 +1,28 @@
|
||||
// BranchX86_2.h
|
||||
|
||||
#ifndef __BRANCHX86_2_H
|
||||
#define __BRANCHX86_2_H
|
||||
|
||||
#include "BranchTypes.h"
|
||||
|
||||
#define BCJ2_RESULT_OK 0
|
||||
#define BCJ2_RESULT_DATA_ERROR 1
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
outSize <= FullOutputSize,
|
||||
where FullOutputSize is full size of output stream of x86_2 filter.
|
||||
|
||||
If buf0 overlaps outBuf, there are two required conditions:
|
||||
1) (buf0 >= outBuf)
|
||||
2) (buf0 + size0 >= outBuf + FullOutputSize).
|
||||
*/
|
||||
|
||||
int x86_2_Decode(
|
||||
const Byte *buf0, SizeT size0,
|
||||
const Byte *buf1, SizeT size1,
|
||||
const Byte *buf2, SizeT size2,
|
||||
const Byte *buf3, SizeT size3,
|
||||
Byte *outBuf, SizeT outSize);
|
||||
|
||||
#endif
|
||||
@@ -227,7 +227,7 @@ int LzmaDecode(
|
||||
else
|
||||
previousByte = dictionary[dictionaryPos - 1];
|
||||
|
||||
while(1)
|
||||
for (;;)
|
||||
{
|
||||
int bufferPos = (int)(Buffer - vs->Buffer);
|
||||
if (BufferSize - bufferPos < kRequiredInBufferSize)
|
||||
|
||||
@@ -29,16 +29,16 @@ typedef unsigned int UInt32;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* #define _LZMA_SYSTEM_SIZE_T */
|
||||
/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
|
||||
/* #define _LZMA_NO_SYSTEM_SIZE_T */
|
||||
/* You can use it, if you don't want <stddef.h> */
|
||||
|
||||
#ifndef _7ZIP_SIZET_DEFINED
|
||||
#define _7ZIP_SIZET_DEFINED
|
||||
#ifdef _LZMA_SYSTEM_SIZE_T
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
#include <stddef.h>
|
||||
typedef size_t SizeT;
|
||||
#else
|
||||
typedef UInt32 SizeT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user