/*\r
LZ4 - Fast LZ compression algorithm\r
- Copyright (C) 2011, Yann Collet.\r
- BSD License\r
+ Copyright (C) 2011-2012, Yann Collet.\r
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\r
\r
Redistribution and use in source and binary forms, with or without\r
modification, are permitted provided that the following conditions are\r
#define restrict // Disable restrict\r
#endif\r
\r
+#ifdef _MSC_VER\r
+#define inline __forceinline\r
+#endif\r
+\r
+\r
\r
//**************************************\r
// Includes\r
// Memory usage formula for 32 bits systems : N->2^(N+2) Bytes (examples : 17 -> 512KB ; 12 -> 16KB)\r
#define HASH_LOG 12\r
\r
+//#define _FORCE_SW_LOWBITCOUNT // Uncomment for better performance if target platform has no hardware support for LowBitCount\r
+\r
\r
//**************************************\r
// Basic Types\r
// Compression CODE\r
//****************************\r
\r
+inline static int LZ4_NbCommonBytes_LittleEndian( register U32 val )\r
+{\r
+ #if defined(_MSC_VER) && !defined(_FORCE_SW_LOWBITCOUNT)\r
+ unsigned long b = 0;\r
+ _BitScanForward( &b, val );\r
+ return (int)(b>>3);\r
+ #elif defined(__GNUC__) && !defined(_FORCE_SW_LOWBITCOUNT)\r
+ return (__builtin_ctz(val) >> 3); \r
+ #else\r
+ static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };\r
+ return DeBruijnBytePos[((U32)((val & -val) * 0x077CB531U)) >> 27];\r
+ #endif\r
+}\r
+\r
+\r
int LZ4_compressCtx(void** ctx,\r
char* source, \r
char* dest,\r
\r
BYTE* op = (BYTE*) dest;\r
\r
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\r
- const size_t DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };\r
-#endif\r
int len, length;\r
const int skipStrength = SKIPSTRENGTH;\r
U32 forwardH;\r
while (ip<matchlimit-3)\r
{\r
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\r
- int diff = A32(ref) ^ A32(ip);\r
+ U32 diff = A32(ref) ^ A32(ip);\r
if (!diff) { ip+=4; ref+=4; continue; }\r
- ip += DeBruijnBytePos[((U32)((diff & -diff) * 0x077CB531U)) >> 27];\r
+ ip += LZ4_NbCommonBytes_LittleEndian(diff);\r
#else\r
if (A32(ref) == A32(ip)) { ip+=4; ref+=4; continue; }\r
if (A16(ref) == A16(ip)) { ip+=2; ref+=2; }\r
if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }\r
if ((ip<matchlimit) && (*ref == *ip)) ip++;\r
_endCount:\r
- len = (ip - anchor);\r
- \r
+\r
// Encode MatchLength\r
+ len = (ip - anchor);\r
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; } \r
else *token += len; \r
\r
\r
BYTE* op = (BYTE*) dest;\r
\r
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\r
- const size_t DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };\r
-#endif\r
int len, length;\r
const int skipStrength = SKIPSTRENGTH;\r
U32 forwardH;\r
while (ip<matchlimit-3)\r
{\r
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\r
- int diff = A32(ref) ^ A32(ip);\r
+ U32 diff = A32(ref) ^ A32(ip);\r
if (!diff) { ip+=4; ref+=4; continue; }\r
- ip += DeBruijnBytePos[((U32)((diff & -diff) * 0x077CB531U)) >> 27];\r
+ ip += LZ4_NbCommonBytes_LittleEndian(diff);\r
#else\r
if (A32(ref) == A32(ip)) { ip+=4; ref+=4; continue; }\r
if (A16(ref) == A16(ip)) { ip+=2; ref+=2; }\r
if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }\r
if ((ip<matchlimit) && (*ref == *ip)) ip++;\r
_endCount:\r
- len = (ip - anchor);\r
\r
// Encode MatchLength\r
+ len = (ip - anchor);\r
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; } \r
else *token += len; \r
\r
// Test end of chunk\r
if (ip > mflimit) { anchor = ip; break; }\r
\r
+ // Fill table\r
+ HashTable[LZ4_HASH64K_VALUE(ip-2)] = ip - 2 - base;\r
+\r
// Test next position\r
ref = base + HashTable[LZ4_HASH64K_VALUE(ip)];\r
HashTable[LZ4_HASH64K_VALUE(ip)] = ip - base;\r