Check In tool source code based on Build tool project revision r1655.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8964 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
263
BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
Normal file
263
BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.c
Normal file
@@ -0,0 +1,263 @@
|
||||
/* 7zFile.c -- File IO
|
||||
2008-11-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "7zFile.h"
|
||||
|
||||
#ifndef USE_WINDOWS_FILE
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
/*
|
||||
ReadFile and WriteFile functions in Windows have BUG:
|
||||
If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
|
||||
from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
|
||||
(Insufficient system resources exist to complete the requested service).
|
||||
Probably in some version of Windows there are problems with other sizes:
|
||||
for 32 MB (maybe also for 16 MB).
|
||||
And message can be "Network connection was lost"
|
||||
*/
|
||||
|
||||
#define kChunkSizeMax (1 << 22)
|
||||
|
||||
#endif
|
||||
|
||||
void File_Construct(CSzFile *p)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
p->handle = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
p->file = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static WRes File_Open(CSzFile *p, const char *name, int writeMode)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
p->handle = CreateFileA(name,
|
||||
writeMode ? GENERIC_WRITE : GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL,
|
||||
writeMode ? CREATE_ALWAYS : OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError();
|
||||
#else
|
||||
p->file = fopen(name, writeMode ? "wb+" : "rb");
|
||||
return (p->file != 0) ? 0 : errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
|
||||
WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
|
||||
|
||||
WRes File_Close(CSzFile *p)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
if (p->handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!CloseHandle(p->handle))
|
||||
return GetLastError();
|
||||
p->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
#else
|
||||
if (p->file != NULL)
|
||||
{
|
||||
int res = fclose(p->file);
|
||||
if (res != 0)
|
||||
return res;
|
||||
p->file = NULL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes File_Read(CSzFile *p, void *data, size_t *size)
|
||||
{
|
||||
size_t originalSize = *size;
|
||||
if (originalSize == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
*size = 0;
|
||||
do
|
||||
{
|
||||
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||
DWORD processed = 0;
|
||||
BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL);
|
||||
data = (void *)((Byte *)data + processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (!res)
|
||||
return GetLastError();
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
*size = fread(data, 1, originalSize, p->file);
|
||||
if (*size == originalSize)
|
||||
return 0;
|
||||
return ferror(p->file);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes File_Write(CSzFile *p, const void *data, size_t *size)
|
||||
{
|
||||
size_t originalSize = *size;
|
||||
if (originalSize == 0)
|
||||
return 0;
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
*size = 0;
|
||||
do
|
||||
{
|
||||
DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize;
|
||||
DWORD processed = 0;
|
||||
BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL);
|
||||
data = (void *)((Byte *)data + processed);
|
||||
originalSize -= processed;
|
||||
*size += processed;
|
||||
if (!res)
|
||||
return GetLastError();
|
||||
if (processed == 0)
|
||||
break;
|
||||
}
|
||||
while (originalSize > 0);
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
*size = fwrite(data, 1, originalSize, p->file);
|
||||
if (*size == originalSize)
|
||||
return 0;
|
||||
return ferror(p->file);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
LARGE_INTEGER value;
|
||||
DWORD moveMethod;
|
||||
value.LowPart = (DWORD)*pos;
|
||||
value.HighPart = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */
|
||||
switch (origin)
|
||||
{
|
||||
case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break;
|
||||
case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break;
|
||||
case SZ_SEEK_END: moveMethod = FILE_END; break;
|
||||
default: return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod);
|
||||
if (value.LowPart == 0xFFFFFFFF)
|
||||
{
|
||||
WRes res = GetLastError();
|
||||
if (res != NO_ERROR)
|
||||
return res;
|
||||
}
|
||||
*pos = ((Int64)value.HighPart << 32) | value.LowPart;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
int moveMethod;
|
||||
int res;
|
||||
switch (origin)
|
||||
{
|
||||
case SZ_SEEK_SET: moveMethod = SEEK_SET; break;
|
||||
case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break;
|
||||
case SZ_SEEK_END: moveMethod = SEEK_END; break;
|
||||
default: return 1;
|
||||
}
|
||||
res = fseek(p->file, (long)*pos, moveMethod);
|
||||
*pos = ftell(p->file);
|
||||
return res;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
WRes File_GetLength(CSzFile *p, UInt64 *length)
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
|
||||
DWORD sizeHigh;
|
||||
DWORD sizeLow = GetFileSize(p->handle, &sizeHigh);
|
||||
if (sizeLow == 0xFFFFFFFF)
|
||||
{
|
||||
DWORD res = GetLastError();
|
||||
if (res != NO_ERROR)
|
||||
return res;
|
||||
}
|
||||
*length = (((UInt64)sizeHigh) << 32) + sizeLow;
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
long pos = ftell(p->file);
|
||||
int res = fseek(p->file, 0, SEEK_END);
|
||||
*length = ftell(p->file);
|
||||
fseek(p->file, pos, SEEK_SET);
|
||||
return res;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileSeqInStream ---------- */
|
||||
|
||||
static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CFileSeqInStream *p = (CFileSeqInStream *)pp;
|
||||
return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
|
||||
{
|
||||
p->s.Read = FileSeqInStream_Read;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileInStream ---------- */
|
||||
|
||||
static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CFileInStream *p = (CFileInStream *)pp;
|
||||
return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
|
||||
}
|
||||
|
||||
static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
CFileInStream *p = (CFileInStream *)pp;
|
||||
return File_Seek(&p->file, pos, origin);
|
||||
}
|
||||
|
||||
void FileInStream_CreateVTable(CFileInStream *p)
|
||||
{
|
||||
p->s.Read = FileInStream_Read;
|
||||
p->s.Seek = FileInStream_Seek;
|
||||
}
|
||||
|
||||
|
||||
/* ---------- FileOutStream ---------- */
|
||||
|
||||
static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
|
||||
{
|
||||
CFileOutStream *p = (CFileOutStream *)pp;
|
||||
File_Write(&p->file, data, &size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p)
|
||||
{
|
||||
p->s.Write = FileOutStream_Write;
|
||||
}
|
74
BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h
Normal file
74
BaseTools/Source/C/LzmaCompress/Sdk/C/7zFile.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 7zFile.h -- File IO
|
||||
2008-11-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_FILE_H
|
||||
#define __7Z_FILE_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#define USE_WINDOWS_FILE
|
||||
#endif
|
||||
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
|
||||
/* ---------- File ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef USE_WINDOWS_FILE
|
||||
HANDLE handle;
|
||||
#else
|
||||
FILE *file;
|
||||
#endif
|
||||
} CSzFile;
|
||||
|
||||
void File_Construct(CSzFile *p);
|
||||
WRes InFile_Open(CSzFile *p, const char *name);
|
||||
WRes OutFile_Open(CSzFile *p, const char *name);
|
||||
WRes File_Close(CSzFile *p);
|
||||
|
||||
/* reads max(*size, remain file's size) bytes */
|
||||
WRes File_Read(CSzFile *p, void *data, size_t *size);
|
||||
|
||||
/* writes *size bytes */
|
||||
WRes File_Write(CSzFile *p, const void *data, size_t *size);
|
||||
|
||||
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
|
||||
WRes File_GetLength(CSzFile *p, UInt64 *length);
|
||||
|
||||
|
||||
/* ---------- FileInStream ---------- */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
CSzFile file;
|
||||
} CFileSeqInStream;
|
||||
|
||||
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeekInStream s;
|
||||
CSzFile file;
|
||||
} CFileInStream;
|
||||
|
||||
void FileInStream_CreateVTable(CFileInStream *p);
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqOutStream s;
|
||||
CSzFile file;
|
||||
} CFileOutStream;
|
||||
|
||||
void FileOutStream_CreateVTable(CFileOutStream *p);
|
||||
|
||||
#endif
|
169
BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c
Normal file
169
BaseTools/Source/C/LzmaCompress/Sdk/C/7zStream.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/* 7zStream.c -- 7z Stream functions
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size)
|
||||
{
|
||||
return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf)
|
||||
{
|
||||
size_t processed = 1;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF;
|
||||
}
|
||||
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
|
||||
{
|
||||
Int64 t = offset;
|
||||
return stream->Seek(stream, &t, SZ_SEEK_SET);
|
||||
}
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size)
|
||||
{
|
||||
void *lookBuf;
|
||||
if (*size == 0)
|
||||
return SZ_OK;
|
||||
RINOK(stream->Look(stream, &lookBuf, size));
|
||||
memcpy(buf, lookBuf, *size);
|
||||
return stream->Skip(stream, *size);
|
||||
}
|
||||
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
|
||||
{
|
||||
while (size != 0)
|
||||
{
|
||||
size_t processed = size;
|
||||
RINOK(stream->Read(stream, buf, &processed));
|
||||
if (processed == 0)
|
||||
return errorType;
|
||||
buf = (void *)((Byte *)buf + processed);
|
||||
size -= processed;
|
||||
}
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
|
||||
{
|
||||
return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Lookahead(void *pp, void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
size2 = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, &size2);
|
||||
p->size = size2;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Look_Exact(void *pp, void **buf, size_t *size)
|
||||
{
|
||||
SRes res = SZ_OK;
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t size2 = p->size - p->pos;
|
||||
if (size2 == 0 && *size > 0)
|
||||
{
|
||||
p->pos = 0;
|
||||
if (*size > LookToRead_BUF_SIZE)
|
||||
*size = LookToRead_BUF_SIZE;
|
||||
res = p->realStream->Read(p->realStream, p->buf, size);
|
||||
size2 = p->size = *size;
|
||||
}
|
||||
if (size2 < *size)
|
||||
*size = size2;
|
||||
*buf = p->buf + p->pos;
|
||||
return res;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Skip(void *pp, size_t offset)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos += offset;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
size_t rem = p->size - p->pos;
|
||||
if (rem == 0)
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
if (rem > *size)
|
||||
rem = *size;
|
||||
memcpy(buf, p->buf + p->pos, rem);
|
||||
p->pos += rem;
|
||||
*size = rem;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
|
||||
{
|
||||
CLookToRead *p = (CLookToRead *)pp;
|
||||
p->pos = p->size = 0;
|
||||
return p->realStream->Seek(p->realStream, pos, origin);
|
||||
}
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
|
||||
{
|
||||
p->s.Look = lookahead ?
|
||||
LookToRead_Look_Lookahead :
|
||||
LookToRead_Look_Exact;
|
||||
p->s.Skip = LookToRead_Skip;
|
||||
p->s.Read = LookToRead_Read;
|
||||
p->s.Seek = LookToRead_Seek;
|
||||
}
|
||||
|
||||
void LookToRead_Init(CLookToRead *p)
|
||||
{
|
||||
p->pos = p->size = 0;
|
||||
}
|
||||
|
||||
static SRes SecToLook_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToLook *p = (CSecToLook *)pp;
|
||||
return LookInStream_LookRead(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p)
|
||||
{
|
||||
p->s.Read = SecToLook_Read;
|
||||
}
|
||||
|
||||
static SRes SecToRead_Read(void *pp, void *buf, size_t *size)
|
||||
{
|
||||
CSecToRead *p = (CSecToRead *)pp;
|
||||
return p->realStream->Read(p->realStream, buf, size);
|
||||
}
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p)
|
||||
{
|
||||
p->s.Read = SecToRead_Read;
|
||||
}
|
7
BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h
Normal file
7
BaseTools/Source/C/LzmaCompress/Sdk/C/7zVersion.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#define MY_VER_MAJOR 4
|
||||
#define MY_VER_MINOR 65
|
||||
#define MY_VER_BUILD 0
|
||||
#define MY_VERSION "4.65"
|
||||
#define MY_DATE "2009-02-03"
|
||||
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
|
||||
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
|
127
BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c
Normal file
127
BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/* Alloc.c -- Memory allocation functions
|
||||
2008-09-24
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "Alloc.h"
|
||||
|
||||
/* #define _SZ_ALLOC_DEBUG */
|
||||
|
||||
/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
#include <stdio.h>
|
||||
int g_allocCount = 0;
|
||||
int g_allocCountMid = 0;
|
||||
int g_allocCountBig = 0;
|
||||
#endif
|
||||
|
||||
void *MyAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
{
|
||||
void *p = malloc(size);
|
||||
fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
|
||||
return p;
|
||||
}
|
||||
#else
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
|
||||
#endif
|
||||
free(address);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void *MidAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void MidFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
|
||||
#endif
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#ifndef MEM_LARGE_PAGES
|
||||
#undef _7ZIP_LARGE_PAGES
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T g_LargePageSize = 0;
|
||||
typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
|
||||
#endif
|
||||
|
||||
void SetLargePageSize()
|
||||
{
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
SIZE_T size = 0;
|
||||
GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
|
||||
GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
|
||||
if (largePageMinimum == 0)
|
||||
return;
|
||||
size = largePageMinimum();
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
return;
|
||||
g_LargePageSize = size;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void *BigAlloc(size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
return 0;
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
|
||||
#endif
|
||||
|
||||
#ifdef _7ZIP_LARGE_PAGES
|
||||
if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
|
||||
{
|
||||
void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
|
||||
MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
void BigFree(void *address)
|
||||
{
|
||||
#ifdef _SZ_ALLOC_DEBUG
|
||||
if (address != 0)
|
||||
fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
|
||||
#endif
|
||||
|
||||
if (address == 0)
|
||||
return;
|
||||
VirtualFree(address, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
#endif
|
32
BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h
Normal file
32
BaseTools/Source/C/LzmaCompress/Sdk/C/Alloc.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* Alloc.h -- Memory allocation functions
|
||||
2008-03-13
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __COMMON_ALLOC_H
|
||||
#define __COMMON_ALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void *MyAlloc(size_t size);
|
||||
void MyFree(void *address);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void SetLargePageSize();
|
||||
|
||||
void *MidAlloc(size_t size);
|
||||
void MidFree(void *address);
|
||||
void *BigAlloc(size_t size);
|
||||
void BigFree(void *address);
|
||||
|
||||
#else
|
||||
|
||||
#define MidAlloc(size) MyAlloc(size)
|
||||
#define MidFree(address) MyFree(address)
|
||||
#define BigAlloc(size) MyAlloc(size)
|
||||
#define BigFree(address) MyFree(address)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
69
BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h
Normal file
69
BaseTools/Source/C/LzmaCompress/Sdk/C/CpuArch.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* CpuArch.h
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#ifndef __CPUARCH_H
|
||||
#define __CPUARCH_H
|
||||
|
||||
/*
|
||||
LITTLE_ENDIAN_UNALIGN means:
|
||||
1) CPU is LITTLE_ENDIAN
|
||||
2) it's allowed to make unaligned memory accesses
|
||||
if LITTLE_ENDIAN_UNALIGN is not defined, it means that we don't know
|
||||
about these properties of platform.
|
||||
*/
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || defined(__i386__) || defined(__x86_64__)
|
||||
#define LITTLE_ENDIAN_UNALIGN
|
||||
#endif
|
||||
|
||||
#ifdef LITTLE_ENDIAN_UNALIGN
|
||||
|
||||
#define GetUi16(p) (*(const UInt16 *)(p))
|
||||
#define GetUi32(p) (*(const UInt32 *)(p))
|
||||
#define GetUi64(p) (*(const UInt64 *)(p))
|
||||
#define SetUi32(p, d) *(UInt32 *)(p) = (d);
|
||||
|
||||
#else
|
||||
|
||||
#define GetUi16(p) (((const Byte *)(p))[0] | ((UInt16)((const Byte *)(p))[1] << 8))
|
||||
|
||||
#define GetUi32(p) ( \
|
||||
((const Byte *)(p))[0] | \
|
||||
((UInt32)((const Byte *)(p))[1] << 8) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[3] << 24))
|
||||
|
||||
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
|
||||
|
||||
#define SetUi32(p, d) { UInt32 _x_ = (d); \
|
||||
((Byte *)(p))[0] = (Byte)_x_; \
|
||||
((Byte *)(p))[1] = (Byte)(_x_ >> 8); \
|
||||
((Byte *)(p))[2] = (Byte)(_x_ >> 16); \
|
||||
((Byte *)(p))[3] = (Byte)(_x_ >> 24); }
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LITTLE_ENDIAN_UNALIGN) && defined(_WIN64) && (_MSC_VER >= 1300)
|
||||
|
||||
#pragma intrinsic(_byteswap_ulong)
|
||||
#pragma intrinsic(_byteswap_uint64)
|
||||
#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
|
||||
#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
|
||||
|
||||
#else
|
||||
|
||||
#define GetBe32(p) ( \
|
||||
((UInt32)((const Byte *)(p))[0] << 24) | \
|
||||
((UInt32)((const Byte *)(p))[1] << 16) | \
|
||||
((UInt32)((const Byte *)(p))[2] << 8) | \
|
||||
((const Byte *)(p))[3] )
|
||||
|
||||
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
|
||||
|
||||
#endif
|
||||
|
||||
#define GetBe16(p) (((UInt16)((const Byte *)(p))[0] << 8) | ((const Byte *)(p))[1])
|
||||
|
||||
#endif
|
751
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c
Normal file
751
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.c
Normal file
@@ -0,0 +1,751 @@
|
||||
/* LzFind.c -- Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "LzFind.h"
|
||||
#include "LzHash.h"
|
||||
|
||||
#define kEmptyHashValue 0
|
||||
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
|
||||
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
|
||||
#define kNormalizeMask (~(kNormalizeStepMin - 1))
|
||||
#define kMaxHistorySize ((UInt32)3 << 30)
|
||||
|
||||
#define kStartMaxLen 3
|
||||
|
||||
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
if (!p->directInput)
|
||||
{
|
||||
alloc->Free(alloc, p->bufferBase);
|
||||
p->bufferBase = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
|
||||
|
||||
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
|
||||
if (p->directInput)
|
||||
{
|
||||
p->blockSize = blockSize;
|
||||
return 1;
|
||||
}
|
||||
if (p->bufferBase == 0 || p->blockSize != blockSize)
|
||||
{
|
||||
LzInWindow_Free(p, alloc);
|
||||
p->blockSize = blockSize;
|
||||
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
|
||||
}
|
||||
return (p->bufferBase != 0);
|
||||
}
|
||||
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||
|
||||
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||
{
|
||||
p->posLimit -= subValue;
|
||||
p->pos -= subValue;
|
||||
p->streamPos -= subValue;
|
||||
}
|
||||
|
||||
static void MatchFinder_ReadBlock(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached || p->result != SZ_OK)
|
||||
return;
|
||||
for (;;)
|
||||
{
|
||||
Byte *dest = p->buffer + (p->streamPos - p->pos);
|
||||
size_t size = (p->bufferBase + p->blockSize - dest);
|
||||
if (size == 0)
|
||||
return;
|
||||
p->result = p->stream->Read(p->stream, dest, &size);
|
||||
if (p->result != SZ_OK)
|
||||
return;
|
||||
if (size == 0)
|
||||
{
|
||||
p->streamEndWasReached = 1;
|
||||
return;
|
||||
}
|
||||
p->streamPos += (UInt32)size;
|
||||
if (p->streamPos - p->pos > p->keepSizeAfter)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p)
|
||||
{
|
||||
memmove(p->bufferBase,
|
||||
p->buffer - p->keepSizeBefore,
|
||||
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
|
||||
p->buffer = p->bufferBase + p->keepSizeBefore;
|
||||
}
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p)
|
||||
{
|
||||
/* if (p->streamEndWasReached) return 0; */
|
||||
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
|
||||
}
|
||||
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p)
|
||||
{
|
||||
if (p->streamEndWasReached)
|
||||
return;
|
||||
if (p->keepSizeAfter >= p->streamPos - p->pos)
|
||||
MatchFinder_ReadBlock(p);
|
||||
}
|
||||
|
||||
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
|
||||
{
|
||||
if (MatchFinder_NeedMove(p))
|
||||
MatchFinder_MoveBlock(p);
|
||||
MatchFinder_ReadBlock(p);
|
||||
}
|
||||
|
||||
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
|
||||
{
|
||||
p->cutValue = 32;
|
||||
p->btMode = 1;
|
||||
p->numHashBytes = 4;
|
||||
/* p->skipModeBits = 0; */
|
||||
p->directInput = 0;
|
||||
p->bigHash = 0;
|
||||
}
|
||||
|
||||
#define kCrcPoly 0xEDB88320
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
p->bufferBase = 0;
|
||||
p->directInput = 0;
|
||||
p->hash = 0;
|
||||
MatchFinder_SetDefaultSettings(p);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UInt32 r = i;
|
||||
int j;
|
||||
for (j = 0; j < 8; j++)
|
||||
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
|
||||
p->crc[i] = r;
|
||||
}
|
||||
}
|
||||
|
||||
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->hash);
|
||||
p->hash = 0;
|
||||
}
|
||||
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
|
||||
{
|
||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||
LzInWindow_Free(p, alloc);
|
||||
}
|
||||
|
||||
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
|
||||
{
|
||||
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
|
||||
if (sizeInBytes / sizeof(CLzRef) != num)
|
||||
return 0;
|
||||
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
|
||||
}
|
||||
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc)
|
||||
{
|
||||
UInt32 sizeReserv;
|
||||
if (historySize > kMaxHistorySize)
|
||||
{
|
||||
MatchFinder_Free(p, alloc);
|
||||
return 0;
|
||||
}
|
||||
sizeReserv = historySize >> 1;
|
||||
if (historySize > ((UInt32)2 << 30))
|
||||
sizeReserv = historySize >> 2;
|
||||
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
|
||||
|
||||
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
|
||||
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
|
||||
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
|
||||
if (LzInWindow_Create(p, sizeReserv, alloc))
|
||||
{
|
||||
UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
|
||||
UInt32 hs;
|
||||
p->matchMaxLen = matchMaxLen;
|
||||
{
|
||||
p->fixedHashSize = 0;
|
||||
if (p->numHashBytes == 2)
|
||||
hs = (1 << 16) - 1;
|
||||
else
|
||||
{
|
||||
hs = historySize - 1;
|
||||
hs |= (hs >> 1);
|
||||
hs |= (hs >> 2);
|
||||
hs |= (hs >> 4);
|
||||
hs |= (hs >> 8);
|
||||
hs >>= 1;
|
||||
/* hs >>= p->skipModeBits; */
|
||||
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
|
||||
if (hs > (1 << 24))
|
||||
{
|
||||
if (p->numHashBytes == 3)
|
||||
hs = (1 << 24) - 1;
|
||||
else
|
||||
hs >>= 1;
|
||||
}
|
||||
}
|
||||
p->hashMask = hs;
|
||||
hs++;
|
||||
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
|
||||
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
|
||||
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
|
||||
hs += p->fixedHashSize;
|
||||
}
|
||||
|
||||
{
|
||||
UInt32 prevSize = p->hashSizeSum + p->numSons;
|
||||
UInt32 newSize;
|
||||
p->historySize = historySize;
|
||||
p->hashSizeSum = hs;
|
||||
p->cyclicBufferSize = newCyclicBufferSize;
|
||||
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
|
||||
newSize = p->hashSizeSum + p->numSons;
|
||||
if (p->hash != 0 && prevSize == newSize)
|
||||
return 1;
|
||||
MatchFinder_FreeThisClassMemory(p, alloc);
|
||||
p->hash = AllocRefs(newSize, alloc);
|
||||
if (p->hash != 0)
|
||||
{
|
||||
p->son = p->hash + p->hashSizeSum;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
MatchFinder_Free(p, alloc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void MatchFinder_SetLimits(CMatchFinder *p)
|
||||
{
|
||||
UInt32 limit = kMaxValForNormalize - p->pos;
|
||||
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
|
||||
if (limit2 < limit)
|
||||
limit = limit2;
|
||||
limit2 = p->streamPos - p->pos;
|
||||
if (limit2 <= p->keepSizeAfter)
|
||||
{
|
||||
if (limit2 > 0)
|
||||
limit2 = 1;
|
||||
}
|
||||
else
|
||||
limit2 -= p->keepSizeAfter;
|
||||
if (limit2 < limit)
|
||||
limit = limit2;
|
||||
{
|
||||
UInt32 lenLimit = p->streamPos - p->pos;
|
||||
if (lenLimit > p->matchMaxLen)
|
||||
lenLimit = p->matchMaxLen;
|
||||
p->lenLimit = lenLimit;
|
||||
}
|
||||
p->posLimit = p->pos + limit;
|
||||
}
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->hashSizeSum; i++)
|
||||
p->hash[i] = kEmptyHashValue;
|
||||
p->cyclicBufferPos = 0;
|
||||
p->buffer = p->bufferBase;
|
||||
p->pos = p->streamPos = p->cyclicBufferSize;
|
||||
p->result = SZ_OK;
|
||||
p->streamEndWasReached = 0;
|
||||
MatchFinder_ReadBlock(p);
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
|
||||
{
|
||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||
}
|
||||
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 value = items[i];
|
||||
if (value <= subValue)
|
||||
value = kEmptyHashValue;
|
||||
else
|
||||
value -= subValue;
|
||||
items[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
static void MatchFinder_Normalize(CMatchFinder *p)
|
||||
{
|
||||
UInt32 subValue = MatchFinder_GetSubValue(p);
|
||||
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
|
||||
MatchFinder_ReduceOffsets(p, subValue);
|
||||
}
|
||||
|
||||
static void MatchFinder_CheckLimits(CMatchFinder *p)
|
||||
{
|
||||
if (p->pos == kMaxValForNormalize)
|
||||
MatchFinder_Normalize(p);
|
||||
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
|
||||
MatchFinder_CheckAndMoveAndRead(p);
|
||||
if (p->cyclicBufferPos == p->cyclicBufferSize)
|
||||
p->cyclicBufferPos = 0;
|
||||
MatchFinder_SetLimits(p);
|
||||
}
|
||||
|
||||
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
son[_cyclicBufferPos] = curMatch;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
return distances;
|
||||
{
|
||||
const Byte *pb = cur - delta;
|
||||
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
|
||||
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
|
||||
{
|
||||
UInt32 len = 0;
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
return distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
return distances;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return distances;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
|
||||
{
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
return;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
{
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MOVE_POS \
|
||||
++p->cyclicBufferPos; \
|
||||
p->buffer++; \
|
||||
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
|
||||
|
||||
#define MOVE_POS_RET MOVE_POS return offset;
|
||||
|
||||
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
|
||||
|
||||
#define GET_MATCHES_HEADER2(minLen, ret_op) \
|
||||
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
|
||||
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
|
||||
cur = p->buffer;
|
||||
|
||||
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
|
||||
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
|
||||
|
||||
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
|
||||
|
||||
#define GET_MATCHES_FOOTER(offset, maxLen) \
|
||||
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
|
||||
distances + offset, maxLen) - distances); MOVE_POS_RET;
|
||||
|
||||
#define SKIP_FOOTER \
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
|
||||
|
||||
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = 0;
|
||||
GET_MATCHES_FOOTER(offset, 1)
|
||||
}
|
||||
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = 0;
|
||||
GET_MATCHES_FOOTER(offset, 2)
|
||||
}
|
||||
|
||||
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, delta2, maxLen, offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
|
||||
HASH3_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[hash2Value];
|
||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||
|
||||
|
||||
maxLen = 2;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[0] = maxLen;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
GET_MATCHES_FOOTER(offset, maxLen)
|
||||
}
|
||||
|
||||
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
HASH4_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[ hash2Value];
|
||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 1;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||
{
|
||||
maxLen = 3;
|
||||
distances[offset + 1] = delta3 - 1;
|
||||
offset += 2;
|
||||
delta2 = delta3;
|
||||
}
|
||||
if (offset != 0)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[offset - 2] = maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
GET_MATCHES_FOOTER(offset, maxLen)
|
||||
}
|
||||
|
||||
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
|
||||
GET_MATCHES_HEADER(4)
|
||||
|
||||
HASH4_CALC;
|
||||
|
||||
delta2 = p->pos - p->hash[ hash2Value];
|
||||
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
|
||||
maxLen = 1;
|
||||
offset = 0;
|
||||
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
|
||||
{
|
||||
distances[0] = maxLen = 2;
|
||||
distances[1] = delta2 - 1;
|
||||
offset = 2;
|
||||
}
|
||||
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
|
||||
{
|
||||
maxLen = 3;
|
||||
distances[offset + 1] = delta3 - 1;
|
||||
offset += 2;
|
||||
delta2 = delta3;
|
||||
}
|
||||
if (offset != 0)
|
||||
{
|
||||
for (; maxLen != lenLimit; maxLen++)
|
||||
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
|
||||
break;
|
||||
distances[offset - 2] = maxLen;
|
||||
if (maxLen == lenLimit)
|
||||
{
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS_RET;
|
||||
}
|
||||
}
|
||||
if (maxLen < 3)
|
||||
maxLen = 3;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances + offset, maxLen) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
|
||||
distances, 2) - (distances));
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(2)
|
||||
HASH2_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value;
|
||||
SKIP_HEADER(3)
|
||||
HASH3_CALC;
|
||||
curMatch = p->hash[kFix3HashSize + hashValue];
|
||||
p->hash[hash2Value] =
|
||||
p->hash[kFix3HashSize + hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value, hash3Value;
|
||||
SKIP_HEADER(4)
|
||||
HASH4_CALC;
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] = p->pos;
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 hash2Value, hash3Value;
|
||||
SKIP_HEADER(4)
|
||||
HASH4_CALC;
|
||||
curMatch = p->hash[kFix4HashSize + hashValue];
|
||||
p->hash[ hash2Value] =
|
||||
p->hash[kFix3HashSize + hash3Value] =
|
||||
p->hash[kFix4HashSize + hashValue] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
HASH_ZIP_CALC;
|
||||
curMatch = p->hash[hashValue];
|
||||
p->hash[hashValue] = p->pos;
|
||||
p->son[p->cyclicBufferPos] = curMatch;
|
||||
MOVE_POS
|
||||
}
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
|
||||
{
|
||||
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
|
||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
|
||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
|
||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
|
||||
if (!p->btMode)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
|
||||
}
|
||||
else if (p->numHashBytes == 2)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
|
||||
}
|
||||
else if (p->numHashBytes == 3)
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
|
||||
}
|
||||
else
|
||||
{
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
|
||||
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
|
||||
}
|
||||
}
|
107
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h
Normal file
107
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFind.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* LzFind.h -- Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZFIND_H
|
||||
#define __LZFIND_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
typedef UInt32 CLzRef;
|
||||
|
||||
typedef struct _CMatchFinder
|
||||
{
|
||||
Byte *buffer;
|
||||
UInt32 pos;
|
||||
UInt32 posLimit;
|
||||
UInt32 streamPos;
|
||||
UInt32 lenLimit;
|
||||
|
||||
UInt32 cyclicBufferPos;
|
||||
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
|
||||
|
||||
UInt32 matchMaxLen;
|
||||
CLzRef *hash;
|
||||
CLzRef *son;
|
||||
UInt32 hashMask;
|
||||
UInt32 cutValue;
|
||||
|
||||
Byte *bufferBase;
|
||||
ISeqInStream *stream;
|
||||
int streamEndWasReached;
|
||||
|
||||
UInt32 blockSize;
|
||||
UInt32 keepSizeBefore;
|
||||
UInt32 keepSizeAfter;
|
||||
|
||||
UInt32 numHashBytes;
|
||||
int directInput;
|
||||
int btMode;
|
||||
/* int skipModeBits; */
|
||||
int bigHash;
|
||||
UInt32 historySize;
|
||||
UInt32 fixedHashSize;
|
||||
UInt32 hashSizeSum;
|
||||
UInt32 numSons;
|
||||
SRes result;
|
||||
UInt32 crc[256];
|
||||
} CMatchFinder;
|
||||
|
||||
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
|
||||
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
|
||||
|
||||
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||
|
||||
int MatchFinder_NeedMove(CMatchFinder *p);
|
||||
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||
void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||
void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||
|
||||
void MatchFinder_Construct(CMatchFinder *p);
|
||||
|
||||
/* Conditions:
|
||||
historySize <= 3 GB
|
||||
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
|
||||
*/
|
||||
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc);
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||
|
||||
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *distances, UInt32 maxLen);
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
|
||||
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
|
||||
*/
|
||||
|
||||
typedef void (*Mf_Init_Func)(void *object);
|
||||
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
|
||||
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
|
||||
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
|
||||
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
|
||||
typedef void (*Mf_Skip_Func)(void *object, UInt32);
|
||||
|
||||
typedef struct _IMatchFinder
|
||||
{
|
||||
Mf_Init_Func Init;
|
||||
Mf_GetIndexByte_Func GetIndexByte;
|
||||
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
|
||||
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
|
||||
Mf_GetMatches_Func GetMatches;
|
||||
Mf_Skip_Func Skip;
|
||||
} IMatchFinder;
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||
|
||||
void MatchFinder_Init(CMatchFinder *p);
|
||||
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
|
||||
#endif
|
793
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c
Normal file
793
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.c
Normal file
@@ -0,0 +1,793 @@
|
||||
/* LzFindMt.c -- multithreaded Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#include "LzHash.h"
|
||||
|
||||
#include "LzFindMt.h"
|
||||
|
||||
void MtSync_Construct(CMtSync *p)
|
||||
{
|
||||
p->wasCreated = False;
|
||||
p->csWasInitialized = False;
|
||||
p->csWasEntered = False;
|
||||
Thread_Construct(&p->thread);
|
||||
Event_Construct(&p->canStart);
|
||||
Event_Construct(&p->wasStarted);
|
||||
Event_Construct(&p->wasStopped);
|
||||
Semaphore_Construct(&p->freeSemaphore);
|
||||
Semaphore_Construct(&p->filledSemaphore);
|
||||
}
|
||||
|
||||
void MtSync_GetNextBlock(CMtSync *p)
|
||||
{
|
||||
if (p->needStart)
|
||||
{
|
||||
p->numProcessedBlocks = 1;
|
||||
p->needStart = False;
|
||||
p->stopWriting = False;
|
||||
p->exit = False;
|
||||
Event_Reset(&p->wasStarted);
|
||||
Event_Reset(&p->wasStopped);
|
||||
|
||||
Event_Set(&p->canStart);
|
||||
Event_Wait(&p->wasStarted);
|
||||
}
|
||||
else
|
||||
{
|
||||
CriticalSection_Leave(&p->cs);
|
||||
p->csWasEntered = False;
|
||||
p->numProcessedBlocks++;
|
||||
Semaphore_Release1(&p->freeSemaphore);
|
||||
}
|
||||
Semaphore_Wait(&p->filledSemaphore);
|
||||
CriticalSection_Enter(&p->cs);
|
||||
p->csWasEntered = True;
|
||||
}
|
||||
|
||||
/* MtSync_StopWriting must be called if Writing was started */
|
||||
|
||||
void MtSync_StopWriting(CMtSync *p)
|
||||
{
|
||||
UInt32 myNumBlocks = p->numProcessedBlocks;
|
||||
if (!Thread_WasCreated(&p->thread) || p->needStart)
|
||||
return;
|
||||
p->stopWriting = True;
|
||||
if (p->csWasEntered)
|
||||
{
|
||||
CriticalSection_Leave(&p->cs);
|
||||
p->csWasEntered = False;
|
||||
}
|
||||
Semaphore_Release1(&p->freeSemaphore);
|
||||
|
||||
Event_Wait(&p->wasStopped);
|
||||
|
||||
while (myNumBlocks++ != p->numProcessedBlocks)
|
||||
{
|
||||
Semaphore_Wait(&p->filledSemaphore);
|
||||
Semaphore_Release1(&p->freeSemaphore);
|
||||
}
|
||||
p->needStart = True;
|
||||
}
|
||||
|
||||
void MtSync_Destruct(CMtSync *p)
|
||||
{
|
||||
if (Thread_WasCreated(&p->thread))
|
||||
{
|
||||
MtSync_StopWriting(p);
|
||||
p->exit = True;
|
||||
if (p->needStart)
|
||||
Event_Set(&p->canStart);
|
||||
Thread_Wait(&p->thread);
|
||||
Thread_Close(&p->thread);
|
||||
}
|
||||
if (p->csWasInitialized)
|
||||
{
|
||||
CriticalSection_Delete(&p->cs);
|
||||
p->csWasInitialized = False;
|
||||
}
|
||||
|
||||
Event_Close(&p->canStart);
|
||||
Event_Close(&p->wasStarted);
|
||||
Event_Close(&p->wasStopped);
|
||||
Semaphore_Close(&p->freeSemaphore);
|
||||
Semaphore_Close(&p->filledSemaphore);
|
||||
|
||||
p->wasCreated = False;
|
||||
}
|
||||
|
||||
#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; }
|
||||
|
||||
static SRes MtSync_Create2(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
{
|
||||
if (p->wasCreated)
|
||||
return SZ_OK;
|
||||
|
||||
RINOK_THREAD(CriticalSection_Init(&p->cs));
|
||||
p->csWasInitialized = True;
|
||||
|
||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart));
|
||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStarted));
|
||||
RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped));
|
||||
|
||||
RINOK_THREAD(Semaphore_Create(&p->freeSemaphore, numBlocks, numBlocks));
|
||||
RINOK_THREAD(Semaphore_Create(&p->filledSemaphore, 0, numBlocks));
|
||||
|
||||
p->needStart = True;
|
||||
|
||||
RINOK_THREAD(Thread_Create(&p->thread, startAddress, obj));
|
||||
p->wasCreated = True;
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
static SRes MtSync_Create(CMtSync *p, unsigned (MY_STD_CALL *startAddress)(void *), void *obj, UInt32 numBlocks)
|
||||
{
|
||||
SRes res = MtSync_Create2(p, startAddress, obj, numBlocks);
|
||||
if (res != SZ_OK)
|
||||
MtSync_Destruct(p);
|
||||
return res;
|
||||
}
|
||||
|
||||
void MtSync_Init(CMtSync *p) { p->needStart = True; }
|
||||
|
||||
#define kMtMaxValForNormalize 0xFFFFFFFF
|
||||
|
||||
#define DEF_GetHeads2(name, v, action) \
|
||||
static void GetHeads ## name(const Byte *p, UInt32 pos, \
|
||||
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc) \
|
||||
{ action; for (; numHeads != 0; numHeads--) { \
|
||||
const UInt32 value = (v); p++; *heads++ = pos - hash[value]; hash[value] = pos++; } }
|
||||
|
||||
#define DEF_GetHeads(name, v) DEF_GetHeads2(name, v, ;)
|
||||
|
||||
DEF_GetHeads2(2, (p[0] | ((UInt32)p[1] << 8)), hashMask = hashMask; crc = crc; )
|
||||
DEF_GetHeads(3, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8)) & hashMask)
|
||||
DEF_GetHeads(4, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5)) & hashMask)
|
||||
DEF_GetHeads(4b, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ ((UInt32)p[3] << 16)) & hashMask)
|
||||
DEF_GetHeads(5, (crc[p[0]] ^ p[1] ^ ((UInt32)p[2] << 8) ^ (crc[p[3]] << 5) ^ (crc[p[4]] << 3)) & hashMask)
|
||||
|
||||
void HashThreadFunc(CMatchFinderMt *mt)
|
||||
{
|
||||
CMtSync *p = &mt->hashSync;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 numProcessedBlocks = 0;
|
||||
Event_Wait(&p->canStart);
|
||||
Event_Set(&p->wasStarted);
|
||||
for (;;)
|
||||
{
|
||||
if (p->exit)
|
||||
return;
|
||||
if (p->stopWriting)
|
||||
{
|
||||
p->numProcessedBlocks = numProcessedBlocks;
|
||||
Event_Set(&p->wasStopped);
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
CMatchFinder *mf = mt->MatchFinder;
|
||||
if (MatchFinder_NeedMove(mf))
|
||||
{
|
||||
CriticalSection_Enter(&mt->btSync.cs);
|
||||
CriticalSection_Enter(&mt->hashSync.cs);
|
||||
{
|
||||
const Byte *beforePtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
const Byte *afterPtr;
|
||||
MatchFinder_MoveBlock(mf);
|
||||
afterPtr = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
mt->pointerToCurPos -= beforePtr - afterPtr;
|
||||
mt->buffer -= beforePtr - afterPtr;
|
||||
}
|
||||
CriticalSection_Leave(&mt->btSync.cs);
|
||||
CriticalSection_Leave(&mt->hashSync.cs);
|
||||
continue;
|
||||
}
|
||||
|
||||
Semaphore_Wait(&p->freeSemaphore);
|
||||
|
||||
MatchFinder_ReadIfRequired(mf);
|
||||
if (mf->pos > (kMtMaxValForNormalize - kMtHashBlockSize))
|
||||
{
|
||||
UInt32 subValue = (mf->pos - mf->historySize - 1);
|
||||
MatchFinder_ReduceOffsets(mf, subValue);
|
||||
MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, mf->hashMask + 1);
|
||||
}
|
||||
{
|
||||
UInt32 *heads = mt->hashBuf + ((numProcessedBlocks++) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
||||
UInt32 num = mf->streamPos - mf->pos;
|
||||
heads[0] = 2;
|
||||
heads[1] = num;
|
||||
if (num >= mf->numHashBytes)
|
||||
{
|
||||
num = num - mf->numHashBytes + 1;
|
||||
if (num > kMtHashBlockSize - 2)
|
||||
num = kMtHashBlockSize - 2;
|
||||
mt->GetHeadsFunc(mf->buffer, mf->pos, mf->hash + mf->fixedHashSize, mf->hashMask, heads + 2, num, mf->crc);
|
||||
heads[0] += num;
|
||||
}
|
||||
mf->pos += num;
|
||||
mf->buffer += num;
|
||||
}
|
||||
}
|
||||
|
||||
Semaphore_Release1(&p->filledSemaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinderMt_GetNextBlock_Hash(CMatchFinderMt *p)
|
||||
{
|
||||
MtSync_GetNextBlock(&p->hashSync);
|
||||
p->hashBufPosLimit = p->hashBufPos = ((p->hashSync.numProcessedBlocks - 1) & kMtHashNumBlocksMask) * kMtHashBlockSize;
|
||||
p->hashBufPosLimit += p->hashBuf[p->hashBufPos++];
|
||||
p->hashNumAvail = p->hashBuf[p->hashBufPos++];
|
||||
}
|
||||
|
||||
#define kEmptyHashValue 0
|
||||
|
||||
/* #define MFMT_GM_INLINE */
|
||||
|
||||
#ifdef MFMT_GM_INLINE
|
||||
|
||||
#define NO_INLINE MY_FAST_CALL
|
||||
|
||||
Int32 NO_INLINE GetMatchesSpecN(UInt32 lenLimit, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
UInt32 *_distances, UInt32 _maxLen, const UInt32 *hash, Int32 limit, UInt32 size, UInt32 *posRes)
|
||||
{
|
||||
do
|
||||
{
|
||||
UInt32 *distances = _distances + 1;
|
||||
UInt32 curMatch = pos - *hash++;
|
||||
|
||||
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
|
||||
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
|
||||
UInt32 len0 = 0, len1 = 0;
|
||||
UInt32 cutValue = _cutValue;
|
||||
UInt32 maxLen = _maxLen;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 delta = pos - curMatch;
|
||||
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
|
||||
{
|
||||
*ptr0 = *ptr1 = kEmptyHashValue;
|
||||
break;
|
||||
}
|
||||
{
|
||||
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
|
||||
const Byte *pb = cur - delta;
|
||||
UInt32 len = (len0 < len1 ? len0 : len1);
|
||||
if (pb[len] == cur[len])
|
||||
{
|
||||
if (++len != lenLimit && pb[len] == cur[len])
|
||||
while (++len != lenLimit)
|
||||
if (pb[len] != cur[len])
|
||||
break;
|
||||
if (maxLen < len)
|
||||
{
|
||||
*distances++ = maxLen = len;
|
||||
*distances++ = delta - 1;
|
||||
if (len == lenLimit)
|
||||
{
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pb[len] < cur[len])
|
||||
{
|
||||
*ptr1 = curMatch;
|
||||
ptr1 = pair + 1;
|
||||
curMatch = *ptr1;
|
||||
len1 = len;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr0 = curMatch;
|
||||
ptr0 = pair;
|
||||
curMatch = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
_cyclicBufferPos++;
|
||||
cur++;
|
||||
{
|
||||
UInt32 num = (UInt32)(distances - _distances);
|
||||
*_distances = num - 1;
|
||||
_distances += num;
|
||||
limit -= num;
|
||||
}
|
||||
}
|
||||
while (limit > 0 && --size != 0);
|
||||
*posRes = pos;
|
||||
return limit;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BtGetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 numProcessed = 0;
|
||||
UInt32 curPos = 2;
|
||||
UInt32 limit = kMtBtBlockSize - (p->matchMaxLen * 2);
|
||||
distances[1] = p->hashNumAvail;
|
||||
while (curPos < limit)
|
||||
{
|
||||
if (p->hashBufPos == p->hashBufPosLimit)
|
||||
{
|
||||
MatchFinderMt_GetNextBlock_Hash(p);
|
||||
distances[1] = numProcessed + p->hashNumAvail;
|
||||
if (p->hashNumAvail >= p->numHashBytes)
|
||||
continue;
|
||||
for (; p->hashNumAvail != 0; p->hashNumAvail--)
|
||||
distances[curPos++] = 0;
|
||||
break;
|
||||
}
|
||||
{
|
||||
UInt32 size = p->hashBufPosLimit - p->hashBufPos;
|
||||
UInt32 lenLimit = p->matchMaxLen;
|
||||
UInt32 pos = p->pos;
|
||||
UInt32 cyclicBufferPos = p->cyclicBufferPos;
|
||||
if (lenLimit >= p->hashNumAvail)
|
||||
lenLimit = p->hashNumAvail;
|
||||
{
|
||||
UInt32 size2 = p->hashNumAvail - lenLimit + 1;
|
||||
if (size2 < size)
|
||||
size = size2;
|
||||
size2 = p->cyclicBufferSize - cyclicBufferPos;
|
||||
if (size2 < size)
|
||||
size = size2;
|
||||
}
|
||||
#ifndef MFMT_GM_INLINE
|
||||
while (curPos < limit && size-- != 0)
|
||||
{
|
||||
UInt32 *startDistances = distances + curPos;
|
||||
UInt32 num = (UInt32)(GetMatchesSpec1(lenLimit, pos - p->hashBuf[p->hashBufPos++],
|
||||
pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||
startDistances + 1, p->numHashBytes - 1) - startDistances);
|
||||
*startDistances = num - 1;
|
||||
curPos += num;
|
||||
cyclicBufferPos++;
|
||||
pos++;
|
||||
p->buffer++;
|
||||
}
|
||||
#else
|
||||
{
|
||||
UInt32 posRes;
|
||||
curPos = limit - GetMatchesSpecN(lenLimit, pos, p->buffer, p->son, cyclicBufferPos, p->cyclicBufferSize, p->cutValue,
|
||||
distances + curPos, p->numHashBytes - 1, p->hashBuf + p->hashBufPos, (Int32)(limit - curPos) , size, &posRes);
|
||||
p->hashBufPos += posRes - pos;
|
||||
cyclicBufferPos += posRes - pos;
|
||||
p->buffer += posRes - pos;
|
||||
pos = posRes;
|
||||
}
|
||||
#endif
|
||||
|
||||
numProcessed += pos - p->pos;
|
||||
p->hashNumAvail -= pos - p->pos;
|
||||
p->pos = pos;
|
||||
if (cyclicBufferPos == p->cyclicBufferSize)
|
||||
cyclicBufferPos = 0;
|
||||
p->cyclicBufferPos = cyclicBufferPos;
|
||||
}
|
||||
}
|
||||
distances[0] = curPos;
|
||||
}
|
||||
|
||||
void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex)
|
||||
{
|
||||
CMtSync *sync = &p->hashSync;
|
||||
if (!sync->needStart)
|
||||
{
|
||||
CriticalSection_Enter(&sync->cs);
|
||||
sync->csWasEntered = True;
|
||||
}
|
||||
|
||||
BtGetMatches(p, p->btBuf + (globalBlockIndex & kMtBtNumBlocksMask) * kMtBtBlockSize);
|
||||
|
||||
if (p->pos > kMtMaxValForNormalize - kMtBtBlockSize)
|
||||
{
|
||||
UInt32 subValue = p->pos - p->cyclicBufferSize;
|
||||
MatchFinder_Normalize3(subValue, p->son, p->cyclicBufferSize * 2);
|
||||
p->pos -= subValue;
|
||||
}
|
||||
|
||||
if (!sync->needStart)
|
||||
{
|
||||
CriticalSection_Leave(&sync->cs);
|
||||
sync->csWasEntered = False;
|
||||
}
|
||||
}
|
||||
|
||||
void BtThreadFunc(CMatchFinderMt *mt)
|
||||
{
|
||||
CMtSync *p = &mt->btSync;
|
||||
for (;;)
|
||||
{
|
||||
UInt32 blockIndex = 0;
|
||||
Event_Wait(&p->canStart);
|
||||
Event_Set(&p->wasStarted);
|
||||
for (;;)
|
||||
{
|
||||
if (p->exit)
|
||||
return;
|
||||
if (p->stopWriting)
|
||||
{
|
||||
p->numProcessedBlocks = blockIndex;
|
||||
MtSync_StopWriting(&mt->hashSync);
|
||||
Event_Set(&p->wasStopped);
|
||||
break;
|
||||
}
|
||||
Semaphore_Wait(&p->freeSemaphore);
|
||||
BtFillBlock(mt, blockIndex++);
|
||||
Semaphore_Release1(&p->filledSemaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MatchFinderMt_Construct(CMatchFinderMt *p)
|
||||
{
|
||||
p->hashBuf = 0;
|
||||
MtSync_Construct(&p->hashSync);
|
||||
MtSync_Construct(&p->btSync);
|
||||
}
|
||||
|
||||
void MatchFinderMt_FreeMem(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->hashBuf);
|
||||
p->hashBuf = 0;
|
||||
}
|
||||
|
||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc)
|
||||
{
|
||||
MtSync_Destruct(&p->hashSync);
|
||||
MtSync_Destruct(&p->btSync);
|
||||
MatchFinderMt_FreeMem(p, alloc);
|
||||
}
|
||||
|
||||
#define kHashBufferSize (kMtHashBlockSize * kMtHashNumBlocks)
|
||||
#define kBtBufferSize (kMtBtBlockSize * kMtBtNumBlocks)
|
||||
|
||||
static unsigned MY_STD_CALL HashThreadFunc2(void *p) { HashThreadFunc((CMatchFinderMt *)p); return 0; }
|
||||
static unsigned MY_STD_CALL BtThreadFunc2(void *p)
|
||||
{
|
||||
Byte allocaDummy[0x180];
|
||||
int i = 0;
|
||||
for (i = 0; i < 16; i++)
|
||||
allocaDummy[i] = (Byte)i;
|
||||
BtThreadFunc((CMatchFinderMt *)p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc)
|
||||
{
|
||||
CMatchFinder *mf = p->MatchFinder;
|
||||
p->historySize = historySize;
|
||||
if (kMtBtBlockSize <= matchMaxLen * 4)
|
||||
return SZ_ERROR_PARAM;
|
||||
if (p->hashBuf == 0)
|
||||
{
|
||||
p->hashBuf = (UInt32 *)alloc->Alloc(alloc, (kHashBufferSize + kBtBufferSize) * sizeof(UInt32));
|
||||
if (p->hashBuf == 0)
|
||||
return SZ_ERROR_MEM;
|
||||
p->btBuf = p->hashBuf + kHashBufferSize;
|
||||
}
|
||||
keepAddBufferBefore += (kHashBufferSize + kBtBufferSize);
|
||||
keepAddBufferAfter += kMtHashBlockSize;
|
||||
if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc))
|
||||
return SZ_ERROR_MEM;
|
||||
|
||||
RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p, kMtHashNumBlocks));
|
||||
RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p, kMtBtNumBlocks));
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
/* Call it after ReleaseStream / SetStream */
|
||||
void MatchFinderMt_Init(CMatchFinderMt *p)
|
||||
{
|
||||
CMatchFinder *mf = p->MatchFinder;
|
||||
p->btBufPos = p->btBufPosLimit = 0;
|
||||
p->hashBufPos = p->hashBufPosLimit = 0;
|
||||
MatchFinder_Init(mf);
|
||||
p->pointerToCurPos = MatchFinder_GetPointerToCurrentPos(mf);
|
||||
p->btNumAvailBytes = 0;
|
||||
p->lzPos = p->historySize + 1;
|
||||
|
||||
p->hash = mf->hash;
|
||||
p->fixedHashSize = mf->fixedHashSize;
|
||||
p->crc = mf->crc;
|
||||
|
||||
p->son = mf->son;
|
||||
p->matchMaxLen = mf->matchMaxLen;
|
||||
p->numHashBytes = mf->numHashBytes;
|
||||
p->pos = mf->pos;
|
||||
p->buffer = mf->buffer;
|
||||
p->cyclicBufferPos = mf->cyclicBufferPos;
|
||||
p->cyclicBufferSize = mf->cyclicBufferSize;
|
||||
p->cutValue = mf->cutValue;
|
||||
}
|
||||
|
||||
/* ReleaseStream is required to finish multithreading */
|
||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p)
|
||||
{
|
||||
MtSync_StopWriting(&p->btSync);
|
||||
/* p->MatchFinder->ReleaseStream(); */
|
||||
}
|
||||
|
||||
void MatchFinderMt_Normalize(CMatchFinderMt *p)
|
||||
{
|
||||
MatchFinder_Normalize3(p->lzPos - p->historySize - 1, p->hash, p->fixedHashSize);
|
||||
p->lzPos = p->historySize + 1;
|
||||
}
|
||||
|
||||
void MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p)
|
||||
{
|
||||
UInt32 blockIndex;
|
||||
MtSync_GetNextBlock(&p->btSync);
|
||||
blockIndex = ((p->btSync.numProcessedBlocks - 1) & kMtBtNumBlocksMask);
|
||||
p->btBufPosLimit = p->btBufPos = blockIndex * kMtBtBlockSize;
|
||||
p->btBufPosLimit += p->btBuf[p->btBufPos++];
|
||||
p->btNumAvailBytes = p->btBuf[p->btBufPos++];
|
||||
if (p->lzPos >= kMtMaxValForNormalize - kMtBtBlockSize)
|
||||
MatchFinderMt_Normalize(p);
|
||||
}
|
||||
|
||||
const Byte * MatchFinderMt_GetPointerToCurrentPos(CMatchFinderMt *p)
|
||||
{
|
||||
return p->pointerToCurPos;
|
||||
}
|
||||
|
||||
#define GET_NEXT_BLOCK_IF_REQUIRED if (p->btBufPos == p->btBufPosLimit) MatchFinderMt_GetNextBlock_Bt(p);
|
||||
|
||||
UInt32 MatchFinderMt_GetNumAvailableBytes(CMatchFinderMt *p)
|
||||
{
|
||||
GET_NEXT_BLOCK_IF_REQUIRED;
|
||||
return p->btNumAvailBytes;
|
||||
}
|
||||
|
||||
Byte MatchFinderMt_GetIndexByte(CMatchFinderMt *p, Int32 index)
|
||||
{
|
||||
return p->pointerToCurPos[index];
|
||||
}
|
||||
|
||||
UInt32 * MixMatches2(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, curMatch2;
|
||||
UInt32 *hash = p->hash;
|
||||
const Byte *cur = p->pointerToCurPos;
|
||||
UInt32 lzPos = p->lzPos;
|
||||
MT_HASH2_CALC
|
||||
|
||||
curMatch2 = hash[hash2Value];
|
||||
hash[hash2Value] = lzPos;
|
||||
|
||||
if (curMatch2 >= matchMinPos)
|
||||
if (cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||
{
|
||||
*distances++ = 2;
|
||||
*distances++ = lzPos - curMatch2 - 1;
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
|
||||
UInt32 * MixMatches3(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, curMatch2, curMatch3;
|
||||
UInt32 *hash = p->hash;
|
||||
const Byte *cur = p->pointerToCurPos;
|
||||
UInt32 lzPos = p->lzPos;
|
||||
MT_HASH3_CALC
|
||||
|
||||
curMatch2 = hash[ hash2Value];
|
||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||
|
||||
hash[ hash2Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
lzPos;
|
||||
|
||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||
{
|
||||
distances[1] = lzPos - curMatch2 - 1;
|
||||
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||
{
|
||||
distances[0] = 3;
|
||||
return distances + 2;
|
||||
}
|
||||
distances[0] = 2;
|
||||
distances += 2;
|
||||
}
|
||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||
{
|
||||
*distances++ = 3;
|
||||
*distances++ = lzPos - curMatch3 - 1;
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
|
||||
/*
|
||||
UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *distances)
|
||||
{
|
||||
UInt32 hash2Value, hash3Value, hash4Value, curMatch2, curMatch3, curMatch4;
|
||||
UInt32 *hash = p->hash;
|
||||
const Byte *cur = p->pointerToCurPos;
|
||||
UInt32 lzPos = p->lzPos;
|
||||
MT_HASH4_CALC
|
||||
|
||||
curMatch2 = hash[ hash2Value];
|
||||
curMatch3 = hash[kFix3HashSize + hash3Value];
|
||||
curMatch4 = hash[kFix4HashSize + hash4Value];
|
||||
|
||||
hash[ hash2Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[kFix4HashSize + hash4Value] =
|
||||
lzPos;
|
||||
|
||||
if (curMatch2 >= matchMinPos && cur[(ptrdiff_t)curMatch2 - lzPos] == cur[0])
|
||||
{
|
||||
distances[1] = lzPos - curMatch2 - 1;
|
||||
if (cur[(ptrdiff_t)curMatch2 - lzPos + 2] == cur[2])
|
||||
{
|
||||
distances[0] = (cur[(ptrdiff_t)curMatch2 - lzPos + 3] == cur[3]) ? 4 : 3;
|
||||
return distances + 2;
|
||||
}
|
||||
distances[0] = 2;
|
||||
distances += 2;
|
||||
}
|
||||
if (curMatch3 >= matchMinPos && cur[(ptrdiff_t)curMatch3 - lzPos] == cur[0])
|
||||
{
|
||||
distances[1] = lzPos - curMatch3 - 1;
|
||||
if (cur[(ptrdiff_t)curMatch3 - lzPos + 3] == cur[3])
|
||||
{
|
||||
distances[0] = 4;
|
||||
return distances + 2;
|
||||
}
|
||||
distances[0] = 3;
|
||||
distances += 2;
|
||||
}
|
||||
|
||||
if (curMatch4 >= matchMinPos)
|
||||
if (
|
||||
cur[(ptrdiff_t)curMatch4 - lzPos] == cur[0] &&
|
||||
cur[(ptrdiff_t)curMatch4 - lzPos + 3] == cur[3]
|
||||
)
|
||||
{
|
||||
*distances++ = 4;
|
||||
*distances++ = lzPos - curMatch4 - 1;
|
||||
}
|
||||
return distances;
|
||||
}
|
||||
*/
|
||||
|
||||
#define INCREASE_LZ_POS p->lzPos++; p->pointerToCurPos++;
|
||||
|
||||
UInt32 MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||
UInt32 len = *btBuf++;
|
||||
p->btBufPos += 1 + len;
|
||||
p->btNumAvailBytes--;
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < len; i += 2)
|
||||
{
|
||||
*distances++ = *btBuf++;
|
||||
*distances++ = *btBuf++;
|
||||
}
|
||||
}
|
||||
INCREASE_LZ_POS
|
||||
return len;
|
||||
}
|
||||
|
||||
UInt32 MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *distances)
|
||||
{
|
||||
const UInt32 *btBuf = p->btBuf + p->btBufPos;
|
||||
UInt32 len = *btBuf++;
|
||||
p->btBufPos += 1 + len;
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
if (p->btNumAvailBytes-- >= 4)
|
||||
len = (UInt32)(p->MixMatchesFunc(p, p->lzPos - p->historySize, distances) - (distances));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Condition: there are matches in btBuf with length < p->numHashBytes */
|
||||
UInt32 *distances2;
|
||||
p->btNumAvailBytes--;
|
||||
distances2 = p->MixMatchesFunc(p, p->lzPos - btBuf[1], distances);
|
||||
do
|
||||
{
|
||||
*distances2++ = *btBuf++;
|
||||
*distances2++ = *btBuf++;
|
||||
}
|
||||
while ((len -= 2) != 0);
|
||||
len = (UInt32)(distances2 - (distances));
|
||||
}
|
||||
INCREASE_LZ_POS
|
||||
return len;
|
||||
}
|
||||
|
||||
#define SKIP_HEADER2 do { GET_NEXT_BLOCK_IF_REQUIRED
|
||||
#define SKIP_HEADER(n) SKIP_HEADER2 if (p->btNumAvailBytes-- >= (n)) { const Byte *cur = p->pointerToCurPos; UInt32 *hash = p->hash;
|
||||
#define SKIP_FOOTER } INCREASE_LZ_POS p->btBufPos += p->btBuf[p->btBufPos] + 1; } while (--num != 0);
|
||||
|
||||
void MatchFinderMt0_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER2 { p->btNumAvailBytes--;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
|
||||
void MatchFinderMt2_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(2)
|
||||
UInt32 hash2Value;
|
||||
MT_HASH2_CALC
|
||||
hash[hash2Value] = p->lzPos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
|
||||
void MatchFinderMt3_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(3)
|
||||
UInt32 hash2Value, hash3Value;
|
||||
MT_HASH3_CALC
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[ hash2Value] =
|
||||
p->lzPos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
|
||||
/*
|
||||
void MatchFinderMt4_Skip(CMatchFinderMt *p, UInt32 num)
|
||||
{
|
||||
SKIP_HEADER(4)
|
||||
UInt32 hash2Value, hash3Value, hash4Value;
|
||||
MT_HASH4_CALC
|
||||
hash[kFix4HashSize + hash4Value] =
|
||||
hash[kFix3HashSize + hash3Value] =
|
||||
hash[ hash2Value] =
|
||||
p->lzPos;
|
||||
SKIP_FOOTER
|
||||
}
|
||||
*/
|
||||
|
||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable)
|
||||
{
|
||||
vTable->Init = (Mf_Init_Func)MatchFinderMt_Init;
|
||||
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinderMt_GetIndexByte;
|
||||
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinderMt_GetNumAvailableBytes;
|
||||
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinderMt_GetPointerToCurrentPos;
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt_GetMatches;
|
||||
switch(p->MatchFinder->numHashBytes)
|
||||
{
|
||||
case 2:
|
||||
p->GetHeadsFunc = GetHeads2;
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)0;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt0_Skip;
|
||||
vTable->GetMatches = (Mf_GetMatches_Func)MatchFinderMt2_GetMatches;
|
||||
break;
|
||||
case 3:
|
||||
p->GetHeadsFunc = GetHeads3;
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches2;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt2_Skip;
|
||||
break;
|
||||
default:
|
||||
/* case 4: */
|
||||
p->GetHeadsFunc = p->MatchFinder->bigHash ? GetHeads4b : GetHeads4;
|
||||
/* p->GetHeadsFunc = GetHeads4; */
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches3;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt3_Skip;
|
||||
break;
|
||||
/*
|
||||
default:
|
||||
p->GetHeadsFunc = GetHeads5;
|
||||
p->MixMatchesFunc = (Mf_Mix_Matches)MixMatches4;
|
||||
vTable->Skip = (Mf_Skip_Func)MatchFinderMt4_Skip;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
}
|
97
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h
Normal file
97
BaseTools/Source/C/LzmaCompress/Sdk/C/LzFindMt.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZFINDMT_H
|
||||
#define __LZFINDMT_H
|
||||
|
||||
#include "Threads.h"
|
||||
#include "LzFind.h"
|
||||
|
||||
#define kMtHashBlockSize (1 << 13)
|
||||
#define kMtHashNumBlocks (1 << 3)
|
||||
#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
|
||||
|
||||
#define kMtBtBlockSize (1 << 14)
|
||||
#define kMtBtNumBlocks (1 << 6)
|
||||
#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
|
||||
|
||||
typedef struct _CMtSync
|
||||
{
|
||||
Bool wasCreated;
|
||||
Bool needStart;
|
||||
Bool exit;
|
||||
Bool stopWriting;
|
||||
|
||||
CThread thread;
|
||||
CAutoResetEvent canStart;
|
||||
CAutoResetEvent wasStarted;
|
||||
CAutoResetEvent wasStopped;
|
||||
CSemaphore freeSemaphore;
|
||||
CSemaphore filledSemaphore;
|
||||
Bool csWasInitialized;
|
||||
Bool csWasEntered;
|
||||
CCriticalSection cs;
|
||||
UInt32 numProcessedBlocks;
|
||||
} CMtSync;
|
||||
|
||||
typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
|
||||
|
||||
/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
|
||||
#define kMtCacheLineDummy 128
|
||||
|
||||
typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
|
||||
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
|
||||
|
||||
typedef struct _CMatchFinderMt
|
||||
{
|
||||
/* LZ */
|
||||
const Byte *pointerToCurPos;
|
||||
UInt32 *btBuf;
|
||||
UInt32 btBufPos;
|
||||
UInt32 btBufPosLimit;
|
||||
UInt32 lzPos;
|
||||
UInt32 btNumAvailBytes;
|
||||
|
||||
UInt32 *hash;
|
||||
UInt32 fixedHashSize;
|
||||
UInt32 historySize;
|
||||
const UInt32 *crc;
|
||||
|
||||
Mf_Mix_Matches MixMatchesFunc;
|
||||
|
||||
/* LZ + BT */
|
||||
CMtSync btSync;
|
||||
Byte btDummy[kMtCacheLineDummy];
|
||||
|
||||
/* BT */
|
||||
UInt32 *hashBuf;
|
||||
UInt32 hashBufPos;
|
||||
UInt32 hashBufPosLimit;
|
||||
UInt32 hashNumAvail;
|
||||
|
||||
CLzRef *son;
|
||||
UInt32 matchMaxLen;
|
||||
UInt32 numHashBytes;
|
||||
UInt32 pos;
|
||||
Byte *buffer;
|
||||
UInt32 cyclicBufferPos;
|
||||
UInt32 cyclicBufferSize; /* it must be historySize + 1 */
|
||||
UInt32 cutValue;
|
||||
|
||||
/* BT + Hash */
|
||||
CMtSync hashSync;
|
||||
/* Byte hashDummy[kMtCacheLineDummy]; */
|
||||
|
||||
/* Hash */
|
||||
Mf_GetHeads GetHeadsFunc;
|
||||
CMatchFinder *MatchFinder;
|
||||
} CMatchFinderMt;
|
||||
|
||||
void MatchFinderMt_Construct(CMatchFinderMt *p);
|
||||
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
|
||||
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
|
||||
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
|
||||
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
|
||||
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
|
||||
|
||||
#endif
|
54
BaseTools/Source/C/LzmaCompress/Sdk/C/LzHash.h
Normal file
54
BaseTools/Source/C/LzmaCompress/Sdk/C/LzHash.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/* LzHash.h -- HASH functions for LZ algorithms
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZHASH_H
|
||||
#define __LZHASH_H
|
||||
|
||||
#define kHash2Size (1 << 10)
|
||||
#define kHash3Size (1 << 16)
|
||||
#define kHash4Size (1 << 20)
|
||||
|
||||
#define kFix3HashSize (kHash2Size)
|
||||
#define kFix4HashSize (kHash2Size + kHash3Size)
|
||||
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
|
||||
|
||||
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
|
||||
|
||||
#define HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
|
||||
|
||||
#define HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
|
||||
|
||||
#define HASH5_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
|
||||
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
|
||||
hash4Value &= (kHash4Size - 1); }
|
||||
|
||||
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
|
||||
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
|
||||
|
||||
|
||||
#define MT_HASH2_CALC \
|
||||
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
|
||||
|
||||
#define MT_HASH3_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
|
||||
|
||||
#define MT_HASH4_CALC { \
|
||||
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
|
||||
hash2Value = temp & (kHash2Size - 1); \
|
||||
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
|
||||
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
|
||||
|
||||
#endif
|
1007
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c
Normal file
1007
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.c
Normal file
File diff suppressed because it is too large
Load Diff
223
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h
Normal file
223
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaDec.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/* LzmaDec.h -- LZMA Decoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMADEC_H
|
||||
#define __LZMADEC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
/* #define _LZMA_PROB32 */
|
||||
/* _LZMA_PROB32 can increase the speed on some CPUs,
|
||||
but memory usage for CLzmaDec::probs will be doubled in that case */
|
||||
|
||||
#ifdef _LZMA_PROB32
|
||||
#define CLzmaProb UInt32
|
||||
#else
|
||||
#define CLzmaProb UInt16
|
||||
#endif
|
||||
|
||||
|
||||
/* ---------- LZMA Properties ---------- */
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaProps
|
||||
{
|
||||
unsigned lc, lp, pb;
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
/* LzmaProps_Decode - decodes properties
|
||||
Returns:
|
||||
SZ_OK
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
|
||||
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
|
||||
|
||||
#define LZMA_REQUIRED_INPUT_MAX 20
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CLzmaProps prop;
|
||||
CLzmaProb *probs;
|
||||
Byte *dic;
|
||||
const Byte *buf;
|
||||
UInt32 range, code;
|
||||
SizeT dicPos;
|
||||
SizeT dicBufSize;
|
||||
UInt32 processedPos;
|
||||
UInt32 checkDicSize;
|
||||
unsigned state;
|
||||
UInt32 reps[4];
|
||||
unsigned remainLen;
|
||||
int needFlush;
|
||||
int needInitState;
|
||||
UInt32 numProbs;
|
||||
unsigned tempBufSize;
|
||||
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
|
||||
} CLzmaDec;
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
void LzmaDec_Init(CLzmaDec *p);
|
||||
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_FINISH_ANY, /* finish at any point */
|
||||
LZMA_FINISH_END /* block must be finished at the end */
|
||||
} ELzmaFinishMode;
|
||||
|
||||
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
|
||||
|
||||
You must use LZMA_FINISH_END, when you know that current output buffer
|
||||
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
|
||||
|
||||
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
|
||||
and output value of destLen will be less than output buffer size limit.
|
||||
You can check status result also.
|
||||
|
||||
You can use multiple checks to test data integrity after full decompression:
|
||||
1) Check Result and "status" variable.
|
||||
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
|
||||
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
|
||||
You must use correct finish mode in that case. */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
|
||||
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
|
||||
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
|
||||
} ELzmaStatus;
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
|
||||
/* ---------- Interfaces ---------- */
|
||||
|
||||
/* There are 3 levels of interfaces:
|
||||
1) Dictionary Interface
|
||||
2) Buffer Interface
|
||||
3) One Call Interface
|
||||
You can select any of these interfaces, but don't mix functions from different
|
||||
groups for same object. */
|
||||
|
||||
|
||||
/* There are two variants to allocate state for Dictionary Interface:
|
||||
1) LzmaDec_Allocate / LzmaDec_Free
|
||||
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
You can use variant 2, if you set dictionary buffer manually.
|
||||
For Buffer Interface you must always use variant 1.
|
||||
|
||||
LzmaDec_Allocate* can return:
|
||||
SZ_OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
*/
|
||||
|
||||
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
|
||||
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
|
||||
/* ---------- Dictionary Interface ---------- */
|
||||
|
||||
/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
dictionary to some other external buffer.
|
||||
You must work with CLzmaDec variables directly in this interface.
|
||||
|
||||
STEPS:
|
||||
LzmaDec_Constr()
|
||||
LzmaDec_Allocate()
|
||||
for (each new stream)
|
||||
{
|
||||
LzmaDec_Init()
|
||||
while (it needs more decompression)
|
||||
{
|
||||
LzmaDec_DecodeToDic()
|
||||
use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
}
|
||||
}
|
||||
LzmaDec_Free()
|
||||
*/
|
||||
|
||||
/* LzmaDec_DecodeToDic
|
||||
|
||||
The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- Buffer Interface ---------- */
|
||||
|
||||
/* It's zlib-like interface.
|
||||
See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||
to work with CLzmaDec variables manually.
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
*/
|
||||
|
||||
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
|
||||
finishMode:
|
||||
It has meaning only if the decoding reaches output limit (*destLen).
|
||||
LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
|
||||
Returns:
|
||||
SZ_OK
|
||||
status:
|
||||
LZMA_STATUS_FINISHED_WITH_MARK
|
||||
LZMA_STATUS_NOT_FINISHED
|
||||
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
SZ_ERROR_DATA - Data error
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
|
||||
*/
|
||||
|
||||
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
|
||||
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
|
||||
ELzmaStatus *status, ISzAlloc *alloc);
|
||||
|
||||
#endif
|
2281
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
Normal file
2281
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
Normal file
File diff suppressed because it is too large
Load Diff
72
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h
Normal file
72
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/* LzmaEnc.h -- LZMA Encoder
|
||||
2008-10-04 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __LZMAENC_H
|
||||
#define __LZMAENC_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#define LZMA_PROPS_SIZE 5
|
||||
|
||||
typedef struct _CLzmaEncProps
|
||||
{
|
||||
int level; /* 0 <= level <= 9 */
|
||||
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
|
||||
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
|
||||
default = (1 << 24) */
|
||||
int lc; /* 0 <= lc <= 8, default = 3 */
|
||||
int lp; /* 0 <= lp <= 4, default = 0 */
|
||||
int pb; /* 0 <= pb <= 4, default = 2 */
|
||||
int algo; /* 0 - fast, 1 - normal, default = 1 */
|
||||
int fb; /* 5 <= fb <= 273, default = 32 */
|
||||
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
|
||||
int numHashBytes; /* 2, 3 or 4, default = 4 */
|
||||
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
|
||||
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
|
||||
int numThreads; /* 1 or 2, default = 2 */
|
||||
} CLzmaEncProps;
|
||||
|
||||
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||
void LzmaEncProps_Normalize(CLzmaEncProps *p);
|
||||
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
||||
|
||||
|
||||
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||
|
||||
/* LzmaEnc_* functions can return the following exit codes:
|
||||
Returns:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater in props
|
||||
SZ_ERROR_WRITE - Write callback error.
|
||||
SZ_ERROR_PROGRESS - some break from progress callback
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
typedef void * CLzmaEncHandle;
|
||||
|
||||
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
|
||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaEncode
|
||||
Return code:
|
||||
SZ_OK - OK
|
||||
SZ_ERROR_MEM - Memory allocation error
|
||||
SZ_ERROR_PARAM - Incorrect paramater
|
||||
SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
*/
|
||||
|
||||
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
#endif
|
109
BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c
Normal file
109
BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/* Threads.c -- multithreading library
|
||||
2008-08-05
|
||||
Igor Pavlov
|
||||
Public domain */
|
||||
|
||||
#include "Threads.h"
|
||||
#include <process.h>
|
||||
|
||||
static WRes GetError()
|
||||
{
|
||||
DWORD res = GetLastError();
|
||||
return (res) ? (WRes)(res) : 1;
|
||||
}
|
||||
|
||||
WRes HandleToWRes(HANDLE h) { return (h != 0) ? 0 : GetError(); }
|
||||
WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
|
||||
|
||||
static WRes MyCloseHandle(HANDLE *h)
|
||||
{
|
||||
if (*h != NULL)
|
||||
if (!CloseHandle(*h))
|
||||
return GetError();
|
||||
*h = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter)
|
||||
{
|
||||
unsigned threadId; /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
|
||||
thread->handle =
|
||||
/* CreateThread(0, 0, startAddress, parameter, 0, &threadId); */
|
||||
(HANDLE)_beginthreadex(NULL, 0, startAddress, parameter, 0, &threadId);
|
||||
/* maybe we must use errno here, but probably GetLastError() is also OK. */
|
||||
return HandleToWRes(thread->handle);
|
||||
}
|
||||
|
||||
WRes WaitObject(HANDLE h)
|
||||
{
|
||||
return (WRes)WaitForSingleObject(h, INFINITE);
|
||||
}
|
||||
|
||||
WRes Thread_Wait(CThread *thread)
|
||||
{
|
||||
if (thread->handle == NULL)
|
||||
return 1;
|
||||
return WaitObject(thread->handle);
|
||||
}
|
||||
|
||||
WRes Thread_Close(CThread *thread)
|
||||
{
|
||||
return MyCloseHandle(&thread->handle);
|
||||
}
|
||||
|
||||
WRes Event_Create(CEvent *p, BOOL manualReset, int initialSignaled)
|
||||
{
|
||||
p->handle = CreateEvent(NULL, manualReset, (initialSignaled ? TRUE : FALSE), NULL);
|
||||
return HandleToWRes(p->handle);
|
||||
}
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, TRUE, initialSignaled); }
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
|
||||
{ return ManualResetEvent_Create(p, 0); }
|
||||
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *p, int initialSignaled)
|
||||
{ return Event_Create(p, FALSE, initialSignaled); }
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
|
||||
{ return AutoResetEvent_Create(p, 0); }
|
||||
|
||||
WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(p->handle)); }
|
||||
WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(p->handle)); }
|
||||
WRes Event_Wait(CEvent *p) { return WaitObject(p->handle); }
|
||||
WRes Event_Close(CEvent *p) { return MyCloseHandle(&p->handle); }
|
||||
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount)
|
||||
{
|
||||
p->handle = CreateSemaphore(NULL, (LONG)initiallyCount, (LONG)maxCount, NULL);
|
||||
return HandleToWRes(p->handle);
|
||||
}
|
||||
|
||||
WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
|
||||
{
|
||||
return BOOLToWRes(ReleaseSemaphore(p->handle, releaseCount, previousCount));
|
||||
}
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
|
||||
{
|
||||
return Semaphore_Release(p, (LONG)releaseCount, NULL);
|
||||
}
|
||||
WRes Semaphore_Release1(CSemaphore *p)
|
||||
{
|
||||
return Semaphore_ReleaseN(p, 1);
|
||||
}
|
||||
|
||||
WRes Semaphore_Wait(CSemaphore *p) { return WaitObject(p->handle); }
|
||||
WRes Semaphore_Close(CSemaphore *p) { return MyCloseHandle(&p->handle); }
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p)
|
||||
{
|
||||
/* InitializeCriticalSection can raise only STATUS_NO_MEMORY exception */
|
||||
__try
|
||||
{
|
||||
InitializeCriticalSection(p);
|
||||
/* InitializeCriticalSectionAndSpinCount(p, 0); */
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) { return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
68
BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h
Normal file
68
BaseTools/Source/C/LzmaCompress/Sdk/C/Threads.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* Threads.h -- multithreading library
|
||||
2008-11-22 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_THRESDS_H
|
||||
#define __7Z_THRESDS_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
typedef struct _CThread
|
||||
{
|
||||
HANDLE handle;
|
||||
} CThread;
|
||||
|
||||
#define Thread_Construct(thread) (thread)->handle = NULL
|
||||
#define Thread_WasCreated(thread) ((thread)->handle != NULL)
|
||||
|
||||
typedef unsigned THREAD_FUNC_RET_TYPE;
|
||||
#define THREAD_FUNC_CALL_TYPE MY_STD_CALL
|
||||
#define THREAD_FUNC_DECL THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE
|
||||
|
||||
WRes Thread_Create(CThread *thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter);
|
||||
WRes Thread_Wait(CThread *thread);
|
||||
WRes Thread_Close(CThread *thread);
|
||||
|
||||
typedef struct _CEvent
|
||||
{
|
||||
HANDLE handle;
|
||||
} CEvent;
|
||||
|
||||
typedef CEvent CAutoResetEvent;
|
||||
typedef CEvent CManualResetEvent;
|
||||
|
||||
#define Event_Construct(event) (event)->handle = NULL
|
||||
#define Event_IsCreated(event) ((event)->handle != NULL)
|
||||
|
||||
WRes ManualResetEvent_Create(CManualResetEvent *event, int initialSignaled);
|
||||
WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *event);
|
||||
WRes AutoResetEvent_Create(CAutoResetEvent *event, int initialSignaled);
|
||||
WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *event);
|
||||
WRes Event_Set(CEvent *event);
|
||||
WRes Event_Reset(CEvent *event);
|
||||
WRes Event_Wait(CEvent *event);
|
||||
WRes Event_Close(CEvent *event);
|
||||
|
||||
|
||||
typedef struct _CSemaphore
|
||||
{
|
||||
HANDLE handle;
|
||||
} CSemaphore;
|
||||
|
||||
#define Semaphore_Construct(p) (p)->handle = NULL
|
||||
|
||||
WRes Semaphore_Create(CSemaphore *p, UInt32 initiallyCount, UInt32 maxCount);
|
||||
WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);
|
||||
WRes Semaphore_Release1(CSemaphore *p);
|
||||
WRes Semaphore_Wait(CSemaphore *p);
|
||||
WRes Semaphore_Close(CSemaphore *p);
|
||||
|
||||
|
||||
typedef CRITICAL_SECTION CCriticalSection;
|
||||
|
||||
WRes CriticalSection_Init(CCriticalSection *p);
|
||||
#define CriticalSection_Delete(p) DeleteCriticalSection(p)
|
||||
#define CriticalSection_Enter(p) EnterCriticalSection(p)
|
||||
#define CriticalSection_Leave(p) LeaveCriticalSection(p)
|
||||
|
||||
#endif
|
||||
|
208
BaseTools/Source/C/LzmaCompress/Sdk/C/Types.h
Normal file
208
BaseTools/Source/C/LzmaCompress/Sdk/C/Types.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/* Types.h -- Basic types
|
||||
2008-11-23 : Igor Pavlov : Public domain */
|
||||
|
||||
#ifndef __7Z_TYPES_H
|
||||
#define __7Z_TYPES_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define SZ_OK 0
|
||||
|
||||
#define SZ_ERROR_DATA 1
|
||||
#define SZ_ERROR_MEM 2
|
||||
#define SZ_ERROR_CRC 3
|
||||
#define SZ_ERROR_UNSUPPORTED 4
|
||||
#define SZ_ERROR_PARAM 5
|
||||
#define SZ_ERROR_INPUT_EOF 6
|
||||
#define SZ_ERROR_OUTPUT_EOF 7
|
||||
#define SZ_ERROR_READ 8
|
||||
#define SZ_ERROR_WRITE 9
|
||||
#define SZ_ERROR_PROGRESS 10
|
||||
#define SZ_ERROR_FAIL 11
|
||||
#define SZ_ERROR_THREAD 12
|
||||
|
||||
#define SZ_ERROR_ARCHIVE 16
|
||||
#define SZ_ERROR_NO_ARCHIVE 17
|
||||
|
||||
typedef int SRes;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef DWORD WRes;
|
||||
#else
|
||||
typedef int WRes;
|
||||
#endif
|
||||
|
||||
#ifndef RINOK
|
||||
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
|
||||
#endif
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#ifdef _LZMA_UINT32_IS_ULONG
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
#else
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
#endif
|
||||
|
||||
#ifdef _SZ_NO_INT_64
|
||||
|
||||
/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
|
||||
NOTES: Some code will work incorrectly in that case! */
|
||||
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
typedef long long int Int64;
|
||||
typedef unsigned long long int UInt64;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _LZMA_NO_SYSTEM_SIZE_T
|
||||
typedef UInt32 SizeT;
|
||||
#else
|
||||
typedef size_t SizeT;
|
||||
#endif
|
||||
|
||||
typedef int Bool;
|
||||
#define True 1
|
||||
#define False 0
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1300
|
||||
#define MY_NO_INLINE __declspec(noinline)
|
||||
#else
|
||||
#define MY_NO_INLINE
|
||||
#endif
|
||||
|
||||
#define MY_CDECL __cdecl
|
||||
#define MY_STD_CALL __stdcall
|
||||
#define MY_FAST_CALL MY_NO_INLINE __fastcall
|
||||
|
||||
#else
|
||||
|
||||
#define MY_CDECL
|
||||
#define MY_STD_CALL
|
||||
#define MY_FAST_CALL
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* The following interfaces use first parameter as pointer to structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
} ISeqInStream;
|
||||
|
||||
/* it can return SZ_ERROR_INPUT_EOF */
|
||||
SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
|
||||
SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t (*Write)(void *p, const void *buf, size_t size);
|
||||
/* Returns: result - the number of actually written bytes.
|
||||
(result < size) means error */
|
||||
} ISeqOutStream;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SZ_SEEK_SET = 0,
|
||||
SZ_SEEK_CUR = 1,
|
||||
SZ_SEEK_END = 2
|
||||
} ESzSeek;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ISeekInStream;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Look)(void *p, void **buf, size_t *size);
|
||||
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
|
||||
(output(*size) > input(*size)) is not allowed
|
||||
(output(*size) < input(*size)) is allowed */
|
||||
SRes (*Skip)(void *p, size_t offset);
|
||||
/* offset must be <= output(*size) of Look */
|
||||
|
||||
SRes (*Read)(void *p, void *buf, size_t *size);
|
||||
/* reads directly (without buffer). It's same as ISeqInStream::Read */
|
||||
SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
|
||||
} ILookInStream;
|
||||
|
||||
SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
|
||||
SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
|
||||
|
||||
/* reads via ILookInStream::Read */
|
||||
SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
|
||||
SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
|
||||
|
||||
#define LookToRead_BUF_SIZE (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ILookInStream s;
|
||||
ISeekInStream *realStream;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
Byte buf[LookToRead_BUF_SIZE];
|
||||
} CLookToRead;
|
||||
|
||||
void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
|
||||
void LookToRead_Init(CLookToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToLook;
|
||||
|
||||
void SecToLook_CreateVTable(CSecToLook *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ISeqInStream s;
|
||||
ILookInStream *realStream;
|
||||
} CSecToRead;
|
||||
|
||||
void SecToRead_CreateVTable(CSecToRead *p);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
|
||||
/* Returns: result. (result != SZ_OK) means break.
|
||||
Value (UInt64)(Int64)-1 for size means unknown value. */
|
||||
} ICompressProgress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*Alloc)(void *p, size_t size);
|
||||
void (*Free)(void *p, void *address); /* address can be 0 */
|
||||
} ISzAlloc;
|
||||
|
||||
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
|
||||
#define IAlloc_Free(p, a) (p)->Free((p), a)
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user