1
0
Fork 0

Merging upstream version 1.4~rc1.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-23 19:16:24 +01:00
parent ef8a63ecab
commit be19348aea
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
29 changed files with 4714 additions and 5971 deletions

240
7zFile.c
View file

@ -1,240 +0,0 @@
/* 7zFile.c -- File IO
2009-11-24 : Igor Pavlov : Public domain */
#define _FILE_OFFSET_BITS 64
#include "7zFile.h"
#ifndef USE_WINDOWS_FILE
#ifndef UNDER_CE
#include <errno.h>
#endif
#else
/*
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
}
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
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
if( !name[0] ) p->file = writeMode ? stdout : stdin;
else p->file = fopen(name, writeMode ? "wb+" : "rb");
return (p->file != 0) ? 0 :
#ifdef UNDER_CE
2; /* ENOENT */
#else
errno;
#endif
#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); }
#endif
#ifdef USE_WINDOWS_FILE
static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode)
{
p->handle = CreateFileW(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();
}
WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); }
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); }
#endif
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
}
/* ---------- 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;
}
/* ---------- 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;
}

View file

@ -1,80 +0,0 @@
/* 7zFile.h -- File IO
2009-11-24 : 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"
EXTERN_C_BEGIN
/* ---------- File ---------- */
typedef struct
{
#ifdef USE_WINDOWS_FILE
HANDLE handle;
#else
FILE *file;
#endif
} CSzFile;
void File_Construct(CSzFile *p);
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
WRes InFile_Open(CSzFile *p, const char *name);
WRes OutFile_Open(CSzFile *p, const char *name);
#endif
#ifdef USE_WINDOWS_FILE
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
#endif
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);
/* ---------- FileInStream ---------- */
typedef struct
{
ISeqInStream s;
CSzFile file;
} CFileSeqInStream;
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct
{
ISeekInStream s;
CSzFile file;
} CFileInStream;
typedef struct
{
ISeqOutStream s;
CSzFile file;
} CFileOutStream;
void FileOutStream_CreateVTable(CFileOutStream *p);
EXTERN_C_END
#endif

View file

@ -1,164 +0,0 @@
/* 7zStream.c -- 7z Stream functions
2008-11-23 : Igor Pavlov : Public domain */
#define _FILE_OFFSET_BITS 64
#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 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;
}

127
Alloc.c
View file

@ -1,127 +0,0 @@
/* Alloc.c -- Memory allocation functions
2008-09-24 : Igor Pavlov : Public domain */
#define _FILE_OFFSET_BITS 64
#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

38
Alloc.h
View file

@ -1,38 +0,0 @@
/* Alloc.h -- Memory allocation functions
2009-02-07 : Igor Pavlov : Public domain */
#ifndef __COMMON_ALLOC_H
#define __COMMON_ALLOC_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
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
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,3 +1,17 @@
2013-02-18 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.4-rc1 released.
* main.c: Added new option '-f, --force'.
* main.c: Added new option '-F, --recompress'.
* main.c: Added new option '-k, --keep'.
* main.c: Added new option '-o, --output'.
* main.c: Accept more than one file in command line.
* Decompression time has been reduced by 5%.
* main.c: '--test' no more needs '/dev/null'.
* configure: 'datadir' renamed to 'datarootdir'.
* Makefile.in: Added new target 'install-as-lzip'.
* Makefile.in: Added new target 'install-bin'.
2012-01-03 Antonio Diaz Diaz <ant_diaz@teleline.es> 2012-01-03 Antonio Diaz Diaz <ant_diaz@teleline.es>
* Version 1.3 released. * Version 1.3 released.
@ -27,7 +41,7 @@
* Using LZMA SDK 9.10 (public domain) from Igor Pavlov. * Using LZMA SDK 9.10 (public domain) from Igor Pavlov.
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
This file is a collection of facts, and thus it is not copyrightable, This file is a collection of facts, and thus it is not copyrightable,
but just in case, you have unlimited permission to copy, distribute and but just in case, you have unlimited permission to copy, distribute and

11
INSTALL
View file

@ -1,7 +1,7 @@
Requirements Requirements
------------ ------------
You will need a C compiler. You will need a C compiler.
I use gcc 4.3.5 and 3.3.6, but the code should compile with any I use gcc 4.7.2 and 3.3.6, but the code should compile with any
standards compliant compiler. standards compliant compiler.
Gcc is available at http://gcc.gnu.org. Gcc is available at http://gcc.gnu.org.
@ -32,6 +32,13 @@ the main archive.
5. Type 'make install' to install the program and any data files and 5. Type 'make install' to install the program and any data files and
documentation. documentation.
You can install only the program, the info manual or the man page
typing 'make install-bin', 'make install-info' or 'make install-man'
respectively.
5a. Type 'make install-as-lzip' to install the program and any data
files and documentation, and link the program to the name 'lzip'.
Another way Another way
----------- -----------
@ -50,7 +57,7 @@ After running 'configure', you can run 'make' and 'make install' as
explained above. explained above.
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute and modify it. distribute and modify it.

454
LzFind.c
View file

