diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2007-06-26 04:00:00 +0400 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:15:52 +0300 |
commit | fd8b1d78b496fe38193bf8c5e86af3b43f0b022d (patch) | |
tree | 5b1e3812ed4d8b6037e5035faf3b638849f618e2 /C | |
parent | 0b33f700a66fcf7f55f92b92e0b3e5c7014d769a (diff) |
4.48 beta
Diffstat (limited to 'C')
-rwxr-xr-x | C/Alloc.c | 1 | ||||
-rwxr-xr-x | C/Archive/7z/7zDecode.c | 367 | ||||
-rwxr-xr-x | C/Archive/7z/7zDecode.h | 5 | ||||
-rwxr-xr-x | C/Archive/7z/7zExtract.c | 43 | ||||
-rwxr-xr-x | C/Archive/7z/7zIn.c | 55 | ||||
-rwxr-xr-x | C/Archive/7z/7zIn.h | 2 | ||||
-rwxr-xr-x | C/Archive/7z/7zItem.c | 1 | ||||
-rwxr-xr-x | C/Archive/7z/7zItem.h | 9 | ||||
-rwxr-xr-x | C/Archive/7z/7zMain.c | 74 | ||||
-rwxr-xr-x | C/Archive/7z/7zMethodID.c | 10 | ||||
-rwxr-xr-x | C/Archive/7z/7zMethodID.h | 10 | ||||
-rwxr-xr-x | C/Archive/7z/7z_C.dsp | 29 | ||||
-rwxr-xr-x | C/Archive/7z/makefile | 16 | ||||
-rwxr-xr-x | C/Archive/7z/makefile.gcc | 9 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchTypes.h | 15 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchX86.c | 113 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchX86.h | 5 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchX86_2.c | 135 | ||||
-rwxr-xr-x | C/Compress/Branch/BranchX86_2.h | 28 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaStateDecode.c | 2 | ||||
-rwxr-xr-x | C/Compress/Lzma/LzmaTypes.h | 10 | ||||
-rwxr-xr-x | C/Types.h | 2 |
22 files changed, 711 insertions, 230 deletions
@@ -60,7 +60,6 @@ void MidFree(void *address) } #ifndef MEM_LARGE_PAGES -wedeed #undef _7ZIP_LARGE_PAGES #endif diff --git a/C/Archive/7z/7zDecode.c b/C/Archive/7z/7zDecode.c index fe530384..aea893da 100755 --- a/C/Archive/7z/7zDecode.c +++ b/C/Archive/7z/7zDecode.c @@ -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 - return SZ_OK; } + 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; +} - if (AreMethodsEqual(&coder->MethodID, &k_LZMA)) +#ifdef _LZMA_IN_CB +SZ_RESULT SzDecodeCopy(CFileSize inSize, ISzInStream *inStream, Byte *outBuffer) +{ + while (inSize > 0) { - #ifdef _LZMA_IN_CB - CLzmaInCallbackImp lzmaCallback; - #else - SizeT inProcessed; - #endif + 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 (f->NumCoders == 2) + { + if (IS_NO_BCJ(f->Coders[1]) || + f->NumPackStreams != 1 || f->PackStreams[0] != 0 || + f->NumBindPairs != 1 || + f->BindPairs[0].InIndex != 1 || f->BindPairs[0].OutIndex != 0) + return 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; +} - CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */ - int result; - SizeT outSizeProcessedLoc; +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 - lzmaCallback.Size = inSize; - lzmaCallback.InStream = inStream; - lzmaCallback.InCallback.Read = LzmaReadImp; + 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; - if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, - coder->Properties.Capacity) != LZMA_RESULT_OK) - return SZE_FAIL; + RINOK(CheckSupportedFolder(folder)); - state.Probs = (CProb *)allocMain->Alloc(LzmaGetNumProbs(&state.Properties) * sizeof(CProb)); - if (state.Probs == 0) - return SZE_OUTOFMEMORY; + for (ci = 0; ci < folder->NumCoders; ci++) + { + CCoderInfo *coder = &folder->Coders[ci]; - #ifdef _LZMA_OUT_READ - if (state.Properties.DictionarySize == 0) - state.Dictionary = 0; - else + if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA) { - state.Dictionary = (unsigned char *)allocMain->Alloc(state.Properties.DictionarySize); - if (state.Dictionary == 0) + UInt32 si = 0; + CFileSize offset; + CFileSize inSize; + Byte *outBufCur = outBuffer; + size_t outSizeCur = outSize; + if (folder->NumCoders == 4) { - allocMain->Free(state.Probs); - return SZE_OUTOFMEMORY; + 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; } - } - LzmaDecoderInit(&state); - #endif + offset = GetSum(packSizes, si); + inSize = packSizes[si]; + #ifdef _LZMA_IN_CB + RINOK(inStream->Seek(inStream, startPos + offset)); + #endif - result = LzmaDecode(&state, + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) + return SZE_DATA_ERROR; + #ifdef _LZMA_IN_CB - &lzmaCallback.InCallback, + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); #else - inBuffer, (SizeT)inSize, &inProcessed, + memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize); #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; - return SZ_OK; + } + 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 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; } diff --git a/C/Archive/7z/7zDecode.h b/C/Archive/7z/7zDecode.h index 74bb180f..175896ef 100755 --- a/C/Archive/7z/7zDecode.h +++ b/C/Archive/7z/7zDecode.h @@ -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 diff --git a/C/Archive/7z/7zExtract.c b/C/Archive/7z/7zExtract.c index 75733fd1..1760a3ce 100755 --- a/C/Archive/7z/7zExtract.c +++ b/C/Archive/7z/7zExtract.c @@ -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; } } } diff --git a/C/Archive/7z/7zIn.c b/C/Archive/7z/7zIn.c index 04e83a8e..ac25dbc7 100755 --- a/C/Archive/7z/7zIn.c +++ b/C/Archive/7z/7zIn.c @@ -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; diff --git a/C/Archive/7z/7zIn.h b/C/Archive/7z/7zIn.h index 6bfa2a70..0b4ca08d 100755 --- a/C/Archive/7z/7zIn.h +++ b/C/Archive/7z/7zIn.h @@ -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 { diff --git a/C/Archive/7z/7zItem.c b/C/Archive/7z/7zItem.c index 2a408050..a88afe9a 100755 --- a/C/Archive/7z/7zItem.c +++ b/C/Archive/7z/7zItem.c @@ -96,6 +96,7 @@ void SzFileInit(CFileItem *fileItem) fileItem->HasStream = 1; fileItem->IsDirectory = 0; fileItem->IsAnti = 0; + fileItem->IsLastWriteTimeDefined = 0; fileItem->Name = 0; } diff --git a/C/Archive/7z/7zItem.h b/C/Archive/7z/7zItem.h index 876539a9..05567bff 100755 --- a/C/Archive/7z/7zItem.h +++ b/C/Archive/7z/7zItem.h @@ -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; diff --git a/C/Archive/7z/7zMain.c b/C/Archive/7z/7zMain.c index 74f0afd5..0deef893 100755 --- a/C/Archive/7z/7zMain.c +++ b/C/Archive/7z/7zMain.c @@ -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; diff --git a/C/Archive/7z/7zMethodID.c b/C/Archive/7z/7zMethodID.c index 5047359f..a7e825de 100755 --- a/C/Archive/7z/7zMethodID.c +++ b/C/Archive/7z/7zMethodID.c @@ -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; } +*/ diff --git a/C/Archive/7z/7zMethodID.h b/C/Archive/7z/7zMethodID.h index 8eb301da..57f22a50 100755 --- a/C/Archive/7z/7zMethodID.h +++ b/C/Archive/7z/7zMethodID.h @@ -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 diff --git a/C/Archive/7z/7z_C.dsp b/C/Archive/7z/7z_C.dsp index e53d1d0a..9a040ad1 100755 --- a/C/Archive/7z/7z_C.dsp +++ b/C/Archive/7z/7z_C.dsp @@ -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 diff --git a/C/Archive/7z/makefile b/C/Archive/7z/makefile index d6181717..6ea3119a 100755 --- a/C/Archive/7z/makefile +++ b/C/Archive/7z/makefile @@ -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) diff --git a/C/Archive/7z/makefile.gcc b/C/Archive/7z/makefile.gcc index 8de50b72..664ac252 100755 --- a/C/Archive/7z/makefile.gcc +++ b/C/Archive/7z/makefile.gcc @@ -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) diff --git a/C/Compress/Branch/BranchTypes.h b/C/Compress/Branch/BranchTypes.h index bdf75131..1bed56a9 100755 --- a/C/Compress/Branch/BranchTypes.h +++ b/C/Compress/Branch/BranchTypes.h @@ -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 diff --git a/C/Compress/Branch/BranchX86.c b/C/Compress/Branch/BranchX86.c index c3f455b8..fd1d334e 100755 --- a/C/Compress/Branch/BranchX86.c +++ b/C/Compress/Branch/BranchX86.c @@ -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) -{ - *prevMask = 0; - *prevPos = (UInt32)(-5); -} -*/ - -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 *prevMaskMix, 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; } diff --git a/C/Compress/Branch/BranchX86.h b/C/Compress/Branch/BranchX86.h index 25c1ae51..5dfd02a7 100755 --- a/C/Compress/Branch/BranchX86.h +++ b/C/Compress/Branch/BranchX86.h @@ -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 diff --git a/C/Compress/Branch/BranchX86_2.c b/C/Compress/Branch/BranchX86_2.c new file mode 100755 index 00000000..241789a5 --- /dev/null +++ b/C/Compress/Branch/BranchX86_2.c @@ -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; +} diff --git a/C/Compress/Branch/BranchX86_2.h b/C/Compress/Branch/BranchX86_2.h new file mode 100755 index 00000000..4d861fa3 --- /dev/null +++ b/C/Compress/Branch/BranchX86_2.h @@ -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 diff --git a/C/Compress/Lzma/LzmaStateDecode.c b/C/Compress/Lzma/LzmaStateDecode.c index e50f88b5..5dc8f0e2 100755 --- a/C/Compress/Lzma/LzmaStateDecode.c +++ b/C/Compress/Lzma/LzmaStateDecode.c @@ -227,7 +227,7 @@ int LzmaDecode( else previousByte = dictionary[dictionaryPos - 1]; - while(1) + for (;;) { int bufferPos = (int)(Buffer - vs->Buffer); if (BufferSize - bufferPos < kRequiredInBufferSize) diff --git a/C/Compress/Lzma/LzmaTypes.h b/C/Compress/Lzma/LzmaTypes.h index 288c5e45..9c272907 100755 --- a/C/Compress/Lzma/LzmaTypes.h +++ b/C/Compress/Lzma/LzmaTypes.h @@ -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 @@ -39,7 +39,7 @@ typedef int Int32; #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; |