lz4c : made display and arguments more compatible with gzip, for easier integration...
authoryann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd>
Sat, 27 Jul 2013 11:19:31 +0000 (11:19 +0000)
committeryann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd>
Sat, 27 Jul 2013 11:19:31 +0000 (11:19 +0000)
Correction : large files support on 32-bits unix (reported by Karthik Rajeswaran)
lz4c : reduce the amount of displayed information in default mode; introduce a verbose mode
lz4c : changed help message
Updated xxHash to r31
Made bench.c compatible with tcc
Corrected : a few minor warnings found by CppCheck, as suggested by Brian White
lz4.c : Pushed BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE farther in the code, since it is reported as providing little benefit
Corrected : minor 64K input condition, detected by Mat Hostetter

git-svn-id: https://lz4.googlecode.com/svn/trunk@99 650e7d94-2a16-8b24-b05c-7c0b3f6821cd

bench.c
bench.h
fullbench.c
fuzzer.c
lz4.c
lz4_encoder.h
lz4c.c
lz4hc.c
lz4hc_encoder.h
xxhash.c

diff --git a/bench.c b/bench.c
index f605249..07fd091 100644 (file)
--- a/bench.c
+++ b/bench.c
 #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
@@ -153,6 +160,7 @@ void BMK_SetPause()
     BMK_pause = 1;\r
 }\r
 \r
+\r
 //*********************************************************\r
 //  Private functions\r
 //*********************************************************\r
@@ -300,11 +308,12 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles, int cLevel)
       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
@@ -330,11 +339,12 @@ int BMK_benchFile(char** fileNamesTable, int nbFiles, int cLevel)
       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
diff --git a/bench.h b/bench.h
index 9d5e4f5..1e26685 100644 (file)
--- a/bench.h
+++ b/bench.h
@@ -16,9 +16,9 @@
     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
index e64664d..66aa0ed 100644 (file)
 #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
@@ -326,6 +334,7 @@ int fullSpeedBench(char** fileNamesTable, int nbFiles)
         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
@@ -356,6 +365,7 @@ int fullSpeedBench(char** fileNamesTable, int nbFiles)
         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
@@ -385,7 +395,7 @@ int fullSpeedBench(char** fileNamesTable, int nbFiles)
             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
@@ -449,7 +459,7 @@ int fullSpeedBench(char** fileNamesTable, int nbFiles)
             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
