void*
LZ4_create(void);
int
LZ4_free(void* ctx);
int
LZ4_compress_heap_limitedOutput(
void* ctx,
char* source,
char* dest,
int inputSize,
int maxOutputSize);
int
LZ4_compress64k_heap_limitedOutput(
void* ctx,
char* source,
char* dest,
int inputSize,
int maxOutputSize);
#ifdef COMPRESS_64K
# define HASHLOG (MEMORY_USAGE-1)
# define CURRENT_H_TYPE U16
# define CURRENTBASE(base) BYTE* base = ip
#else
# define HASHLOG (MEMORY_USAGE-2)
# define CURRENT_H_TYPE HTYPE
# define CURRENTBASE(base) INITBASE(base)
#endif
#define HASHTABLE_NBCELLS (1U<<HASHLOG)
#define LZ4_HASH(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASHLOG))
#define LZ4_HASHVALUE(p) LZ4_HASH(A32(p))
int
LZ4_compress_heap_limitedOutput(
void* ctx,
char* source,
char* dest,
int inputSize,
int maxOutputSize)
{
CURRENT_H_TYPE* HashTable = (CURRENT_H_TYPE*)ctx;
BYTE* ip = (BYTE*) source;
CURRENTBASE(base);
BYTE* anchor = ip;
BYTE* iend = ip + inputSize;
BYTE* mflimit = iend - MFLIMIT;
#define matchlimit (iend - LASTLITERALS)
BYTE* op = (BYTE*) dest;
BYTE* oend = op + maxOutputSize;
int length;
int skipStrength = SKIPSTRENGTH;
U32 forwardH;
if (inputSize<MINLENGTH) goto _last_literals;
memset((void*)HashTable, 0, HASHTABLESIZE);
HashTable[LZ4_HASHVALUE(ip)] = (CURRENT_H_TYPE)(ip - base);
ip++;
forwardH = LZ4_HASHVALUE(ip);
for ( ; ; )
{
int findMatchAttempts = (1U << skipStrength) + 3;
BYTE* forwardIp = ip;
BYTE* ref;
BYTE* token;
do {
U32 h = forwardH;
int step = findMatchAttempts++ >> skipStrength;
ip = forwardIp;
forwardIp = ip + step;
if unlikely(forwardIp > mflimit) {
goto _last_literals;
}
forwardH = LZ4_HASHVALUE(forwardIp);
ref = base + HashTable[h];
HashTable[h] = (CURRENT_H_TYPE)(ip - base);
} while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip)));
while ((ip>anchor) && (ref>(BYTE*)source) && unlikely(ip[-1]==ref[-1])) {
ip--;
ref--;
}
length = (int)(ip - anchor);
token = op++;
if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend)
return 0;
if (length>=(int)RUN_MASK)
{
int len = length-RUN_MASK;
*token=(RUN_MASK<<ML_BITS);
for(; len >= 255 ; len-=255)
*op++ = 255;
*op++ = (BYTE)len;
}
else *token = (BYTE)(length<<ML_BITS);
LZ4_BLINDCOPY(anchor, op, length);
_next_match:
LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
ip+=MINMATCH; ref+=MINMATCH;
anchor = ip;
while likely(ip<matchlimit-(STEPSIZE-1))
{
UARCH diff = AARCH(ref) ^ AARCH(ip);
if (!diff) {
ip+=STEPSIZE;
ref+=STEPSIZE;
continue;
}
ip += LZ4_NbCommonBytes(diff);
goto _endCount;
}
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:
length = (int)(ip - anchor);
if unlikely(op + (1 + LASTLITERALS) + (length>>8) > oend)
return 0;
if (length>=(int)ML_MASK)
{
*token += ML_MASK;
length -= ML_MASK;
for (; length > 509 ; length-=510) {
*op++ = 255;
*op++ = 255;
}
if (length >= 255) {
length-=255;
*op++ = 255;
}
*op++ = (BYTE)length;
}
else *token += (BYTE)length;
if (ip > mflimit) {
anchor = ip;
break;
}
HashTable[LZ4_HASHVALUE(ip-2)] = (CURRENT_H_TYPE)(ip - 2 - base);
ref = base + HashTable[LZ4_HASHVALUE(ip)];
HashTable[LZ4_HASHVALUE(ip)] = (CURRENT_H_TYPE)(ip - base);
if ((ref >= ip - MAX_DISTANCE) && (A32(ref) == A32(ip))) {
token = op++;
*token=0;
goto _next_match;
}
anchor = ip++;
forwardH = LZ4_HASHVALUE(ip);
}
_last_literals:
{
int lastRun = (int)(iend - anchor);
if (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)
return 0;
if (lastRun>=(int)RUN_MASK) {
*op++=(RUN_MASK<<ML_BITS);
lastRun-=RUN_MASK;
for(; lastRun >= 255 ; lastRun-=255)
*op++ = 255;
*op++ = (BYTE) lastRun;
}
else *op++ = (BYTE)(lastRun<<ML_BITS);
memcpy(op, anchor, iend - anchor);
op += iend-anchor;
}
return (int) (((char*)op)-dest);
}
int
LZ4_compress64k_heap_limitedOutput(
void* ctx,
char* source,
char* dest,
int inputSize,
int maxOutputSize)
{
CURRENT_H_TYPE* HashTable = (CURRENT_H_TYPE*)ctx;
BYTE* ip = (BYTE*) source;
CURRENTBASE(base);
BYTE* anchor = ip;
BYTE* iend = ip + inputSize;
BYTE* mflimit = iend - MFLIMIT;
#define matchlimit (iend - LASTLITERALS)
BYTE* op = (BYTE*) dest;
BYTE* oend = op + maxOutputSize;
int length;
int skipStrength = SKIPSTRENGTH;
U32 forwardH;
if (inputSize<MINLENGTH) goto _last_literals;
memset((void*)HashTable, 0, HASHTABLESIZE);
HashTable[LZ4_HASHVALUE(ip)] = (CURRENT_H_TYPE)(ip - base);
ip++;
forwardH = LZ4_HASHVALUE(ip);
for ( ; ; )
{
int findMatchAttempts = (1U << skipStrength) + 3;
BYTE* forwardIp = ip;
BYTE* ref;
BYTE* token;
do {
U32 h = forwardH;
int step = findMatchAttempts++ >> skipStrength;
ip = forwardIp;
forwardIp = ip + step;
if unlikely(forwardIp > mflimit) {
goto _last_literals;
}
forwardH = LZ4_HASHVALUE(forwardIp);
ref = base + HashTable[h];
HashTable[h] = (CURRENT_H_TYPE)(ip - base);
} while ((ref < ip - MAX_DISTANCE) || (A32(ref) != A32(ip)));
while ((ip>anchor) && (ref>(BYTE*)source) && unlikely(ip[-1]==ref[-1])) {
ip--;
ref--;
}
length = (int)(ip - anchor);
token = op++;
if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) > oend)
return 0;
if (length>=(int)RUN_MASK)
{
int len = length-RUN_MASK;
*token=(RUN_MASK<<ML_BITS);
for(; len >= 255 ; len-=255)
*op++ = 255;
*op++ = (BYTE)len;
}
else *token = (BYTE)(length<<ML_BITS);
LZ4_BLINDCOPY(anchor, op, length);
_next_match:
LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
ip+=MINMATCH; ref+=MINMATCH;
anchor = ip;
while likely(ip<matchlimit-(STEPSIZE-1))
{
UARCH diff = AARCH(ref) ^ AARCH(ip);
if (!diff) {
ip+=STEPSIZE;
ref+=STEPSIZE;
continue;
}
ip += LZ4_NbCommonBytes(diff);
goto _endCount;
}
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:
length = (int)(ip - anchor);
if unlikely(op + (1 + LASTLITERALS) + (length>>8) > oend)
return 0;
if (length>=(int)ML_MASK)
{
*token += ML_MASK;
length -= ML_MASK;
for (; length > 509 ; length-=510) {
*op++ = 255;
*op++ = 255;
}
if (length >= 255) {
length-=255;
*op++ = 255;
}
*op++ = (BYTE)length;
}
else *token += (BYTE)length;
if (ip > mflimit) {
anchor = ip;
break;
}
HashTable[LZ4_HASHVALUE(ip-2)] = (CURRENT_H_TYPE)(ip - 2 - base);
ref = base + HashTable[LZ4_HASHVALUE(ip)];
HashTable[LZ4_HASHVALUE(ip)] = (CURRENT_H_TYPE)(ip - base);
if ((ref >= ip - MAX_DISTANCE) && (A32(ref) == A32(ip))) {
token = op++;
*token=0;
goto _next_match;
}
anchor = ip++;
forwardH = LZ4_HASHVALUE(ip);
}
_last_literals:
{
int lastRun = (int)(iend - anchor);
if (((char*)op - dest) + lastRun + 1 +
((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)
return 0;
if (lastRun>=(int)RUN_MASK) {
*op++=(RUN_MASK<<ML_BITS);
lastRun-=RUN_MASK;
for(; lastRun >= 255 ; lastRun-=255)
*op++ = 255;
*op++ = (BYTE) lastRun;
}
else *op++ = (BYTE)(lastRun<<ML_BITS);
memcpy(op, anchor, iend - anchor);
op += iend-anchor;
}
return (int) (((char*)op)-dest);
}
#undef HASHLOG
#undef HASHTABLE_NBCELLS
#undef LZ4_HASH
#undef LZ4_HASHVALUE
#undef CURRENT_H_TYPE
#undef CURRENTBASE