mirror of
https://github.com/dborth/fceugx.git
synced 2025-01-07 14:28:18 +01:00
7z working for SD
This commit is contained in:
parent
ab3f20ab07
commit
79bcbc1b72
@ -47,7 +47,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
#else
|
#else
|
||||||
const Byte *inBuffer,
|
const Byte *inBuffer,
|
||||||
#endif
|
#endif
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain)
|
size_t *outSizeProcessed, ISzAlloc *allocMain)
|
||||||
{
|
{
|
||||||
UInt32 si;
|
UInt32 si;
|
||||||
@ -109,7 +109,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
lzmaCallback.InCallback.Read = LzmaReadImp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
||||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
||||||
return SZE_FAIL;
|
return SZE_FAIL;
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
if (state.Dictionary == 0)
|
if (state.Dictionary == 0)
|
||||||
{
|
{
|
||||||
allocMain->Free(state.Probs);
|
allocMain->Free(state.Probs);
|
||||||
return SZE_OUTOFMEMORY;
|
return SZE_OUTOFMEMORYDIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LzmaDecoderInit(&state);
|
LzmaDecoderInit(&state);
|
||||||
@ -157,7 +157,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
// like SzDecode but uses less memory
|
// like SzDecode but uses less memory
|
||||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
||||||
size_t *fileOffset, size_t *fileSize)
|
size_t *fileOffset, size_t *fileSize)
|
||||||
{
|
{
|
||||||
@ -220,7 +220,7 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
lzmaCallback.InCallback.Read = LzmaReadImp;
|
lzmaCallback.InCallback.Read = LzmaReadImp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items,
|
||||||
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
coder->Properties.Capacity) != LZMA_RESULT_OK)
|
||||||
return SZE_FAIL;
|
return SZE_FAIL;
|
||||||
|
|
||||||
@ -240,97 +240,51 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LzmaDecoderInit(&state);
|
LzmaDecoderInit(&state);
|
||||||
|
|
||||||
// allocate memory for the temporary buffer
|
// allocate memory for the temporary buffer
|
||||||
Byte *tmpBuffer = (Byte *)allocMain->Alloc(_LZMA_TEMP_BUFFER_SIZE);
|
Byte *tmpBuffer = (Byte *)allocMain->Alloc(_LZMA_TEMP_BUFFER_SIZE);
|
||||||
|
|
||||||
// variables containing the number of the first and the last bytes of the buffer
|
|
||||||
size_t bufferStart, bufferEnd;
|
|
||||||
bufferStart = bufferEnd = 0;
|
|
||||||
|
|
||||||
// integers contains the offset, the size and the already copied data which will be
|
|
||||||
// copied from the tmpBuffer to outBuffer
|
|
||||||
size_t copyOffset, copySize, copyDone;
|
|
||||||
copyOffset = copySize = copyDone = 0;
|
|
||||||
|
|
||||||
UInt32 i = 0;
|
|
||||||
|
|
||||||
// decompress data in _LZMA_TEMP_BUFFER_SIZE byte steps and copy the wanted file to outBuffer
|
// decompress data in _LZMA_TEMP_BUFFER_SIZE byte steps and copy the wanted file to outBuffer
|
||||||
do
|
size_t bytesLeft = *fileSize; // total bytes remaining to be read
|
||||||
{
|
size_t bytesToRead = 0; // bytes to read on this pass
|
||||||
|
size_t bytesRead = 0; // total bytes read
|
||||||
|
size_t offset = 0; // buffer offset
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(bytesLeft > _LZMA_TEMP_BUFFER_SIZE)
|
||||||
|
bytesToRead = _LZMA_TEMP_BUFFER_SIZE;
|
||||||
|
else
|
||||||
|
bytesToRead = bytesLeft;
|
||||||
|
|
||||||
|
bytesLeft -= bytesToRead;
|
||||||
|
|
||||||
// decompress next bytes
|
// decompress next bytes
|
||||||
result = LzmaDecode(&state,
|
result = LzmaDecode(&state,
|
||||||
#ifdef _LZMA_IN_CB
|
#ifdef _LZMA_IN_CB
|
||||||
&lzmaCallback.InCallback,
|
&lzmaCallback.InCallback,
|
||||||
#else
|
#else
|
||||||
//inBuffer, (SizeT)inSize, &inProcessed, //TODO!
|
//inBuffer, (SizeT)inSize, &inProcessed, //TODO!
|
||||||
#endif
|
#endif
|
||||||
tmpBuffer, _LZMA_TEMP_BUFFER_SIZE, &outSizeProcessedLoc
|
tmpBuffer, bytesToRead, &outSizeProcessedLoc
|
||||||
);
|
);
|
||||||
|
|
||||||
// check result
|
// check result
|
||||||
if(result == LZMA_RESULT_DATA_ERROR)
|
if(result == LZMA_RESULT_DATA_ERROR)
|
||||||
{
|
|
||||||
return SZE_DATA_ERROR;
|
return SZE_DATA_ERROR;
|
||||||
}
|
else if(result != LZMA_RESULT_OK)
|
||||||
if(result != LZMA_RESULT_OK)
|
|
||||||
{
|
|
||||||
return SZE_FAIL;
|
return SZE_FAIL;
|
||||||
}
|
|
||||||
|
|
||||||
// normally this should never happen
|
// normally this should never happen
|
||||||
if(outSizeProcessedLoc > _LZMA_TEMP_BUFFER_SIZE)
|
if(outSizeProcessedLoc > _LZMA_TEMP_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
return SZE_FAIL;
|
return SZE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update bufferStart and bufferEnd
|
memcpy(outBuffer + offset, tmpBuffer, outSizeProcessedLoc);
|
||||||
bufferStart = _LZMA_TEMP_BUFFER_SIZE * i;
|
bytesRead += bytesToRead;
|
||||||
bufferEnd = bufferStart + outSizeProcessedLoc;
|
offset += outSizeProcessedLoc;
|
||||||
i++;
|
|
||||||
|
|
||||||
// calculate copy offset and size
|
|
||||||
if(*fileOffset > bufferEnd)
|
|
||||||
{
|
|
||||||
// we haven't reached the start of the file yet
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate offset
|
|
||||||
if(*fileOffset < bufferStart)
|
|
||||||
{
|
|
||||||
// the file has already started before this decompression step
|
|
||||||
copyOffset = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// the file starts somewhere inside this buffer
|
|
||||||
copyDone = 0;
|
|
||||||
copyOffset = _LZMA_TEMP_BUFFER_SIZE - (bufferEnd - *fileOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate size
|
|
||||||
if((*fileOffset + *fileSize) > bufferEnd)
|
|
||||||
{
|
|
||||||
// we'll need the whole buffer after copyOffset
|
|
||||||
copySize = _LZMA_TEMP_BUFFER_SIZE - copyOffset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we'll stop somewhere inside the buffer
|
|
||||||
copySize = (*fileOffset + *fileSize) - (bufferStart + copyOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy bytes to the real output buffer
|
|
||||||
if(copySize == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// printf("memcpy(outBuffer + %d, tmpBuffer + %d, %d)\n", copyDone, copyOffset, copySize);
|
|
||||||
memcpy(outBuffer + copyDone, tmpBuffer + copyOffset, copySize);
|
|
||||||
copyDone += copySize;
|
|
||||||
}
|
}
|
||||||
while((*fileOffset + *fileSize) > bufferEnd);
|
while(bytesLeft > 0);
|
||||||
|
|
||||||
/* result = LzmaDecode(&state,
|
/* result = LzmaDecode(&state,
|
||||||
#ifdef _LZMA_IN_CB
|
#ifdef _LZMA_IN_CB
|
||||||
@ -340,7 +294,7 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
#endif
|
#endif
|
||||||
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);*/
|
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);*/
|
||||||
//*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
//*outSizeProcessed = (size_t)outSizeProcessedLoc;
|
||||||
*outSizeProcessed = copyDone;
|
*outSizeProcessed = offset;
|
||||||
allocMain->Free(tmpBuffer); // free the temporary buffer again
|
allocMain->Free(tmpBuffer); // free the temporary buffer again
|
||||||
allocMain->Free(state.Probs);
|
allocMain->Free(state.Probs);
|
||||||
allocMain->Free(state.Dictionary);
|
allocMain->Free(state.Dictionary);
|
||||||
|
@ -19,17 +19,17 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
|
|||||||
#else
|
#else
|
||||||
const Byte *inBuffer,
|
const Byte *inBuffer,
|
||||||
#endif
|
#endif
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain);
|
size_t *outSizeProcessed, ISzAlloc *allocMain);
|
||||||
|
|
||||||
#ifdef _LZMA_OUT_READ
|
#ifdef _LZMA_OUT_READ
|
||||||
#ifndef _LZMA_TEMP_BUFFER_SIZE
|
#ifndef _LZMA_TEMP_BUFFER_SIZE
|
||||||
#define _LZMA_TEMP_BUFFER_SIZE (1 << 15) // size of the temporary buffer in bytes
|
#define _LZMA_TEMP_BUFFER_SIZE (1024) // size of the temporary buffer in bytes
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder,
|
||||||
ISzInStream *stream,
|
ISzInStream *stream,
|
||||||
Byte *outBuffer, size_t outSize,
|
Byte *outBuffer, size_t outSize,
|
||||||
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
size_t *outSizeProcessed, ISzAlloc *allocMain,
|
||||||
size_t *fileOffset, size_t *fileSize);
|
size_t *fileOffset, size_t *fileSize);
|
||||||
#endif // #ifdef _LZMA_OUT_READ
|
#endif // #ifdef _LZMA_OUT_READ
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
#include "7zCrc.h"
|
#include "7zCrc.h"
|
||||||
|
|
||||||
SZ_RESULT SzExtract(
|
SZ_RESULT SzExtract(
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
CArchiveDatabaseEx *db,
|
CArchiveDatabaseEx *db,
|
||||||
UInt32 fileIndex,
|
UInt32 fileIndex,
|
||||||
UInt32 *blockIndex,
|
UInt32 *blockIndex,
|
||||||
Byte **outBuffer,
|
Byte **outBuffer,
|
||||||
size_t *outBufferSize,
|
size_t *outBufferSize,
|
||||||
size_t *offset,
|
size_t *offset,
|
||||||
size_t *outSizeProcessed,
|
size_t *outSizeProcessed,
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
@ -41,9 +41,9 @@ SZ_RESULT SzExtract(
|
|||||||
*blockIndex = folderIndex;
|
*blockIndex = folderIndex;
|
||||||
allocMain->Free(*outBuffer);
|
allocMain->Free(*outBuffer);
|
||||||
*outBuffer = 0;
|
*outBuffer = 0;
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
#ifndef _LZMA_IN_CB
|
||||||
if (packSize != 0)
|
if (packSize != 0)
|
||||||
{
|
{
|
||||||
@ -67,12 +67,12 @@ SZ_RESULT SzExtract(
|
|||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
size_t outRealSize;
|
size_t outRealSize;
|
||||||
res = SzDecode(db->Database.PackSizes +
|
res = SzDecode(db->Database.PackSizes +
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
db->FolderStartPackStreamIndex[folderIndex], folder,
|
||||||
#ifdef _LZMA_IN_CB
|
#ifdef _LZMA_IN_CB
|
||||||
inStream,
|
inStream,
|
||||||
#else
|
#else
|
||||||
inBuffer,
|
inBuffer,
|
||||||
#endif
|
#endif
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
|
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp);
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
@ -96,7 +96,7 @@ SZ_RESULT SzExtract(
|
|||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
CFileItem *fileItem = db->Database.Files + fileIndex;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||||
@ -118,14 +118,14 @@ SZ_RESULT SzExtract(
|
|||||||
#ifdef _LZMA_OUT_READ
|
#ifdef _LZMA_OUT_READ
|
||||||
// similar to SzExtract but needs less memory
|
// similar to SzExtract but needs less memory
|
||||||
SZ_RESULT SzExtract2(
|
SZ_RESULT SzExtract2(
|
||||||
ISzInStream *inStream,
|
ISzInStream *inStream,
|
||||||
CArchiveDatabaseEx *db,
|
CArchiveDatabaseEx *db,
|
||||||
UInt32 fileIndex,
|
UInt32 fileIndex,
|
||||||
UInt32 *blockIndex,
|
UInt32 *blockIndex,
|
||||||
Byte **outBuffer,
|
Byte **outBuffer,
|
||||||
size_t *outBufferSize,
|
size_t *outBufferSize,
|
||||||
size_t *offset,
|
size_t *offset,
|
||||||
size_t *outSizeProcessed,
|
size_t *outSizeProcessed,
|
||||||
ISzAlloc *allocMain,
|
ISzAlloc *allocMain,
|
||||||
ISzAlloc *allocTemp)
|
ISzAlloc *allocTemp)
|
||||||
{
|
{
|
||||||
@ -158,9 +158,9 @@ SZ_RESULT SzExtract2(
|
|||||||
allocMain->Free(*outBuffer);
|
allocMain->Free(*outBuffer);
|
||||||
*outBuffer = 0;
|
*outBuffer = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0)));
|
||||||
|
|
||||||
#ifndef _LZMA_IN_CB
|
#ifndef _LZMA_IN_CB
|
||||||
if (packSize != 0)
|
if (packSize != 0)
|
||||||
{
|
{
|
||||||
@ -176,7 +176,7 @@ SZ_RESULT SzExtract2(
|
|||||||
{
|
{
|
||||||
// calculate file offset and filesize
|
// calculate file offset and filesize
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
CFileItem *fileItem = db->Database.Files + fileIndex;
|
||||||
UInt32 i;
|
UInt32 i;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
*offset += (UInt32)db->Database.Files[i].Size;
|
||||||
@ -192,14 +192,14 @@ SZ_RESULT SzExtract2(
|
|||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
|
|
||||||
size_t outRealSize;
|
size_t outRealSize;
|
||||||
res = SzDecode2(db->Database.PackSizes +
|
res = SzDecode2(db->Database.PackSizes +
|
||||||
db->FolderStartPackStreamIndex[folderIndex], folder,
|
db->FolderStartPackStreamIndex[folderIndex], folder,
|
||||||
#ifdef _LZMA_IN_CB
|
#ifdef _LZMA_IN_CB
|
||||||
inStream,
|
inStream,
|
||||||
#else
|
#else
|
||||||
inBuffer,
|
inBuffer,
|
||||||
#endif
|
#endif
|
||||||
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp,
|
*outBuffer, (size_t)unPackSize, &outRealSize, allocTemp,
|
||||||
offset, outSizeProcessed
|
offset, outSizeProcessed
|
||||||
@ -226,24 +226,24 @@ SZ_RESULT SzExtract2(
|
|||||||
}
|
}
|
||||||
if (res == SZ_OK)
|
if (res == SZ_OK)
|
||||||
{
|
{
|
||||||
/* UInt32 i;
|
/* UInt32 i;
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
CFileItem *fileItem = db->Database.Files + fileIndex;
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
|
||||||
*offset += (UInt32)db->Database.Files[i].Size;
|
*offset += (UInt32)db->Database.Files[i].Size;
|
||||||
*outSizeProcessed = (size_t)fileItem->Size;*/
|
*outSizeProcessed = (size_t)fileItem->Size;*/
|
||||||
CFileItem *fileItem = db->Database.Files + fileIndex;
|
//CFileItem *fileItem = db->Database.Files + fileIndex;
|
||||||
if (/**offset +*/ *outSizeProcessed > *outBufferSize)
|
if (/**offset +*/ *outSizeProcessed > *outBufferSize)
|
||||||
return SZE_FAIL;
|
return SZE_FAIL;
|
||||||
{
|
{
|
||||||
if (fileItem->IsFileCRCDefined)
|
//if (fileItem->IsFileCRCDefined)
|
||||||
{
|
//{
|
||||||
if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer/* + *offset*/, *outSizeProcessed))
|
// if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer/* + *offset*/, *outSizeProcessed))
|
||||||
res = SZE_CRC_ERROR; // why does SzExtract return SZE_FAIL when we can return SZE_CRC_ERROR?
|
// res = SZE_CRC_ERROR; // why does SzExtract return SZE_FAIL when we can return SZE_CRC_ERROR?
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// change *offset to 0 because SzExtract normally decompresses the whole solid block
|
// change *offset to 0 because SzExtract normally decompresses the whole solid block
|
||||||
// and sets *offset to the offset of the wanted file.
|
// and sets *offset to the offset of the wanted file.
|
||||||
// SzDecode2 does only copy the needed file to the output buffer and has to set *offset
|
// SzDecode2 does only copy the needed file to the output buffer and has to set *offset
|
||||||
|
@ -64,6 +64,8 @@ typedef UInt32 CFileSize;
|
|||||||
|
|
||||||
#define SZE_ARCHIVE_ERROR (6)
|
#define SZE_ARCHIVE_ERROR (6)
|
||||||
|
|
||||||
|
#define SZE_OUTOFMEMORYDIC (7)
|
||||||
|
|
||||||
#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
|
#define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user