@ -3,191 +3,150 @@
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <errno.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "pdlzip.h" #include "clzip.h"
#include "LzFind.h" #include "LzFind.h"
#include "LzHash.h"
#define kHash2Size (1 << 10)
#define kHash3Size (1 << 16)
#define kHash4Size (1 << 20)
#define kFix3HashSize (kHash2Size)
#define kFix4HashSize (kHash2Size + kHash3Size)
#define HASH2_CALC hashValue = cur[0] | ((uint32_t)cur[1] << 8);
#define HASH3_CALC { \
uint32_t temp = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hashValue = (temp ^ ((uint32_t)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
uint32_t temp = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((uint32_t)cur[2] << 8)) & (kHash3Size - 1); \
hashValue = (temp ^ ((uint32_t)cur[2] << 8) ^ (crc32[cur[3]] << 5)) & p->hashMask; }
#define kEmptyHashValue 0 #define kEmptyHashValue 0
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) #define kMaxValForNormalize ((uint32_t)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ #define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
#define kNormalizeMask (~(kNormalizeStepMin - 1)) #define kNormalizeMask (~(kNormalizeStepMin - 1))
#define kMaxHistorySize ((UInt32)3 << 30)
#define kStartMaxLen 3 #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 void Mf_ReadBlock(CMatchFinder *p)
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) if (p->streamEndWasReached || p->result != SZ_OK)
return; return;
if (p->directInput)
{
UInt32 curSize = 0xFFFFFFFF - p->streamPos;
if (curSize > p->directInputRem)
curSize = (UInt32)p->directInputRem;
p->directInputRem -= curSize;
p->streamPos += curSize;
if (p->directInputRem == 0)
p->streamEndWasReached = 1;
return;
}
for (;;) for (;;)
{ {
Byte *dest = p->buffer + (p->streamPos - p->pos); uint8_t * const dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest); const int size = (p->bufferBase + p->blockSize - dest);
int rd;
if (size == 0) if (size == 0)
return; return;
p->result = p->stream->Read(p->stream, dest, &size); rd = readblock( p->infd, dest, size );
if (p->result != SZ_OK) if (rd != size && errno)
return; { p->result = SZ_ERROR_READ; return; }
if (size == 0) if (rd == 0)
{ {
p->streamEndWasReached = 1; p->streamEndWasReached = true;
return; return;
} }
CRC32_update_buf( &p->crc, dest, size ); CRC32_update_buf( &p->crc, dest, rd );
p->streamPos += (UInt32)size; p->streamPos += rd;
if (p->streamPos - p->pos > p->keepSizeAfter) if (p->streamPos - p->pos > p->keepSizeAfter)
return; return;
} }
} }
void MatchFinder_MoveBlock(CMatchFinder *p)
static void Mf_CheckAndMoveAndRead(CMatchFinder *p)
{ {
if ((uint32_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter)
{
memmove(p->bufferBase, memmove(p->bufferBase,
p->buffer - p->keepSizeBefore, p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore)); p->streamPos - p->pos + p->keepSizeBefore);
p->buffer = p->bufferBase + p->keepSizeBefore; p->buffer = p->bufferBase + p->keepSizeBefore;
}
int MatchFinder_NeedMove(CMatchFinder *p)
{
if (p->directInput)
return 0;
/* 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->bigHash = 0;
}
void MatchFinder_Construct(CMatchFinder *p)
{
p->bufferBase = 0;
p->directInput = 0;
p->hash = 0;
MatchFinder_SetDefaultSettings(p);
p->crc = 0xFFFFFFFFU;
} }
Mf_ReadBlock(p);
}
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
void Mf_Free(CMatchFinder *p)
{ {
alloc->Free(alloc, p->hash); free(p->hash);
p->hash = 0; p->hash = 0;
free(p->bufferBase);
p->bufferBase = 0;
} }
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) static CLzRef* AllocRefs(uint32_t num)
{ {
MatchFinder_FreeThisClassMemory(p, alloc); uint32_t sizeInBytes = num * sizeof(CLzRef);
LzInWindow_Free(p, alloc);
}
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num) if (sizeInBytes / sizeof(CLzRef) != num)
return 0; return 0;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); return (CLzRef *)malloc(sizeInBytes);
} }
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, static void Mf_SetLimits(CMatchFinder *p)
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc)
{ {
UInt32 sizeReserv; uint32_t limit = kMaxValForNormalize - p->pos;
if (historySize > kMaxHistorySize) uint32_t limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
if (limit2 < limit)
limit = limit2;
limit2 = p->streamPos - p->pos;
if (limit2 <= p->keepSizeAfter)
{ {
MatchFinder_Free(p, alloc); if (limit2 > 0)
return 0; limit2 = 1;
} }
sizeReserv = historySize >> 1; else
if (historySize > ((UInt32)2 << 30)) limit2 -= p->keepSizeAfter;
sizeReserv = historySize >> 2; if (limit2 < limit)
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); limit = limit2;
{
uint32_t lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
lenLimit = p->matchMaxLen;
p->lenLimit = lenLimit;
}
p->posLimit = p->pos + limit;
}
int Mf_Init(CMatchFinder *p, const int ifd, const int mc, uint32_t historySize,
uint32_t keepAddBufferBefore, uint32_t matchMaxLen, uint32_t keepAddBufferAfter)
{
const uint32_t sizeReserv = ( historySize >> 1 ) +
(keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->hash = 0;
p->cutValue = mc;
p->infd = ifd;
p->btMode = true;
p->numHashBytes = 4;
p->crc = 0xFFFFFFFFU;
p->keepSizeBefore = historySize + keepAddBufferBefore + 1; p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
if (LzInWindow_Create(p, sizeReserv, alloc)) /* keepSizeBefore + keepSizeAfter + sizeReserv must be < 4G) */
p->blockSize = p->keepSizeBefore + p->keepSizeAfter + sizeReserv;
p->buffer = p->bufferBase = (uint8_t *)malloc(p->blockSize);
if( p->bufferBase )
{ {
UInt32 newCyclicBufferSize = historySize + 1; uint32_t newCyclicBufferSize = historySize + 1;
UInt32 hs; uint32_t hs;
p->matchMaxLen = matchMaxLen; p->matchMaxLen = matchMaxLen;
{ {
p->fixedHashSize = 0;
if (p->numHashBytes == 2) if (p->numHashBytes == 2)
hs = (1 << 16) - 1; hs = (1 << 16) - 1;
else else
@ -209,85 +168,45 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
} }
p->hashMask = hs; p->hashMask = hs;
hs++; hs++;
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; if (p->numHashBytes > 2) hs += kHash2Size;
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; if (p->numHashBytes > 3) hs += kHash3Size;
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; if (p->numHashBytes > 4) hs += kHash4Size;
hs += p->fixedHashSize;
} }
{ {
UInt32 prevSize = p->hashSizeSum + p->numSons; uint32_t newSize;
UInt32 newSize;
p->historySize = historySize; p->historySize = historySize;
p->hashSizeSum = hs; p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize; p->cyclicBufferSize = newCyclicBufferSize;
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
newSize = p->hashSizeSum + p->numSons; newSize = p->hashSizeSum + p->numSons;
if (p->hash != 0 && prevSize == newSize) p->hash = AllocRefs(newSize);
return 1;
MatchFinder_FreeThisClassMemory(p, alloc);
p->hash = AllocRefs(newSize, alloc);
if (p->hash != 0) if (p->hash != 0)
{ {
uint32_t i;
p->son = p->hash + p->hashSizeSum; 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++) for (i = 0; i < p->hashSizeSum; i++)
p->hash[i] = kEmptyHashValue; p->hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0; p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize; p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK; p->result = SZ_OK;
p->streamEndWasReached = 0; p->streamEndWasReached = false;
MatchFinder_ReadBlock(p); Mf_ReadBlock(p);
MatchFinder_SetLimits(p); Mf_SetLimits(p);
return 1;
}
}
}
Mf_Free(p);
return 0;
} }
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) static void Mf_Normalize3(uint32_t subValue, CLzRef *items, uint32_t numItems)
{ {
return (p->pos - p->historySize - 1) & kNormalizeMask; uint32_t i;
}
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
{
UInt32 i;
for (i = 0; i < numItems; i++) for (i = 0; i < numItems; i++)
{ {
UInt32 value = items[i]; uint32_t value = items[i];
if (value <= subValue) if (value <= subValue)
value = kEmptyHashValue; value = kEmptyHashValue;
else else
@ -296,40 +215,42 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
} }
} }
static void MatchFinder_Normalize(CMatchFinder *p) static void Mf_Normalize(CMatchFinder *p)
{ {
UInt32 subValue = MatchFinder_GetSubValue(p); uint32_t subValue = (p->pos - p->historySize - 1) & kNormalizeMask;
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); Mf_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
MatchFinder_ReduceOffsets(p, subValue); p->posLimit -= subValue;
p->pos -= subValue;
p->streamPos -= subValue;
} }
static void MatchFinder_CheckLimits(CMatchFinder *p) static void Mf_CheckLimits(CMatchFinder *p)
{ {
if (p->pos == kMaxValForNormalize) if (p->pos == kMaxValForNormalize)
MatchFinder_Normalize(p); Mf_Normalize(p);
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
MatchFinder_CheckAndMoveAndRead(p); Mf_CheckAndMoveAndRead(p);
if (p->cyclicBufferPos == p->cyclicBufferSize) if (p->cyclicBufferPos == p->cyclicBufferSize)
p->cyclicBufferPos = 0; p->cyclicBufferPos = 0;
MatchFinder_SetLimits(p); Mf_SetLimits(p);
} }
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, static uint32_t * Hc_GetMatchesSpec(uint32_t lenLimit, uint32_t curMatch, uint32_t pos, const uint8_t *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, uint32_t _cyclicBufferPos, uint32_t _cyclicBufferSize, uint32_t cutValue,
UInt32 *distances, UInt32 maxLen) uint32_t *distances, uint32_t maxLen)
{ {
son[_cyclicBufferPos] = curMatch; son[_cyclicBufferPos] = curMatch;
for (;;) for (;;)
{ {
UInt32 delta = pos - curMatch; uint32_t delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize) if (cutValue-- == 0 || delta >= _cyclicBufferSize)
return distances; return distances;
{ {
const Byte *pb = cur - delta; const uint8_t *pb = cur - delta;
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
if (pb[maxLen] == cur[maxLen] && *pb == *cur) if (pb[maxLen] == cur[maxLen] && *pb == *cur)
{ {
UInt32 len = 0; uint32_t len = 0;
while (++len != lenLimit) while (++len != lenLimit)
if (pb[len] != cur[len]) if (pb[len] != cur[len])
break; break;
@ -345,16 +266,18 @@ static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos,
} }
} }
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, static uint32_t * GetMatchesSpec1( uint32_t lenLimit, uint32_t curMatch,
UInt32 *distances, UInt32 maxLen) uint32_t pos, const uint8_t *cur, CLzRef *son,
uint32_t _cyclicBufferPos, uint32_t _cyclicBufferSize, uint32_t cutValue,
uint32_t *distances, uint32_t maxLen )
{ {
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1); CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
UInt32 len0 = 0, len1 = 0; uint32_t len0 = 0, len1 = 0;
for (;;) for (;;)
{ {
UInt32 delta = pos - curMatch; uint32_t delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize) if (cutValue-- == 0 || delta >= _cyclicBufferSize)
{ {
*ptr0 = *ptr1 = kEmptyHashValue; *ptr0 = *ptr1 = kEmptyHashValue;
@ -362,8 +285,8 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt
} }
{ {
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta; const uint8_t *pb = cur - delta;
UInt32 len = (len0 < len1 ? len0 : len1); uint32_t len = (len0 < len1 ? len0 : len1);
if (pb[len] == cur[len]) if (pb[len] == cur[len])
{ {
if (++len != lenLimit && pb[len] == cur[len]) if (++len != lenLimit && pb[len] == cur[len])
@ -400,15 +323,15 @@ UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byt
} }
} }
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, static void SkipMatchesSpec(uint32_t lenLimit, uint32_t curMatch, uint32_t pos, const uint8_t *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) uint32_t _cyclicBufferPos, uint32_t _cyclicBufferSize, uint32_t cutValue)
{ {
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1); CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
UInt32 len0 = 0, len1 = 0; uint32_t len0 = 0, len1 = 0;
for (;;) for (;;)
{ {
UInt32 delta = pos - curMatch; uint32_t delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize) if (cutValue-- == 0 || delta >= _cyclicBufferSize)
{ {
*ptr0 = *ptr1 = kEmptyHashValue; *ptr0 = *ptr1 = kEmptyHashValue;
@ -416,8 +339,8 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
} }
{ {
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta; const uint8_t *pb = cur - delta;
UInt32 len = (len0 < len1 ? len0 : len1); uint32_t len = (len0 < len1 ? len0 : len1);
if (pb[len] == cur[len]) if (pb[len] == cur[len])
{ {
while (++len != lenLimit) while (++len != lenLimit)
@ -453,15 +376,15 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const
#define MOVE_POS \ #define MOVE_POS \
++p->cyclicBufferPos; \ ++p->cyclicBufferPos; \
p->buffer++; \ p->buffer++; \
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); if (++p->pos == p->posLimit) Mf_CheckLimits(p);
#define MOVE_POS_RET MOVE_POS return offset; #define MOVE_POS_RET MOVE_POS return offset;
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } static void Mf_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \ #define GET_MATCHES_HEADER2(minLen, ret_op) \
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ uint32_t lenLimit; uint32_t hashValue; const uint8_t *cur; uint32_t curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ lenLimit = p->lenLimit; { if (lenLimit < minLen) { Mf_MovePos(p); ret_op; }} \
cur = p->buffer; cur = p->buffer;
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) #define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
@ -470,15 +393,15 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue #define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
#define GET_MATCHES_FOOTER(offset, maxLen) \ #define GET_MATCHES_FOOTER(offset, maxLen) \
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ offset = (uint32_t)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
distances + offset, maxLen) - distances); MOVE_POS_RET; distances + offset, maxLen) - distances); MOVE_POS_RET;
#define SKIP_FOOTER \ #define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static uint32_t Bt2_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances)
{ {
UInt32 offset; uint32_t offset;
GET_MATCHES_HEADER(2) GET_MATCHES_HEADER(2)
HASH2_CALC; HASH2_CALC;
curMatch = p->hash[hashValue]; curMatch = p->hash[hashValue];
@ -487,20 +410,9 @@ static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
GET_MATCHES_FOOTER(offset, 1) GET_MATCHES_FOOTER(offset, 1)
} }
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static uint32_t Bt3_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances)
{ {
UInt32 offset; uint32_t hash2Value, delta2, maxLen, 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) GET_MATCHES_HEADER(3)
HASH3_CALC; HASH3_CALC;
@ -531,9 +443,9 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
GET_MATCHES_FOOTER(offset, maxLen) GET_MATCHES_FOOTER(offset, maxLen)
} }
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static uint32_t Bt4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances)
{ {
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; uint32_t hash2Value, hash3Value, delta2, delta3, maxLen, offset;
GET_MATCHES_HEADER(4) GET_MATCHES_HEADER(4)
HASH4_CALC; HASH4_CALC;
@ -578,9 +490,9 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
GET_MATCHES_FOOTER(offset, maxLen) GET_MATCHES_FOOTER(offset, maxLen)
} }
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) static uint32_t Hc4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances)
{ {
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; uint32_t hash2Value, hash3Value, delta2, delta3, maxLen, offset;
GET_MATCHES_HEADER(4) GET_MATCHES_HEADER(4)
HASH4_CALC; HASH4_CALC;
@ -622,24 +534,13 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
} }
if (maxLen < 3) if (maxLen < 3)
maxLen = 3; maxLen = 3;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), offset = (uint32_t)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances)); distances + offset, maxLen) - (distances));
MOVE_POS_RET 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) static void Bt2_MatchFinder_Skip(CMatchFinder *p, uint32_t num)
{ {
do do
{ {
@ -652,24 +553,12 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
while (--num != 0); 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) static void Bt3_MatchFinder_Skip(CMatchFinder *p, uint32_t num)
{ {
do do
{ {
UInt32 hash2Value; uint32_t hash2Value;
SKIP_HEADER(3) SKIP_HEADER(3)
HASH3_CALC; HASH3_CALC;
curMatch = p->hash[kFix3HashSize + hashValue]; curMatch = p->hash[kFix3HashSize + hashValue];
@ -680,11 +569,11 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
while (--num != 0); while (--num != 0);
} }
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) static void Bt4_MatchFinder_Skip(CMatchFinder *p, uint32_t num)
{ {
do do
{ {
UInt32 hash2Value, hash3Value; uint32_t hash2Value, hash3Value;
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue]; curMatch = p->hash[kFix4HashSize + hashValue];
@ -696,11 +585,11 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
while (--num != 0); while (--num != 0);
} }
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) static void Hc4_MatchFinder_Skip(CMatchFinder *p, uint32_t num)
{ {
do do
{ {
UInt32 hash2Value, hash3Value; uint32_t hash2Value, hash3Value;
SKIP_HEADER(4) SKIP_HEADER(4)
HASH4_CALC; HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue]; curMatch = p->hash[kFix4HashSize + hashValue];
@ -713,26 +602,9 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
while (--num != 0); 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) void Mf_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) if (!p->btMode)
{ {
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;

117
LzFind.h
View file

@ -1,81 +1,51 @@
/* LzFind.h -- Match finder for LZ algorithms /* LzFind.h -- Match finder for LZ algorithms
2009-04-22 : Igor Pavlov : Public domain */ 2009-04-22 : Igor Pavlov : Public domain */
#ifndef __LZ_FIND_H typedef uint32_t CLzRef;
#define __LZ_FIND_H
#include "Types.h" typedef struct
#ifdef __cplusplus
extern "C" {
#endif
typedef UInt32 CLzRef;
typedef struct _CMatchFinder
{ {
Byte *buffer; uint8_t *bufferBase;
UInt32 pos; uint8_t *buffer;
UInt32 posLimit;
UInt32 streamPos;
UInt32 lenLimit;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
UInt32 matchMaxLen;
CLzRef *hash; CLzRef *hash;
CLzRef *son; CLzRef *son;
UInt32 hashMask; uint32_t pos;
UInt32 cutValue; uint32_t posLimit;
uint32_t streamPos;
uint32_t lenLimit;
Byte *bufferBase; uint32_t cyclicBufferPos;
ISeqInStream *stream; uint32_t cyclicBufferSize; /* it must be = (historySize + 1) */
int streamEndWasReached;
UInt32 blockSize; uint32_t matchMaxLen;
UInt32 keepSizeBefore; uint32_t hashMask;
UInt32 keepSizeAfter; uint32_t cutValue;
UInt32 numHashBytes; uint32_t blockSize;
int directInput; uint32_t keepSizeBefore;
size_t directInputRem; uint32_t keepSizeAfter;
int btMode;
int bigHash; uint32_t numHashBytes;
UInt32 historySize; uint32_t historySize;
UInt32 fixedHashSize; uint32_t hashSizeSum;
UInt32 hashSizeSum; uint32_t numSons;
UInt32 numSons; int infd;
SRes result; int result;
uint32_t crc; uint32_t crc;
bool btMode;
bool streamEndWasReached;
} CMatchFinder; } 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: /* Conditions:
historySize <= 3 GB historySize <= 3 GB
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
*/ */
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, int Mf_Init(CMatchFinder *p, const int ifd, const int mc, uint32_t historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, uint32_t keepAddBufferBefore, uint32_t matchMaxLen, uint32_t keepAddBufferAfter);
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); void Mf_Free(CMatchFinder *p);
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: Conditions:
@ -83,33 +53,22 @@ Conditions:
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
*/ */
typedef void (*Mf_Init_Func)(void *object); typedef uint32_t (*Mf_GetMatches_Func)(void *object, uint32_t *distances);
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); typedef void (*Mf_Skip_Func)(void *object, uint32_t);
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 typedef struct _IMatchFinder
{ {
Mf_Init_Func Init;
Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches; Mf_GetMatches_Func GetMatches;
Mf_Skip_Func Skip; Mf_Skip_Func Skip;
} IMatchFinder; } IMatchFinder;
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); void Mf_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init(CMatchFinder *p); static inline uint32_t Mf_GetNumAvailableBytes(CMatchFinder *p)
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); { return p->streamPos - p->pos; }
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
#ifdef __cplusplus static inline uint8_t Mf_GetIndexByte(CMatchFinder *p, int index)
} { return p->buffer[index]; }
#endif
#endif static inline uint8_t * Mf_GetPointerToCurrentPos(CMatchFinder *p)
{ return p->buffer; }

View file

@ -1,54 +0,0 @@
/* LzHash.h -- HASH functions for LZ algorithms
2009-02-07 : Igor Pavlov : Public domain */
#ifndef __LZ_HASH_H
#define __LZ_HASH_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 = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
UInt32 temp = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (crc32[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
UInt32 temp = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (crc32[cur[3]] << 5)); \
hashValue = (hash4Value ^ (crc32[cur[4]] << 3)) & p->hashMask; \
hash4Value &= (kHash4Size - 1); }
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ crc32[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ crc32[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
hash2Value = (crc32[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
UInt32 temp = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
UInt32 temp = crc32[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (crc32[cur[3]] << 5)) & (kHash4Size - 1); }
#endif

382
LzmaDec.c
View file

@ -3,12 +3,60 @@
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "clzip.h"
#include "LzmaDec.h" #include "LzmaDec.h"
#include <string.h>
CRC32 crc32;
/* Returns the number of bytes really read.
If (returned value < size) and (errno == 0), means EOF was reached.
*/
int readblock( const int fd, uint8_t * const buf, const int size )
{
int rest = size;
errno = 0;
while( rest > 0 )
{
const int n = read( fd, buf + size - rest, rest );
if( n > 0 ) rest -= n;
else if( n == 0 ) break; /* EOF */
else if( errno != EINTR && errno != EAGAIN ) break;
errno = 0;
}
return size - rest;
}
/* Returns the number of bytes really written.
If (returned value < size), it is always an error.
*/
int writeblock( const int fd, const uint8_t * const buf, const int size )
{
int rest = size;
errno = 0;
while( rest > 0 )
{
const int n = write( fd, buf + size - rest, rest );
if( n > 0 ) rest -= n;
else if( n < 0 && errno != EINTR && errno != EAGAIN ) break;
errno = 0;
}
return size - rest;
}
#define kNumTopBits 24 #define kNumTopBits 24
#define kTopValue ((UInt32)1 << kNumTopBits) #define kTopValue ((uint32_t)1 << kNumTopBits)
#define kNumBitModelTotalBits 11 #define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits) #define kBitModelTotal (1 << kNumBitModelTotalBits)
@ -19,8 +67,8 @@
#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) #define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); #define UPDATE_0(p) range = bound; *(p) = (int)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (int)(ttt - (ttt >> kNumMoveBits));
#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
{ UPDATE_0(p); i = (i + i); A0; } else \ { UPDATE_0(p); i = (i + i); A0; } else \
{ UPDATE_1(p); i = (i + i) + 1; A1; } { UPDATE_1(p); i = (i + i) + 1; A1; }
@ -109,20 +157,19 @@
#define LZMA_BASE_SIZE 1846 #define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768 #define LZMA_LIT_SIZE 768
#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) #define LzmaProps_GetNumProbs(p) ((uint32_t)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
#if Literal != LZMA_BASE_SIZE #if Literal != LZMA_BASE_SIZE
StopCompilingDueBUG StopCompilingDueBUG
#endif #endif
#define LZMA_DIC_MIN (1 << 12)
/* First LZMA-symbol is always decoded. /* First LZMA-symbol is always decoded.
And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
Out: Out:
Result: Result:
SZ_OK - OK true - OK
SZ_ERROR_DATA - Error false - Error
p->remainLen: p->remainLen:
< kMatchSpecLenStart : normal remain < kMatchSpecLenStart : normal remain
= kMatchSpecLenStart : finished = kMatchSpecLenStart : finished
@ -130,32 +177,32 @@ Out:
= kMatchSpecLenStart + 2 : State Init Marker = kMatchSpecLenStart + 2 : State Init Marker
*/ */
static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) static bool LzmaDec_DecodeReal(CLzmaDec *p, uint32_t limit, const uint8_t *bufLimit)
{ {
CLzmaProb *probs = p->probs; int *probs = p->probs;
unsigned state = p->state; State state = p->state;
UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; uint32_t rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; unsigned pbMask = ((unsigned)1 << (p->pb)) - 1;
unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; unsigned lpMask = ((unsigned)1 << (p->lp)) - 1;
unsigned lc = p->prop.lc; const unsigned lc = p->lc;
Byte *dic = p->dic; uint8_t *dic = p->dic;
SizeT dicBufSize = p->dicBufSize; const uint32_t dicBufSize = p->dicBufSize;
SizeT dicPos = p->dicPos; uint32_t dicPos = p->dicPos;
UInt32 processedPos = p->processedPos; uint32_t processedPos = p->processedPos;
UInt32 checkDicSize = p->checkDicSize; uint32_t checkDicSize = p->checkDicSize;
unsigned len = 0; unsigned len = 0;
const Byte *buf = p->buf; const uint8_t *buf = p->buf;
UInt32 range = p->range; uint32_t range = p->range;
UInt32 code = p->code; uint32_t code = p->code;
do do
{ {
CLzmaProb *prob; int *prob;
UInt32 bound; uint32_t bound;
unsigned ttt; unsigned ttt;
unsigned posState = processedPos & pbMask; unsigned posState = processedPos & pbMask;
@ -184,7 +231,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
do do
{ {
unsigned bit; unsigned bit;
CLzmaProb *probLit; int *probLit;
matchByte <<= 1; matchByte <<= 1;
bit = (matchByte & offs); bit = (matchByte & offs);
probLit = prob + offs + bit + symbol; probLit = prob + offs + bit + symbol;
@ -192,7 +239,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
} }
while (symbol < 0x100); while (symbol < 0x100);
} }
dic[dicPos++] = (Byte)symbol; dic[dicPos++] = (uint8_t)symbol;
processedPos++; processedPos++;
continue; continue;
} }
@ -210,7 +257,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
{ {
UPDATE_1(prob); UPDATE_1(prob);
if (checkDicSize == 0 && processedPos == 0) if (checkDicSize == 0 && processedPos == 0)
return SZ_ERROR_DATA; return false;
prob = probs + IsRepG0 + state; prob = probs + IsRepG0 + state;
IF_BIT_0(prob) IF_BIT_0(prob)
{ {
@ -229,7 +276,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
} }
else else
{ {
UInt32 distance; uint32_t distance;
UPDATE_1(prob); UPDATE_1(prob);
prob = probs + IsRepG1 + state; prob = probs + IsRepG1 + state;
IF_BIT_0(prob) IF_BIT_0(prob)
@ -262,7 +309,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
} }
{ {
unsigned limit, offset; unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice; int *probLen = prob + LenChoice;
IF_BIT_0(probLen) IF_BIT_0(probLen)
{ {
UPDATE_0(probLen); UPDATE_0(probLen);
@ -295,7 +342,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (state >= kNumStates) if (state >= kNumStates)
{ {
UInt32 distance; uint32_t distance;
prob = probs + PosSlot + prob = probs + PosSlot +
((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
TREE_6_DECODE(prob, distance); TREE_6_DECODE(prob, distance);
@ -309,7 +356,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
distance <<= numDirectBits; distance <<= numDirectBits;
prob = probs + SpecPos + distance - posSlot - 1; prob = probs + SpecPos + distance - posSlot - 1;
{ {
UInt32 mask = 1; uint32_t mask = 1;
unsigned i = 1; unsigned i = 1;
do do
{ {
@ -328,9 +375,9 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
range >>= 1; range >>= 1;
{ {
UInt32 t; uint32_t t;
code -= range; code -= range;
t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ t = (0 - ((uint32_t)code >> 31)); /* (uint32_t)((int)code >> 31) */
distance = (distance << 1) + (t + 1); distance = (distance << 1) + (t + 1);
code += range & t; code += range & t;
} }
@ -353,7 +400,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
GET_BIT2(prob + i, i, ; , distance |= 4); GET_BIT2(prob + i, i, ; , distance |= 4);
GET_BIT2(prob + i, i, ; , distance |= 8); GET_BIT2(prob + i, i, ; , distance |= 8);
} }
if (distance == (UInt32)0xFFFFFFFF) if (distance == (uint32_t)0xFFFFFFFF)
{ {
len += kMatchSpecLenStart; len += kMatchSpecLenStart;
state -= kNumStates; state -= kNumStates;
@ -368,33 +415,33 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
if (checkDicSize == 0) if (checkDicSize == 0)
{ {
if (distance >= processedPos) if (distance >= processedPos)
return SZ_ERROR_DATA; return false;
} }
else if (distance >= checkDicSize) else if (distance >= checkDicSize)
return SZ_ERROR_DATA; return false;
state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
} }
len += kMatchMinLen; len += kMatchMinLen;
if (limit == dicPos) if (limit == dicPos)
return SZ_ERROR_DATA; return false;
{ {
SizeT rem = limit - dicPos; uint32_t rem = limit - dicPos;
unsigned curLen = ((rem < len) ? (unsigned)rem : len); unsigned curLen = ((rem < len) ? (unsigned)rem : len);
SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); uint32_t pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
processedPos += curLen; processedPos += curLen;
len -= curLen; len -= curLen;
if (pos + curLen <= dicBufSize) if (pos + curLen <= dicBufSize)
{ {
Byte *dest = dic + dicPos; uint8_t *dest = dic + dicPos;
ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
const Byte *lim = dest + curLen; const uint8_t *lim = dest + curLen;
dicPos += curLen; dicPos += curLen;
do do
*(dest) = (Byte)*(dest + src); *(dest) = (uint8_t)*(dest + src);
while (++dest != lim); while (++dest != lim);
} }
else else
@ -424,23 +471,23 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte
p->reps[3] = rep3; p->reps[3] = rep3;
p->state = state; p->state = state;
return SZ_OK; return true;
} }
static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) static void LzmaDec_WriteRem(CLzmaDec *p, uint32_t limit)
{ {
if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
{ {
Byte *dic = p->dic; uint8_t *dic = p->dic;
SizeT dicPos = p->dicPos; uint32_t dicPos = p->dicPos;
SizeT dicBufSize = p->dicBufSize; const uint32_t dicBufSize = p->dicBufSize;
unsigned len = p->remainLen; unsigned len = p->remainLen;
UInt32 rep0 = p->reps[0]; uint32_t rep0 = p->reps[0];
if (limit - dicPos < len) if (limit - dicPos < len)
len = (unsigned)(limit - dicPos); len = (unsigned)(limit - dicPos);
if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) if (p->checkDicSize == 0 && dicBufSize - p->processedPos <= len)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = dicBufSize;
p->processedPos += len; p->processedPos += len;
p->remainLen -= len; p->remainLen -= len;
@ -453,20 +500,21 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
} }
} }
static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) static int LzmaDec_DecodeReal2(CLzmaDec *p, uint32_t limit, const uint8_t *bufLimit)
{ {
const uint32_t dicBufSize = p->dicBufSize;
do do
{ {
SizeT limit2 = limit; uint32_t limit2 = limit;
if (p->checkDicSize == 0) if (p->checkDicSize == 0)
{ {
UInt32 rem = p->prop.dicSize - p->processedPos; uint32_t rem = dicBufSize - p->processedPos;
if (limit - p->dicPos > rem) if (limit - p->dicPos > rem)
limit2 = p->dicPos + rem; limit2 = p->dicPos + rem;
} }
RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); if( !LzmaDec_DecodeReal(p, limit2, bufLimit) ) return false;
if (p->processedPos >= p->prop.dicSize) if (p->processedPos >= dicBufSize)
p->checkDicSize = p->prop.dicSize; p->checkDicSize = dicBufSize;
LzmaDec_WriteRem(p, limit); LzmaDec_WriteRem(p, limit);
} }
while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
@ -475,7 +523,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte
{ {
p->remainLen = kMatchSpecLenStart; p->remainLen = kMatchSpecLenStart;
} }
return 0; return true;
} }
typedef enum typedef enum
@ -486,20 +534,20 @@ typedef enum
DUMMY_REP DUMMY_REP
} ELzmaDummy; } ELzmaDummy;
static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const uint8_t *buf, uint32_t inSize)
{ {
UInt32 range = p->range; uint32_t range = p->range;
UInt32 code = p->code; uint32_t code = p->code;
const Byte *bufLimit = buf + inSize; const uint8_t *bufLimit = buf + inSize;
CLzmaProb *probs = p->probs; int *probs = p->probs;
unsigned state = p->state; State state = p->state;
ELzmaDummy res; ELzmaDummy res;
{ {
CLzmaProb *prob; int *prob;
UInt32 bound; uint32_t bound;
unsigned ttt; unsigned ttt;
unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); unsigned posState = (p->processedPos) & ((1 << p->pb) - 1);
prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
IF_BIT_0_CHECK(prob) IF_BIT_0_CHECK(prob)
@ -511,8 +559,8 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
prob = probs + Literal; prob = probs + Literal;
if (p->checkDicSize != 0 || p->processedPos != 0) if (p->checkDicSize != 0 || p->processedPos != 0)
prob += (LZMA_LIT_SIZE * prob += (LZMA_LIT_SIZE *
((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + ((((p->processedPos) & ((1 << (p->lp)) - 1)) << p->lc) +
(p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->lc))));
if (state < kNumLitStates) if (state < kNumLitStates)
{ {
@ -528,7 +576,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
do do
{ {
unsigned bit; unsigned bit;
CLzmaProb *probLit; int *probLit;
matchByte <<= 1; matchByte <<= 1;
bit = (matchByte & offs); bit = (matchByte & offs);
probLit = prob + offs + bit + symbol; probLit = prob + offs + bit + symbol;
@ -598,7 +646,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
} }
{ {
unsigned limit, offset; unsigned limit, offset;
CLzmaProb *probLen = prob + LenChoice; int *probLen = prob + LenChoice;
IF_BIT_0_CHECK(probLen) IF_BIT_0_CHECK(probLen)
{ {
UPDATE_0_CHECK; UPDATE_0_CHECK;
@ -677,51 +725,19 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inS
} }
static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) static void LzmaDec_InitRc(CLzmaDec *p, const uint8_t *data)
{ {
p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); p->code = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]);
p->range = 0xFFFFFFFF; p->range = 0xFFFFFFFF;
p->needFlush = 0; p->needFlush = false;
} }
void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
{
p->needFlush = 1;
p->remainLen = 0;
p->tempBufSize = 0;
if (initDic) static bool LzmaDec_DecodeToDic(CLzmaDec *p, uint32_t dicLimit,
{ const uint8_t *src, uint32_t *srcLen,
p->processedPos = 0;
p->checkDicSize = 0;
p->needInitState = 1;
}
if (initState)
p->needInitState = 1;
}
void LzmaDec_Init(CLzmaDec *p)
{
p->dicPos = 0;
LzmaDec_InitDicAndState(p, True, True);
}
static void LzmaDec_InitStateReal(CLzmaDec *p)
{
UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
UInt32 i;
CLzmaProb *probs = p->probs;
for (i = 0; i < numProbs; i++)
probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
p->needInitState = 0;
}
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status) ELzmaFinishMode finishMode, ELzmaStatus *status)
{ {
SizeT inSize = *srcLen; uint32_t inSize = *srcLen;
(*srcLen) = 0; (*srcLen) = 0;
LzmaDec_WriteRem(p, dicLimit); LzmaDec_WriteRem(p, dicLimit);
@ -731,17 +747,17 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{ {
int checkEndMarkNow; int checkEndMarkNow;
if (p->needFlush != 0) if( p->needFlush )
{ {
for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
p->tempBuf[p->tempBufSize++] = *src++; p->tempBuf[p->tempBufSize++] = *src++;
if (p->tempBufSize < RC_INIT_SIZE) if (p->tempBufSize < RC_INIT_SIZE)
{ {
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return true;
} }
if (p->tempBuf[0] != 0) if (p->tempBuf[0] != 0)
return SZ_ERROR_DATA; return false;
LzmaDec_InitRc(p, p->tempBuf); LzmaDec_InitRc(p, p->tempBuf);
p->tempBufSize = 0; p->tempBufSize = 0;
@ -753,28 +769,25 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
if (p->remainLen == 0 && p->code == 0) if (p->remainLen == 0 && p->code == 0)
{ {
*status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
return SZ_OK; return true;
} }
if (finishMode == LZMA_FINISH_ANY) if (finishMode == LZMA_FINISH_ANY)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_OK; return true;
} }
if (p->remainLen != 0) if (p->remainLen != 0)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA; return false;
} }
checkEndMarkNow = 1; checkEndMarkNow = 1;
} }
if (p->needInitState)
LzmaDec_InitStateReal(p);
if (p->tempBufSize == 0) if (p->tempBufSize == 0)
{ {
SizeT processed; uint32_t processed;
const Byte *bufLimit; const uint8_t *bufLimit;
if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
{ {
int dummyRes = LzmaDec_TryDummy(p, src, inSize); int dummyRes = LzmaDec_TryDummy(p, src, inSize);
@ -784,21 +797,21 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
p->tempBufSize = (unsigned)inSize; p->tempBufSize = (unsigned)inSize;
(*srcLen) += inSize; (*srcLen) += inSize;
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return true;
} }
if (checkEndMarkNow && dummyRes != DUMMY_MATCH) if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA; return false;
} }
bufLimit = src; bufLimit = src;
} }
else else
bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
p->buf = src; p->buf = src;
if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) if( !LzmaDec_DecodeReal2(p, dicLimit, bufLimit) )
return SZ_ERROR_DATA; return false;
processed = (SizeT)(p->buf - src); processed = (uint32_t)(p->buf - src);
(*srcLen) += processed; (*srcLen) += processed;
src += processed; src += processed;
inSize -= processed; inSize -= processed;
@ -816,17 +829,17 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
{ {
(*srcLen) += lookAhead; (*srcLen) += lookAhead;
*status = LZMA_STATUS_NEEDS_MORE_INPUT; *status = LZMA_STATUS_NEEDS_MORE_INPUT;
return SZ_OK; return true;
} }
if (checkEndMarkNow && dummyRes != DUMMY_MATCH) if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
{ {
*status = LZMA_STATUS_NOT_FINISHED; *status = LZMA_STATUS_NOT_FINISHED;
return SZ_ERROR_DATA; return false;
} }
} }
p->buf = p->tempBuf; p->buf = p->tempBuf;
if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) if( !LzmaDec_DecodeReal2(p, dicLimit, p->buf) )
return SZ_ERROR_DATA; return false;
lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
(*srcLen) += lookAhead; (*srcLen) += lookAhead;
src += lookAhead; src += lookAhead;
@ -836,19 +849,21 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr
} }
if (p->code == 0) if (p->code == 0)
*status = LZMA_STATUS_FINISHED_WITH_MARK; *status = LZMA_STATUS_FINISHED_WITH_MARK;
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; return (p->code == 0);
} }
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) bool LzmaDec_DecodeToBuf( CLzmaDec *p, uint8_t *dest, uint32_t *destLen,
const uint8_t *src, uint32_t *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status )
{ {
SizeT outSize = *destLen; uint32_t outSize = *destLen;
SizeT inSize = *srcLen; uint32_t inSize = *srcLen;
*srcLen = *destLen = 0; *srcLen = *destLen = 0;
for (;;) for (;;)
{ {
SizeT inSizeCur = inSize, outSizeCur, dicPos; uint32_t inSizeCur = inSize, outSizeCur, dicPos;
ELzmaFinishMode curFinishMode; ELzmaFinishMode curFinishMode;
SRes res; bool res;
if (p->dicPos == p->dicBufSize) if (p->dicPos == p->dicBufSize)
p->dicPos = 0; p->dicPos = 0;
dicPos = p->dicPos; dicPos = p->dicPos;
@ -872,89 +887,52 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *sr
dest += outSizeCur; dest += outSizeCur;
outSize -= outSizeCur; outSize -= outSizeCur;
*destLen += outSizeCur; *destLen += outSizeCur;
if (res != 0) if( !res )
return res; return false;
if (outSizeCur == 0 || outSize == 0) if (outSizeCur == 0 || outSize == 0)
return SZ_OK; return true;
} }
} }
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
void LzmaDec_Free(CLzmaDec *p)
{ {
alloc->Free(alloc, p->probs); free( p->dic );
p->probs = 0; free( p->probs );
} }
static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
bool LzmaDec_Init(CLzmaDec *p, const uint8_t *raw_props)
{ {
alloc->Free(alloc, p->dic); uint32_t i;
p->dic = 0; uint8_t d = raw_props[0];
}
void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
{
LzmaDec_FreeProbs(p, alloc);
LzmaDec_FreeDict(p, alloc);
}
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
{
UInt32 dicSize;
Byte d;
if (size < LZMA_PROPS_SIZE)
return SZ_ERROR_UNSUPPORTED;
else
dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
if (dicSize < LZMA_DIC_MIN)
dicSize = LZMA_DIC_MIN;
p->dicSize = dicSize;
d = data[0];
if (d >= (9 * 5 * 5))
return SZ_ERROR_UNSUPPORTED;
p->lc = d % 9; p->lc = d % 9;
d /= 9; d /= 9;
p->pb = d / 5; p->pb = d / 5;
p->lp = d % 5; p->lp = d % 5;
return SZ_OK; p->dicBufSize = raw_props[1] | ((uint32_t)raw_props[2] << 8) |
} ((uint32_t)raw_props[3] << 16) | ((uint32_t)raw_props[4] << 24);
if (p->dicBufSize < min_dictionary_size) p->dicBufSize = min_dictionary_size;
static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) p->numProbs = LzmaProps_GetNumProbs(p);
{ p->probs = (int *)malloc(p->numProbs * sizeof(int));
UInt32 numProbs = LzmaProps_GetNumProbs(propNew); if( !p->probs ) return false;
if (p->probs == 0 || numProbs != p->numProbs) p->dic = (uint8_t *)malloc(p->dicBufSize);
{
LzmaDec_FreeProbs(p, alloc);
p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
p->numProbs = numProbs;
if (p->probs == 0)
return SZ_ERROR_MEM;
}
return SZ_OK;
}
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
{
CLzmaProps propNew;
SizeT dicBufSize;
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
dicBufSize = propNew.dicSize;
if (p->dic == 0 || dicBufSize != p->dicBufSize)
{
LzmaDec_FreeDict(p, alloc);
p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
if (p->dic == 0) if (p->dic == 0)
{ {
LzmaDec_FreeProbs(p, alloc); free( p->probs );
return SZ_ERROR_MEM; return false;
} }
} p->dicPos = 0;
p->dicBufSize = dicBufSize; p->needFlush = true;
p->prop = propNew; p->remainLen = 0;
return SZ_OK; p->tempBufSize = 0;
p->processedPos = 0;
p->checkDicSize = 0;
for( i = 0; i < p->numProbs; ++i ) p->probs[i] = kBitModelTotal >> 1;
p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
p->state = 0;
return true;
} }

139
LzmaDec.h
View file

@ -1,44 +1,10 @@
/* LzmaDec.h -- LZMA Decoder /* LzmaDec.h -- LZMA Decoder
2009-02-07 : Igor Pavlov : Public domain */ 2009-02-07 : Igor Pavlov : Public domain */
#ifndef __LZMA_DEC_H
#define __LZMA_DEC_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* #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 ---------- */ /* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5 #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 Decoder state ---------- */
@ -49,28 +15,24 @@ SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
typedef struct typedef struct
{ {
CLzmaProps prop; int *probs;
CLzmaProb *probs; uint8_t *dic;
Byte *dic; const uint8_t *buf;
const Byte *buf; uint32_t range, code;
UInt32 range, code; uint32_t dicPos;
SizeT dicPos; uint32_t dicBufSize;
SizeT dicBufSize; uint32_t processedPos;
UInt32 processedPos; uint32_t checkDicSize;
UInt32 checkDicSize; unsigned lc, lp, pb;
unsigned state; State state;
UInt32 reps[4]; uint32_t reps[4];
unsigned remainLen; unsigned remainLen;
int needFlush; uint32_t numProbs;
int needInitState;
UInt32 numProbs;
unsigned tempBufSize; unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; bool needFlush;
uint8_t tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec; } CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams: /* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
@ -109,70 +71,13 @@ typedef enum
/* ELzmaStatus is used only as output value for function call */ /* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */ bool LzmaDec_Init(CLzmaDec *p, const uint8_t *raw_props);
void LzmaDec_Free(CLzmaDec *p);
/* 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. */
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 ---------- */ /* ---------- Buffer Interface ---------- */
/* It's zlib-like 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: finishMode:
It has meaning only if the decoding reaches output limit (*destLen). It has meaning only if the decoding reaches output limit (*destLen).
@ -180,12 +85,6 @@ finishMode:
LZMA_FINISH_END - Stream must be finished after (*destLen). LZMA_FINISH_END - Stream must be finished after (*destLen).
*/ */
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, bool LzmaDec_DecodeToBuf( CLzmaDec *p, uint8_t *dest, uint32_t *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); const uint8_t *src, uint32_t *srcLen,
ELzmaFinishMode finishMode, ELzmaStatus *status );
#ifdef __cplusplus
}
#endif
#endif

1092
LzmaEnc.c

File diff suppressed because it is too large Load diff

View file

@ -1,59 +1,18 @@
/* LzmaEnc.h -- LZMA Encoder /* LzmaEnc.h -- LZMA Encoder
2009-02-07 : Igor Pavlov : Public domain */ 2009-02-07 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
#include "Types.h"
#ifdef __cplusplus
extern "C" {
#endif
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 */
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 ---------- */ /* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc_* functions can return the following exit codes: /* LzmaEnc_* functions can return the following exit codes:
Returns: Returns:
SZ_OK - OK SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - Write callback error. 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; typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); CLzmaEncHandle LzmaEnc_Init( const int dict_size, const int match_len_limit,
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); const int infd, const int outfd );
void LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); void LzmaEnc_Free(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, int LzmaEnc_Encode(CLzmaEncHandle p);
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -6,21 +6,20 @@ INSTALL_DATA = $(INSTALL) -p -m 644
INSTALL_DIR = $(INSTALL) -d -m 755 INSTALL_DIR = $(INSTALL) -d -m 755
SHELL = /bin/sh SHELL = /bin/sh
objs = 7zFile.o 7zStream.o Alloc.o LzFind.o LzmaDec.o LzmaEnc.o \ objs = carg_parser.o LzFind.o LzmaEnc.o LzmaDec.o main.o
pdarg_parser.o main.o
.PHONY : all install install-info install-man install-strip \ .PHONY : all install install-bin install-info install-man install-strip \
uninstall uninstall-info uninstall-man \ install-as-lzip uninstall uninstall-bin uninstall-info uninstall-man \
doc info man check dist clean distclean doc info man check dist clean distclean
all : $(progname) all : $(progname)
$(progname) : $(objs) $(progname) : $(objs)
$(CC) $(LDFLAGS) -o $@ $^ $(CC) $(LDFLAGS) -o $@ $(objs)
$(progname)_profiled : $(objs) $(progname)_profiled : $(objs)
$(CC) $(LDFLAGS) -pg -o $@ $^ $(CC) $(LDFLAGS) -pg -o $@ $(objs)
main.o : main.c main.o : main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -DPROGVERSION=\"$(pkgversion)\" -c -o $@ $< $(CC) $(CPPFLAGS) $(CFLAGS) -DPROGVERSION=\"$(pkgversion)\" -c -o $@ $<
@ -29,14 +28,11 @@ main.o : main.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
$(objs) : Makefile $(objs) : Makefile
7zFile.o : 7zFile.h Types.h carg_parser.o : carg_parser.h
7zStream.o : Types.h LzmaDec.o : clzip.h LzmaDec.h
Alloc.o : Alloc.h LzFind.o : clzip.h LzFind.h
LzFind.o : LzFind.h LzHash.h Types.h pdlzip.h LzmaEnc.o : clzip.h LzFind.h LzmaEnc.h
LzmaDec.o : LzmaDec.h Types.h main.o : carg_parser.h clzip.h LzmaDec.h LzmaEnc.h
LzmaEnc.o : LzFind.h LzmaEnc.h Types.h pdlzip.h
pdarg_parser.o : pdarg_parser.h
main.o : 7zFile.h Alloc.h LzmaDec.h LzmaEnc.h pdarg_parser.h pdlzip.h
doc : man doc : man
@ -58,14 +54,16 @@ Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
check : all check : all
@$(VPATH)/testsuite/check.sh $(VPATH)/testsuite $(pkgversion) @$(VPATH)/testsuite/check.sh $(VPATH)/testsuite $(pkgversion)
install : all install-man install : install-bin install-man
install-bin : all
if [ ! -d "$(DESTDIR)$(bindir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(bindir)" ; fi if [ ! -d "$(DESTDIR)$(bindir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(bindir)" ; fi
$(INSTALL_PROGRAM) ./$(progname) "$(DESTDIR)$(bindir)/$(progname)" $(INSTALL_PROGRAM) ./$(progname) "$(DESTDIR)$(bindir)/$(progname)"
install-info : install-info :
if [ ! -d "$(DESTDIR)$(infodir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(infodir)" ; fi if [ ! -d "$(DESTDIR)$(infodir)" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(infodir)" ; fi
$(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info" $(INSTALL_DATA) $(VPATH)/doc/$(pkgname).info "$(DESTDIR)$(infodir)/$(pkgname).info"
-install-info --info-dir="$(DESTDIR)$(infodir)" $(DESTDIR)$(infodir)/$(pkgname).info -install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$(pkgname).info"
install-man : install-man :
if [ ! -d "$(DESTDIR)$(mandir)/man1" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1" ; fi if [ ! -d "$(DESTDIR)$(mandir)/man1" ] ; then $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1" ; fi
@ -74,7 +72,13 @@ install-man :
install-strip : all install-strip : all
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
uninstall : uninstall-man install-as-lzip : install
-rm -f "$(DESTDIR)$(bindir)/lzip"
cd "$(DESTDIR)$(bindir)" && ln -s $(progname) lzip
uninstall : uninstall-bin uninstall-man
uninstall-bin :
-rm -f "$(DESTDIR)$(bindir)/$(progname)" -rm -f "$(DESTDIR)$(bindir)/$(progname)"
uninstall-info : uninstall-info :
@ -97,8 +101,8 @@ dist : doc
$(DISTNAME)/doc/$(progname).1 \ $(DISTNAME)/doc/$(progname).1 \
$(DISTNAME)/testsuite/check.sh \ $(DISTNAME)/testsuite/check.sh \
$(DISTNAME)/testsuite/test.txt \ $(DISTNAME)/testsuite/test.txt \
$(DISTNAME)/testsuite/test.lz \ $(DISTNAME)/testsuite/test.txt.lz \
$(DISTNAME)/testsuite/test.lzma \ $(DISTNAME)/testsuite/test.txt.lzma \
$(DISTNAME)/*.h \ $(DISTNAME)/*.h \
$(DISTNAME)/*.c $(DISTNAME)/*.c
rm -f $(DISTNAME) rm -f $(DISTNAME)

20
NEWS
View file

@ -1,8 +1,18 @@
Changes in version 1.3: Changes in version 1.4:
A small change has been made in the "--help" output and man page. The options "-f, --force", "-F, --recompress", "-k, --keep", and
"-o, --output", have been ported from clzip.
Quote characters in messages have been changed as advised by GNU Coding Pdlzip now accepts more than one file in the command line.
Standards.
Standard input and standard output are now set in binary mode on OS2. Decompression time has been reduced by 5%.
The dependence of "--test" on the existence of "/dev/null" has been
removed.
Configure option "--datadir" has been renamed to "--datarootdir" to
follow GNU Standards.
The target "install-as-lzip" has been added to the Makefile.
The target "install-bin" has been added to the Makefile.

13
README
View file

@ -6,17 +6,20 @@ gzip or bzip2. Pdlzip decompresses almost as fast as gzip and compresses
better than bzip2, which makes it well suited for software distribution better than bzip2, which makes it well suited for software distribution
and data archiving. and data archiving.
Pdlzip uses the lzip file format; the files produced by pdlzip are
(hope)fully compatible with lzip-1.4 or newer. Pdlzip is in fact a
"public domain" version of the lzip data compressor, intended for those
who can't distribute GPL licensed Free Software.
Pdlzip is also able to decompress legacy lzma-alone (.lzma) files. Pdlzip is also able to decompress legacy lzma-alone (.lzma) files.
Pdlzip is a "public domain" version of the lzip data compressor,
intended for those who can't distribute GPL licensed Free Software.
Pdlzip is written in C. Pdlzip is written in C.
Pdlzip uses public domain compression code from the LZMA SDK written by Pdlzip includes public domain compression code from the LZMA SDK written
Igor Pavlov. by Igor Pavlov.
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
This file is free documentation: you have unlimited permission to copy, This file is free documentation: you have unlimited permission to copy,
distribute and modify it. distribute and modify it.

225
Types.h
View file

@ -1,225 +0,0 @@
/* Types.h -- Basic types
2009-11-23 : Igor Pavlov : Public domain */
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#include <stddef.h>
#ifdef _WIN32
#include <windows.h>
#endif
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#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 _WIN32
#define MY_STD_CALL __stdcall
#else
#define MY_STD_CALL
#endif
#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_FAST_CALL __fastcall
#else
#define MY_CDECL
#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);
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)
EXTERN_C_END
#endif

