7z working for SD

This commit is contained in:
dborth 2008-10-14 07:18:03 +00:00
parent ab3f20ab07
commit 79bcbc1b72
4 changed files with 71 additions and 115 deletions

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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