#define _CRT_SECURE_NO_DEPRECATE // VS2005\r
\r
// Unix Large Files support (>4GB)\r
+#define _FILE_OFFSET_BITS 64\r
#if (defined(__sun__) && (!defined(__LP64__))) // Sun Solaris 32-bits requires specific definitions\r
# define _LARGEFILE_SOURCE \r
-# define _FILE_OFFSET_BITS 64\r
#elif ! defined(__LP64__) // No point defining Large file for 64 bit\r
# define _LARGEFILE64_SOURCE\r
#endif\r
\r
// S_ISREG & gettimeofday() are not supported by MSVC\r
-#if defined(_MSC_VER)\r
-# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)\r
+#if defined(_MSC_VER) || defined(_WIN32)\r
# define BMK_LEGACY_TIMER 1\r
#endif\r
\r
-// GCC does not support _rotl outside of Windows\r
-#if !defined(_WIN32)\r
-# define _rotl(x,r) ((x << r) | (x >> (32 - r)))\r
-#endif\r
-\r
\r
//**************************************\r
// Includes\r
\r
\r
//**************************************\r
+// Compiler specifics\r
+//**************************************\r
+#if !defined(S_ISREG)\r
+# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)\r
+#endif\r
+\r
+// GCC does not support _rotl outside of Windows\r
+#if !defined(_WIN32)\r
+# define _rotl(x,r) ((x << r) | (x >> (32 - r)))\r
+#endif\r
+\r
+\r
+//**************************************\r
// Basic Types\r
//**************************************\r
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99\r
BMK_pause = 1;\r
}\r
\r
+\r
//*********************************************************\r
// Private functions\r
//*********************************************************\r
compressed_buff = (char*)malloc((size_t )compressed_buff_size);\r
\r
\r
- if(!orig_buff || !compressed_buff)\r
+ if (!orig_buff || !compressed_buff)\r
{\r
DISPLAY("\nError: not enough memory!\n");\r
free(orig_buff);\r
free(compressed_buff);\r
+ free(chunkP);\r
fclose(fileIn);\r
return 12;\r
}\r
readSize = fread(orig_buff, 1, benchedSize, fileIn);\r
fclose(fileIn);\r
\r
- if(readSize != benchedSize)\r
+ if (readSize != benchedSize)\r
{\r
DISPLAY("\nError: problem reading file '%s' !! \n", infilename);\r
free(orig_buff);\r
free(compressed_buff);\r
+ free(chunkP);\r
return 13;\r
}\r
\r
with this program; if not, write to the Free Software Foundation, Inc.,\r
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
\r
- You can contact the author at :\r
- - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html\r
- - LZ4 source repository : http://code.google.com/p/lz4/\r
+ You can contact the author at :\r
+ - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html\r
+ - LZ4 source repository : http://code.google.com/p/lz4/\r
*/\r
#pragma once\r
\r
#endif\r
\r
// S_ISREG & gettimeofday() are not supported by MSVC\r
-#if defined(_MSC_VER)\r
-# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)\r
+#if defined(_MSC_VER) || defined(_WIN32)\r
# define BMK_LEGACY_TIMER 1\r
#endif\r
\r
-// GCC does not support _rotl outside of Windows\r
-#if !defined(_WIN32)\r
-# define _rotl(x,r) ((x << r) | (x >> (32 - r)))\r
-#endif\r
-\r
\r
//**************************************\r
// Includes\r
\r
\r
//**************************************\r
+// Compiler Options\r
+//**************************************\r
+// S_ISREG & gettimeofday() are not supported by MSVC\r
+#if !defined(S_ISREG)\r
+# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)\r
+#endif\r
+\r
+// GCC does not support _rotl outside of Windows\r
+#if !defined(_WIN32)\r
+# define _rotl(x,r) ((x << r) | (x >> (32 - r)))\r
+#endif\r
+\r
+\r
+//**************************************\r
// Basic Types\r
//**************************************\r
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99\r
DISPLAY("\nError: not enough memory!\n");\r
free(orig_buff);\r
free(compressed_buff);\r
+ free(chunkP);\r
fclose(fileIn);\r
return 12;\r
}\r
DISPLAY("\nError: problem reading file '%s' !! \n", infilename);\r
free(orig_buff);\r
free(compressed_buff);\r
+ free(chunkP);\r
return 13;\r
}\r
\r
case 1: compressionFunction = local_LZ4_compress_limitedOutput; break;\r
case 2: compressionFunction = LZ4_compressHC; break;\r
case 3: compressionFunction = local_LZ4_compressHC_limitedOutput; break;\r
- default : DISPLAY("ERROR ! Bad algorithm Id !! \n"); return 1;\r
+ default : DISPLAY("ERROR ! Bad algorithm Id !! \n"); free(chunkP); return 1;\r
}\r
\r
for (loopNb = 1; loopNb <= nbIterations; loopNb++)\r
case 2: decompressionFunction = LZ4_decompress_safe; break;\r
case 3: decompressionFunction = LZ4_decompress_safe_withPrefix64k; break;\r
case 4: decompressionFunction = local_LZ4_decompress_safe_partial; break;\r
- default : DISPLAY("ERROR ! Bad algorithm Id !! \n"); return 1;\r
+ default : DISPLAY("ERROR ! Bad algorithm Id !! \n"); free(chunkP); return 1;\r
}\r
\r
for (loopNb = 1; loopNb <= nbIterations; loopNb++)\r
unsigned int seed, randState, cur_seq=PRIME3, seeds[NUM_SEQ], timestamp=FUZ_GetMilliStart();\r
int i, j, k, ret, len, lenHC, attemptNb;\r
char userInput[30] = {0};\r
-# define FUZ_CHECKTEST(cond, message) testNb++; if (cond) { printf("Test %i : %s : seed %u, cycle %u \n", testNb, message, seed, attemptNb); goto _output_error; }\r
+# define FUZ_CHECKTEST(cond, message) testNb++; if (cond) { printf("Test %i : %s : seed %u, cycle %i \n", testNb, message, seed, attemptNb); goto _output_error; }\r
\r
printf("starting LZ4 fuzzer\n");\r
printf("Select an Initialisation number (default : random) : ");\r
// Note : explicit functions *_stack* and *_heap* are unaffected by this setting\r
#define HEAPMODE 0\r
\r
-// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :\r
-// This will provide a small boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU.\r
-// You can set this option to 1 in situations where data will remain within closed environment\r
-// This option is useless on Little_Endian CPU (such as x86)\r
-//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1\r
-\r
-\r
\r
//**************************************\r
// CPU Feature Detection\r
#endif\r
\r
// Unaligned memory access is automatically enabled for "common" CPU, such as x86.\r
-// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected\r
+// For others CPU, such as ARM, the compiler may be more cautious, inserting unnecessary extra code to ensure aligned access property\r
// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance\r
#if defined(__ARM_FEATURE_UNALIGNED)\r
# define LZ4_FORCE_UNALIGNED_ACCESS 1\r
# define LZ4_FORCE_SW_BITCOUNT\r
#endif\r
\r
+// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :\r
+// This option may provide a small boost to performance for some big endian cpu, although probably modest.\r
+// You may set this option to 1 if data will remain within closed environment.\r
+// This option is useless on Little_Endian CPU (such as x86)\r
+//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1\r
+\r
\r
//**************************************\r
// Compiler Options\r
//**************************************\r
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99\r
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) // C99\r
/* "restrict" is a known keyword */\r
#else\r
# define restrict // Disable restrict\r
#endif\r
\r
-#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\r
-\r
#ifdef _MSC_VER // Visual Studio\r
# define forceinline static __forceinline\r
-# include <intrin.h> // For Visual 2005\r
-# if LZ4_ARCH64 // 64-bits\r
+# include <intrin.h> // For Visual 2005\r
+# if LZ4_ARCH64 // 64-bits\r
# pragma intrinsic(_BitScanForward64) // For Visual 2005\r
# pragma intrinsic(_BitScanReverse64) // For Visual 2005\r
-# else // 32-bits\r
+# else // 32-bits\r
# pragma intrinsic(_BitScanForward) // For Visual 2005\r
# pragma intrinsic(_BitScanReverse) // For Visual 2005\r
# endif\r
# define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))\r
#endif\r
\r
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\r
+\r
#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)\r
# define expect(expr,value) (__builtin_expect ((expr),(value)) )\r
#else\r
//**************************************\r
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99\r
# include <stdint.h>\r
- typedef uint8_t BYTE;\r
+ typedef uint8_t BYTE;\r
typedef uint16_t U16;\r
typedef uint32_t U32;\r
typedef int32_t S32;\r
# endif\r
#endif\r
\r
-typedef struct _U16_S { U16 v; } _PACKED U16_S;\r
-typedef struct _U32_S { U32 v; } _PACKED U32_S;\r
-typedef struct _U64_S { U64 v; } _PACKED U64_S;\r
+typedef struct { U16 v; } _PACKED U16_S;\r
+typedef struct { U32 v; } _PACKED U32_S;\r
+typedef struct { U64 v; } _PACKED U64_S;\r
+typedef struct {size_t v;} _PACKED size_t_S;\r
\r
#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)\r
# pragma pack(pop)\r
#endif\r
\r
-#define A64(x) (((U64_S *)(x))->v)\r
-#define A32(x) (((U32_S *)(x))->v)\r
-#define A16(x) (((U16_S *)(x))->v)\r
+#define A16(x) (((U16_S *)(x))->v)\r
+#define A32(x) (((U32_S *)(x))->v)\r
+#define A64(x) (((U64_S *)(x))->v)\r
+#define AARCH(x) (((size_t_S *)(x))->v)\r
\r
\r
//**************************************\r
//**************************************\r
// Architecture-specific macros\r
//**************************************\r
+#define STEPSIZE sizeof(size_t)\r
+#define LZ4_COPYSTEP(s,d) { AARCH(d) = AARCH(s); d+=STEPSIZE; s+=STEPSIZE; }\r
+#define LZ4_COPY8(s,d) { LZ4_COPYSTEP(s,d); if (STEPSIZE<8) LZ4_COPYSTEP(s,d); }\r
+#define LZ4_SECURECOPY(s,d,e) { if ((STEPSIZE==8)&&(d<e)) LZ4_WILDCOPY(s,d,e); }\r
+\r
#if LZ4_ARCH64 // 64-bit\r
-# define STEPSIZE 8\r
-# define UARCH U64\r
-# define AARCH A64\r
-# define LZ4_COPYSTEP(s,d) A64(d) = A64(s); d+=8; s+=8;\r
-# define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d)\r
-# define LZ4_SECURECOPY(s,d,e) if (d<e) LZ4_WILDCOPY(s,d,e)\r
# define HTYPE U32\r
# define INITBASE(base) const BYTE* const base = ip\r
-#else // 32-bit\r
-# define STEPSIZE 4\r
-# define UARCH U32\r
-# define AARCH A32\r
-# define LZ4_COPYSTEP(s,d) A32(d) = A32(s); d+=4; s+=4;\r
-# define LZ4_COPYPACKET(s,d) LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);\r
-# define LZ4_SECURECOPY LZ4_WILDCOPY\r
+#else // 32-bit\r
# define HTYPE const BYTE*\r
# define INITBASE(base) const int base = 0\r
#endif\r
//**************************************\r
// Macros\r
//**************************************\r
-#define LZ4_WILDCOPY(s,d,e) do { LZ4_COPYPACKET(s,d) } while (d<e);\r
+#define LZ4_WILDCOPY(s,d,e) { do { LZ4_COPY8(s,d) } while (d<e); }\r
#define LZ4_BLINDCOPY(s,d,l) { BYTE* e=(d)+(l); LZ4_WILDCOPY(s,d,e); d=e; }\r
\r
\r
\r
forceinline int LZ4_NbCommonBytes (register U64 val)\r
{\r
-#if defined(LZ4_BIG_ENDIAN)\r
- #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# if defined(LZ4_BIG_ENDIAN)\r
+# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
unsigned long r = 0;\r
_BitScanReverse64( &r, val );\r
return (int)(r>>3);\r
- #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
return (__builtin_clzll(val) >> 3);\r
- #else\r
+# else\r
int r;\r
if (!(val>>32)) { r=4; } else { r=0; val>>=32; }\r
if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }\r
r += (!val);\r
return r;\r
- #endif\r
-#else\r
- #if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# endif\r
+# else\r
+# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
unsigned long r = 0;\r
_BitScanForward64( &r, val );\r
return (int)(r>>3);\r
- #elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
return (__builtin_ctzll(val) >> 3);\r
- #else\r
+# else\r
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };\r
- return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];\r
- #endif\r
-#endif\r
+ return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];\r
+# endif\r
+# endif\r
}\r
\r
#else\r
\r
forceinline int LZ4_NbCommonBytes (register U32 val)\r
{\r
-#if defined(LZ4_BIG_ENDIAN)\r
-# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# if defined(LZ4_BIG_ENDIAN)\r
+# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
unsigned long r = 0;\r
_BitScanReverse( &r, val );\r
return (int)(r>>3);\r
-# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
return (__builtin_clz(val) >> 3);\r
-# else\r
+# else\r
int r;\r
if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }\r
r += (!val);\r
return r;\r
-# endif\r
-#else\r
-# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# endif\r
+# else\r
+# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
unsigned long r;\r
_BitScanForward( &r, val );\r
return (int)(r>>3);\r
-# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
+# elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
return (__builtin_ctz(val) >> 3);\r
-# else\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 & -(S32)val) * 0x077CB531U)) >> 27];\r
-# endif\r
-#endif\r
+# endif\r
+# endif\r
}\r
\r
#endif\r
//****************************\r
\r
typedef enum { noPrefix = 0, withPrefix = 1 } prefix64k_directive;\r
-typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } end_directive;\r
-typedef enum { full = 0, partial = 1 } exit_directive;\r
+typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;\r
+typedef enum { full = 0, partial = 1 } earlyEnd_directive;\r
\r
\r
// This generic decompression function cover all use cases.\r
#endif\r
\r
\r
- // Special case\r
+ // Special cases\r
if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; // targetOutputSize too high => decode everything\r
if ((endOnInput) && unlikely(outputSize==0)) return ((inputSize==1) && (*ip==0)) ? 0 : -1; // Empty output buffer\r
if ((!endOnInput) && unlikely(outputSize==0)) return (*ip==0?1:-1);\r
{\r
if (partialDecoding)\r
{\r
- if (cpy > oend) goto _output_error; // Error : write attempt beyond end of output buffer\r
- if ((endOnInput) && (ip+length > iend)) goto _output_error; // Error : read attempt beyond end of input buffer\r
+ if (cpy > oend) goto _output_error; // Error : write attempt beyond end of output buffer\r
+ if ((endOnInput) && (ip+length > iend)) goto _output_error; // Error : read attempt beyond end of input buffer\r
}\r
else\r
{\r
- if ((!endOnInput) && (cpy != oend)) goto _output_error; // Error : block decoding must stop exactly there\r
+ if ((!endOnInput) && (cpy != oend)) goto _output_error; // Error : block decoding must stop exactly there\r
if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; // Error : input must be consumed\r
}\r
memcpy(op, ip, length);\r
}\r
\r
// copy repeated sequence\r
- if unlikely((op-ref)<STEPSIZE)\r
+ if unlikely((op-ref)<(int)STEPSIZE)\r
{\r
#if LZ4_ARCH64\r
size_t dec64 = dec64table[op-ref];\r
// Init\r
if (inputSize<MINLENGTH) goto _last_literals;\r
#ifdef COMPRESS_64K\r
- if (inputSize>LZ4_64KLIMIT) return 0; // Size too large (not within 64K limit)\r
+ if (inputSize>=LZ4_64KLIMIT) return 0; // Size too large (not within 64K limit)\r
#endif\r
#ifdef USE_HEAPMEMORY\r
memset((void*)HashTable, 0, HASHTABLESIZE);\r
anchor = ip;\r
while likely(ip<matchlimit-(STEPSIZE-1))\r
{\r
- UARCH diff = AARCH(ref) ^ AARCH(ip);\r
+ size_t diff = AARCH(ref) ^ AARCH(ip);\r
if (!diff) { ip+=STEPSIZE; ref+=STEPSIZE; continue; }\r
ip += LZ4_NbCommonBytes(diff);\r
goto _endCount;\r
# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant\r
#endif\r
\r
+// Large file support on 32-bits unix\r
+#define _FILE_OFFSET_BITS 64\r
+\r
\r
//****************************\r
// Includes\r
#elif GCC_VERSION >= 403\r
# define swap32 __builtin_bswap32\r
#else\r
- static inline unsigned int swap32(unsigned int x) {\r
- return ((x << 24) & 0xff000000 ) |\r
- ((x << 8) & 0x00ff0000 ) |\r
- ((x >> 8) & 0x0000ff00 ) |\r
- ((x >> 24) & 0x000000ff );\r
+ static inline unsigned int swap32(unsigned int x) \r
+ {\r
+ return ((x << 24) & 0xff000000 ) |\r
+ ((x << 8) & 0x00ff0000 ) |\r
+ ((x >> 8) & 0x0000ff00 ) |\r
+ ((x >> 24) & 0x000000ff );\r
}\r
#endif\r
\r
#define EXTENSION ".lz4"\r
#define WELCOME_MESSAGE "*** %s %s, by %s (%s) ***\n", COMPRESSOR_NAME, COMPRESSOR_VERSION, AUTHOR, COMPILED\r
\r
+#define UNLZ4 "unlz4"\r
+#define LZ4CAT "lz4cat"\r
+\r
#define KB *(1U<<10)\r
#define MB *(1U<<20)\r
#define GB *(1U<<30)\r
#define LZ4S_BLOCKSIZEID_DEFAULT 7\r
#define LZ4S_CHECKSUM_SEED 0\r
#define LZ4S_EOS 0\r
-#define LZ4S_MAXHEADERSIZE (4+2+8+4+1)\r
+#define LZ4S_MAXHEADERSIZE (MAGICNUMBER_SIZE+2+8+4+1)\r
\r
\r
//**************************************\r
//**************************************\r
// Special input/output\r
//**************************************\r
-#define NULL_INPUT "null"\r
+#define NULL_OUTPUT "null"\r
char stdinmark[] = "stdin";\r
char stdoutmark[] = "stdout";\r
#ifdef _WIN32\r
//**************************************\r
// Local Parameters\r
//**************************************\r
+static char* programName;\r
+static int silence = 0;\r
+static int verbose = 0;\r
static int overwrite = 0;\r
static int blockSizeId = LZ4S_BLOCKSIZEID_DEFAULT;\r
static int blockChecksum = 0;\r
static int streamChecksum = 1;\r
static int blockIndependence = 1;\r
\r
+\r
//**************************************\r
// Exceptions\r
//**************************************\r
//****************************\r
// Functions\r
//****************************\r
-int usage(char* exename)\r
+int usage()\r
{\r
DISPLAY( "Usage :\n");\r
- DISPLAY( " %s [arg] input [output]\n", exename);\r
+ DISPLAY( " %s [arg] [input] [output]\n", programName);\r
+ DISPLAY( "\n");\r
+ DISPLAY( "input : a filename, or \n");\r
+ DISPLAY( " '%s' or '-' for pipe mode (default if empty)\n", stdinmark);\r
DISPLAY( "Arguments :\n");\r
DISPLAY( " -c0/-c : Fast compression (default) \n");\r
DISPLAY( " -c1/-hc: High compression \n");\r
DISPLAY( " -d : decompression \n");\r
DISPLAY( " -y : overwrite without prompting \n");\r
- DISPLAY( " -H : Help (this text + advanced options)\n");\r
+ DISPLAY( " -h/-H : Help (this text + advanced options)\n");\r
return 0;\r
}\r
\r
int usage_advanced()\r
{\r
- DISPLAY( "\nAdvanced options :\n");\r
+ usage();\r
+ DISPLAY( "\n");\r
+ DISPLAY( "Advanced options :\n");\r
+ DISPLAY( " -v : be verbose \n");\r
DISPLAY( " -t : test compressed file \n");\r
DISPLAY( " -B# : Block size [4-7](default : 7)\n");\r
DISPLAY( " -BD : Block dependency (improve compression ratio)\n");\r
DISPLAY( " -Sx : disable stream checksum (default:enabled)\n");\r
DISPLAY( " -b# : benchmark files, using # [0-1] compression level\n");\r
DISPLAY( " -i# : iteration loops [1-9](default : 3), benchmark mode only\n");\r
- DISPLAY( "input : can be 'stdin' (pipe) or a filename\n");\r
- DISPLAY( "output : can be 'stdout'(pipe) or a filename or 'null'\n");\r
- DISPLAY( " example 1 : lz4c -hc stdin compressedfile.lz4\n");\r
- DISPLAY( " example 2 : lz4c -hcyB4D filename \n");\r
+ DISPLAY( "\n");\r
+ DISPLAY( "output : a filename, or \n");\r
+ DISPLAY( " '%s', or '-' for pipe mode\n", stdoutmark);\r
+ DISPLAY( " or '%s'\n", NULL_OUTPUT);\r
+ DISPLAY( " default if empty : stdout if input is stdin\n");\r
+ DISPLAY( " input.lz4 if compression selected\n");\r
+ DISPLAY( " input without '.lz4' if decompression\n");\r
+ DISPLAY( "\n");\r
+ DISPLAY( "Examples :\n");\r
+ DISPLAY( "1 : compress file 'filename', using default output name 'filename.lz4'\n");\r
+ DISPLAY( " %s filename\n", programName);\r
+ DISPLAY( "2 : compress 'filename' in high compression mode, overwrite output if exists\n");\r
+ DISPLAY( " %s -hcy filename \n", programName);\r
+ DISPLAY( "3 : compress data stream from 'generator', send result to 'consumer'\n");\r
+ DISPLAY( " generator | %s | consumer \n", programName);\r
return 0;\r
}\r
\r
-int badusage(char* exename)\r
+int badusage()\r
{\r
DISPLAY("Wrong parameters\n");\r
- usage(exename);\r
- return 0;\r
+ usage();\r
+ exit(1);\r
}\r
\r
\r
\r
if (!strcmp (input_filename, stdinmark)) \r
{\r
- DISPLAY( "Using stdin for input\n");\r
+ if (verbose) DISPLAY( "Using stdin for input\n");\r
*pfinput = stdin;\r
#ifdef _WIN32 // Need to set stdin/stdout to binary mode specifically for windows\r
_setmode( _fileno( stdin ), _O_BINARY );\r
\r
if (!strcmp (output_filename, stdoutmark)) \r
{\r
- DISPLAY( "Using stdout for output\n");\r
+ if (verbose) DISPLAY( "Using stdout for output\n");\r
*pfoutput = stdout;\r
#ifdef _WIN32 // Need to set stdin/stdout to binary mode specifically for windows\r
_setmode( _fileno( stdout ), _O_BINARY );\r
{ \r
char ch;\r
fclose(*pfoutput); \r
- DISPLAY( "Warning : %s already exists\n", output_filename); \r
if (!overwrite)\r
{\r
+ DISPLAY( "Warning : %s already exists\n", output_filename); \r
DISPLAY( "Overwrite ? (Y/N) : ");\r
ch = (char)getchar();\r
- if (ch!='Y') EXM_THROW(11, "Operation aborted : %s already exists", output_filename);\r
+ if ((ch!='Y') && (ch!='y')) EXM_THROW(11, "Operation aborted : %s already exists", output_filename);\r
}\r
}\r
*pfoutput = fopen( output_filename, "wb" );\r
\r
// Status\r
end = clock();\r
- DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
+ if (!silence) DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
(unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);\r
{\r
double seconds = (double)(end - start)/CLOCKS_PER_SEC;\r
- DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
+ if (verbose) DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
}\r
\r
// Close & Free\r
char* out_buff;\r
FILE* finput;\r
FILE* foutput;\r
- int errorcode;\r
int displayLevel = (compressionlevel>0);\r
clock_t start, end;\r
unsigned int blockSize, inputBufferSize;\r
translateFunction = LZ4_slideInputBufferHC;\r
freeFunction = LZ4_freeHC;\r
}\r
- errorcode = get_fileHandle(input_filename, output_filename, &finput, &foutput);\r
- if (errorcode) return errorcode;\r
+ get_fileHandle(input_filename, output_filename, &finput, &foutput);\r
blockSize = LZ4S_GetBlockSize_FromBlockId (blockSizeId);\r
\r
// Allocate Memory\r
// Read Block\r
if ((in_start+blockSize) > in_end) in_start = translateFunction(ctx);\r
inSize = (unsigned int) fread(in_start, (size_t)1, (size_t)blockSize, finput);\r
- if( inSize<=0 ) break; // No more input : end of compression\r
+ if( inSize==0 ) break; // No more input : end of compression\r
filesize += inSize;\r
if (displayLevel) DISPLAY("Read : %i MB \r", (int)(filesize>>20));\r
if (streamChecksum) XXH32_update(streamChecksumState, in_start, inSize);\r
\r
// Status\r
end = clock();\r
- DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
+ if (!silence) DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
(unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);\r
{\r
double seconds = (double)(end - start)/CLOCKS_PER_SEC;\r
- DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
+ if (verbose) DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
}\r
\r
// Close & Free\r
unsigned int checkbits;\r
char* in_buff;\r
char* out_buff;\r
+ char* headerBuffer;\r
FILE* finput;\r
FILE* foutput;\r
- int errorcode;\r
- int displayLevel = (compressionlevel>0);\r
+ int displayLevel = ((compressionlevel>0) && (!silence)) || (verbose);\r
clock_t start, end;\r
int blockSize;\r
- size_t sizeCheck, header_size;\r
+ size_t sizeCheck, header_size, readSize;\r
void* streamChecksumState=NULL;\r
\r
// Branch out\r
case 1 : compressionFunction = LZ4_compressHC_limitedOutput; break;\r
default: compressionFunction = LZ4_compress_limitedOutput;\r
}\r
- errorcode = get_fileHandle(input_filename, output_filename, &finput, &foutput);\r
- if (errorcode) return errorcode;\r
+ get_fileHandle(input_filename, output_filename, &finput, &foutput);\r
blockSize = LZ4S_GetBlockSize_FromBlockId (blockSizeId);\r
\r
// Allocate Memory\r
in_buff = (char*)malloc(blockSize);\r
out_buff = (char*)malloc(blockSize+CACHELINE);\r
- if (!in_buff || !out_buff) EXM_THROW(31, "Allocation error : not enough memory");\r
+ headerBuffer = (char*)malloc(LZ4S_MAXHEADERSIZE);\r
+ if (!in_buff || !out_buff || !(headerBuffer)) EXM_THROW(31, "Allocation error : not enough memory");\r
if (streamChecksum) streamChecksumState = XXH32_init(LZ4S_CHECKSUM_SEED);\r
\r
// Write Archive Header\r
- *(unsigned int*)out_buff = LITTLE_ENDIAN_32(LZ4S_MAGICNUMBER); // Magic Number, in Little Endian convention\r
- *(out_buff+4) = (1 & _2BITS) << 6 ; // Version('01')\r
- *(out_buff+4) |= (blockIndependence & _1BIT) << 5;\r
- *(out_buff+4) |= (blockChecksum & _1BIT) << 4;\r
- *(out_buff+4) |= (streamChecksum & _1BIT) << 2;\r
- *(out_buff+5) = (char)((blockSizeId & _3BITS) << 4);\r
- checkbits = XXH32((out_buff+4), 2, LZ4S_CHECKSUM_SEED);\r
+ *(unsigned int*)headerBuffer = LITTLE_ENDIAN_32(LZ4S_MAGICNUMBER); // Magic Number, in Little Endian convention\r
+ *(headerBuffer+4) = (1 & _2BITS) << 6 ; // Version('01')\r
+ *(headerBuffer+4) |= (blockIndependence & _1BIT) << 5;\r
+ *(headerBuffer+4) |= (blockChecksum & _1BIT) << 4;\r
+ *(headerBuffer+4) |= (streamChecksum & _1BIT) << 2;\r
+ *(headerBuffer+5) = (char)((blockSizeId & _3BITS) << 4);\r
+ checkbits = XXH32((headerBuffer+4), 2, LZ4S_CHECKSUM_SEED);\r
checkbits = LZ4S_GetCheckBits_FromXXH(checkbits);\r
- *(out_buff+6) = (unsigned char) checkbits;\r
+ *(headerBuffer+6) = (unsigned char) checkbits;\r
header_size = 7;\r
- sizeCheck = fwrite(out_buff, 1, header_size, foutput);\r
+\r
+ // Write header\r
+ sizeCheck = fwrite(headerBuffer, 1, header_size, foutput);\r
if (sizeCheck!=header_size) EXM_THROW(32, "Write error : cannot write header");\r
compressedfilesize += header_size;\r
\r
+ // read first block\r
+ readSize = fread(in_buff, (size_t)1, (size_t)blockSize, finput);\r
+\r
// Main Loop\r
- while (1)\r
+ while (readSize>0)\r
{\r
unsigned int outSize;\r
- // Read Block\r
- unsigned int inSize = (unsigned int) fread(in_buff, (size_t)1, (size_t)blockSize, finput);\r
- if( inSize<=0 ) break; // No more input : end of compression\r
- filesize += inSize;\r
+\r
+ filesize += readSize;\r
if (displayLevel) DISPLAY("Read : %i MB \r", (int)(filesize>>20));\r
- if (streamChecksum) XXH32_update(streamChecksumState, in_buff, inSize);\r
+ if (streamChecksum) XXH32_update(streamChecksumState, in_buff, (int)readSize);\r
\r
// Compress Block\r
- outSize = compressionFunction(in_buff, out_buff+4, inSize, inSize-1);\r
- if (outSize > 0) compressedfilesize += outSize+4; else compressedfilesize += inSize+4;\r
+ outSize = compressionFunction(in_buff, out_buff+4, (int)readSize, (int)readSize-1);\r
+ if (outSize > 0) compressedfilesize += outSize+4; else compressedfilesize += readSize+4;\r
if (blockChecksum) compressedfilesize+=4;\r
if (displayLevel) DISPLAY("Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);\r
\r
sizeToWrite = 4 + outSize + (4*blockChecksum);\r
sizeCheck = fwrite(out_buff, 1, sizeToWrite, foutput);\r
if (sizeCheck!=(size_t)(sizeToWrite)) EXM_THROW(33, "Write error : cannot write compressed block");\r
-\r
}\r
- else // Copy Original\r
+ else // Copy Original Uncompressed\r
{\r
unsigned int checksum;\r
- * (unsigned int*) out_buff = LITTLE_ENDIAN_32(inSize|0x80000000); // Add Uncompressed flag\r
+ * (unsigned int*) out_buff = LITTLE_ENDIAN_32(((unsigned long)readSize)|0x80000000); // Add Uncompressed flag\r
sizeCheck = fwrite(out_buff, 1, 4, foutput);\r
if (sizeCheck!=(size_t)(4)) EXM_THROW(34, "Write error : cannot write block header");\r
- sizeCheck = fwrite(in_buff, 1, inSize, foutput);\r
- if (sizeCheck!=(size_t)(inSize)) EXM_THROW(35, "Write error : cannot write block");\r
+ sizeCheck = fwrite(in_buff, 1, readSize, foutput);\r
+ if (sizeCheck!=readSize) EXM_THROW(35, "Write error : cannot write block");\r
if (blockChecksum)\r
{\r
- checksum = XXH32(in_buff, inSize, LZ4S_CHECKSUM_SEED);\r
+ checksum = XXH32(in_buff, (int)readSize, LZ4S_CHECKSUM_SEED);\r
* (unsigned int*) out_buff = LITTLE_ENDIAN_32(checksum);\r
sizeCheck = fwrite(out_buff, 1, 4, foutput);\r
if (sizeCheck!=(size_t)(4)) EXM_THROW(36, "Write error : cannot write block checksum");\r
}\r
}\r
+\r
+ // Read next block\r
+ readSize = fread(in_buff, (size_t)1, (size_t)blockSize, finput);\r
}\r
\r
// End of Stream mark\r
compressedfilesize += 4;\r
}\r
\r
- // Status\r
- end = clock();\r
- DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
- (unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);\r
- {\r
- double seconds = (double)(end - start)/CLOCKS_PER_SEC;\r
- DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
- }\r
-\r
// Close & Free\r
free(in_buff);\r
free(out_buff);\r
+ free(headerBuffer);\r
fclose(finput);\r
fclose(foutput);\r
\r
+ // Final Status\r
+ end = clock();\r
+ if (!silence) DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
+ (unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100);\r
+ {\r
+ double seconds = (double)(end - start)/CLOCKS_PER_SEC;\r
+ if (verbose) DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
+ }\r
+\r
return 0;\r
}\r
\r
else\r
{\r
memcpy(out_start, in_buff, blockSize);\r
+ decodedBytes = blockSize;\r
}\r
}\r
}\r
case LZ4S_MAGICNUMBER:\r
return decodeLZ4S(finput, foutput);\r
case LEGACY_MAGICNUMBER:\r
- DISPLAY("Detected : Legacy format \n");\r
+ if (verbose) DISPLAY("Detected : Legacy format \n");\r
return decodeLegacyStream(finput, foutput);\r
case LZ4S_SKIPPABLE0:\r
nbReadBytes = fread(&size, 1, 4, finput);\r
\r
// Final Status\r
end = clock();\r
- DISPLAY( "Successfully decoded %llu bytes \n", filesize);\r
+ if (!silence) DISPLAY( "Successfully decoded %llu bytes \n", filesize);\r
{\r
double seconds = (double)(end - start)/CLOCKS_PER_SEC;\r
- DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
+ if (verbose) DISPLAY( "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
}\r
\r
// Close\r
bench=0,\r
filenamesStart=2,\r
legacy_format=0;\r
- char* exename=argv[0];\r
char* input_filename=0;\r
char* output_filename=0;\r
- char nullinput[] = NULL_INPUT;\r
+ char nullOutput[] = NULL_OUTPUT;\r
char extension[] = EXTENSION;\r
\r
- // Welcome message\r
- DISPLAY( WELCOME_MESSAGE);\r
-\r
- if (argc<2) { badusage(exename); return 1; }\r
+ // Select behavior\r
+ programName = argv[0];\r
+ if (strstr(programName, UNLZ4)) { decode=1; silence=1; }\r
+ else if (strstr(programName, LZ4CAT)) { decode=1; silence=1; output_filename=stdoutmark; }\r
\r
for(i=1; i<argc; i++)\r
{\r
// Decode command (note : aggregated commands are allowed)\r
if (argument[0]=='-')\r
{\r
+ if (argument[1]==0)\r
+ {\r
+ if (!input_filename) input_filename=stdinmark;\r
+ else output_filename=stdoutmark;\r
+ }\r
+\r
while (argument[1]!=0)\r
{\r
argument ++;\r
switch(argument[0])\r
{\r
// Display help on usage\r
- case 'H': usage(exename); usage_advanced(); return 0;\r
+ case 'H': usage_advanced(); return 0;\r
\r
// Compression (default)\r
case 'c': if ((argument[1] >='0') && (argument[1] <='1')) { cLevel=argument[1] - '0'; argument++; } break;\r
- case 'h': if (argument[1]=='c') { cLevel=1; argument++; } break;\r
+ case 'h': if (argument[1]=='c') { cLevel=1; argument++; } else { usage_advanced(); return 0; } break;\r
\r
// Use Legacy format (hidden option)\r
case 'l': legacy_format=1; break;\r
break;\r
\r
// Modify Stream properties\r
- case 'S': if (argument[1]=='x') { streamChecksum=0; argument++; break; } else { badusage(exename); return 1; }\r
+ case 'S': if (argument[1]=='x') { streamChecksum=0; argument++; break; } else { badusage(); }\r
\r
// Bench\r
case 'b': bench=1; \r
// Overwrite\r
case 'y': overwrite=1; break;\r
\r
+ // Verbose mode\r
+ case 'v': verbose=1; break;\r
+\r
// Unrecognised command\r
- default : badusage(exename); return 1;\r
+ default : badusage();\r
}\r
}\r
continue;\r
if (!output_filename)\r
{\r
output_filename=argument;\r
- if (!strcmp (output_filename, nullinput)) output_filename = nulmark;\r
+ if (!strcmp (output_filename, nullOutput)) output_filename = nulmark;\r
continue;\r
}\r
}\r
\r
- // No input filename ==> Error\r
- if(!input_filename) { badusage(exename); return 1; }\r
+ if (verbose) DISPLAY( WELCOME_MESSAGE);\r
+\r
+ // No input filename ==> use stdin\r
+ if(!input_filename) { input_filename=stdinmark; }\r
\r
+ // Check if benchmark was required\r
if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, cLevel);\r
\r
- // No output filename ==> build one automatically (when possible)\r
+ // No output filename ==> select one automatically (when possible)\r
if (!output_filename) \r
- { \r
- if (!decode) // compression\r
+ {\r
+ if (input_filename == stdinmark) { output_filename=stdoutmark; silence=1; }\r
+ else if (!decode) // compression\r
{\r
int i=0, l=0;\r
while (input_filename[l]!=0) l++;\r
output_filename = (char*)calloc(1,l+5);\r
for (i=0;i<l;i++) output_filename[i] = input_filename[i];\r
for (i=l;i<l+4;i++) output_filename[i] = extension[i-l];\r
+ if (!silence) DISPLAY("Compressed filename will be : %s \n", output_filename);\r
}\r
- else // decompression (input file must respect format extension ".lz4")\r
+ else // decompression (input file must respect format extension ".lz4")\r
{\r
int inl=0,outl;\r
while (input_filename[inl]!=0) inl++;\r
for (outl=0;outl<inl;outl++) output_filename[outl] = input_filename[outl];\r
if (inl>4)\r
while ((outl >= inl-4) && (input_filename[outl] == extension[outl-inl+4])) output_filename[outl--]=0;\r
- if (outl != inl-5) output_filename = NULL;\r
+ if (outl != inl-5) { DISPLAY("Cannot automatically decide an output filename\n"); badusage(); }\r
}\r
- if (!output_filename) { badusage(exename); return 1; }\r
}\r
\r
+ if ((decode ? input_filename==stdinmark : output_filename==stdoutmark)\r
+ && !overwrite\r
+#ifdef _WIN32\r
+ && _isatty (_fileno ((decode ? stdin : stdout))))\r
+#else\r
+ && isatty ( fileno ((decode ? stdin : stdout))))\r
+#endif\r
+ badusage();\r
+\r
+ if ((input_filename == stdinmark) && (output_filename == stdoutmark)) silence=1;\r
+\r
+ if (verbose) silence=0;\r
+\r
if (decode) return decodeFile(input_filename, output_filename);\r
\r
// compression is default action\r
if (legacy_format)\r
{\r
- DISPLAY("! Generating compressed LZ4 using Legacy format (deprecated !) ! \n");\r
+ if (!silence) DISPLAY("! Generating compressed LZ4 using Legacy format (deprecated !) ! \n");\r
return legacy_compress_file(input_filename, output_filename, cLevel); \r
}\r
else\r
{\r
- return compress_file(input_filename, output_filename, cLevel); \r
+ return compress_file(input_filename, output_filename, cLevel);\r
}\r
}\r
# define restrict // Disable restrict\r
#endif\r
\r
-#ifdef _MSC_VER\r
-# define forceinline __forceinline\r
-# include <intrin.h> // For Visual 2005\r
-# if LZ4_ARCH64 // 64-bits\r
+#ifdef _MSC_VER // Visual Studio\r
+# define forceinline static __forceinline\r
+# include <intrin.h> // For Visual 2005\r
+# if LZ4_ARCH64 // 64-bits\r
# pragma intrinsic(_BitScanForward64) // For Visual 2005\r
# pragma intrinsic(_BitScanReverse64) // For Visual 2005\r
-# else // 32-bits\r
+# else // 32-bits\r
# pragma intrinsic(_BitScanForward) // For Visual 2005\r
# pragma intrinsic(_BitScanReverse) // For Visual 2005\r
# endif\r
# pragma warning(disable : 4701) // disable: C4701: potentially uninitialized local variable used\r
#else \r
# ifdef __GNUC__\r
-# define forceinline inline __attribute__((always_inline))\r
+# define forceinline static inline __attribute__((always_inline))\r
# else\r
-# define forceinline inline\r
+# define forceinline static inline\r
# endif\r
#endif\r
\r
#ifdef _MSC_VER // Visual Studio\r
-#define lz4_bswap16(x) _byteswap_ushort(x)\r
+# define lz4_bswap16(x) _byteswap_ushort(x)\r
#else\r
-#define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))\r
+# define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))\r
#endif\r
\r
\r
//**************************************\r
#if LZ4_ARCH64\r
\r
-inline static int LZ4_NbCommonBytes (register U64 val)\r
+forceinline int LZ4_NbCommonBytes (register U64 val)\r
{\r
#if defined(LZ4_BIG_ENDIAN)\r
# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
\r
#else\r
\r
-inline static int LZ4_NbCommonBytes (register U32 val)\r
+forceinline int LZ4_NbCommonBytes (register U32 val)\r
{\r
#if defined(LZ4_BIG_ENDIAN)\r
# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
#endif\r
\r
\r
-static inline int LZ4_InitHC (LZ4HC_Data_Structure* hc4, const BYTE* base)\r
+forceinline int LZ4_InitHC (LZ4HC_Data_Structure* hc4, const BYTE* base)\r
{\r
MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));\r
MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));\r
\r
\r
// Update chains up to ip (excluded)\r
-static forceinline void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)\r
+forceinline void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)\r
{\r
U16* chainTable = hc4->chainTable;\r
HTYPE* HashTable = hc4->hashTable;\r
}\r
\r
\r
-static forceinline size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit)\r
+forceinline size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit)\r
{\r
const BYTE* p1t = p1;\r
\r
}\r
\r
\r
-static forceinline int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)\r
+forceinline int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)\r
{\r
U16* const chainTable = hc4->chainTable;\r
HTYPE* const HashTable = hc4->hashTable;\r
}\r
\r
\r
-static forceinline int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)\r
+forceinline int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)\r
{\r
U16* const chainTable = hc4->chainTable;\r
HTYPE* const HashTable = hc4->hashTable;\r
// Function code\r
//****************************\r
\r
-forceinline static int ENCODE_SEQUENCE_NAME (\r
+forceinline int ENCODE_SEQUENCE_NAME (\r
const BYTE** ip, \r
BYTE** op, \r
const BYTE** anchor, \r
*/\r
\r
\r
-\r
//**************************************\r
// Tuning parameters\r
//**************************************\r
#endif\r
\r
// XXH_ACCEPT_NULL_INPUT_POINTER :\r
-// If the input pointer is a null pointer, xxHash default behavior is to crash, since it is a bad input.\r
-// If this option is enabled, xxHash output for null input pointers will be the same as a null-length input.\r
+// If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.\r
+// When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.\r
// This option has a very small performance cost (only measurable on small inputs).\r
// By default, this option is disabled. To enable it, uncomment below define :\r
//#define XXH_ACCEPT_NULL_INPUT_POINTER 1\r
// By default, xxHash library provides endian-independant Hash values, based on little-endian convention.\r
// Results are therefore identical for little-endian and big-endian CPU.\r
// This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.\r
-// Should endian-independance be of no importance for your application, you may uncomment the #define below.\r
+// Should endian-independance be of no importance for your application, you may set the #define below to 1.\r
// It will improve speed for Big-endian CPU.\r
// This option has no impact on Little_Endian CPU.\r
-//#define XXH_FORCE_NATIVE_FORMAT 1\r
+#define XXH_FORCE_NATIVE_FORMAT 0\r
\r
\r
//**************************************\r
-// Compiler Options\r
+// Compiler Specific Options\r
//**************************************\r
-#if defined(_MSC_VER) && !defined(__cplusplus) // Visual Studio\r
-# define inline __inline // Visual C is not C99, but supports some kind of inline\r
+// Disable some Visual warning messages\r
+#ifdef _MSC_VER // Visual Studio\r
+# pragma warning(disable : 4127) // disable: C4127: conditional expression is constant\r
+#endif\r
+\r
+#ifdef _MSC_VER // Visual Studio\r
+# define forceinline static __forceinline\r
+#else \r
+# ifdef __GNUC__\r
+# define forceinline static inline __attribute__((always_inline))\r
+# else\r
+# define forceinline static inline\r
+# endif\r
#endif\r
\r
\r
// Modify the local functions below should you wish to use some other memory related routines\r
// for malloc(), free()\r
#include <stdlib.h>\r
-static inline void* XXH_malloc(size_t s) { return malloc(s); }\r
-static inline void XXH_free (void* p) { free(p); }\r
+forceinline void* XXH_malloc(size_t s) { return malloc(s); }\r
+forceinline void XXH_free (void* p) { free(p); }\r
// for memcpy()\r
#include <string.h>\r
-static inline void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }\r
-\r
-\r
-//**************************************\r
-// CPU Feature Detection\r
-//**************************************\r
-// Little Endian or Big Endian ?\r
-// You can overwrite the #define below if you know your architecture endianess\r
-#if defined(XXH_FORCE_NATIVE_FORMAT) && (XXH_FORCE_NATIVE_FORMAT==1)\r
-// Force native format. The result will be endian dependant.\r
-# define XXH_BIG_ENDIAN 0\r
-#elif defined (__GLIBC__)\r
-# include <endian.h>\r
-# if (__BYTE_ORDER == __BIG_ENDIAN)\r
-# define XXH_BIG_ENDIAN 1\r
-# endif\r
-#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN))\r
-# define XXH_BIG_ENDIAN 1\r
-#elif defined(__sparc) || defined(__sparc__) \\r
- || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \\r
- || defined(__hpux) || defined(__hppa) \\r
- || defined(_MIPSEB) || defined(__s390__)\r
-# define XXH_BIG_ENDIAN 1\r
-#endif\r
-\r
-#if !defined(XXH_BIG_ENDIAN)\r
-// Little Endian assumed. PDP Endian and other very rare endian format are unsupported.\r
-# define XXH_BIG_ENDIAN 0\r
-#endif\r
+forceinline void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }\r
\r
\r
//**************************************\r
#endif\r
\r
#if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__)\r
-# pragma pack(push, 1)\r
+# ifdef __IBMC__\r
+# pragma pack(1)\r
+# else\r
+# pragma pack(push, 1)\r
+# endif\r
#endif\r
\r
typedef struct _U32_S { U32 v; } _PACKED U32_S;\r
\r
\r
//**************************************\r
-// Macros\r
+// Architecture Macros\r
//**************************************\r
-#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations\r
-#define XXH_LE32(p) (XXH_BIG_ENDIAN ? XXH_swap32(A32(p)) : A32(p))\r
-#define XXH_alignedLE32(p) (XXH_BIG_ENDIAN ? XXH_swap32(*(U32*)(p)) : *(U32*)(p))\r
+typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;\r
+#ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch\r
+ static const int one = 1;\r
+# define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one))\r
+#endif\r
\r
\r
+//**************************************\r
+// Macros\r
+//**************************************\r
+#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations\r
+\r
\r
//****************************\r
-// Simple Hash Functions\r
+// Memory reads\r
//****************************\r
+typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;\r
\r
-#if !defined(XXH_USE_UNALIGNED_ACCESS)\r
-// Specific version, for aligned 32-bits input. Useless for CPU supporting unaligned access.\r
-static U32 XXH32_alignedInput(const void* input, int len, U32 seed)\r
-{\r
- const BYTE* p = (const BYTE*)input;\r
- const BYTE* const bEnd = p + len;\r
- U32 h32;\r
-\r
- if (len>=16)\r
- {\r
- const BYTE* const limit = bEnd - 16;\r
- U32 v1 = seed + PRIME32_1 + PRIME32_2;\r
- U32 v2 = seed + PRIME32_2;\r
- U32 v3 = seed + 0;\r
- U32 v4 = seed - PRIME32_1;\r
- do\r
- {\r
- v1 += XXH_alignedLE32(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;\r
- v2 += XXH_alignedLE32(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;\r
- v3 += XXH_alignedLE32(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;\r
- v4 += XXH_alignedLE32(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;\r
- } while (p<=limit);\r
- h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);\r
- }\r
- else { h32 = seed + PRIME32_5; }\r
- h32 += (U32) len;\r
- while (p<=bEnd-4)\r
- {\r
- h32 += XXH_alignedLE32(p) * PRIME32_3;\r
- h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;\r
- p+=4;\r
- }\r
- while (p<bEnd)\r
- {\r
- h32 += (*p) * PRIME32_5;\r
- h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;\r
- p++;\r
- }\r
- h32 ^= h32 >> 15;\r
- h32 *= PRIME32_2;\r
- h32 ^= h32 >> 13;\r
- h32 *= PRIME32_3;\r
- h32 ^= h32 >> 16;\r
- return h32;\r
+forceinline U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align)\r
+{ \r
+ if (align==XXH_unaligned)\r
+ return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr)); \r
+ else\r
+ return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr); \r
}\r
-#endif\r
\r
-U32 XXH32(const void* input, int len, U32 seed)\r
-{\r
-#if 0\r
- // Simple version, good for code maintenance, but unfortunately slow for small inputs\r
- void* state = XXH32_init(seed);\r
- XXH32_update(state, input, len);\r
- return XXH32_digest(state);\r
-#else\r
+forceinline U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); }\r
\r
+\r
+//****************************\r
+// Simple Hash Functions\r
+//****************************\r
+forceinline U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align)\r
+{\r
const BYTE* p = (const BYTE*)input;\r
const BYTE* const bEnd = p + len;\r
U32 h32;\r
\r
#ifdef XXH_ACCEPT_NULL_INPUT_POINTER\r
- if (p==NULL) { len=0; p=(const BYTE*)16; }\r
-#endif\r
-\r
-#if !defined(XXH_USE_UNALIGNED_ACCESS)\r
- if ((((U32)p) & 3) == 0) return XXH32_alignedInput(input, len, seed); // Input is aligned, let's leverage the speed advantage\r
+ if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; }\r
#endif\r
\r
if (len>=16)\r
{\r
- const BYTE* const limit = bEnd - 16;\r
+ const BYTE* const limit = bEnd - 32;\r
U32 v1 = seed + PRIME32_1 + PRIME32_2;\r
U32 v2 = seed + PRIME32_2;\r
U32 v3 = seed + 0;\r
\r
do\r
{\r
- v1 += XXH_LE32(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;\r
- v2 += XXH_LE32(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;\r
- v3 += XXH_LE32(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;\r
- v4 += XXH_LE32(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;\r
+ v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;\r
+ v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;\r
+ v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;\r
+ v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;\r
} while (p<=limit);\r
\r
h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);\r
\r
while (p<=bEnd-4)\r
{\r
- h32 += XXH_LE32(p) * PRIME32_3;\r
- h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;\r
+ h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3;\r
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;\r
p+=4;\r
}\r
\r
h32 ^= h32 >> 16;\r
\r
return h32;\r
+}\r
+\r
\r
+U32 XXH32(const void* input, int len, U32 seed)\r
+{\r
+#if 0\r
+ // Simple version, good for code maintenance, but unfortunately slow for small inputs\r
+ void* state = XXH32_init(seed);\r
+ XXH32_update(state, input, len);\r
+ return XXH32_digest(state);\r
+#else\r
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\r
+\r
+# if !defined(XXH_USE_UNALIGNED_ACCESS)\r
+ if ((((size_t)input) & 3)) // Input is aligned, let's leverage the speed advantage\r
+ {\r
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\r
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);\r
+ else\r
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);\r
+ }\r
+# endif\r
+\r
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\r
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);\r
+ else\r
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);\r
#endif\r
}\r
\r
}\r
\r
\r
-XXH_errorcode XXH32_update (void* state_in, const void* input, int len)\r
+forceinline XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian)\r
{\r
struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;\r
const BYTE* p = (const BYTE*)input;\r
XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize);\r
{\r
const U32* p32 = (const U32*)state->memory;\r
- state->v1 += XXH_LE32(p32) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;\r
- state->v2 += XXH_LE32(p32) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++; \r
- state->v3 += XXH_LE32(p32) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;\r
- state->v4 += XXH_LE32(p32) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;\r
+ state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++;\r
+ state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++; \r
+ state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++;\r
+ state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++;\r
}\r
p += 16-state->memsize;\r
state->memsize = 0;\r
\r
do\r
{\r
- v1 += XXH_LE32(p) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;\r
- v2 += XXH_LE32(p) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;\r
- v3 += XXH_LE32(p) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;\r
- v4 += XXH_LE32(p) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;\r
+ v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4;\r
+ v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4;\r
+ v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4;\r
+ v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4;\r
} while (p<=limit);\r
\r
state->v1 = v1;\r
return XXH_OK;\r
}\r
\r
+XXH_errorcode XXH32_update (void* state_in, const void* input, int len)\r
+{\r
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\r
+ \r
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\r
+ return XXH32_update_endian(state_in, input, len, XXH_littleEndian);\r
+ else\r
+ return XXH32_update_endian(state_in, input, len, XXH_bigEndian);\r
+}\r
\r
-U32 XXH32_intermediateDigest (void* state_in)\r
+\r
+\r
+forceinline U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian)\r
{\r
struct XXH_state32_t * state = (struct XXH_state32_t *) state_in;\r
- BYTE * p = (BYTE*)state->memory;\r
+ const BYTE * p = (const BYTE*)state->memory;\r
BYTE* bEnd = (BYTE*)state->memory + state->memsize;\r
U32 h32;\r
\r
\r
while (p<=bEnd-4)\r
{\r
- h32 += XXH_LE32(p) * PRIME32_3;\r
- h32 = XXH_rotl32(h32, 17) * PRIME32_4;\r
+ h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3;\r
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4;\r
p+=4;\r
}\r
\r
}\r
\r
\r
+U32 XXH32_intermediateDigest (void* state_in)\r
+{\r
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\r
+ \r
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\r
+ return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian);\r
+ else\r
+ return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian);\r
+}\r
+\r
+\r
U32 XXH32_digest (void* state_in)\r
{\r
U32 h32 = XXH32_intermediateDigest(state_in);\r