View file

@ -12,7 +12,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "pdarg_parser.h" #include "carg_parser.h"
/* assure at least a minimum size for buffer 'buf' */ /* assure at least a minimum size for buffer 'buf' */
@ -71,7 +71,7 @@ static char parse_long_option( struct Arg_parser * const ap,
const struct ap_Option options[], const struct ap_Option options[],
int * const argindp ) int * const argindp )
{ {
unsigned int len; unsigned len;
int index = -1; int index = -1;
int i; int i;
char exact = 0, ambig = 0; char exact = 0, ambig = 0;

View file

@ -1,5 +1,5 @@
/* Pdlzip - Data compressor based on the LZMA algorithm /* Pdlzip - Data compressor based on the LZMA algorithm
Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
This program is free software: you have unlimited permission This program is free software: you have unlimited permission
to copy, distribute and modify it. to copy, distribute and modify it.
@ -21,10 +21,12 @@ typedef enum Bool bool;
#define min(x,y) ((x) <= (y) ? (x) : (y)) #define min(x,y) ((x) <= (y) ? (x) : (y))
#endif #endif
typedef int State;
enum { enum {
min_dictionary_bits = 12, min_dictionary_bits = 12,
min_dictionary_size = 1 << min_dictionary_bits, min_dictionary_size = 1 << min_dictionary_bits,
max_dictionary_bits = 26, max_dictionary_bits = 29,
max_dictionary_size = 1 << max_dictionary_bits, max_dictionary_size = 1 << max_dictionary_bits,
literal_context_bits = 3, literal_context_bits = 3,
pos_state_bits = 2, pos_state_bits = 2,
@ -41,16 +43,43 @@ enum {
max_match_len = min_match_len + max_len_symbols - 1, /* 273 */ max_match_len = min_match_len + max_len_symbols - 1, /* 273 */
min_match_len_limit = 5 }; min_match_len_limit = 5 };
struct Pretty_print
{
const char * name;
const char * stdin_name;
int longest_name;
int verbosity;
bool first_post;
};
void Pp_init( struct Pretty_print * const pp, const char * const filenames[],
const int num_filenames, const int v );
static inline void Pp_set_name( struct Pretty_print * const pp,
const char * const filename )
{
if( filename && filename[0] && strcmp( filename, "-" ) != 0 )
pp->name = filename;
else pp->name = pp->stdin_name;
pp->first_post = true;
}
static inline void Pp_reset( struct Pretty_print * const pp )
{ if( pp->name && pp->name[0] ) pp->first_post = true; }
void Pp_show_msg( struct Pretty_print * const pp, const char * const msg );
typedef uint32_t CRC32[256]; /* Table of CRCs of all 8-bit messages. */ typedef uint32_t CRC32[256]; /* Table of CRCs of all 8-bit messages. */
extern CRC32 crc32; extern CRC32 crc32;
static inline void CRC32_init() static inline void CRC32_init( void )
{ {
unsigned int n; unsigned n;
for( n = 0; n < 256; ++n ) for( n = 0; n < 256; ++n )
{ {
unsigned int c = n; unsigned c = n;
int k; int k;
for( k = 0; k < 8; ++k ) for( k = 0; k < 8; ++k )
{ if( c & 1 ) c = 0xEDB88320U ^ ( c >> 1 ); else c >>= 1; } { if( c & 1 ) c = 0xEDB88320U ^ ( c >> 1 ); else c >>= 1; }
@ -58,10 +87,11 @@ static inline void CRC32_init()
} }
} }
static inline void CRC32_update_byte( uint32_t * crc, const uint8_t byte ) static inline void CRC32_update_byte( uint32_t * const crc, const uint8_t byte )
{ *crc = crc32[(*crc^byte)&0xFF] ^ ( *crc >> 8 ); } { *crc = crc32[(*crc^byte)&0xFF] ^ ( *crc >> 8 ); }
static inline void CRC32_update_buf( uint32_t * crc, const uint8_t * const buffer,
const int size ) static inline void CRC32_update_buf( uint32_t * const crc,
const uint8_t * const buffer, const int size )
{ {
int i; int i;
for( i = 0; i < size; ++i ) for( i = 0; i < size; ++i )
@ -69,16 +99,15 @@ static inline void CRC32_update_buf( uint32_t * crc, const uint8_t * const buffe
} }
static inline int real_bits( const int value ) static inline int real_bits( unsigned value )
{ {
int bits = 0, i, mask; int bits = 0;
for( i = 1, mask = 1; mask > 0; ++i, mask <<= 1 ) while( value > 0 ) { value >>= 1; ++bits; }
if( value & mask ) bits = i;
return bits; return bits;
} }
static const uint8_t magic_string[4] = { 'L', 'Z', 'I', 'P' }; static const uint8_t magic_string[4] = { 0x4C, 0x5A, 0x49, 0x50 }; /* "LZIP" */
typedef uint8_t File_header[6]; /* 0-3 magic bytes */ typedef uint8_t File_header[6]; /* 0-3 magic bytes */
/* 4 version */ /* 4 version */
@ -86,15 +115,10 @@ typedef uint8_t File_header[6]; /* 0-3 magic bytes */
enum { Fh_size = 6 }; enum { Fh_size = 6 };
static inline void Fh_set_magic( File_header data ) static inline void Fh_set_magic( File_header data )
{ { memcpy( data, magic_string, 4 ); data[4] = 1; }
memcpy( data, magic_string, 4 );
data[4] = 1;
}
static inline bool Fh_verify_magic( const File_header data ) static inline bool Fh_verify_magic( const File_header data )
{ { return ( memcmp( data, magic_string, 4 ) == 0 ); }
return ( memcmp( data, magic_string, 4 ) == 0 );
}
static inline uint8_t Fh_version( const File_header data ) static inline uint8_t Fh_version( const File_header data )
{ return data[4]; } { return data[4]; }
@ -102,11 +126,11 @@ static inline uint8_t Fh_version( const File_header data )
static inline bool Fh_verify_version( const File_header data ) static inline bool Fh_verify_version( const File_header data )
{ return ( data[4] <= 1 ); } { return ( data[4] <= 1 ); }
static inline int Fh_get_dictionary_size( const File_header data ) static inline unsigned Fh_get_dictionary_size( const File_header data )
{ {
int sz = ( 1 << ( data[5] & 0x1F ) ); unsigned sz = ( 1 << ( data[5] & 0x1F ) );
if( sz > min_dictionary_size && sz <= max_dictionary_size ) if( sz > min_dictionary_size )
sz -= ( sz / 16 ) * ( ( data[5] >> 5 ) & 0x07 ); sz -= ( sz / 16 ) * ( ( data[5] >> 5 ) & 7 );
return sz; return sz;
} }
@ -140,51 +164,60 @@ enum { Ft_size = 20 };
static inline int Ft_versioned_size( const int version ) static inline int Ft_versioned_size( const int version )
{ return ( ( version >= 1 ) ? 20 : 12 ); } { return ( ( version >= 1 ) ? 20 : 12 ); }
static inline uint32_t Ft_get_data_crc( const File_trailer data ) static inline unsigned Ft_get_data_crc( const File_trailer data )
{ {
uint32_t tmp = 0; unsigned tmp = 0;
int i; int i;
for( i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; } for( i = 3; i >= 0; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp; return tmp;
} }
static inline void Ft_set_data_crc( File_trailer data, uint32_t crc ) static inline void Ft_set_data_crc( File_trailer data, unsigned crc )
{ {
int i; int i;
for( i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; } for( i = 0; i <= 3; ++i ) { data[i] = (uint8_t)crc; crc >>= 8; }
} }
static inline long long Ft_get_data_size( const File_trailer data ) static inline unsigned long long Ft_get_data_size( const File_trailer data )
{ {
long long tmp = 0; unsigned long long tmp = 0;
int i; int i;
for( i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; } for( i = 11; i >= 4; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp; return tmp;
} }
static inline void Ft_set_data_size( File_trailer data, long long sz ) static inline void Ft_set_data_size( File_trailer data, unsigned long long sz )
{ {
int i; int i;
for( i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } for( i = 4; i <= 11; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; }
} }
static inline long long Ft_get_member_size( const File_trailer data ) static inline unsigned long long Ft_get_member_size( const File_trailer data )
{ {
long long tmp = 0; unsigned long long tmp = 0;
int i; int i;
for( i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; } for( i = 19; i >= 12; --i ) { tmp <<= 8; tmp += data[i]; }
return tmp; return tmp;
} }
static inline void Ft_set_member_size( File_trailer data, long long sz ) static inline void Ft_set_member_size( File_trailer data, unsigned long long sz )
{ {
int i; int i;
for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; } for( i = 12; i <= 19; ++i ) { data[i] = (uint8_t)sz; sz >>= 8; }
} }
/* defined in LzmaDec.c */
int readblock( const int fd, uint8_t * const buf, const int size );
int writeblock( const int fd, const uint8_t * const buf, const int size );
/* defined in main.c */ /* defined in main.c */
extern int verbosity; extern int verbosity;
void show_error( const char * const msg, const int errcode, const bool help ); void show_error( const char * const msg, const int errcode, const bool help );
void internal_error( const char * const msg ); void internal_error( const char * const msg );
#define SZ_OK 0
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9

87
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# configure script for Pdlzip - Data compressor based on the LZMA algorithm # configure script for Pdlzip - Data compressor based on the LZMA algorithm
# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. # Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
# #
# This configure script is free software: you have unlimited permission # This configure script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute and modify it.
@ -8,9 +8,9 @@
args= args=
no_create= no_create=
pkgname=pdlzip pkgname=pdlzip
pkgversion=1.3 pkgversion=1.4-rc1
progname=pdlzip progname=pdlzip
srctrigger=pdlzip.h srctrigger=clzip.h
# clear some things potentially inherited from environment. # clear some things potentially inherited from environment.
LC_ALL=C LC_ALL=C
@ -19,15 +19,22 @@ srcdir=
prefix=/usr/local prefix=/usr/local
exec_prefix='$(prefix)' exec_prefix='$(prefix)'
bindir='$(exec_prefix)/bin' bindir='$(exec_prefix)/bin'
datadir='$(prefix)/share' datarootdir='$(prefix)/share'
infodir='$(datadir)/info' infodir='$(datarootdir)/info'
mandir='$(datadir)/man' mandir='$(datarootdir)/man'
sysconfdir='$(prefix)/etc' CC=gcc
CC=
CPPFLAGS= CPPFLAGS=
CFLAGS='-Wall -W -O2' CFLAGS='-Wall -W -O2'
LDFLAGS= LDFLAGS=
# checking whether we are using GNU C.
if [ ! -x /bin/gcc ] &&
[ ! -x /usr/bin/gcc ] &&
[ ! -x /usr/local/bin/gcc ] ; then
CC=cc
CFLAGS='-W -O2'
fi
# Loop over all args # Loop over all args
while [ -n "$1" ] ; do while [ -n "$1" ] ; do
@ -40,12 +47,12 @@ while [ -n "$1" ] ; do
# Split out the argument for options that take them # Split out the argument for options that take them
case ${option} in case ${option} in
*=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,'` ;; *=*) optarg=`echo ${option} | sed -e 's,^[^=]*=,,;s,/$,,'` ;;
esac esac
# Process the options # Process the options
case ${option} in case ${option} in
--help | --he* | -h) --help | -h)
echo "Usage: configure [options]" echo "Usage: configure [options]"
echo echo
echo "Options: [defaults in brackets]" echo "Options: [defaults in brackets]"
@ -55,37 +62,26 @@ while [ -n "$1" ] ; do
echo " --prefix=DIR install into DIR [${prefix}]" echo " --prefix=DIR install into DIR [${prefix}]"
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]" echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
echo " --bindir=DIR user executables directory [${bindir}]" echo " --bindir=DIR user executables directory [${bindir}]"
echo " --datadir=DIR base directory for doc and data [${datadir}]" echo " --datarootdir=DIR base directory for doc and data [${datarootdir}]"
echo " --infodir=DIR info files directory [${infodir}]" echo " --infodir=DIR info files directory [${infodir}]"
echo " --mandir=DIR man pages directory [${mandir}]" echo " --mandir=DIR man pages directory [${mandir}]"
echo " --sysconfdir=DIR read-only single-machine data directory [${sysconfdir}]"
echo " CC=COMPILER C compiler to use [gcc]" echo " CC=COMPILER C compiler to use [gcc]"
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]" echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]"
echo " CFLAGS=OPTIONS command line options for the C compiler [${CFLAGS}]" echo " CFLAGS=OPTIONS command line options for the C compiler [${CFLAGS}]"
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]" echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
echo echo
exit 0 ;; exit 0 ;;
--version | --ve* | -V) --version | -V)
echo "Configure script for ${pkgname} version ${pkgversion}" echo "Configure script for ${pkgname} version ${pkgversion}"
exit 0 ;; exit 0 ;;
--srcdir* | --sr*) --srcdir=*) srcdir=${optarg} ;;
srcdir=`echo ${optarg} | sed -e 's,/$,,'` ;; --prefix=*) prefix=${optarg} ;;
--prefix* | --pr*) --exec-prefix=*) exec_prefix=${optarg} ;;
prefix=`echo ${optarg} | sed -e 's,/$,,'` ;; --bindir=*) bindir=${optarg} ;;
--exec-prefix* | --ex*) --datarootdir=*) datarootdir=${optarg} ;;
exec_prefix=`echo ${optarg} | sed -e 's,/$,,'` ;; --infodir=*) infodir=${optarg} ;;
--bindir* | --bi*) --mandir=*) mandir=${optarg} ;;
bindir=`echo ${optarg} | sed -e 's,/$,,'` ;; --no-create) no_create=yes ;;
--datadir* | --da*)
datadir=`echo ${optarg} | sed -e 's,/$,,'` ;;
--infodir* | --inf*)
infodir=`echo ${optarg} | sed -e 's,/$,,'` ;;
--mandir* | --ma*)
mandir=`echo ${optarg} | sed -e 's,/$,,'` ;;
--sysconfdir* | --sy*)
sysconfdir=`echo ${optarg} | sed -e 's,/$,,'` ;;
--no-create | --no-c*)
no_create=yes ;;
CC=*) CC=${optarg} ;; CC=*) CC=${optarg} ;;
CPPFLAGS=*) CPPFLAGS=${optarg} ;; CPPFLAGS=*) CPPFLAGS=${optarg} ;;
@ -103,14 +99,14 @@ done
srcdirtext= srcdirtext=
if [ -z "${srcdir}" ] ; then if [ -z "${srcdir}" ] ; then
srcdirtext="or . or .." ; srcdir=. srcdirtext="or . or .." ; srcdir=.
if [ ! -r ${srcdir}/${srctrigger} ] ; then srcdir=.. ; fi if [ ! -r "${srcdir}/${srctrigger}" ] ; then srcdir=.. ; fi
if [ ! -r ${srcdir}/${srctrigger} ] ; then if [ ! -r "${srcdir}/${srctrigger}" ] ; then
## the sed command below emulates the dirname command ## the sed command below emulates the dirname command
srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` srcdir=`echo $0 | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
fi fi
fi fi
if [ ! -r ${srcdir}/${srctrigger} ] ; then if [ ! -r "${srcdir}/${srctrigger}" ] ; then
exec 1>&2 exec 1>&2
echo echo
echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" echo "configure: Can't find sources in ${srcdir} ${srcdirtext}"
@ -119,18 +115,7 @@ if [ ! -r ${srcdir}/${srctrigger} ] ; then
fi fi
# Set srcdir to . if that's what it is. # Set srcdir to . if that's what it is.
if [ "`pwd`" = "`cd ${srcdir} ; pwd`" ] ; then srcdir=. ; fi if [ "`pwd`" = "`cd "${srcdir}" ; pwd`" ] ; then srcdir=. ; fi
# checking whether we are using GNU C.
if [ -z "${CC}" ] ; then # Let the user override the test.
if [ -x /bin/gcc ] ||
[ -x /usr/bin/gcc ] ||
[ -x /usr/local/bin/gcc ] ; then
CC="gcc"
else
CC="cc"
fi
fi
echo echo
if [ -z "${no_create}" ] ; then if [ -z "${no_create}" ] ; then
@ -154,10 +139,9 @@ echo "VPATH = ${srcdir}"
echo "prefix = ${prefix}" echo "prefix = ${prefix}"
echo "exec_prefix = ${exec_prefix}" echo "exec_prefix = ${exec_prefix}"
echo "bindir = ${bindir}" echo "bindir = ${bindir}"
echo "datadir = ${datadir}" echo "datarootdir = ${datarootdir}"
echo "infodir = ${infodir}" echo "infodir = ${infodir}"
echo "mandir = ${mandir}" echo "mandir = ${mandir}"
echo "sysconfdir = ${sysconfdir}"
echo "CC = ${CC}" echo "CC = ${CC}"
echo "CPPFLAGS = ${CPPFLAGS}" echo "CPPFLAGS = ${CPPFLAGS}"
echo "CFLAGS = ${CFLAGS}" echo "CFLAGS = ${CFLAGS}"
@ -165,7 +149,7 @@ echo "LDFLAGS = ${LDFLAGS}"
rm -f Makefile rm -f Makefile
cat > Makefile << EOF cat > Makefile << EOF
# Makefile for Pdlzip - Data compressor based on the LZMA algorithm # Makefile for Pdlzip - Data compressor based on the LZMA algorithm
# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. # Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
# This file was generated automatically by configure. Do not edit. # This file was generated automatically by configure. Do not edit.
# #
# This Makefile is free software: you have unlimited permission # This Makefile is free software: you have unlimited permission
@ -178,15 +162,14 @@ VPATH = ${srcdir}
prefix = ${prefix} prefix = ${prefix}
exec_prefix = ${exec_prefix} exec_prefix = ${exec_prefix}
bindir = ${bindir} bindir = ${bindir}
datadir = ${datadir} datarootdir = ${datarootdir}
infodir = ${infodir} infodir = ${infodir}
mandir = ${mandir} mandir = ${mandir}
sysconfdir = ${sysconfdir}
CC = ${CC} CC = ${CC}
CPPFLAGS = ${CPPFLAGS} CPPFLAGS = ${CPPFLAGS}
CFLAGS = ${CFLAGS} CFLAGS = ${CFLAGS}
LDFLAGS = ${LDFLAGS} LDFLAGS = ${LDFLAGS}
EOF EOF
cat ${srcdir}/Makefile.in >> Makefile cat "${srcdir}/Makefile.in" >> Makefile
echo "OK. Now you can run make." echo "OK. Now you can run make."

