Rewritten 7zip/lzma support (thanks, Dennis!)

This commit is contained in:
Ryan C. Gordon 2006-09-27 07:05:03 +00:00
parent 25909afde4
commit ab32c0313d
11 changed files with 304 additions and 958 deletions

View File

@ -2,6 +2,7 @@
* CHANGELOG.
*/
09272006 - Reworked 7zip archiver (thanks, Dennis!).
09232006 - Fixed typo in doxygen comment.
04112006 - Added LZMA archiver...7zip support (thanks, Dennis!).
03232006 - Added -fvisibility for gcc4 (http://gcc.gnu.org/wiki/Visibility)

View File

@ -92,6 +92,7 @@ Bug fixes:
Jörg Walter
Windows .rc file:
7zip/lzma archiver,
Dennis Schridde
Other stuff:

View File

@ -13,54 +13,71 @@
#if (defined PHYSFS_SUPPORTS_LZMA)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "physfs.h"
#include "7zIn.h"
#include "LzmaStateDecode.h"
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
#define LZMA_READBUFSIZE (16 * 1024)
#define LZMA_7Z_FILE_SIG 0x7a37
#define _LZMA_IN_CB
/* Use callback for input data */
typedef struct
/* #define _LZMA_OUT_READ */
/* Use read function for output data */
#define _LZMA_PROB32
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
#define _LZMA_SYSTEM_SIZE_T
/* Use system's size_t. You can use it to enable 64-bit sizes supporting */
#include "7zIn.h"
#include "7zCrc.h"
#include "7zExtract.h"
/* 7z internal from 7zIn.c */
int TestSignatureCandidate(Byte *testBytes);
typedef struct _CFileInStream
{
ISzInStream InStream;
void *File;
} CFileInStream;
typedef struct
/* Set by LZMA_openArchive, except blockXXX which is handled by LZMA_read() */
typedef struct _LZMAarchive
{
CArchiveDatabaseEx db;
CFileInStream stream;
struct _LZMAentry *firstEntry;
struct _LZMAentry *firstEntry; /* Used for cleanup on shutdown */
struct _LZMAentry *lastEntry;
CArchiveDatabaseEx db; /* For 7z: Database */
CFileInStream stream; /* For 7z: Input file incl. read and seek callbacks */
unsigned char *block; /* Currently cached block */
size_t blockSize; /* Size of current block */
PHYSFS_uint32 blockIndex; /* Index of current block */
} LZMAarchive;
/* Set by LZMA_openRead(), except offset which is set by LZMA_read() */
typedef struct _LZMAentry
{
LZMAarchive *archive;
struct _LZMAentry *next;
struct _LZMAentry *next; /* Used for cleanup on shutdown */
struct _LZMAentry *previous;
CFileItem *file;
CLzmaDecoderState state;
PHYSFS_uint32 index;
PHYSFS_uint32 folderIndex;
PHYSFS_uint32 bufferedBytes;
PHYSFS_uint32 compressedSize;
PHYSFS_uint32 position;
PHYSFS_uint32 compressedPosition;
PHYSFS_uint8 buffer[LZMA_READBUFSIZE];
PHYSFS_uint8 *bufferPos;
LZMAarchive *archive; /* Link to corresponding archive */
CFileItem *file; /* For 7z: File info, eg. name, size */
PHYSFS_uint32 index; /* Index inside the archive */
size_t offset; /* Offset inside archive block */
PHYSFS_uint32 position; /* Current "virtual" position in file */
} LZMAentry;
/* Memory management implementations to be passed to 7z */
static void *SzAllocPhysicsFS(size_t size)
{
return ((size == 0) ? NULL : allocator.Malloc(size));
@ -74,19 +91,40 @@ static void SzFreePhysicsFS(void *address)
} /* SzFreePhysicsFS */
SZ_RESULT SzFileReadImp(void *object, void *buffer,
size_t size, size_t *processedSize)
/* Filesystem implementations to be passed to 7z */
#ifdef _LZMA_IN_CB
#define kBufferSize (1 << 12)
static Byte g_Buffer[kBufferSize]; /* !!! FIXME: not thread safe! */
SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxReqSize,
size_t *processedSize)
{
CFileInStream *s = (CFileInStream *) object;
CFileInStream *s = (CFileInStream *)object;
size_t processedSizeLoc;
processedSizeLoc = __PHYSFS_platformRead(s->File, buffer, size, 1) * size;
if (processedSize != NULL)
if (maxReqSize > kBufferSize)
maxReqSize = kBufferSize;
processedSizeLoc = __PHYSFS_platformRead(s->File, g_Buffer, 1, maxReqSize);
*buffer = g_Buffer;
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
} /* SzFileReadImp */
#else
SZ_RESULT SzFileReadImp(void *object, void *buffer, size_t size,
size_t *processedSize)
{
CFileInStream *s = (CFileInStream *)object;
size_t processedSizeLoc = __PHYSFS_platformRead(s->File, buffer, 1, size);
if (processedSize != 0)
*processedSize = processedSizeLoc;
return SZ_OK;
} /* SzFileReadImp */
#endif
SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
{
@ -97,23 +135,25 @@ SZ_RESULT SzFileSeekImp(void *object, CFileSize pos)
} /* SzFileSeekImp */
LZMAentry *lzma_find_entry(LZMAarchive *archive, const char *name)
/*
* Find entry 'name' in 'archive' and report the 'index' back
*/
static int lzma_find_entry(LZMAarchive *archive, const char *name,
PHYSFS_uint32 *index)
{
/* !!! FIXME: don't malloc here */
LZMAentry *entry = (LZMAentry *) allocator.Malloc(sizeof (LZMAentry));
const PHYSFS_uint32 imax = archive->db.Database.NumFiles;
for (entry->index = 0; entry->index < imax; entry->index++)
for (*index = 0; *index < archive->db.Database.NumFiles; (*index)++)
{
entry->file = archive->db.Database.Files + entry->index;
if (strcmp(entry->file->Name, name) == 0)
return entry;
if (strcmp(archive->db.Database.Files[*index].Name, name) == 0)
return 1;
} /* for */
allocator.Free(entry);
BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
BAIL_MACRO(ERR_NO_SUCH_FILE, 0);
} /* lzma_find_entry */
/*
* Report the first file index of a directory
*/
static PHYSFS_sint32 lzma_find_start_of_dir(LZMAarchive *archive,
const char *path,
int stop_on_first_find)
@ -208,58 +248,51 @@ static PHYSFS_sint64 LZMA_read(fvoid *opaque, void *outBuffer,
{
LZMAentry *entry = (LZMAentry *) opaque;
size_t wantBytes = objSize * objCount;
size_t decodedBytes = 0;
size_t totalDecodedBytes = 0;
size_t bufferBytes = 0;
size_t usedBufferedBytes = 0;
size_t availableBytes = entry->file->Size - entry->position;
PHYSFS_sint64 wantedSize = objSize*objCount;
PHYSFS_sint64 remainingSize = entry->file->Size - entry->position;
BAIL_IF_MACRO(wantBytes == 0, NULL, 0); /* quick rejection. */
BAIL_IF_MACRO(wantedSize == 0, NULL, 0); /* quick rejection. */
BAIL_IF_MACRO(remainingSize == 0, ERR_PAST_EOF, 0);
if (availableBytes < wantBytes)
if (remainingSize < wantedSize)
{
wantBytes = availableBytes - (availableBytes % objSize);
objCount = wantBytes / objSize;
wantedSize = remainingSize - (remainingSize % objSize);
objCount = (PHYSFS_uint32) (remainingSize / objSize);
BAIL_IF_MACRO(objCount == 0, ERR_PAST_EOF, 0); /* quick rejection. */
__PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */
__PHYSFS_setError(ERR_PAST_EOF); /* this is always true here. */
} /* if */
while (totalDecodedBytes < wantBytes)
{
if (entry->bufferedBytes == 0)
{
bufferBytes = entry->compressedSize - entry->compressedPosition;
if (bufferBytes > 0)
{
if (bufferBytes > LZMA_READBUFSIZE)
bufferBytes = LZMA_READBUFSIZE;
size_t fileSize;
ISzAlloc allocImp;
ISzAlloc allocTempImp;
entry->bufferedBytes =
__PHYSFS_platformRead(entry->archive->stream.File,
entry->buffer, 1, bufferBytes);
/* Prepare callbacks for 7z */
allocImp.Alloc = SzAllocPhysicsFS;
allocImp.Free = SzFreePhysicsFS;
if (entry->bufferedBytes <= 0)
break;
allocTempImp.Alloc = SzAllocPhysicsFS;
allocTempImp.Free = SzFreePhysicsFS;
entry->compressedPosition += entry->bufferedBytes;
entry->bufferPos = entry->buffer;
} /* if */
} /* if */
if (lzma_err(SzExtract(
&entry->archive->stream.InStream, /* compressed data */
&entry->archive->db,
entry->index,
&entry->archive->blockIndex, /* Index of currently cached block, may be changed by SzExtract */
&entry->archive->block, /* Cache of current decompressed block, may be allocated/freed by SzExtract */
&entry->archive->blockSize, /* Size of current cache, may be changed by SzExtract */
&entry->offset, /* Offset of this file inside the cache block, set by SzExtract */
&fileSize, /* Size of this file */
&allocImp,
&allocTempImp
)) != SZ_OK)
return -1;
/* bufferedBytes == 0 if we finished decompressing */
lzma_err(LzmaDecode(&entry->state,
entry->bufferPos, entry->bufferedBytes, &usedBufferedBytes,
outBuffer, wantBytes, &decodedBytes,
(entry->bufferedBytes == 0)));
entry->bufferedBytes -= usedBufferedBytes;
entry->bufferPos += usedBufferedBytes;
totalDecodedBytes += decodedBytes;
entry->position += decodedBytes;
} /* while */
return(decodedBytes);
/* Copy wanted bytes over from cache to outBuffer */
strncpy(outBuffer,
(void*)(entry->archive->block + entry->offset + entry->position),
wantedSize);
entry->position += wantedSize;
return objCount;
} /* LZMA_read */
@ -273,7 +306,7 @@ static PHYSFS_sint64 LZMA_write(fvoid *opaque, const void *buf,
static int LZMA_eof(fvoid *opaque)
{
LZMAentry *entry = (LZMAentry *) opaque;
return (entry->compressedPosition >= entry->compressedSize);
return (entry->position >= entry->file->Size);
} /* LZMA_eof */
@ -287,38 +320,19 @@ static PHYSFS_sint64 LZMA_tell(fvoid *opaque)
static int LZMA_seek(fvoid *opaque, PHYSFS_uint64 offset)
{
LZMAentry *entry = (LZMAentry *) opaque;
PHYSFS_uint8 buf[512];
PHYSFS_uint32 maxread;
BAIL_IF_MACRO(offset < 0, ERR_SEEK_OUT_OF_RANGE, 0);
BAIL_IF_MACRO(offset > entry->file->Size, ERR_PAST_EOF, 0);
if (offset < entry->position)
{
__PHYSFS_platformSeek(entry->archive->stream.File,
SzArDbGetFolderStreamPos(&entry->archive->db,
entry->folderIndex, 0));
entry->position = 0;
entry->compressedPosition = 0;
LzmaDecoderInit(&entry->state);
} /* if */
while (offset != entry->position)
{
maxread = (PHYSFS_uint32) (offset - entry->position);
if (maxread > sizeof (buf))
maxread = sizeof (buf);
if (!LZMA_read(entry, buf, maxread, 1))
return(0);
} /* while */
return(1);
entry->position = offset;
return 1;
} /* LZMA_seek */
static PHYSFS_sint64 LZMA_fileLength(fvoid *opaque)
{
return ((LZMAentry *) opaque)->file->Size;
LZMAentry *entry = (LZMAentry *) opaque;
return (entry->file->Size);
} /* LZMA_fileLength */
@ -338,13 +352,9 @@ static int LZMA_fileClose(fvoid *opaque)
if (entry->next != NULL)
entry->next->previous = entry->previous;
/* Free */
if (entry->state.Probs != NULL)
allocator.Free(entry->state.Probs);
if (entry->state.Dictionary != NULL)
allocator.Free(entry->state.Dictionary);
allocator.Free(entry);
entry = NULL;
return(1);
} /* LZMA_fileClose */
@ -363,7 +373,9 @@ static int LZMA_isArchive(const char *filename, int forWriting)
if (__PHYSFS_platformRead(in, sig, k7zSignatureSize, 1) != 1)
BAIL_MACRO(NULL, 0);
/* Test whether sig is the 7z signature */
res = TestSignatureCandidate(sig);
__PHYSFS_platformClose(in);
return res;
@ -377,20 +389,25 @@ static void *LZMA_openArchive(const char *name, int forWriting)
ISzAlloc allocTempImp;
BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, NULL);
BAIL_IF_MACRO(!LZMA_isArchive(name, forWriting), ERR_UNSUPPORTED_ARCHIVE, 0);
archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
BAIL_IF_MACRO(archive == NULL, ERR_OUT_OF_MEMORY, NULL);
archive->block = NULL;
archive->firstEntry = NULL;
archive->lastEntry = NULL;
archive = (LZMAarchive *) allocator.Malloc(sizeof(LZMAarchive));
if ((archive->stream.File = __PHYSFS_platformOpenRead(name)) == NULL)
{
allocator.Free(archive);
return NULL;
} /* if */
/* Prepare structs for 7z */
archive->stream.InStream.Read = SzFileReadImp;
archive->stream.InStream.Seek = SzFileSeekImp;
archive->firstEntry = NULL;
archive->lastEntry = NULL;
allocImp.Alloc = SzAllocPhysicsFS;
allocImp.Free = SzFreePhysicsFS;
@ -402,7 +419,6 @@ static void *LZMA_openArchive(const char *name, int forWriting)
if (lzma_err(SzArchiveOpen(&archive->stream.InStream, &archive->db,
&allocImp, &allocTempImp)) != SZ_OK)
{
SzArDbExFree(&archive->db, allocImp.Free);
__PHYSFS_platformClose(archive->stream.File);
allocator.Free(archive);
return NULL;
@ -477,27 +493,29 @@ static void LZMA_enumerateFiles(dvoid *opaque, const char *dname,
static int LZMA_exists(dvoid *opaque, const char *name)
{
return(lzma_find_entry((LZMAarchive *) opaque, name) != NULL);
LZMAarchive *archive = (LZMAarchive *) opaque;
PHYSFS_uint32 index = 0;
return(lzma_find_entry(archive, name, &index));
} /* LZMA_exists */
static PHYSFS_sint64 LZMA_getLastModTime(dvoid *opaque,
const char *name,
int *fileExists)
const char *name,
int *fileExists)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1); /* !!! FIXME: Implement this! */
/* !!! FIXME: Lacking support in the LZMA C SDK. */
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* LZMA_getLastModTime */
static int LZMA_isDirectory(dvoid *opaque, const char *name, int *fileExists)
{
LZMAentry *entry = lzma_find_entry((LZMAarchive *) opaque, name);
int isDir = entry->file->IsDirectory;
LZMAarchive *archive = (LZMAarchive *) opaque;
PHYSFS_uint32 index = 0;
*fileExists = (entry != NULL);
allocator.Free(entry);
*fileExists = lzma_find_entry(archive, name, &index);
return(isDir);
return(archive->db.Database.Files[index].IsDirectory);
} /* LZMA_isDirectory */
@ -510,14 +528,19 @@ static int LZMA_isSymLink(dvoid *opaque, const char *name, int *fileExists)
static fvoid *LZMA_openRead(dvoid *opaque, const char *name, int *fileExists)
{
LZMAarchive *archive = (LZMAarchive *) opaque;
LZMAentry *entry = lzma_find_entry(archive, name);
BAIL_IF_MACRO(entry == NULL, ERR_NO_SUCH_FILE, NULL);
PHYSFS_uint32 index = 0;
LZMAentry *entry;
*fileExists = lzma_find_entry(archive, name, &index);
BAIL_IF_MACRO(!*fileExists, ERR_NO_SUCH_FILE, NULL);
entry = (LZMAentry *) allocator.Malloc(sizeof (LZMAentry));
BAIL_IF_MACRO(entry == NULL, ERR_OUT_OF_MEMORY, NULL);
entry->index = index;
entry->archive = archive;
entry->compressedPosition = 0;
entry->file = archive->db.Database.Files + entry->index;
entry->offset = 0; /* Offset will be set by LZMA_read() */
entry->position = 0;
entry->folderIndex =
entry->archive->db.FileIndexToFolderIndexMap[entry->index];
entry->next = NULL;
entry->previous = entry->archive->lastEntry;
@ -527,49 +550,7 @@ static fvoid *LZMA_openRead(dvoid *opaque, const char *name, int *fileExists)
if (entry->archive->firstEntry == NULL)
entry->archive->firstEntry = entry;
entry->bufferPos = entry->buffer;
entry->bufferedBytes = 0;
entry->compressedSize = SzArDbGetFolderFullPackSize(&entry->archive->db,
entry->folderIndex);
__PHYSFS_platformSeek(entry->archive->stream.File,
SzArDbGetFolderStreamPos(&entry->archive->db,
entry->folderIndex, 0));
/* Create one CLzmaDecoderState per entry */
CFolder *folder = entry->archive->db.Database.Folders + entry->folderIndex;
CCoderInfo *coder = folder->Coders;
if ((folder->NumPackStreams != 1) || (folder->NumCoders != 1))
{
LZMA_fileClose(entry);
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* if */
if (lzma_err(LzmaDecodeProperties(&entry->state.Properties, coder->Properties.Items, coder->Properties.Capacity)) != LZMA_RESULT_OK)
return NULL;
entry->state.Probs = (CProb *) allocator.Malloc(LzmaGetNumProbs(&entry->state.Properties) * sizeof(CProb));
if (entry->state.Probs == NULL)
{
LZMA_fileClose(entry);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
if (entry->state.Properties.DictionarySize == 0)
entry->state.Dictionary = NULL;
else
{
entry->state.Dictionary = (unsigned char *) allocator.Malloc(entry->state.Properties.DictionarySize);
if (entry->state.Dictionary == NULL)
{
LZMA_fileClose(entry);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
} /* else */
LzmaDecoderInit(&entry->state);
return(entry);
return(entry);
} /* LZMA_openRead */
@ -587,17 +568,22 @@ static fvoid *LZMA_openAppend(dvoid *opaque, const char *filename)
static void LZMA_dirClose(dvoid *opaque)
{
LZMAarchive *archive = (LZMAarchive *) opaque;
LZMAentry *entry = archive->firstEntry;
LZMAarchive *archive = (LZMAarchive *) opaque;
LZMAentry *entry = archive->firstEntry;
LZMAentry *tmpEntry = entry;
while (entry != NULL)
{
entry = entry->next;
LZMA_fileClose(entry->previous);
} /* while */
while (entry != NULL)
{
tmpEntry = entry->next;
LZMA_fileClose(entry);
entry = tmpEntry;
} /* while */
SzArDbExFree(&archive->db, SzFreePhysicsFS);
__PHYSFS_platformClose(archive->stream.File);
SzArDbExFree(&archive->db, SzFreePhysicsFS);
__PHYSFS_platformClose(archive->stream.File);
/* Free the cache which might have been allocated by LZMA_read() */
allocator.Free(archive->block);
allocator.Free(archive);
} /* LZMA_dirClose */

View File

@ -18,4 +18,3 @@ void *SzAllocTemp(size_t size);
void SzFreeTemp(void *address);
#endif

View File

@ -1,7 +1,11 @@
/* 7zDecode.c */
#include "7zDecode.h"
#include "LzmaStateDecode.h" /* NOTE : Modified to use LzmaStateDecode(.c,.h) instead of LzmaDecode(.c,.h) and hardcoded _SZ_ONE_DIRECTORY behaviour */
#ifdef _SZ_ONE_DIRECTORY
#include "LzmaDecode.h"
#else
#include "../../Compress/LZMA_C/LzmaDecode.h"
#endif
CMethodID k_Copy = { { 0x0 }, 1 };
CMethodID k_LZMA = { { 0x3, 0x1, 0x1 }, 3 };
@ -15,14 +19,14 @@ typedef struct _CLzmaInCallbackImp
size_t Size;
} CLzmaInCallbackImp;
int LzmaReadImp(void *object, const unsigned char **buffer, size_t *size)
int LzmaReadImp(void *object, const unsigned char **buffer, SizeT *size)
{
CLzmaInCallbackImp *cb = (CLzmaInCallbackImp *)object;
size_t processedSize;
SZ_RESULT res;
*size = 0;
res = cb->InStream->Read((void *)cb->InStream, (void **)buffer, cb->Size, &processedSize);
*size = (size_t)processedSize;
*size = (SizeT)processedSize;
if (processedSize > cb->Size)
return (int)SZE_FAIL;
cb->Size -= processedSize;
@ -64,7 +68,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
for (i = 0; i < inSize;)
{
size_t j;
Byte *inBuffer;
void *inBuffer;
size_t bufferSize;
RINOK(inStream->Read((void *)inStream, (void **)&inBuffer, inSize - i, &bufferSize));
if (bufferSize == 0)
@ -73,7 +77,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
return SZE_FAIL;
*outSizeProcessed += bufferSize;
for (j = 0; j < bufferSize && i < inSize; j++, i++)
outBuffer[i] = inBuffer[j];
outBuffer[i] = ((Byte*)inBuffer)[j];
}
#else
for (i = 0; i < inSize; i++)
@ -88,12 +92,12 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
CLzmaInCallbackImp lzmaCallback;
#else
size_t inProcessed;
SizeT inProcessed;
#endif
CLzmaDecoderState state; /* it's about 24-80 bytes structure, if int is 32-bit */
int result;
size_t outSizeProcessedLoc;
SizeT outSizeProcessedLoc;
#ifdef _LZMA_IN_CB
lzmaCallback.Size = inSize;
@ -128,10 +132,9 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder,
#ifdef _LZMA_IN_CB
&lzmaCallback.InCallback,
#else
inBuffer, (size_t)inSize, &inProcessed,
inBuffer, (SizeT)inSize, &inProcessed,
#endif
outBuffer, (size_t)outSize, &outSizeProcessedLoc,
1); /* NOTE : Added by Dennis Schridde to make SzDecode be compatible with LzmaStateDecode(.c,.h) */
outBuffer, (SizeT)outSize, &outSizeProcessedLoc);
*outSizeProcessed = (size_t)outSizeProcessedLoc;
allocMain->Free(state.Probs);
#ifdef _LZMA_OUT_READ

View File

@ -26,7 +26,7 @@ void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
}
/*
CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
{
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
}
@ -44,18 +44,8 @@ CFileSize GetFilePackSize(int fileIndex) const
}
*/
SZ_RESULT MySzInAlloc(void **p, size_t size, void * (*allocFunc)(size_t size))
{
if (size == 0)
*p = 0;
else
{
*p = allocFunc(size);
RINOM(*p);
}
return SZ_OK;
}
#define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
{
@ -64,14 +54,14 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
UInt32 i;
UInt32 folderIndex = 0;
UInt32 indexInFolder = 0;
RINOK(MySzInAlloc((void **)&db->FolderStartPackStreamIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
for(i = 0; i < db->Database.NumFolders; i++)
{
db->FolderStartPackStreamIndex[i] = startPos;
startPos += db->Database.Folders[i].NumPackStreams;
}
RINOK(MySzInAlloc((void **)&db->PackStreamStartPositions, db->Database.NumPackStreams * sizeof(CFileSize), allocFunc));
MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
for(i = 0; i < db->Database.NumPackStreams; i++)
{
@ -79,8 +69,8 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
startPosSize += db->Database.PackSizes[i];
}
RINOK(MySzInAlloc((void **)&db->FolderStartFileIndex, db->Database.NumFolders * sizeof(UInt32), allocFunc));
RINOK(MySzInAlloc((void **)&db->FileIndexToFolderIndexMap, db->Database.NumFiles * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
for (i = 0; i < db->Database.NumFiles; i++)
{
@ -123,7 +113,7 @@ SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
{
return db->ArchiveInfo.DataStartPosition +
return db->ArchiveInfo.DataStartPosition +
db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
}
@ -190,7 +180,7 @@ SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
#ifdef _LZMA_IN_CB
while (size > 0)
{
Byte *inBuffer;
void *inBuffer; // Dennis Schridde: Make this compile with -Wall -Werror. Was Byte* before.
size_t processedSize;
RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
if (processedSize == 0 || processedSize > size)
@ -198,7 +188,7 @@ SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
size -= processedSize;
do
{
*data++ = *inBuffer++;
*data++ = *(Byte*)inBuffer++;
}
while (--processedSize != 0);
}
@ -332,9 +322,9 @@ SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
return SZ_OK;
}
SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
{
return SzReadNumber(sd, value);
SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
{
return SzReadNumber(sd, value);
}
SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
@ -385,7 +375,7 @@ SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allo
Byte b = 0;
Byte mask = 0;
size_t i;
RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
MY_ALLOC(Byte, *v, numItems, allocFunc);
for(i = 0; i < numItems; i++)
{
if (mask == 0)
@ -406,22 +396,22 @@ SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*all
RINOK(SzReadByte(sd, &allAreDefined));
if (allAreDefined == 0)
return SzReadBoolVector(sd, numItems, v, allocFunc);
RINOK(MySzInAlloc((void **)v, numItems * sizeof(Byte), allocFunc));
MY_ALLOC(Byte, *v, numItems, allocFunc);
for(i = 0; i < numItems; i++)
(*v)[i] = 1;
return SZ_OK;
}
SZ_RESULT SzReadHashDigests(
CSzData *sd,
CSzData *sd,
size_t numItems,
Byte **digestsDefined,
UInt32 **digests,
Byte **digestsDefined,
UInt32 **digests,
void * (*allocFunc)(size_t size))
{
size_t i;
RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
RINOK(MySzInAlloc((void **)digests, numItems * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, *digests, numItems, allocFunc);
for(i = 0; i < numItems; i++)
if ((*digestsDefined)[i])
{
@ -431,7 +421,7 @@ SZ_RESULT SzReadHashDigests(
}
SZ_RESULT SzReadPackInfo(
CSzData *sd,
CSzData *sd,
CFileSize *dataOffset,
UInt32 *numPackStreams,
CFileSize **packSizes,
@ -445,7 +435,7 @@ SZ_RESULT SzReadPackInfo(
RINOK(SzWaitAttribute(sd, k7zIdSize));
RINOK(MySzInAlloc((void **)packSizes, (size_t)*numPackStreams * sizeof(CFileSize), allocFunc));
MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
for(i = 0; i < *numPackStreams; i++)
{
@ -460,15 +450,15 @@ SZ_RESULT SzReadPackInfo(
break;
if (type == k7zIdCRC)
{
RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
continue;
}
RINOK(SzSkeepData(sd));
}
if (*packCRCsDefined == 0)
{
RINOK(MySzInAlloc((void **)packCRCsDefined, (size_t)*numPackStreams * sizeof(Byte), allocFunc));
RINOK(MySzInAlloc((void **)packCRCs, (size_t)*numPackStreams * sizeof(UInt32), allocFunc));
MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
for(i = 0; i < *numPackStreams; i++)
{
(*packCRCsDefined)[i] = 0;
@ -496,7 +486,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
RINOK(SzReadNumber32(sd, &numCoders));
folder->NumCoders = numCoders;
RINOK(MySzInAlloc((void **)&folder->Coders, (size_t)numCoders * sizeof(CCoderInfo), allocFunc));
MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
for (i = 0; i < numCoders; i++)
SzCoderInfoInit(folder->Coders + i);
@ -553,19 +543,19 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
folder->NumBindPairs = numBindPairs;
RINOK(MySzInAlloc((void **)&folder->BindPairs, (size_t)numBindPairs * sizeof(CBindPair), allocFunc));
MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
for (i = 0; i < numBindPairs; i++)
{
CBindPair *bindPair = folder->BindPairs + i;;
RINOK(SzReadNumber32(sd, &bindPair->InIndex));
RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
}
numPackedStreams = numInStreams - (UInt32)numBindPairs;
folder->NumPackStreams = numPackedStreams;
RINOK(MySzInAlloc((void **)&folder->PackStreams, (size_t)numPackedStreams * sizeof(UInt32), allocFunc));
MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
if (numPackedStreams == 1)
{
@ -587,7 +577,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
}
SZ_RESULT SzReadUnPackInfo(
CSzData *sd,
CSzData *sd,
UInt32 *numFolders,
CFolder **folders, /* for allocFunc */
void * (*allocFunc)(size_t size),
@ -599,8 +589,7 @@ SZ_RESULT SzReadUnPackInfo(
{
RINOK(SzReadSwitch(sd));
RINOK(MySzInAlloc((void **)folders, (size_t)*numFolders * sizeof(CFolder), allocFunc));
MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
for(i = 0; i < *numFolders; i++)
SzFolderInit((*folders) + i);
@ -619,7 +608,7 @@ SZ_RESULT SzReadUnPackInfo(
CFolder *folder = (*folders) + i;
UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
RINOK(MySzInAlloc((void **)&folder->UnPackSizes, (size_t)numOutStreams * sizeof(CFileSize), allocFunc));
MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
for(j = 0; j < numOutStreams; j++)
{
@ -638,7 +627,7 @@ SZ_RESULT SzReadUnPackInfo(
SZ_RESULT res;
Byte *crcsDefined = 0;
UInt32 *crcs = 0;
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
if (res == SZ_OK)
{
for(i = 0; i < *numFolders; i++)
@ -658,7 +647,7 @@ SZ_RESULT SzReadUnPackInfo(
}
SZ_RESULT SzReadSubStreamsInfo(
CSzData *sd,
CSzData *sd,
UInt32 numFolders,
CFolder *folders,
UInt32 *numUnPackStreams,
@ -754,14 +743,14 @@ SZ_RESULT SzReadSubStreamsInfo(
numDigests += numSubstreams;
}
si = 0;
while(1)
{
if (type == k7zIdCRC)
{
int digestIndex = 0;
Byte *digestsDefined2 = 0;
Byte *digestsDefined2 = 0;
UInt32 *digests2 = 0;
SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
if (res == SZ_OK)
@ -804,7 +793,7 @@ SZ_RESULT SzReadSubStreamsInfo(
SZ_RESULT SzReadStreamsInfo(
CSzData *sd,
CSzData *sd,
CFileSize *dataOffset,
CArchiveDatabase *db,
UInt32 *numUnPackStreams,
@ -826,7 +815,7 @@ SZ_RESULT SzReadStreamsInfo(
return SZ_OK;
case k7zIdPackInfo:
{
RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
&db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
break;
}
@ -837,7 +826,7 @@ SZ_RESULT SzReadStreamsInfo(
}
case k7zIdSubStreamsInfo:
{
RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
break;
}
@ -849,7 +838,7 @@ SZ_RESULT SzReadStreamsInfo(
Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
void * (*allocFunc)(size_t size))
{
UInt32 i;
@ -887,7 +876,7 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
len += numAdds;
}
RINOK(MySzInAlloc((void **)&file->Name, (size_t)len * sizeof(char), allocFunc));
MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
len = 0;
while(2 <= sd->Size)
@ -926,14 +915,14 @@ SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
}
SZ_RESULT SzReadHeader2(
CSzData *sd,
CSzData *sd,
CArchiveDatabaseEx *db, /* allocMain */
CFileSize **unPackSizes, /* allocTemp */
Byte **digestsDefined, /* allocTemp */
UInt32 **digests, /* allocTemp */
Byte **emptyStreamVector, /* allocTemp */
Byte **emptyFileVector, /* allocTemp */
ISzAlloc *allocMain,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
UInt64 type;
@ -950,13 +939,13 @@ SZ_RESULT SzReadHeader2(
RINOK(SzReadArchiveProperties(sd));
RINOK(SzReadID(sd, &type));
}
if (type == k7zIdMainStreamsInfo)
{
RINOK(SzReadStreamsInfo(sd,
&db->ArchiveInfo.DataStartPosition,
&db->Database,
&db->Database,
&numUnPackStreams,
unPackSizes,
digestsDefined,
@ -969,11 +958,11 @@ SZ_RESULT SzReadHeader2(
return SZ_OK;
if (type != k7zIdFilesInfo)
return SZE_ARCHIVE_ERROR;
RINOK(SzReadNumber32(sd, &numFiles));
db->Database.NumFiles = numFiles;
RINOK(MySzInAlloc((void **)&files, (size_t)numFiles * sizeof(CFileItem), allocMain->Alloc));
MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
db->Database.Files = files;
for(i = 0; i < numFiles; i++)
@ -1057,9 +1046,9 @@ SZ_RESULT SzReadHeader2(
}
SZ_RESULT SzReadHeader(
CSzData *sd,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
CSzData *sd,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
CFileSize *unPackSizes = 0;
@ -1067,7 +1056,7 @@ SZ_RESULT SzReadHeader(
UInt32 *digests = 0;
Byte *emptyStreamVector = 0;
Byte *emptyFileVector = 0;
SZ_RESULT res = SzReadHeader2(sd, db,
SZ_RESULT res = SzReadHeader2(sd, db,
&unPackSizes, &digestsDefined, &digests,
&emptyStreamVector, &emptyFileVector,
allocMain, allocTemp);
@ -1077,13 +1066,13 @@ SZ_RESULT SzReadHeader(
allocTemp->Free(emptyStreamVector);
allocTemp->Free(emptyFileVector);
return res;
}
}
SZ_RESULT SzReadAndDecodePackedStreams2(
ISzInStream *inStream,
ISzInStream *inStream,
CSzData *sd,
CSzByteBuffer *outBuffer,
CFileSize baseOffset,
CFileSize baseOffset,
CArchiveDatabase *db,
CFileSize **unPackSizes,
Byte **digestsDefined,
@ -1106,35 +1095,35 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
SZ_RESULT res;
RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
&numUnPackStreams, unPackSizes, digestsDefined, digests,
&numUnPackStreams, unPackSizes, digestsDefined, digests,
allocTemp->Alloc, allocTemp));
dataStartPos += baseOffset;
if (db->NumFolders != 1)
return SZE_ARCHIVE_ERROR;
folder = db->Folders;
unPackSize = SzFolderGetUnPackSize(folder);
RINOK(inStream->Seek(inStream, dataStartPos));
#ifndef _LZMA_IN_CB
for (i = 0; i < db->NumPackStreams; i++)
packSize += db->PackSizes[i];
RINOK(MySzInAlloc((void **)inBuffer, (size_t)packSize, allocTemp->Alloc));
MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
#endif
if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
return SZE_OUTOFMEMORY;
res = SzDecode(db->PackSizes, folder,
res = SzDecode(db->PackSizes, folder,
#ifdef _LZMA_IN_CB
inStream,
#else
*inBuffer,
*inBuffer,
#endif
outBuffer->Items, (size_t)unPackSize,
&outRealSize, allocTemp);
@ -1148,10 +1137,10 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
}
SZ_RESULT SzReadAndDecodePackedStreams(
ISzInStream *inStream,
ISzInStream *inStream,
CSzData *sd,
CSzByteBuffer *outBuffer,
CFileSize baseOffset,
CFileSize baseOffset,
ISzAlloc *allocTemp)
{
CArchiveDatabase db;
@ -1163,8 +1152,8 @@ SZ_RESULT SzReadAndDecodePackedStreams(
#endif
SZ_RESULT res;
SzArchiveDatabaseInit(&db);
res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
&db, &unPackSizes, &digestsDefined, &digests,
res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
&db, &unPackSizes, &digestsDefined, &digests,
#ifndef _LZMA_IN_CB
&inBuffer,
#endif
@ -1180,9 +1169,9 @@ SZ_RESULT SzReadAndDecodePackedStreams(
}
SZ_RESULT SzArchiveOpen2(
ISzInStream *inStream,
ISzInStream *inStream,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
Byte signature[k7zSignatureSize];
@ -1223,7 +1212,7 @@ SZ_RESULT SzArchiveOpen2(
pos = k7zStartHeaderSize;
db->ArchiveInfo.StartPositionAfterHeader = pos;
if (CrcGetDigest(&crc) != crcFromArchive)
return SZE_ARCHIVE_ERROR;
@ -1260,8 +1249,8 @@ SZ_RESULT SzArchiveOpen2(
}
{
CSzByteBuffer outBuffer;
res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
db->ArchiveInfo.StartPositionAfterHeader,
res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
db->ArchiveInfo.StartPositionAfterHeader,
allocTemp);
if (res != SZ_OK)
{
@ -1280,9 +1269,9 @@ SZ_RESULT SzArchiveOpen2(
}
SZ_RESULT SzArchiveOpen(
ISzInStream *inStream,
ISzInStream *inStream,
CArchiveDatabaseEx *db,
ISzAlloc *allocMain,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);

View File

@ -3,32 +3,38 @@
#ifndef __COMMON_TYPES_H
#define __COMMON_TYPES_H
#ifndef UInt32
#ifndef _7ZIP_BYTE_DEFINED
#define _7ZIP_BYTE_DEFINED
typedef unsigned char Byte;
#endif
#ifndef _7ZIP_UINT16_DEFINED
#define _7ZIP_UINT16_DEFINED
typedef unsigned short UInt16;
#endif
#ifndef _7ZIP_UINT32_DEFINED
#define _7ZIP_UINT32_DEFINED
#ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long
typedef unsigned long UInt32;
#else
#define UInt32 unsigned int
#endif
#endif
#ifndef Byte
#define Byte unsigned char
#endif
#ifndef UInt16
#define UInt16 unsigned short
typedef unsigned int UInt32;
#endif
#endif
/* #define _SZ_NO_INT_64 */
/* define it your compiler doesn't support long long int */
#ifndef _7ZIP_UINT64_DEFINED
#define _7ZIP_UINT64_DEFINED
#ifdef _SZ_NO_INT_64
#define UInt64 unsigned long
typedef unsigned long UInt64;
#else
#ifdef _MSC_VER
#define UInt64 unsigned __int64
typedef unsigned __int64 UInt64;
#else
#define UInt64 unsigned long long int
typedef unsigned long long int UInt64;
#endif
#endif
#endif
@ -38,9 +44,9 @@
#ifndef CFileSize
#ifdef _SZ_FILE_SIZE_64
#define CFileSize UInt64
typedef UInt64 CFileSize;
#else
#define CFileSize UInt32
typedef UInt32 CFileSize;
#endif
#endif

View File

@ -1,18 +1,10 @@
(These are the licensing details for this directory, taken from lzma.txt in
the original source distribution. The basic gist is you can do what you want
with this code, including sell it in a closed-source app...changes to LZMA
itself must be released as source code, which in the case of PhysicsFS, you
can just point people to our source code repository unless you make further
changes yourself. --ryan.)
LZMA SDK 4.27
LZMA SDK 4.43
-------------
LZMA SDK 4.27 Copyright (C) 1999-2005 Igor Pavlov
LZMA SDK Copyright (C) 1999-2006 Igor Pavlov
LZMA SDK provides developers with documentation, source code,
and sample code necessary to write software that uses LZMA compression.
LZMA SDK provides the documentation, samples, header files, libraries,
and tools you need to develop applications that use LZMA compression.
LZMA is default and general compression method of 7z format
in 7-Zip compression program (www.7-zip.org). LZMA provides high
@ -28,15 +20,24 @@ decompressing.
LICENSE
-------
LZMA SDK is licensed under two licenses:
LZMA SDK is available under any of the following licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
4) Proprietary license
It means that you can select one of these two licenses and
follow rules of that license.
It means that you can select one of these four options and follow rules of that license.
1,2) GNU LGPL and CPL licenses are pretty similar and both these
licenses are classified as
- "Free software licenses" at http://www.gnu.org/
- "OSI-approved" at http://www.opensource.org/
3) SPECIAL EXCEPTION
SPECIAL EXCEPTION
Igor Pavlov, as the author of this code, expressly permits you
to statically or dynamically link your code (or bind by name)
to the files from LZMA SDK without subjecting your linked
@ -44,7 +45,6 @@ code to the terms of the CPL or GNU LGPL.
Any modifications or additions to files from LZMA SDK, however,
are subject to the GNU LGPL or CPL terms.
SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
while you keep LZMA SDK code unmodified.
@ -58,17 +58,13 @@ of LZMA SDK as update for previous versions.
SPECIAL EXCEPTION #3: Igor Pavlov, as the author of this code, expressly permits
you to use code of examples (LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp) as
public domain code.
GNU LGPL and CPL licenses are pretty similar and both these
licenses are classified as
1) "Free software licenses" at http://www.gnu.org/
2) "OSI-approved" at http://www.opensource.org/
you to use code of the following files:
BranchTypes.h, LzmaTypes.h, LzmaTest.c, LzmaStateTest.c, LzmaAlone.cpp,
LzmaAlone.cs, LzmaAlone.java
as public domain code.
4) Proprietary license
LZMA SDK also can be available under a proprietary license which
can include:
@ -88,10 +84,4 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
You should have received a copy of the Common Public License
along with this library.
---
http://www.7-zip.org
http://www.7-zip.org/support.html
k

View File

@ -1,521 +0,0 @@
/*
LzmaStateDecode.c
LZMA Decoder (State version)
LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this Code, expressly permits you to
statically or dynamically link your Code (or bind by name) to the
interfaces of this file without subjecting your linked Code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#include "LzmaStateDecode.h"
#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_INIT Code = 0; Range = 0xFFFFFFFF; \
{ int i; for(i = 0; i < 5; i++) { Code = (Code << 8) | RC_READ_BYTE; }}
#define RC_NORMALIZE if (Range < kTopValue) { 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 RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \
{ UpdateBit0(p); mi <<= 1; A0; } else \
{ UpdateBit1(p); mi = (mi + mi) + 1; A1; }
#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;)
#define RangeDecoderBitTreeDecode(probs, numLevels, res) \
{ int i = numLevels; res = 1; \
do { CProb *p = probs + res; RC_GET_BIT(p, res) } while(--i != 0); \
res -= (1 << numLevels); }
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG
#endif
/* kRequiredInBufferSize = number of required input bytes for worst case:
longest match with longest distance.
kLzmaInBufferSize must be larger than kRequiredInBufferSize
23 bits = 2 (match select) + 10 (len) + 6 (distance) + 4(align) + 1 (RC_NORMALIZE)
*/
#define kRequiredInBufferSize ((23 * (kNumBitModelTotalBits - kNumMoveBits + 1) + 26 + 9) / 8)
#define kLzmaStreamWasFinishedId (-1)
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size)
{
unsigned char prop0;
if (size < LZMA_PROPERTIES_SIZE)
return LZMA_RESULT_DATA_ERROR;
prop0 = propsData[0];
if (prop0 >= (9 * 5 * 5))
return LZMA_RESULT_DATA_ERROR;
{
for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5));
for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9);
propsRes->lc = prop0;
/*
unsigned char remainder = (unsigned char)(prop0 / 9);
propsRes->lc = prop0 % 9;
propsRes->pb = remainder / 5;
propsRes->lp = remainder % 5;
*/
}
{
int i;
propsRes->DictionarySize = 0;
for (i = 0; i < 4; i++)
propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8);
if (propsRes->DictionarySize == 0)
propsRes->DictionarySize = 1;
return LZMA_RESULT_OK;
}
}
int LzmaDecode(
CLzmaDecoderState *vs,
const unsigned char *inStream, size_t inSize, size_t *inSizeProcessed,
unsigned char *outStream, size_t outSize, size_t *outSizeProcessed,
int finishDecoding)
{
UInt32 Range = vs->Range;
UInt32 Code = vs->Code;
unsigned char *Buffer = vs->Buffer;
int BufferSize = vs->BufferSize; /* don't change it to unsigned int */
CProb *p = vs->Probs;
int state = vs->State;
unsigned char previousByte;
UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3];
size_t nowPos = 0;
UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1;
UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1;
int lc = vs->Properties.lc;
int len = vs->RemainLen;
UInt32 globalPos = vs->GlobalPos;
UInt32 distanceLimit = vs->DistanceLimit;
unsigned char *dictionary = vs->Dictionary;
UInt32 dictionarySize = vs->Properties.DictionarySize;
UInt32 dictionaryPos = vs->DictionaryPos;
unsigned char tempDictionary[4];
(*inSizeProcessed) = 0;
(*outSizeProcessed) = 0;
if (len == kLzmaStreamWasFinishedId)
return LZMA_RESULT_OK;
if (dictionarySize == 0)
{
dictionary = tempDictionary;
dictionarySize = 1;
tempDictionary[0] = vs->TempDictionary[0];
}
if (len == kLzmaNeedInitId)
{
while (inSize > 0 && BufferSize < kLzmaInBufferSize)
{
Buffer[BufferSize++] = *inStream++;
(*inSizeProcessed)++;
inSize--;
}
if (BufferSize < 5)
{
vs->BufferSize = BufferSize;
return finishDecoding ? LZMA_RESULT_DATA_ERROR : LZMA_RESULT_OK;
}
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp));
UInt32 i;
for (i = 0; i < numProbs; i++)
p[i] = kBitModelTotal >> 1;
rep0 = rep1 = rep2 = rep3 = 1;
state = 0;
globalPos = 0;
distanceLimit = 0;
dictionaryPos = 0;
dictionary[dictionarySize - 1] = 0;
RC_INIT;
}
len = 0;
}
while(len != 0 && nowPos < outSize)
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos];
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
}
if (dictionaryPos == 0)
previousByte = dictionary[dictionarySize - 1];
else
previousByte = dictionary[dictionaryPos - 1];
while(1)
{
int bufferPos = (int)(Buffer - vs->Buffer);
if (BufferSize - bufferPos < kRequiredInBufferSize)
{
int i;
BufferSize -= bufferPos;
if (BufferSize < 0)
return LZMA_RESULT_DATA_ERROR;
for (i = 0; i < BufferSize; i++)
vs->Buffer[i] = Buffer[i];
Buffer = vs->Buffer;
while (inSize > 0 && BufferSize < kLzmaInBufferSize)
{
Buffer[BufferSize++] = *inStream++;
(*inSizeProcessed)++;
inSize--;
}
if (BufferSize < kRequiredInBufferSize && !finishDecoding)
break;
}
if (nowPos >= outSize)
break;
{
CProb *prob;
UInt32 bound;
int posState = (int)((nowPos + globalPos) & posStateMask);
prob = p + IsMatch + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
int symbol = 1;
UpdateBit0(prob)
prob = p + Literal + (LZMA_LIT_SIZE *
((((nowPos + globalPos)& literalPosMask) << lc) + (previousByte >> (8 - lc))));
if (state >= kNumLitStates)
{
int matchByte;
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
matchByte = dictionary[pos];
do
{
int bit;
CProb *probLit;
matchByte <<= 1;
bit = (matchByte & 0x100);
probLit = prob + 0x100 + bit + symbol;
RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break)
}
while (symbol < 0x100);
}
while (symbol < 0x100)
{
CProb *probLit = prob + symbol;
RC_GET_BIT(probLit, symbol)
}
previousByte = (unsigned char)symbol;
outStream[nowPos++] = previousByte;
if (distanceLimit < dictionarySize)
distanceLimit++;
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
if (state < 4) state = 0;
else if (state < 10) state -= 3;
else state -= 6;
}
else
{
UpdateBit1(prob);
prob = p + IsRep + state;
IfBit0(prob)
{
UpdateBit0(prob);
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
state = state < kNumLitStates ? 0 : 3;
prob = p + LenCoder;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG0 + state;
IfBit0(prob)
{
UpdateBit0(prob);
prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState;
IfBit0(prob)
{
UInt32 pos;
UpdateBit0(prob);
if (distanceLimit == 0)
return LZMA_RESULT_DATA_ERROR;
if (distanceLimit < dictionarySize)
distanceLimit++;
state = state < kNumLitStates ? 9 : 11;
pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
outStream[nowPos++] = previousByte;
continue;
}
else
{
UpdateBit1(prob);
}
}
else
{
UInt32 distance;
UpdateBit1(prob);
prob = p + IsRepG1 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep1;
}
else
{
UpdateBit1(prob);
prob = p + IsRepG2 + state;
IfBit0(prob)
{
UpdateBit0(prob);
distance = rep2;
}
else
{
UpdateBit1(prob);
distance = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = distance;
}
state = state < kNumLitStates ? 8 : 11;
prob = p + RepLenCoder;
}
{
int numBits, offset;
CProb *probLen = prob + LenChoice;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenLow + (posState << kLenNumLowBits);
offset = 0;
numBits = kLenNumLowBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenChoice2;
IfBit0(probLen)
{
UpdateBit0(probLen);
probLen = prob + LenMid + (posState << kLenNumMidBits);
offset = kLenNumLowSymbols;
numBits = kLenNumMidBits;
}
else
{
UpdateBit1(probLen);
probLen = prob + LenHigh;
offset = kLenNumLowSymbols + kLenNumMidSymbols;
numBits = kLenNumHighBits;
}
}
RangeDecoderBitTreeDecode(probLen, numBits, len);
len += offset;
}
if (state < 4)
{
int posSlot;
state += kNumLitStates;
prob = p + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
kNumPosSlotBits);
RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
int numDirectBits = ((posSlot >> 1) - 1);
rep0 = (2 | ((UInt32)posSlot & 1));
if (posSlot < kEndPosModelIndex)
{
rep0 <<= numDirectBits;
prob = p + SpecPos + rep0 - posSlot - 1;
}
else
{
numDirectBits -= kNumAlignBits;
do
{
RC_NORMALIZE
Range >>= 1;
rep0 <<= 1;
if (Code >= Range)
{
Code -= Range;
rep0 |= 1;
}
}
while (--numDirectBits != 0);
prob = p + Align;
rep0 <<= kNumAlignBits;
numDirectBits = kNumAlignBits;
}
{
int i = 1;
int mi = 1;
do
{
CProb *prob3 = prob + mi;
RC_GET_BIT2(prob3, mi, ; , rep0 |= i);
i <<= 1;
}
while(--numDirectBits != 0);
}
}
else
rep0 = posSlot;
if (++rep0 == (UInt32)(0))
{
/* it's for stream version */
len = kLzmaStreamWasFinishedId;
break;
}
}
len += kMatchMinLen;
if (rep0 > distanceLimit)
return LZMA_RESULT_DATA_ERROR;
if (dictionarySize - distanceLimit > (UInt32)len)
distanceLimit += len;
else
distanceLimit = dictionarySize;
do
{
UInt32 pos = dictionaryPos - rep0;
if (pos >= dictionarySize)
pos += dictionarySize;
previousByte = dictionary[pos];
dictionary[dictionaryPos] = previousByte;
if (++dictionaryPos == dictionarySize)
dictionaryPos = 0;
len--;
outStream[nowPos++] = previousByte;
}
while(len != 0 && nowPos < outSize);
}
}
}
RC_NORMALIZE;
BufferSize -= (int)(Buffer - vs->Buffer);
if (BufferSize < 0)
return LZMA_RESULT_DATA_ERROR;
{
int i;
for (i = 0; i < BufferSize; i++)
vs->Buffer[i] = Buffer[i];
}
vs->BufferSize = BufferSize;
vs->Range = Range;
vs->Code = Code;
vs->DictionaryPos = dictionaryPos;
vs->GlobalPos = (UInt32)(globalPos + nowPos);
vs->DistanceLimit = distanceLimit;
vs->Reps[0] = rep0;
vs->Reps[1] = rep1;
vs->Reps[2] = rep2;
vs->Reps[3] = rep3;
vs->State = state;
vs->RemainLen = len;
vs->TempDictionary[0] = tempDictionary[0];
(*outSizeProcessed) = nowPos;
return LZMA_RESULT_OK;
}

View File

@ -1,109 +0,0 @@
/*
LzmaStateDecode.h
LZMA Decoder interface (State version)
LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08)
http://www.7-zip.org/
LZMA SDK is licensed under two licenses:
1) GNU Lesser General Public License (GNU LGPL)
2) Common Public License (CPL)
It means that you can select one of these two licenses and
follow rules of that license.
SPECIAL EXCEPTION:
Igor Pavlov, as the author of this code, expressly permits you to
statically or dynamically link your code (or bind by name) to the
interfaces of this file without subjecting your linked code to the
terms of the CPL or GNU LGPL. Any modifications or additions
to this file, however, are subject to the LGPL or CPL terms.
*/
#ifndef __LZMASTATEDECODE_H
#define __LZMASTATEDECODE_H
/* #define _LZMA_PROB32 */
/* It can increase speed on some 32-bit CPUs,
but memory usage will be doubled in that case */
/* #define _LZMA_SYSTEM_SIZE_T */
/* Use system's size_t. You can use it to enable 64-bit sizes supporting*/
#ifndef UInt32
#ifdef _LZMA_UINT32_IS_ULONG
#define UInt32 unsigned long
#else
#define UInt32 unsigned int
#endif
#endif
/* NOTE : Hardcoded _LZMA_SYSTEM_SIZE_T behaviour by Dennis Schridde */
#include <stddef.h>
#ifdef _LZMA_PROB32
#define CProb UInt32
#else
#define CProb unsigned short
#endif
#define LZMA_RESULT_OK 0
#define LZMA_RESULT_DATA_ERROR 1
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
typedef struct _CLzmaProperties
{
int lc;
int lp;
int pb;
UInt32 DictionarySize;
}CLzmaProperties;
int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size);
#define LzmaGetNumProbs(lzmaProps) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((lzmaProps)->lc + (lzmaProps)->lp)))
#define kLzmaInBufferSize 64 /* don't change it. it must be larger than kRequiredInBufferSize */
#define kLzmaNeedInitId (-2)
typedef struct _CLzmaDecoderState
{
CLzmaProperties Properties;
CProb *Probs;
unsigned char *Dictionary;
unsigned char Buffer[kLzmaInBufferSize];
int BufferSize;
UInt32 Range;
UInt32 Code;
UInt32 DictionaryPos;
UInt32 GlobalPos;
UInt32 DistanceLimit;
UInt32 Reps[4];
int State;
int RemainLen; /* -2: decoder needs internal initialization
-1: stream was finished,
0: ok
> 0: need to write RemainLen bytes as match Reps[0],
*/
unsigned char TempDictionary[4]; /* it's required when DictionarySize = 0 */
} CLzmaDecoderState;
#define LzmaDecoderInit(vs) { (vs)->RemainLen = kLzmaNeedInitId; (vs)->BufferSize = 0; }
/* LzmaDecode: decoding from input stream to output stream.
If finishDecoding != 0, then there are no more bytes in input stream
after inStream[inSize - 1]. */
int LzmaDecode(CLzmaDecoderState *vs,
const unsigned char *inStream, size_t inSize, size_t *inSizeProcessed,
unsigned char *outStream, size_t outSize, size_t *outSizeProcessed,
int finishDecoding);
#endif

View File

@ -1,5 +1,6 @@
if BUILD_LZMA
noinst_LTLIBRARIES = liblzma.la
liblzma_la_CFLAGS = -D_LZMA_IN_CB -D_LZMA_PROB32 -D_LZMA_SYSTEM_SIZE_T -D_SZ_ONE_DIRECTORY
liblzma_la_SOURCES = 7zBuffer.c 7zCrc.c 7zHeader.c 7zIn.c 7zItem.c \
7zMethodID.c LzmaStateDecode.c 7zDecode.c
7zMethodID.c 7zExtract.c 7zDecode.c LzmaDecode.c
endif