index 44ca885..a10b222 100644 (file)
--- a/fuzzer.c
+++ b/fuzzer.c
@@ -132,7 +132,7 @@ int main() {
         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
diff --git a/lz4.c b/lz4.c
index fa7f3ba..779d68a 100644 (file)
--- a/lz4.c
+++ b/lz4.c
@@ -52,13 +52,6 @@ Note : this source file requires "lz4_encoder.h"
 // 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
@@ -92,7 +85,7 @@ Note : this source file requires "lz4_encoder.h"
 #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
@@ -103,25 +96,29 @@ Note : this source file requires "lz4_encoder.h"
 #  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
@@ -140,6 +137,8 @@ Note : this source file requires "lz4_encoder.h"
 #  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
@@ -163,7 +162,7 @@ Note : this source file requires "lz4_encoder.h"
 //**************************************\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
@@ -190,17 +189,19 @@ Note : this source file requires "lz4_encoder.h"
 #  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
@@ -230,22 +231,15 @@ typedef struct _U64_S { U64 v; } _PACKED U64_S;
 //**************************************\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
@@ -262,7 +256,7 @@ typedef struct _U64_S { U64 v; } _PACKED U64_S;
 //**************************************\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
@@ -273,63 +267,63 @@ typedef struct _U64_S { U64 v; } _PACKED U64_S;
 \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
@@ -535,8 +529,8 @@ int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, in
 //****************************\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
@@ -571,7 +565,7 @@ forceinline int LZ4_decompress_generic(
 #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
@@ -602,12 +596,12 @@ forceinline int LZ4_decompress_generic(
         {\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
@@ -634,7 +628,7 @@ forceinline int LZ4_decompress_generic(
         }\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
index 69f097b..84bb591 100644 (file)
@@ -110,7 +110,7 @@ int FUNCTION_NAME(
     // 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
@@ -173,7 +173,7 @@ _next_match:
         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
diff --git a/lz4c.c b/lz4c.c
index 8da1e5f..4d90bef 100644 (file)
--- a/lz4c.c
+++ b/lz4c.c
@@ -39,6 +39,9 @@
 #  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
@@ -86,6 +90,9 @@
 #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
@@ -129,7 +136,7 @@ static const int one = 1;
 //**************************************\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
@@ -142,12 +149,16 @@ char nulmark[] = "/dev/null";
 //**************************************\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
@@ -167,22 +178,28 @@ static int blockIndependence = 1;
 //****************************\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
@@ -190,18 +207,29 @@ int usage_advanced()
     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
@@ -215,7 +243,7 @@ int get_fileHandle(char* input_filename, char* output_filename, FILE** pfinput,
 \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
@@ -228,7 +256,7 @@ int get_fileHandle(char* input_filename, char* output_filename, FILE** pfinput,
 \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
@@ -243,12 +271,12 @@ int get_fileHandle(char* input_filename, char* output_filename, FILE** pfinput,
         { \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
@@ -319,11 +347,11 @@ int legacy_compress_file(char* input_filename, char* output_filename, int compre
 \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
@@ -350,7 +378,6 @@ int compress_file_blockDependency(char* input_filename, char* output_filename, i
     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
@@ -370,8 +397,7 @@ int compress_file_blockDependency(char* input_filename, char* output_filename, i
         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
@@ -407,7 +433,7 @@ int compress_file_blockDependency(char* input_filename, char* output_filename, i
         // 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
@@ -469,11 +495,11 @@ int compress_file_blockDependency(char* input_filename, char* output_filename, i
 \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
@@ -495,13 +521,13 @@ int compress_file(char* input_filename, char* output_filename, int compressionle
     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
@@ -515,45 +541,48 @@ int compress_file(char* input_filename, char* output_filename, int compressionle
     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
@@ -571,24 +600,26 @@ int compress_file(char* input_filename, char* output_filename, int compressionle
             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
@@ -605,21 +636,22 @@ int compress_file(char* input_filename, char* output_filename, int compressionle
         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
@@ -788,6 +820,7 @@ unsigned long long decodeLZ4S(FILE* finput, FILE* foutput)
                 else\r
                 {\r
                     memcpy(out_start, in_buff, blockSize);\r
+                    decodedBytes = blockSize;\r
                 }\r
             }\r
         }\r
@@ -852,7 +885,7 @@ unsigned long long selectDecoder( FILE* finput,  FILE* foutput)
     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
@@ -890,10 +923,10 @@ int decodeFile(char* input_filename, char* output_filename)
 \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
@@ -913,16 +946,15 @@ int main(int argc, char** argv)
         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
@@ -933,6 +965,12 @@ int main(int argc, char** argv)
         // 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
@@ -940,11 +978,11 @@ int main(int argc, char** argv)
                 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
@@ -980,7 +1018,7 @@ _exit_blockProperties:
                     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
@@ -1003,8 +1041,11 @@ _exit_blockProperties:
                     // 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
@@ -1017,28 +1058,33 @@ _exit_blockProperties:
         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
@@ -1046,21 +1092,33 @@ _exit_blockProperties:
             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
diff --git a/lz4hc.c b/lz4hc.c
index 729bfd3..8f2b422 100644 (file)
--- a/lz4hc.c
+++ b/lz4hc.c
@@ -99,13 +99,13 @@ Note : this source file requires "lz4hc_encoder.h"
 #  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
@@ -113,16 +113,16 @@ Note : this source file requires "lz4hc_encoder.h"
 #  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
@@ -273,7 +273,7 @@ typedef struct
 //**************************************\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
@@ -305,7 +305,7 @@ inline static int LZ4_NbCommonBytes (register U64 val)
 \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
@@ -337,7 +337,7 @@ inline static int LZ4_NbCommonBytes (register U32 val)
 #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
@@ -365,7 +365,7 @@ int LZ4_freeHC (void* LZ4HC_Data)
 \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
@@ -403,7 +403,7 @@ char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
 }\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
@@ -421,7 +421,7 @@ static forceinline size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, co
 }\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
@@ -489,7 +489,7 @@ static forceinline int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
 }\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
index b59bef3..49a0f23 100644 (file)
@@ -62,7 +62,7 @@
 // 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
index 6dacdcb..914421f 100644 (file)
--- a/xxhash.c
+++ b/xxhash.c
@@ -31,7 +31,6 @@ You can contact the author at :
 */\r
 \r
 \r
-\r
 //**************************************\r
 // Tuning parameters\r
 //**************************************\r
@@ -44,8 +43,8 @@ You can contact the author at :
 #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
@@ -54,17 +53,28 @@ You can contact the author at :
 // 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
@@ -75,39 +85,11 @@ You can contact the author at :
 // 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
@@ -135,7 +117,11 @@ static inline void* XXH_memcpy(void* dest, const void* src, size_t size) { retur
 #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
@@ -183,89 +169,53 @@ static inline U32 XXH_swap32 (U32 x) {
 \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
@@ -273,10 +223,10 @@ U32 XXH32(const void* input, int len, U32 seed)
 \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
@@ -290,8 +240,8 @@ U32 XXH32(const void* input, int len, U32 seed)
 \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
@@ -309,7 +259,33 @@ U32 XXH32(const void* input, int len, U32 seed)
     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
@@ -360,7 +336,7 @@ void* XXH32_init (U32 seed)
 }\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
@@ -384,10 +360,10 @@ XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
         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
@@ -403,10 +379,10 @@ XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
 \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
@@ -424,11 +400,22 @@ XXH_errorcode XXH32_update (void* state_in, const void* input, int len)
     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
@@ -445,8 +432,8 @@ U32 XXH32_intermediateDigest (void* state_in)
 \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
@@ -467,6 +454,17 @@ U32 XXH32_intermediateDigest (void* state_in)
 }\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