Rewritten 7zip/lzma support (thanks, Dennis!)
This commit is contained in:
parent
25909afde4
commit
ab32c0313d
|
@ -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)
|
||||
|
|
1
CREDITS
1
CREDITS
|
@ -92,6 +92,7 @@ Bug fixes:
|
|||
Jörg Walter
|
||||
|
||||
Windows .rc file:
|
||||
7zip/lzma archiver,
|
||||
Dennis Schridde
|
||||
|
||||
Other stuff:
|
||||
|
|
330
archivers/lzma.c
330
archivers/lzma.c
|
@ -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. */
|
||||
} /* 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,7 +493,9 @@ 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 */
|
||||
|
||||
|
||||
|
@ -485,19 +503,19 @@ static PHYSFS_sint64 LZMA_getLastModTime(dvoid *opaque,
|
|||
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,48 +550,6 @@ 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);
|
||||
} /* LZMA_openRead */
|
||||
|
||||
|
@ -589,15 +570,20 @@ static void LZMA_dirClose(dvoid *opaque)
|
|||
{
|
||||
LZMAarchive *archive = (LZMAarchive *) opaque;
|
||||
LZMAentry *entry = archive->firstEntry;
|
||||
LZMAentry *tmpEntry = entry;
|
||||
|
||||
while (entry != NULL)
|
||||
{
|
||||
entry = entry->next;
|
||||
LZMA_fileClose(entry->previous);
|
||||
tmpEntry = entry->next;
|
||||
LZMA_fileClose(entry);
|
||||
entry = tmpEntry;
|
||||
} /* while */
|
||||
|
||||
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 */
|
||||
|
||||
|
|
|
@ -18,4 +18,3 @@ void *SzAllocTemp(size_t size);
|
|||
void SzFreeTemp(void *address);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
55
lzma/7zIn.c
55
lzma/7zIn.c
|
@ -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++)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,7 +396,7 @@ 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;
|
||||
|
@ -421,7 +411,7 @@ SZ_RESULT SzReadHashDigests(
|
|||
{
|
||||
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])
|
||||
{
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -467,8 +457,8 @@ SZ_RESULT SzReadPackInfo(
|
|||
}
|
||||
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,7 +543,7 @@ 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++)
|
||||
{
|
||||
|
@ -565,7 +555,7 @@ SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(
|
|||
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)
|
||||
{
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -973,7 +962,7 @@ SZ_RESULT SzReadHeader2(
|
|||
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++)
|
||||
|
@ -1122,7 +1111,7 @@ SZ_RESULT SzReadAndDecodePackedStreams2(
|
|||
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
|
||||
|
|
|
@ -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
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef Byte
|
||||
#define Byte unsigned char
|
||||
#endif
|
||||
|
||||
#ifndef UInt16
|
||||
#define UInt16 unsigned short
|
||||
#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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue