Added : LZ4_compressBound() function
corrected : bench.c now correctly detects file size on a wider ranger of compilers; thanks to Erik Andersen minor : removed warnings on undefined (-Wundef on gcc), thanks David Sterba for suggestion git-svn-id: https://lz4.googlecode.com/svn/trunk@55 650e7d94-2a16-8b24-b05c-7c0b3f6821cd
This commit is contained in:
parent
7b6ba0421d
commit
4045a42bb1
6
Makefile
6
Makefile
@ -1,10 +1,10 @@
|
||||
all: lz4demo64 lz4demo32
|
||||
|
||||
lz4demo64: lz4.c lz4.h bench.c lz4demo.c
|
||||
gcc -O3 -I. -std=c99 -Wall -W -Wno-implicit-function-declaration lz4.c bench.c lz4demo.c -o lz4demo64.exe
|
||||
lz4demo64: lz4.c lz4.h bench.c lz4demo.c
|
||||
gcc -O3 -I. -std=c99 -Wall -W -Wundef -Wno-implicit-function-declaration lz4.c bench.c lz4demo.c -o lz4demo64.exe
|
||||
|
||||
lz4demo32: lz4.c lz4.h bench.c lz4demo.c
|
||||
gcc -m32 -O3 -I. -std=c99 -Wall -W -Wno-implicit-function-declaration lz4.c bench.c lz4demo.c -o lz4demo32.exe
|
||||
gcc -m32 -O3 -I. -std=c99 -Wall -W -Wundef -Wno-implicit-function-declaration lz4.c bench.c lz4demo.c -o lz4demo32.exe
|
||||
|
||||
clean:
|
||||
rm -f core *.o lz4demo32.exe lz4demo64.exe
|
||||
|
58
bench.c
58
bench.c
@ -22,9 +22,17 @@
|
||||
*/
|
||||
|
||||
//**************************************
|
||||
// Compilation Directives
|
||||
// Compiler Options
|
||||
//**************************************
|
||||
|
||||
// Under Linux at least, pull in the *64 commands
|
||||
#define _LARGEFILE64_SOURCE
|
||||
|
||||
// MSVC does not support S_ISREG
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
|
||||
//**************************************
|
||||
// Includes
|
||||
@ -32,6 +40,8 @@
|
||||
#include <stdio.h> // fprintf, fopen, ftello64
|
||||
#include <stdlib.h> // malloc
|
||||
#include <sys/timeb.h> // timeb
|
||||
#include <sys/types.h> // stat64
|
||||
#include <sys/stat.h> // stat64
|
||||
#include "lz4.h"
|
||||
|
||||
|
||||
@ -65,7 +75,7 @@
|
||||
#define CHUNKSIZE (8<<20)
|
||||
#define MAX_NB_CHUNKS ((MAX_MEM / CHUNKSIZE) + 1)
|
||||
|
||||
|
||||
|
||||
//**************************************
|
||||
// Local structures
|
||||
//**************************************
|
||||
@ -96,7 +106,6 @@ struct compressionParameters
|
||||
// Private functions
|
||||
//*********************************************************
|
||||
|
||||
|
||||
static int BMK_GetMilliStart()
|
||||
{
|
||||
// Supposed to be portable
|
||||
@ -163,19 +172,18 @@ static size_t BMK_findMaxMem(U64 requiredMem)
|
||||
}
|
||||
|
||||
|
||||
static U64 BMK_GetFileSize(FILE* f)
|
||||
static U64 BMK_GetFileSize(char* infilename)
|
||||
{
|
||||
U64 r;
|
||||
#ifdef _MSC_VER
|
||||
r = _fseeki64(f, 0L, SEEK_END);
|
||||
r = (U64) _ftelli64(f);
|
||||
_fseeki64(f, 0L, SEEK_SET);
|
||||
int r;
|
||||
#if defined(_MSC_VER)
|
||||
struct _stat64 statbuf;
|
||||
r = _stat64(infilename, &statbuf);
|
||||
#else
|
||||
r = (U64) fseeko64(f, 0LL, SEEK_END);
|
||||
r = (U64) ftello64(f);
|
||||
fseeko64(f, 0LL, SEEK_SET);
|
||||
struct stat statbuf;
|
||||
r = stat(infilename, &statbuf);
|
||||
#endif
|
||||
return r;
|
||||
if (r || !S_ISREG(statbuf.st_mode)) return 0; // No good...
|
||||
return (U64)statbuf.st_size;
|
||||
}
|
||||
|
||||
|
||||
@ -183,7 +191,7 @@ static U64 BMK_GetFileSize(FILE* f)
|
||||
// Public function
|
||||
//*********************************************************
|
||||
|
||||
int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
{
|
||||
int fileIdx=0;
|
||||
FILE* fileIn;
|
||||
@ -203,7 +211,7 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
U64 totalz = 0;
|
||||
double totalc = 0.;
|
||||
double totald = 0.;
|
||||
|
||||
|
||||
|
||||
// Init
|
||||
compP.compressionFunction = LZ4_compress;
|
||||
@ -222,7 +230,7 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
}
|
||||
|
||||
// Memory allocation & restrictions
|
||||
largefilesize = BMK_GetFileSize(fileIn);
|
||||
largefilesize = BMK_GetFileSize(infilename);
|
||||
benchedsize = (size_t) BMK_findMaxMem(largefilesize) / 2;
|
||||
if ((U64)benchedsize > largefilesize) benchedsize = (size_t)largefilesize;
|
||||
if (benchedsize < largefilesize)
|
||||
@ -233,7 +241,7 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
// Alloc
|
||||
in_buff = malloc((size_t )benchedsize);
|
||||
nbChunks = (benchedsize / CHUNKSIZE) + 1;
|
||||
maxCChunkSize = CHUNKSIZE + CHUNKSIZE/255 + 64;
|
||||
maxCChunkSize = LZ4_compressBound(CHUNKSIZE);
|
||||
out_buff_size = nbChunks * maxCChunkSize;
|
||||
out_buff = malloc((size_t )out_buff_size);
|
||||
|
||||
@ -288,10 +296,10 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
|
||||
for (loopNb = 1; loopNb <= NBLOOPS; loopNb++)
|
||||
{
|
||||
// Compression
|
||||
// Compression
|
||||
DISPLAY("%1i-%-14.14s : %9i ->\r", loopNb, infilename, (int)benchedsize);
|
||||
{ size_t i; for (i=0; i<benchedsize; i++) out_buff[i]=(char)i; } // warmimg up memory
|
||||
|
||||
|
||||
nb_loops = 0;
|
||||
milliTime = BMK_GetMilliStart();
|
||||
while(BMK_GetMilliStart() == milliTime);
|
||||
@ -299,13 +307,13 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
|
||||
{
|
||||
for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
|
||||
chunkP[chunkNb].outputSize = compP.compressionFunction(chunkP[chunkNb].inputBuffer, chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputSize);
|
||||
chunkP[chunkNb].outputSize = compP.compressionFunction(chunkP[chunkNb].inputBuffer, chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputSize);
|
||||
nb_loops++;
|
||||
}
|
||||
milliTime = BMK_GetMilliSpan(milliTime);
|
||||
|
||||
if ((double)milliTime < fastestC*nb_loops) fastestC = (double)milliTime/nb_loops;
|
||||
cSize=0; for (chunkNb=0; chunkNb<nbChunks; chunkNb++) cSize += chunkP[chunkNb].outputSize;
|
||||
cSize=0; for (chunkNb=0; chunkNb<nbChunks; chunkNb++) cSize += chunkP[chunkNb].outputSize;
|
||||
|
||||
DISPLAY("%1i-%-14.14s : %9i -> %9i (%5.2f%%), %6.1f MB/s\r", loopNb, infilename, (int)benchedsize, (int)cSize, (double)cSize/(double)benchedsize*100., (double)benchedsize / fastestC / 1000.);
|
||||
|
||||
@ -316,17 +324,17 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles)
|
||||
milliTime = BMK_GetMilliStart();
|
||||
while(BMK_GetMilliStart() == milliTime);
|
||||
milliTime = BMK_GetMilliStart();
|
||||
while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
|
||||
while(BMK_GetMilliSpan(milliTime) < TIMELOOP)
|
||||
{
|
||||
for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
|
||||
chunkP[chunkNb].outputSize = compP.decompressionFunction(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].inputSize);
|
||||
for (chunkNb=0; chunkNb<nbChunks; chunkNb++)
|
||||
chunkP[chunkNb].outputSize = compP.decompressionFunction(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].inputSize);
|
||||
nb_loops++;
|
||||
}
|
||||
milliTime = BMK_GetMilliSpan(milliTime);
|
||||
|
||||
if ((double)milliTime < fastestD*nb_loops) fastestD = (double)milliTime/nb_loops;
|
||||
DISPLAY("%1i-%-14.14s : %9i -> %9i (%5.2f%%), %6.1f MB/s , %6.1f MB/s\r", loopNb, infilename, (int)benchedsize, (int)cSize, (double)cSize/(double)benchedsize*100., (double)benchedsize / fastestC / 1000., (double)benchedsize / fastestD / 1000.);
|
||||
|
||||
|
||||
// CRC Checking
|
||||
crcd = BMK_checksum(in_buff, benchedsize);
|
||||
if (crcc!=crcd) { DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", infilename, (unsigned)crcc, (unsigned)crcd); break; }
|
||||
|
179
lz4.c
179
lz4.c
@ -6,14 +6,14 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@ -37,13 +37,13 @@
|
||||
// Memory usage formula : N->2^(N+2) Bytes (examples : 12 -> 16KB ; 17 -> 512KB)
|
||||
#define COMPRESSIONLEVEL 12
|
||||
|
||||
// NONCOMPRESSIBLE_CONFIRMATION :
|
||||
// NOTCOMPRESSIBLE_CONFIRMATION :
|
||||
// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
|
||||
// This may decrease compression ratio dramatically, but will be faster on incompressible data
|
||||
// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
|
||||
// This could improve compression a bit, but will be slower on incompressible data
|
||||
// The default value (6) is recommended
|
||||
#define NONCOMPRESSIBLE_CONFIRMATION 6
|
||||
#define NOTCOMPRESSIBLE_CONFIRMATION 6
|
||||
|
||||
// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :
|
||||
// This will provide a boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU.
|
||||
@ -57,15 +57,15 @@
|
||||
// CPU Feature Detection
|
||||
//**************************************
|
||||
// 32 or 64 bits ?
|
||||
#if (__x86_64__ || __x86_64 || __amd64__ || __amd64 || __ppc64__ || _WIN64 || __LP64__ || _LP64) // Detects 64 bits mode
|
||||
#define ARCH64 1
|
||||
#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) ) // Detects 64 bits mode
|
||||
#define LZ4_ARCH64 1
|
||||
#else
|
||||
#define ARCH64 0
|
||||
#define LZ4_ARCH64 0
|
||||
#endif
|
||||
|
||||
// Little Endian or Big Endian ?
|
||||
#if (__BIG_ENDIAN__ || _BIG_ENDIAN || _ARCH_PPC || __PPC__ || __PPC || PPC || __powerpc__ || __powerpc || powerpc || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) )
|
||||
#define CPU_BIG_ENDIAN 1
|
||||
#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) )
|
||||
#define LZ4_BIG_ENDIAN 1
|
||||
#else
|
||||
// Little Endian assumed. PDP Endian and other very rare endian format are unsupported.
|
||||
#endif
|
||||
@ -73,8 +73,8 @@
|
||||
// Unaligned memory access ?
|
||||
// This feature is automatically enabled for "common" CPU, such as x86.
|
||||
// For others CPU, you may want to force this option manually to improve performance if your target CPU supports unaligned memory access
|
||||
#if (__ARM_FEATURE_UNALIGNED)
|
||||
#define CPU_UNALIGNED_ACCESS 1
|
||||
#if defined(__ARM_FEATURE_UNALIGNED)
|
||||
#define LZ4_FORCE_UNALIGNED_ACCESS 1
|
||||
#endif
|
||||
|
||||
// Uncomment this parameter if your target system does not support hardware bit count
|
||||
@ -95,7 +95,7 @@
|
||||
#define inline __forceinline // Visual is not C99, but supports inline
|
||||
#endif
|
||||
|
||||
#if (defined(__GNUC__) && (!(CPU_UNALIGNED_ACCESS)))
|
||||
#if (defined(__GNUC__) && (!defined(LZ4_FORCE_UNALIGNED_ACCESS)))
|
||||
#define _PACKED __attribute__ ((packed))
|
||||
#else
|
||||
#define _PACKED
|
||||
@ -139,7 +139,7 @@
|
||||
// Constants
|
||||
//**************************************
|
||||
#define MINMATCH 4
|
||||
#define SKIPSTRENGTH (NONCOMPRESSIBLE_CONFIRMATION>2?NONCOMPRESSIBLE_CONFIRMATION:2)
|
||||
#define SKIPSTRENGTH (NOTCOMPRESSIBLE_CONFIRMATION>2?NOTCOMPRESSIBLE_CONFIRMATION:2)
|
||||
#define STACKLIMIT 13
|
||||
#define HEAPMODE (HASH_LOG>STACKLIMIT) // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).
|
||||
#define COPYLENGTH 8
|
||||
@ -160,12 +160,44 @@
|
||||
#define RUN_MASK ((1U<<RUN_BITS)-1)
|
||||
|
||||
|
||||
//**************************************
|
||||
// Architecture-specific macros
|
||||
//**************************************
|
||||
#if LZ4_ARCH64 // 64-bit
|
||||
#define STEPSIZE 8
|
||||
#define UARCH U64
|
||||
#define AARCH A64
|
||||
#define LZ4_COPYSTEP(s,d) A64(d) = A64(s); d+=8; s+=8;
|
||||
#define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d)
|
||||
#define LZ4_SECURECOPY(s,d,e) if (d<e) LZ4_WILDCOPY(s,d,e)
|
||||
#define HTYPE U32
|
||||
#define INITBASE(base) const BYTE* const base = ip
|
||||
#else // 32-bit
|
||||
#define STEPSIZE 4
|
||||
#define UARCH U32
|
||||
#define AARCH A32
|
||||
#define LZ4_COPYSTEP(s,d) A32(d) = A32(s); d+=4; s+=4;
|
||||
#define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
|
||||
#define LZ4_SECURECOPY LZ4_WILDCOPY
|
||||
#define HTYPE const BYTE*
|
||||
#define INITBASE(base) const int base = 0
|
||||
#endif
|
||||
|
||||
#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = bswap16(v); d = (s) - v; }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p,i) { U16 v = (U16)(i); v = bswap16(v); A16(p) = v; p+=2; }
|
||||
#else // Little Endian
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p,v) { A16(p) = v; p+=2; }
|
||||
#endif
|
||||
|
||||
|
||||
//**************************************
|
||||
// Local structures
|
||||
//**************************************
|
||||
struct refTables
|
||||
{
|
||||
const BYTE* hashTable[HASHTABLESIZE];
|
||||
HTYPE hashTable[HASHTABLESIZE];
|
||||
};
|
||||
|
||||
typedef struct _U64_S
|
||||
@ -188,38 +220,6 @@ typedef struct _U16_S
|
||||
#define A16(x) (((U16_S *)(x))->v)
|
||||
|
||||
|
||||
//**************************************
|
||||
// Architecture-specific macros
|
||||
//**************************************
|
||||
#if ARCH64 // 64-bit
|
||||
#define STEPSIZE 8
|
||||
#define UARCH U64
|
||||
#define AARCH A64
|
||||
#define LZ4_COPYSTEP(s,d) A64(d) = A64(s); d+=8; s+=8;
|
||||
#define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d)
|
||||
#define LZ4_SECURECOPY(s,d,e) if (d<e) LZ4_WILDCOPY(s,d,e)
|
||||
#define HTYPE U32
|
||||
#define INITBASE(base) const BYTE* const base = ip
|
||||
#else // 32-bit
|
||||
#define STEPSIZE 4
|
||||
#define UARCH U32
|
||||
#define AARCH A32
|
||||
#define LZ4_COPYSTEP(s,d) A32(d) = A32(s); d+=4; s+=4;
|
||||
#define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
|
||||
#define LZ4_SECURECOPY LZ4_WILDCOPY
|
||||
#define HTYPE const BYTE*
|
||||
#define INITBASE(base) const int base = 0
|
||||
#endif
|
||||
|
||||
#if ((CPU_BIG_ENDIAN) && !(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = bswap16(v); d = (s) - v; }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p,i) { U16 v = (U16)(i); v = bswap16(v); A16(p) = v; p+=2; }
|
||||
#else // Little Endian
|
||||
#define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
|
||||
#define LZ4_WRITE_LITTLEENDIAN_16(p,v) { A16(p) = v; p+=2; }
|
||||
#endif
|
||||
|
||||
|
||||
//**************************************
|
||||
// Macros
|
||||
//**************************************
|
||||
@ -232,11 +232,11 @@ typedef struct _U16_S
|
||||
//****************************
|
||||
// Private functions
|
||||
//****************************
|
||||
#if ARCH64
|
||||
#if LZ4_ARCH64
|
||||
|
||||
inline static int LZ4_NbCommonBytes (register U64 val)
|
||||
{
|
||||
#if CPU_BIG_ENDIAN
|
||||
#if defined(LZ4_BIG_ENDIAN)
|
||||
#if defined(_MSC_VER) && !defined(_FORCE_SW_BITCOUNT)
|
||||
unsigned long r = 0;
|
||||
_BitScanReverse64( &r, val );
|
||||
@ -268,7 +268,7 @@ inline static int LZ4_NbCommonBytes (register U64 val)
|
||||
|
||||
inline static int LZ4_NbCommonBytes (register U32 val)
|
||||
{
|
||||
#if CPU_BIG_ENDIAN
|
||||
#if defined(LZ4_BIG_ENDIAN)
|
||||
#if defined(_MSC_VER) && !defined(_FORCE_SW_BITCOUNT)
|
||||
unsigned long r = 0;
|
||||
_BitScanReverse( &r, val );
|
||||
@ -298,12 +298,23 @@ inline static int LZ4_NbCommonBytes (register U32 val)
|
||||
#endif
|
||||
|
||||
|
||||
//****************************
|
||||
// Public functions
|
||||
//****************************
|
||||
|
||||
int LZ4_compressBound(int isize)
|
||||
{
|
||||
return (isize + (isize/255) + 16);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//******************************
|
||||
// Public Compression functions
|
||||
// Compression functions
|
||||
//******************************
|
||||
|
||||
int LZ4_compressCtx(void** ctx,
|
||||
const char* source,
|
||||
const char* source,
|
||||
char* dest,
|
||||
int isize)
|
||||
{
|
||||
@ -371,7 +382,7 @@ int LZ4_compressCtx(void** ctx,
|
||||
} while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip)));
|
||||
|
||||
// Catch up
|
||||
while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
|
||||
while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
|
||||
|
||||
// Encode Literal length
|
||||
length = ip - anchor;
|
||||
@ -396,14 +407,14 @@ _next_match:
|
||||
ip += LZ4_NbCommonBytes(diff);
|
||||
goto _endCount;
|
||||
}
|
||||
if (ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
|
||||
if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
|
||||
if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
|
||||
if ((ip<matchlimit) && (*ref == *ip)) ip++;
|
||||
_endCount:
|
||||
|
||||
|
||||
// Encode MatchLength
|
||||
len = (ip - anchor);
|
||||
if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
|
||||
if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
|
||||
else *token += len;
|
||||
|
||||
// Test end of chunk
|
||||
@ -426,11 +437,11 @@ _last_literals:
|
||||
// Encode Last Literals
|
||||
{
|
||||
int lastRun = iend - anchor;
|
||||
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
|
||||
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
|
||||
else *op++ = (lastRun<<ML_BITS);
|
||||
memcpy(op, anchor, iend - anchor);
|
||||
op += iend-anchor;
|
||||
}
|
||||
}
|
||||
|
||||
// End
|
||||
return (int) (((char*)op)-dest);
|
||||
@ -445,10 +456,10 @@ _last_literals:
|
||||
#define LZ4_HASH64K_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASHLOG64K))
|
||||
#define LZ4_HASH64K_VALUE(p) LZ4_HASH64K_FUNCTION(A32(p))
|
||||
int LZ4_compress64kCtx(void** ctx,
|
||||
const char* source,
|
||||
const char* source,
|
||||
char* dest,
|
||||
int isize)
|
||||
{
|
||||
{
|
||||
#if HEAPMODE
|
||||
struct refTables *srt = (struct refTables *) (*ctx);
|
||||
U16* HashTable;
|
||||
@ -456,7 +467,7 @@ int LZ4_compress64kCtx(void** ctx,
|
||||
U16 HashTable[HASH64KTABLESIZE] = {0};
|
||||
#endif
|
||||
|
||||
const BYTE* ip = (BYTE*) source;
|
||||
const BYTE* ip = (BYTE*) source;
|
||||
const BYTE* anchor = ip;
|
||||
const BYTE* const base = ip;
|
||||
const BYTE* const iend = ip + isize;
|
||||
@ -464,7 +475,7 @@ int LZ4_compress64kCtx(void** ctx,
|
||||
#define matchlimit (iend - LASTLITERALS)
|
||||
|
||||
BYTE* op = (BYTE*) dest;
|
||||
|
||||
|
||||
int len, length;
|
||||
const int skipStrength = SKIPSTRENGTH;
|
||||
U32 forwardH;
|
||||
@ -487,9 +498,9 @@ int LZ4_compress64kCtx(void** ctx,
|
||||
|
||||
// First Byte
|
||||
ip++; forwardH = LZ4_HASH64K_VALUE(ip);
|
||||
|
||||
|
||||
// Main Loop
|
||||
for ( ; ; )
|
||||
for ( ; ; )
|
||||
{
|
||||
int findMatchAttempts = (1U << skipStrength) + 3;
|
||||
const BYTE* forwardIp = ip;
|
||||
@ -512,12 +523,12 @@ int LZ4_compress64kCtx(void** ctx,
|
||||
} while (A32(ref) != A32(ip));
|
||||
|
||||
// Catch up
|
||||
while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
|
||||
while ((ip>anchor) && (ref>(BYTE*)source) && (ip[-1]==ref[-1])) { ip--; ref--; }
|
||||
|
||||
// Encode Literal length
|
||||
length = ip - anchor;
|
||||
token = op++;
|
||||
if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
|
||||
if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
|
||||
else *token = (length<<ML_BITS);
|
||||
|
||||
// Copy Literals
|
||||
@ -537,14 +548,14 @@ _next_match:
|
||||
ip += LZ4_NbCommonBytes(diff);
|
||||
goto _endCount;
|
||||
}
|
||||
if (ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
|
||||
if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { ip+=4; ref+=4; }
|
||||
if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
|
||||
if ((ip<matchlimit) && (*ref == *ip)) ip++;
|
||||
_endCount:
|
||||
|
||||
|
||||
// Encode MatchLength
|
||||
len = (ip - anchor);
|
||||
if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
|
||||
if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }
|
||||
else *token += len;
|
||||
|
||||
// Test end of chunk
|
||||
@ -559,7 +570,7 @@ _endCount:
|
||||
if (A32(ref) == A32(ip)) { token = op++; *token=0; goto _next_match; }
|
||||
|
||||
// Prepare next loop
|
||||
anchor = ip++;
|
||||
anchor = ip++;
|
||||
forwardH = LZ4_HASH64K_VALUE(ip);
|
||||
}
|
||||
|
||||
@ -567,7 +578,7 @@ _last_literals:
|
||||
// Encode Last Literals
|
||||
{
|
||||
int lastRun = iend - anchor;
|
||||
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
|
||||
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
|
||||
else *op++ = (lastRun<<ML_BITS);
|
||||
memcpy(op, anchor, iend - anchor);
|
||||
op += iend-anchor;
|
||||
@ -579,7 +590,7 @@ _last_literals:
|
||||
|
||||
|
||||
|
||||
int LZ4_compress(const char* source,
|
||||
int LZ4_compress(const char* source,
|
||||
char* dest,
|
||||
int isize)
|
||||
{
|
||||
@ -604,12 +615,12 @@ int LZ4_compress(const char* source,
|
||||
// Decompression functions
|
||||
//****************************
|
||||
|
||||
// Note : The decoding functions LZ4_uncompress() and LZ4_uncompress_unknownOutputSize()
|
||||
// Note : The decoding functions LZ4_uncompress() and LZ4_uncompress_unknownOutputSize()
|
||||
// are safe against "buffer overflow" attack type.
|
||||
// They will never write nor read outside of the provided input and output buffers.
|
||||
// A corrupted input will produce an error result, a negative int, indicating the position of the error within input stream.
|
||||
|
||||
int LZ4_uncompress(const char* source,
|
||||
int LZ4_uncompress(const char* source,
|
||||
char* dest,
|
||||
int osize)
|
||||
{
|
||||
@ -622,7 +633,7 @@ int LZ4_uncompress(const char* source,
|
||||
BYTE* cpy;
|
||||
|
||||
BYTE token;
|
||||
|
||||
|
||||
int len, length;
|
||||
size_t dec[] ={0, 3, 2, 3, 0, 0, 0, 0};
|
||||
|
||||
@ -632,12 +643,12 @@ int LZ4_uncompress(const char* source,
|
||||
{
|
||||
// get runlength
|
||||
token = *ip++;
|
||||
if ((length=(token>>ML_BITS)) == RUN_MASK) { for (;(len=*ip++)==255;length+=255){} length += len; }
|
||||
if ((length=(token>>ML_BITS)) == RUN_MASK) { for (;(len=*ip++)==255;length+=255){} length += len; }
|
||||
|
||||
// copy literals
|
||||
cpy = op+length;
|
||||
if (cpy>oend-COPYLENGTH)
|
||||
{
|
||||
if (cpy>oend-COPYLENGTH)
|
||||
{
|
||||
if (cpy > oend) goto _output_error;
|
||||
memcpy(op, ip, length);
|
||||
ip += length;
|
||||
@ -650,12 +661,12 @@ int LZ4_uncompress(const char* source,
|
||||
if (ref < (BYTE* const)dest) goto _output_error;
|
||||
|
||||
// get matchlength
|
||||
if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; }
|
||||
if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; }
|
||||
|
||||
// copy repeated sequence
|
||||
if (op-ref<STEPSIZE)
|
||||
{
|
||||
#if ARCH64
|
||||
#if LZ4_ARCH64
|
||||
size_t dec2table[]={0, 0, 0, -1, 0, 1, 2, 3};
|
||||
size_t dec2 = dec2table[op-ref];
|
||||
#else
|
||||
@ -693,7 +704,7 @@ _output_error:
|
||||
|
||||
|
||||
int LZ4_uncompress_unknownOutputSize(
|
||||
const char* source,
|
||||
const char* source,
|
||||
char* dest,
|
||||
int isize,
|
||||
int maxOutputSize)
|
||||
@ -718,12 +729,12 @@ int LZ4_uncompress_unknownOutputSize(
|
||||
{
|
||||
// get runlength
|
||||
token = *ip++;
|
||||
if ((length=(token>>ML_BITS)) == RUN_MASK) { for (;(len=*ip++)==255;length+=255){} length += len; }
|
||||
if ((length=(token>>ML_BITS)) == RUN_MASK) { for (;(len=*ip++)==255;length+=255){} length += len; }
|
||||
|
||||
// copy literals
|
||||
cpy = op+length;
|
||||
if (cpy>oend-COPYLENGTH)
|
||||
{
|
||||
if (cpy>oend-COPYLENGTH)
|
||||
{
|
||||
if (cpy > oend) goto _output_error;
|
||||
memcpy(op, ip, length);
|
||||
op += length;
|
||||
@ -742,7 +753,7 @@ int LZ4_uncompress_unknownOutputSize(
|
||||
// copy repeated sequence
|
||||
if (op-ref<STEPSIZE)
|
||||
{
|
||||
#if ARCH64
|
||||
#if LZ4_ARCH64
|
||||
size_t dec2table[]={0, 0, 0, -1, 0, 1, 2, 3};
|
||||
size_t dec2 = dec2table[op-ref];
|
||||
#else
|
||||
|
12
lz4.h
12
lz4.h
@ -61,6 +61,18 @@ LZ4_uncompress() :
|
||||
// Advanced Functions
|
||||
//****************************
|
||||
|
||||
int LZ4_compressBound(int isize);
|
||||
|
||||
/*
|
||||
LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 may output in a "worst case" scenario, for memory allocation of output buffer.
|
||||
|
||||
isize : is the input size
|
||||
return : maximum size that LZ4 may output in a "worst case" scenario
|
||||
note : this function is limited by "int" range
|
||||
*/
|
||||
|
||||
|
||||
int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
|
||||
|
||||
/*
|
||||
|
@ -65,7 +65,6 @@
|
||||
|
||||
#define CHUNKSIZE (8<<20) // 8 MB
|
||||
#define CACHELINE 64
|
||||
#define OUT_CHUNKSIZE (CHUNKSIZE + (CHUNKSIZE/255) + CACHELINE)
|
||||
#define ARCHIVE_MAGICNUMBER 0x184C2102
|
||||
#define ARCHIVE_MAGICNUMBER_SIZE 4
|
||||
|
||||
@ -166,7 +165,7 @@ int compress_file(char* input_filename, char* output_filename)
|
||||
|
||||
// Allocate Memory
|
||||
in_buff = (char*)malloc(CHUNKSIZE);
|
||||
out_buff = (char*)malloc(OUT_CHUNKSIZE);
|
||||
out_buff = (char*)malloc(LZ4_compressBound(CHUNKSIZE));
|
||||
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 8; }
|
||||
|
||||
// Write Archive Header
|
||||
@ -234,7 +233,7 @@ int decode_file(char* input_filename, char* output_filename)
|
||||
if (r) return r;
|
||||
|
||||
// Allocate Memory
|
||||
in_buff = (char*)malloc(OUT_CHUNKSIZE);
|
||||
in_buff = (char*)malloc(LZ4_compressBound(CHUNKSIZE));
|
||||
out_buff = (char*)malloc(CHUNKSIZE);
|
||||
if (!in_buff || !out_buff) { DISPLAY("Allocation error : not enough memory\n"); return 7; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user