View file

@ -1,10 +1,10 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1. .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.37.1.
.TH PDLZIP "1" "January 2012" "Pdlzip 1.3" "User Commands" .TH PDLZIP "1" "February 2013" "Pdlzip 1.4-rc1" "User Commands"
.SH NAME .SH NAME
Pdlzip \- reduces the size of files Pdlzip \- reduces the size of files
.SH SYNOPSIS .SH SYNOPSIS
.B pdlzip .B pdlzip
[\fIoptions\fR] [\fIfile\fR] [\fIoptions\fR] [\fIfiles\fR]
.SH DESCRIPTION .SH DESCRIPTION
Pdlzip \- A "public domain" version of the lzip data compressor Pdlzip \- A "public domain" version of the lzip data compressor
also able to decompress legacy lzma\-alone (.lzma) files. also able to decompress legacy lzma\-alone (.lzma) files.
@ -22,9 +22,21 @@ send output to standard output
\fB\-d\fR, \fB\-\-decompress\fR \fB\-d\fR, \fB\-\-decompress\fR
decompress decompress
.TP .TP
\fB\-f\fR, \fB\-\-force\fR
overwrite existing output files
.TP
\fB\-F\fR, \fB\-\-recompress\fR
force recompression of compressed files
.TP
\fB\-k\fR, \fB\-\-keep\fR
keep (don't delete) input files
.TP
\fB\-m\fR, \fB\-\-match\-length=\fR<bytes> \fB\-m\fR, \fB\-\-match\-length=\fR<bytes>
set match length limit in bytes [36] set match length limit in bytes [36]
.TP .TP
\fB\-o\fR, \fB\-\-output=\fR<file>
if reading stdin, place the output into <file>
.TP
\fB\-q\fR, \fB\-\-quiet\fR \fB\-q\fR, \fB\-\-quiet\fR
suppress all messages suppress all messages
.TP .TP
@ -46,7 +58,7 @@ alias for \fB\-1\fR
\fB\-\-best\fR \fB\-\-best\fR
alias for \fB\-9\fR alias for \fB\-9\fR
.PP .PP
If no file name is given, pdlzip compresses or decompresses If no file names are given, pdlzip compresses or decompresses
from standard input to standard output. from standard input to standard output.
Numbers may be followed by a multiplier: k = kB = 10^3 = 1000, Numbers may be followed by a multiplier: k = kB = 10^3 = 1000,
Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc... Ki = KiB = 2^10 = 1024, M = 10^6, Mi = 2^20, G = 10^9, Gi = 2^30, etc...
@ -59,7 +71,7 @@ Report bugs to lzip\-bug@nongnu.org
.br .br
Pdlzip home page: http://www.nongnu.org/lzip/pdlzip.html Pdlzip home page: http://www.nongnu.org/lzip/pdlzip.html
.SH COPYRIGHT .SH COPYRIGHT
Copyright \(co 2012 Antonio Diaz Diaz. Copyright \(co 2013 Antonio Diaz Diaz.
Public Domain 2009 Igor Pavlov. Public Domain 2009 Igor Pavlov.
.br .br
This is free software: you are free to change and redistribute it. This is free software: you are free to change and redistribute it.

1165
main.c

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# check script for Pdlzip - Data compressor based on the LZMA algorithm # check script for Pdlzip - Data compressor based on the LZMA algorithm
# Copyright (C) 2010, 2011, 2012 Antonio Diaz Diaz. # Copyright (C) 2010, 2011, 2012, 2013 Antonio Diaz Diaz.
# #
# This script is free software: you have unlimited permission # This script is free software: you have unlimited permission
# to copy, distribute and modify it. # to copy, distribute and modify it.
@ -26,18 +26,32 @@ fail=0
printf "testing pdlzip-%s..." "$2" printf "testing pdlzip-%s..." "$2"
"${LZIP}" -t "${testdir}"/test.lz || fail=1 "${LZIP}" -t "${testdir}"/test.txt.lz || fail=1
printf . "${LZIP}" -cd "${testdir}"/test.txt.lz > copy || fail=1
"${LZIP}" -cd "${testdir}"/test.lz > copy || fail=1
cmp in copy || fail=1 cmp in copy || fail=1
printf . printf .
"${LZIP}" -t "${testdir}"/test.lzma || fail=1 "${LZIP}" -cfq "${testdir}"/test.txt.lz > out
printf . if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi
"${LZIP}" -cd "${testdir}"/test.lzma > copy || fail=1 "${LZIP}" -cF "${testdir}"/test.txt.lz > out || fail=1
"${LZIP}" -cd out | "${LZIP}" -d > copy || fail=1
cmp in copy || fail=1 cmp in copy || fail=1
printf . printf .
"${LZIP}" -t "${testdir}"/test.txt.lzma || fail=1
"${LZIP}" -cd "${testdir}"/test.txt.lzma > copy || fail=1
cmp in copy || fail=1
printf .
"${LZIP}" -cqs-1 in > out
if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi
"${LZIP}" -cqs0 in > out
if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi
"${LZIP}" -cqs4095 in > out
if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi
"${LZIP}" -cqm274 in > out
if [ $? != 1 ] ; then fail=1 ; printf - ; else printf . ; fi
for i in s4Ki 0 1 2 3 4 5 6 7 8s16 9s16 ; do for i in s4Ki 0 1 2 3 4 5 6 7 8s16 9s16 ; do
"${LZIP}" -k -$i in || fail=1 "${LZIP}" -k -$i in || fail=1
mv -f in.lz copy.lz || fail=1 mv -f in.lz copy.lz || fail=1
@ -62,11 +76,24 @@ for i in s4Ki 0 1 2 3 4 5 6 7 8s16 9s16 ; do
printf . printf .
done done
for i in s4Ki 0 1 2 3 4 5 6 7 8s16 9s16 ; do
"${LZIP}" -f -$i -o out < in || fail=1
"${LZIP}" -df -o copy < out.lz || fail=1
cmp in copy || fail=1
printf .
done
"${LZIP}" < in > anyothername || fail=1 "${LZIP}" < in > anyothername || fail=1
"${LZIP}" -d anyothername || fail=1 "${LZIP}" -d anyothername || fail=1
cmp in anyothername.out || fail=1 cmp in anyothername.out || fail=1
printf . printf .
cat in in > in2 || framework_failure
"${LZIP}" < in2 > out2 || fail=1
"${LZIP}" -d < out2 > copy2 || fail=1
cmp in2 copy2 || fail=1
printf .
echo echo
if [ ${fail} = 0 ] ; then if [ ${fail} = 0 ] ; then
echo "tests completed successfully." echo "tests completed successfully."

Binary file not shown.

Binary file not shown.

BIN
testsuite/test.txt.lz Normal file

Binary file not shown.

BIN
testsuite/test.txt.lzma Normal file

Binary file not shown.