typedef unsigned long long U64;\r
#endif\r
\r
-typedef const BYTE* Ptr;\r
-\r
#if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS)\r
# define _PACKED __attribute__ ((packed))\r
#else\r
#endif\r
\r
#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)\r
-# ifdef __IBMC__\r
+# if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)\r
# pragma pack(1)\r
# else\r
# pragma pack(push, 1)\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
+# if defined(__SUNPRO_C) || defined(__SUNPRO_CC)\r
+# pragma pack(0)\r
+# else\r
+# pragma pack(pop)\r
+# endif\r
#endif\r
\r
#define A16(x) (((U16_S *)(x))->v)\r
\r
typedef struct {\r
U32 hashTable[HASHNBCELLS4];\r
- Ptr bufferStart;\r
- Ptr base;\r
- Ptr nextBlock;\r
+ const BYTE* bufferStart;\r
+ const BYTE* base;\r
+ const BYTE* nextBlock;\r
} LZ4_Data_Structure;\r
\r
typedef enum { notLimited = 0, limited = 1 } limitedOutput_directive;\r
\r
#if LZ4_ARCH64 // 64-bit\r
# define HTYPE U32\r
-# define INITBASE(base) Ptr const base = ip\r
+# define INITBASE(base) const BYTE* const base = ip\r
#else // 32-bit\r
-# define HTYPE Ptr\r
+# define HTYPE const BYTE*\r
# define INITBASE(base) const int base = 0\r
#endif\r
\r
return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));\r
}\r
\r
-FORCE_INLINE int LZ4_hashPosition(Ptr p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); }\r
+FORCE_INLINE int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); }\r
\r
-FORCE_INLINE void LZ4_putPositionOnHash(Ptr p, U32 h, void* tableBase, tableType_t tableType, Ptr srcBase)\r
+FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)\r
{\r
switch (tableType)\r
{\r
- case byPtr: { Ptr* hashTable = (Ptr*) tableBase; hashTable[h] = p; break; }\r
- case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = p-srcBase; break; }\r
+ case byPtr: { const BYTE** hashTable = (const BYTE**) tableBase; hashTable[h] = p; break; }\r
+ case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); break; }\r
case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); break; }\r
}\r
}\r
\r
-FORCE_INLINE void LZ4_putPosition(Ptr p, void* tableBase, tableType_t tableType, Ptr srcBase)\r
+FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)\r
{\r
U32 h = LZ4_hashPosition(p, tableType);\r
LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);\r
}\r
\r
-FORCE_INLINE Ptr LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, Ptr srcBase)\r
+FORCE_INLINE const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)\r
{\r
- if (tableType == byPtr) { Ptr* hashTable = (Ptr*) tableBase; return hashTable[h]; }\r
+ if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }\r
if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }\r
{ U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } // default, to ensure a return\r
}\r
\r
-FORCE_INLINE Ptr LZ4_getPosition(Ptr p, void* tableBase, tableType_t tableType, Ptr srcBase)\r
+FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)\r
{\r
U32 h = LZ4_hashPosition(p, tableType);\r
return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);\r
tableType_t tableType,\r
prefix64k_directive prefix)\r
{\r
- Ptr ip = (Ptr) source;\r
- Ptr const base = (prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->base : (Ptr) source;\r
- Ptr const lowLimit = ((prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->bufferStart : (Ptr)source);\r
- Ptr anchor = (Ptr) source;\r
- Ptr const iend = ip + inputSize;\r
- Ptr const mflimit = iend - MFLIMIT;\r
- Ptr const matchlimit = iend - LASTLITERALS;\r
+ const BYTE* ip = (const BYTE*) source;\r
+ const BYTE* const base = (prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->base : (const BYTE*) source;\r
+ const BYTE* const lowLimit = ((prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->bufferStart : (const BYTE*)source);\r
+ const BYTE* anchor = (const BYTE*) source;\r
+ const BYTE* const iend = ip + inputSize;\r
+ const BYTE* const mflimit = iend - MFLIMIT;\r
+ const BYTE* const matchlimit = iend - LASTLITERALS;\r
\r
BYTE* op = (BYTE*) dest;\r
BYTE* const oend = op + maxOutputSize;\r
for ( ; ; )\r
{\r
int findMatchAttempts = (1U << skipStrength) + 3;\r
- Ptr forwardIp = ip;\r
- Ptr ref;\r
+ const BYTE* forwardIp = ip;\r
+ const BYTE* ref;\r
BYTE* token;\r
\r
// Find a match\r
// Stream functions\r
//****************************\r
\r
-FORCE_INLINE void LZ4_init(LZ4_Data_Structure* lz4ds, Ptr base)\r
+FORCE_INLINE void LZ4_init(LZ4_Data_Structure* lz4ds, const BYTE* base)\r
{\r
MEM_INIT(lz4ds->hashTable, 0, sizeof(lz4ds->hashTable));\r
lz4ds->bufferStart = base;\r
void* LZ4_create (const char* inputBuffer)\r
{\r
void* lz4ds = ALLOCATOR(1, sizeof(LZ4_Data_Structure));\r
- LZ4_init ((LZ4_Data_Structure*)lz4ds, (Ptr)inputBuffer);\r
+ LZ4_init ((LZ4_Data_Structure*)lz4ds, (const BYTE*)inputBuffer);\r
return lz4ds;\r
}\r
\r
for (nH=0; nH < HASHNBCELLS4; nH++)\r
{\r
if (lz4ds->hashTable[nH] < (U32)newBaseDelta) lz4ds->hashTable[nH] = 0;\r
- else lz4ds->hashTable[nH] -= newBaseDelta;\r
+ else lz4ds->hashTable[nH] -= (U32)newBaseDelta;\r
}\r
lz4ds->base += newBaseDelta;\r
}\r
const char* source,\r
char* dest,\r
int inputSize, //\r
- int outputSize, // OutputSize must be != 0; if endOnInput==endOnInputSize, this value is the max size of Output Buffer.\r
+ int outputSize, // If endOnInput==endOnInputSize, this value is the max size of Output Buffer.\r
\r
int endOnInput, // endOnOutputSize, endOnInputSize\r
int prefix64k, // noPrefix, withPrefix\r
)\r
{\r
// Local Variables\r
- Ptr restrict ip = (Ptr) source;\r
- Ptr ref;\r
- Ptr const iend = ip + inputSize;\r
+ const BYTE* restrict ip = (const BYTE*) source;\r
+ const BYTE* ref;\r
+ const BYTE* const iend = ip + inputSize;\r
\r
BYTE* op = (BYTE*) dest;\r
BYTE* const oend = op + outputSize;\r
BYTE* cpy;\r
BYTE* oexit = op + targetOutputSize;\r
\r
- size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};\r
-#if LZ4_ARCH64\r
- size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};\r
-#endif\r
+ const size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; // static reduces speed for LZ4_decompress_safe() on GCC64\r
+ static const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};\r
\r
\r
// Special cases\r
// copy repeated sequence\r
if unlikely((op-ref)<(int)STEPSIZE)\r
{\r
-#if LZ4_ARCH64\r
- size_t dec64 = dec64table[op-ref];\r
-#else\r
- const size_t dec64 = 0;\r
-#endif\r
+ const size_t dec64 = dec64table[(sizeof(void*)==4) ? 0 : op-ref];\r
op[0] = ref[0];\r
op[1] = ref[1];\r
op[2] = ref[2];\r
return LZ4_decompress_generic(source, dest, inputSize, maxOutputSize, endOnInputSize, noPrefix, partial, targetOutputSize);\r
}\r
\r
+int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize)\r
+{\r
+ return LZ4_decompress_generic(source, dest, 0, outputSize, endOnOutputSize, withPrefix, full, 0);\r
+}\r
+\r
int LZ4_decompress_fast(const char* source, char* dest, int outputSize)\r
{\r
#ifdef _MSC_VER // This version is faster with Visual\r
#endif\r
}\r
\r
-int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize)\r
-{\r
- return LZ4_decompress_generic(source, dest, 0, outputSize, endOnOutputSize, withPrefix, full, 0);\r
-}\r
-\r
/*\r
- LZ4c - LZ4 Compression CLI program \r
+ LZ4cli.c - LZ4 Command Line Interface\r
Copyright (C) Yann Collet 2011-2013\r
GPL v2 License\r
\r
*/\r
/*\r
Note : this is stand-alone program.\r
- It is not part of LZ4 compression library, it is a user program of LZ4 library.\r
+ It is not part of LZ4 compression library, it is a user program of the LZ4 library.\r
The license of LZ4 library is BSD.\r
The license of xxHash library is BSD.\r
The license of this compression CLI program is GPLv2.\r
*/\r
\r
//**************************************\r
+// Tuning parameters\r
+//**************************************\r
+// DISABLE_LZ4C_LEGACY_OPTIONS :\r
+// Control the availability of -c0, -c1 and -hc legacy arguments\r
+// Default : Legacy options are enabled\r
+// #define DISABLE_LZ4C_LEGACY_OPTIONS\r
+\r
+\r
+//**************************************\r
// Compiler Options\r
//**************************************\r
// Disable some Visual warning messages\r
//****************************\r
// Includes\r
//****************************\r
-#include <stdio.h> // fprintf, fopen, fread, _fileno(?)\r
+#include <stdio.h> // fprintf, fopen, fread, _fileno, stdin, stdout\r
#include <stdlib.h> // malloc\r
#include <string.h> // strcmp\r
#include <time.h> // clock\r
-#ifdef _WIN32\r
-#include <io.h> // _setmode\r
-#include <fcntl.h> // _O_BINARY\r
-#endif\r
#include "lz4.h"\r
#include "lz4hc.h"\r
+#include "lz4stream.h"\r
#include "bench.h"\r
#include "xxhash.h"\r
\r
\r
+//****************************\r
+// OS-specific Includes\r
+//****************************\r
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)\r
+# include <fcntl.h> // _O_BINARY\r
+# include <io.h> // _setmode, _isatty\r
+# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY)\r
+# define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream))\r
+#else\r
+# define SET_BINARY_MODE(file)\r
+# define IS_CONSOLE(stdStream) isatty(fileno(stdStream))\r
+#endif\r
+\r
+\r
//**************************************\r
// Compiler-specific functions\r
//**************************************\r
// Constants\r
//****************************\r
#define COMPRESSOR_NAME "LZ4 Compression CLI"\r
-#define COMPRESSOR_VERSION ""\r
+#define COMPRESSOR_VERSION "1.0.3"\r
#define COMPILED __DATE__\r
#define AUTHOR "Yann Collet"\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
+#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", COMPRESSOR_NAME, COMPRESSOR_VERSION, (int)(sizeof(void*)*8), AUTHOR, COMPILED\r
\r
#define KB *(1U<<10)\r
#define MB *(1U<<20)\r
//**************************************\r
// Macros\r
//**************************************\r
-#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)\r
+#define DISPLAY(...) fprintf(stderr, __VA_ARGS__)\r
+#define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); }\r
\r
\r
//**************************************\r
// Local Parameters\r
//**************************************\r
static char* programName;\r
-static int silence = 0;\r
-static int verbose = 0;\r
+static int displayLevel = 2; // 0 : no display // 1: errors // 2 : + result + interaction + warnings ; // 3 : + progression; // 4 : + information\r
static int overwrite = 0;\r
static int blockSizeId = LZ4S_BLOCKSIZEID_DEFAULT;\r
static int blockChecksum = 0;\r
#define EXM_THROW(error, ...) \\r
{ \\r
DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \\r
- DISPLAY("Error %i : ", error); \\r
- DISPLAY(__VA_ARGS__); \\r
- DISPLAY("\n"); \\r
+ DISPLAYLEVEL(1, "Error %i : ", error); \\r
+ DISPLAYLEVEL(1, __VA_ARGS__); \\r
+ DISPLAYLEVEL(1, "\n"); \\r
exit(error); \\r
}\r
\r
DISPLAY( "Usage :\n");\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( "input : a filename\n");\r
+ DISPLAY( " with no FILE, or when FILE is - or %s, read standard input\n", stdinmark);\r
DISPLAY( "Arguments :\n");\r
- DISPLAY( " -c0/-c : Fast compression (default) \n");\r
- DISPLAY( " -c1/-hc: High compression \n");\r
+ DISPLAY( " -1 : Fast compression (default) \n");\r
+ DISPLAY( " -9 : High compression \n");\r
DISPLAY( " -d : decompression \n");\r
- DISPLAY( " -y : overwrite without prompting \n");\r
- DISPLAY( " -h/-H : Help (this text + advanced options)\n");\r
+ DISPLAY( " -f : overwrite output without prompting \n");\r
+ DISPLAY( " -h/-H : display help/long help and exit\n");\r
return 0;\r
}\r
\r
int usage_advanced()\r
{\r
+ DISPLAY(WELCOME_MESSAGE);\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( "Advanced arguments :\n");\r
+ DISPLAY( " -V : display Version number and exit\n");\r
+ DISPLAY( " -v : verbose mode\n");\r
+ DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n");\r
+ DISPLAY( " -c : force write to standard output, even if it is the console\n");\r
+ DISPLAY( " -t : test compressed file integrity\n");\r
+ DISPLAY( " -z : force compression\n");\r
DISPLAY( " -B# : Block size [4-7](default : 7)\n");\r
DISPLAY( " -BD : Block dependency (improve compression ratio)\n");\r
DISPLAY( " -BX : enable block checksum (default:disabled)\n");\r
DISPLAY( " -Sx : disable stream checksum (default:enabled)\n");\r
- DISPLAY( " -b# : benchmark files, using # [0-1] compression level\n");\r
+ DISPLAY( "Benchmark arguments :\n");\r
+ DISPLAY( " -b : benchmark file(s)\n");\r
DISPLAY( " -i# : iteration loops [1-9](default : 3), benchmark mode only\n");\r
+#if !defined(DISABLE_LZ4C_LEGACY_OPTIONS)\r
+ DISPLAY( "Legacy arguments :\n");\r
+ DISPLAY( " -c0 : fast compression\n");\r
+ DISPLAY( " -c1 : high compression\n");\r
+ DISPLAY( " -hc : high compression\n");\r
+ DISPLAY( " -y : overwrite output without prompting \n");\r
+ DISPLAY( " -s : suppress warnings \n");\r
+#endif // DISABLE_LZ4C_LEGACY_OPTIONS\r
+ return 0;\r
+}\r
+\r
+int usage_longhelp()\r
+{\r
+ DISPLAY( "\n");\r
+ DISPLAY( "Which values can get [output] ? \n");\r
+ DISPLAY( "[output] : a filename\n");\r
+ DISPLAY( " '%s', or '-' for standard output (pipe mode)\n", stdoutmark);\r
+ DISPLAY( " '%s' to discard output (test mode)\n", NULL_OUTPUT);\r
+ DISPLAY( "[output] can be left empty. In this case, it receives the following value : \n");\r
+ DISPLAY( " - if stdout is not the console, then [output] = stdout \n");\r
+ DISPLAY( " - if stdout is console : \n");\r
+ DISPLAY( " + if compression selected, output to filename%s \n", EXTENSION);\r
+ DISPLAY( " + if decompression selected, output to filename without '%s'\n", EXTENSION);\r
+ DISPLAY( " > if input filename has no '%s' extension : error\n", EXTENSION);\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( "Compression levels : \n");\r
+ DISPLAY( "There are technically 2 accessible compression levels.\n");\r
+ DISPLAY( "-0 ... -2 => Fast compression\n");\r
+ DISPLAY( "-3 ... -9 => High compression\n");\r
DISPLAY( "\n");\r
- DISPLAY( "Examples :\n");\r
- DISPLAY( "1 : compress file 'filename', using default output name 'filename.lz4'\n");\r
+ DISPLAY( "stdin, stdout and the console : \n");\r
+ DISPLAY( "To protect the console from binary flooding (bad argument mistake)\n");\r
+ DISPLAY( "%s will refuse to read from console, or write to console \n", programName);\r
+ DISPLAY( "except if '-c' command is specified, to force output to console \n");\r
+ DISPLAY( "\n");\r
+ DISPLAY( "Simple example :\n");\r
+ DISPLAY( "1 : compress 'filename' fast, using default output name 'filename.lz4'\n");\r
DISPLAY( " %s filename\n", programName);\r
+ DISPLAY( "\n");\r
+ DISPLAY( "Arguments can be appended together, or provided independently. For example :\n");\r
DISPLAY( "2 : compress 'filename' in high compression mode, overwrite output if exists\n");\r
- DISPLAY( " %s -hcy filename \n", programName);\r
+ DISPLAY( " %s -f9 filename \n", programName);\r
+ DISPLAY( " is equivalent to :\n");\r
+ DISPLAY( " %s -f -9 filename \n", programName);\r
+ DISPLAY( "\n");\r
+ DISPLAY( "%s can be used in 'pure pipe mode', for example :\n", programName);\r
DISPLAY( "3 : compress data stream from 'generator', send result to 'consumer'\n");\r
DISPLAY( " generator | %s | consumer \n", programName);\r
+#if !defined(DISABLE_LZ4C_LEGACY_OPTIONS)\r
+ DISPLAY( "\n");\r
+ DISPLAY( "Warning :\n");\r
+ DISPLAY( "Legacy arguments take precedence. Therefore : \n");\r
+ DISPLAY( " %s -hc filename\n", programName);\r
+ DISPLAY( "means 'compress filename in high compression mode'\n");\r
+ DISPLAY( "It is not equivalent to :\n");\r
+ DISPLAY( " %s -h -c filename\n", programName);\r
+ DISPLAY( "which would display help text and exit\n");\r
+#endif // DISABLE_LZ4C_LEGACY_OPTIONS\r
return 0;\r
}\r
\r
int badusage()\r
{\r
- DISPLAY("Wrong parameters\n");\r
- usage();\r
+ DISPLAYLEVEL(1, "Incorrect parameters\n");\r
+ if (displayLevel >= 1) usage();\r
exit(1);\r
}\r
\r
\r
if (!strcmp (input_filename, stdinmark)) \r
{\r
- if (verbose) DISPLAY( "Using stdin for input\n");\r
+ DISPLAYLEVEL(4,"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
-#endif\r
+ SET_BINARY_MODE(stdin);\r
} \r
else \r
{\r
\r
if (!strcmp (output_filename, stdoutmark)) \r
{\r
- if (verbose) DISPLAY( "Using stdout for output\n");\r
+ DISPLAYLEVEL(4,"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
-#endif\r
+ SET_BINARY_MODE(stdout);\r
} \r
else \r
{\r
if (!overwrite)\r
{\r
char ch;\r
- DISPLAY( "Warning : %s already exists\n", output_filename); \r
- DISPLAY( "Overwrite ? (Y/N) : ");\r
+ DISPLAYLEVEL(2, "Warning : %s already exists\n", output_filename); \r
+ DISPLAYLEVEL(2, "Overwrite ? (Y/N) : ");\r
+ if (displayLevel <= 1) EXM_THROW(11, "Operation aborted : %s already exists", output_filename); // No interaction possible\r
ch = (char)getchar();\r
if ((ch!='Y') && (ch!='y')) EXM_THROW(11, "Operation aborted : %s already exists", output_filename);\r
}\r
}\r
start = clock();\r
get_fileHandle(input_filename, output_filename, &finput, &foutput);\r
+ if ((displayLevel==2) && (compressionlevel==1)) displayLevel=3;\r
\r
// Allocate Memory\r
in_buff = (char*)malloc(LEGACY_BLOCKSIZE);\r
int inSize = (int) fread(in_buff, (size_t)1, (size_t)LEGACY_BLOCKSIZE, finput);\r
if( inSize<=0 ) break;\r
filesize += inSize;\r
- if (displayLevel) DISPLAY("Read : %i MB \r", (int)(filesize>>20));\r
+ DISPLAYLEVEL(3, "Read : %i MB \r", (int)(filesize>>20));\r
\r
// Compress Block\r
outSize = compressionFunction(in_buff, out_buff+4, inSize);\r
compressedfilesize += outSize+4;\r
- if (displayLevel) DISPLAY("Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);\r
+ DISPLAYLEVEL(3, "Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);\r
\r
// Write Block\r
* (unsigned int*) out_buff = LITTLE_ENDIAN_32(outSize);\r
\r
// Status\r
end = clock();\r
- if (!silence) DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
+ DISPLAYLEVEL(2,"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
+ DISPLAYLEVEL(4,"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 displayLevel = ((compressionlevel>0) && (!silence)) || (verbose);\r
clock_t start, end;\r
unsigned int blockSize, inputBufferSize;\r
size_t sizeCheck, header_size;\r
\r
// Init\r
start = clock();\r
+ if ((displayLevel==2) && (compressionlevel==1)) displayLevel=3;\r
switch (compressionlevel)\r
{\r
case 0 :\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
filesize += inSize;\r
- if (displayLevel) DISPLAY("Read : %i MB \r", (int)(filesize>>20));\r
+ DISPLAYLEVEL(3, "Read : %i MB \r", (int)(filesize>>20));\r
if (streamChecksum) XXH32_update(streamChecksumState, in_start, inSize);\r
\r
// Compress Block\r
outSize = compressionFunction(ctx, in_start, out_buff+4, inSize, inSize-1);\r
if (outSize > 0) compressedfilesize += outSize+4; else compressedfilesize += inSize+4;\r
if (blockChecksum) compressedfilesize+=4;\r
- if (displayLevel) DISPLAY("Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);\r
+ DISPLAYLEVEL(3, "Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);\r
\r
// Write Block\r
if (outSize > 0)\r
\r
// Status\r
end = clock();\r
- if (!silence) DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
+ DISPLAYLEVEL(2, "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
+ DISPLAYLEVEL(4, "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
}\r
\r
// Close & Free\r
char* headerBuffer;\r
FILE* finput;\r
FILE* foutput;\r
- int displayLevel = ((compressionlevel>0) && (!silence)) || (verbose);\r
clock_t start, end;\r
int blockSize;\r
size_t sizeCheck, header_size, readSize;\r
\r
// Init\r
start = clock();\r
+ if ((displayLevel==2) && (compressionlevel==1)) displayLevel=3;\r
switch (compressionlevel)\r
{\r
case 0 : compressionFunction = LZ4_compress_limitedOutput; break;\r
unsigned int outSize;\r
\r
filesize += readSize;\r
- if (displayLevel) DISPLAY("Read : %i MB \r", (int)(filesize>>20));\r
+ DISPLAYLEVEL(3, "Read : %i MB \r", (int)(filesize>>20));\r
if (streamChecksum) XXH32_update(streamChecksumState, in_buff, (int)readSize);\r
\r
// Compress Block\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
+ DISPLAYLEVEL(3, "Read : %i MB ==> %.2f%%\r", (int)(filesize>>20), (double)compressedfilesize/filesize*100);\r
\r
// Write Block\r
if (outSize > 0)\r
\r
// Final Status\r
end = clock();\r
- if (!silence) DISPLAY( "Compressed %llu bytes into %llu bytes ==> %.2f%%\n",\r
+ DISPLAYLEVEL(2, "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
+ DISPLAYLEVEL(4, "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
}\r
\r
return 0;\r
case LZ4S_MAGICNUMBER:\r
return decodeLZ4S(finput, foutput);\r
case LEGACY_MAGICNUMBER:\r
- if (verbose) DISPLAY("Detected : Legacy format \n");\r
+ DISPLAYLEVEL(4, "Detected : Legacy format \n");\r
return decodeLegacyStream(finput, foutput);\r
case LZ4S_SKIPPABLE0:\r
+ DISPLAYLEVEL(4, "Skipping detected skippable area \n");\r
nbReadBytes = fread(&size, 1, 4, finput);\r
if (nbReadBytes != 4) EXM_THROW(42, "Stream error : skippable size unreadable");\r
size = LITTLE_ENDIAN_32(size); // Convert to Little Endian format\r
return selectDecoder(finput, foutput);\r
default:\r
if (ftell(finput) == MAGICNUMBER_SIZE) EXM_THROW(44,"Unrecognized header : file cannot be decoded"); // Wrong magic number at the beginning of 1st stream\r
- DISPLAY("Stream followed by unrecognized data\n");\r
+ DISPLAYLEVEL(2, "Stream followed by unrecognized data\n");\r
return 0;\r
}\r
}\r
\r
// Final Status\r
end = clock();\r
- if (!silence) DISPLAY( "Successfully decoded %llu bytes \n", filesize);\r
+ DISPLAYLEVEL(2, "Successfully decoded %llu bytes \n", filesize);\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
+ DISPLAYLEVEL(4, "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024);\r
}\r
\r
// Close\r
decode=0,\r
bench=0,\r
filenamesStart=2,\r
- legacy_format=0;\r
+ legacy_format=0,\r
+ forceStdout=0;\r
char* input_filename=0;\r
char* output_filename=0;\r
char nullOutput[] = NULL_OUTPUT;\r
char extension[] = EXTENSION;\r
\r
- // Select behavior\r
+ // Init\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
+ // '-' means stdin/stdout\r
if (argument[1]==0)\r
{\r
if (!input_filename) input_filename=stdinmark;\r
{\r
argument ++;\r
\r
+#if !defined(DISABLE_LZ4C_LEGACY_OPTIONS)\r
+ // Legacy options (-c0, -c1, -hc, -y, -s, -b0, -b1)\r
+ if ((argument[0]=='c') && (argument[1]=='0')) { cLevel=0; argument++; continue; } // -c0 (fast compression)\r
+ if ((argument[0]=='c') && (argument[1]=='1')) { cLevel=1; argument++; continue; } // -c1 (high compression)\r
+ if ((argument[0]=='h') && (argument[1]=='c')) { cLevel=1; argument++; continue; } // -hc (high compression)\r
+ if (*argument=='y') { overwrite=1; continue; } // -y (answer 'yes' to overwrite permission)\r
+ if (*argument=='s') { displayLevel=1; continue; } // -s (silent mode)\r
+ if ((argument[0]=='b') && (argument[1]=='0')) { bench=1; cLevel=0; argument++; continue; } // -b0 (fast bench)\r
+ if ((argument[0]=='b') && (argument[1]=='1')) { bench=1; cLevel=1; argument++; continue; } // -b1 (HC bench)\r
+#endif // DISABLE_LZ4C_LEGACY_OPTIONS\r
+\r
switch(argument[0])\r
{\r
- // Display help on usage\r
- case 'H': usage_advanced(); return 0;\r
+ // Display help\r
+ case 'V': DISPLAY(WELCOME_MESSAGE); return 0; // Version\r
+ case 'h': usage_advanced(); return 0;\r
+ case 'H': usage_advanced(); usage_longhelp(); 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++; } else { usage_advanced(); return 0; } break;\r
+ case 'z': break;\r
+\r
+ // Compression level\r
+ case '0': \r
+ case '1':\r
+ case '2': cLevel=0; break;\r
+ case '3':\r
+ case '4':\r
+ case '5':\r
+ case '6':\r
+ case '7':\r
+ case '8':\r
+ case '9': cLevel=1; break;\r
\r
// Use Legacy format (hidden option)\r
case 'l': legacy_format=1; break;\r
// Decoding\r
case 'd': decode=1; break;\r
\r
+ // Force stdout, even if stdout==console\r
+ case 'c': forceStdout=1; output_filename=stdoutmark; displayLevel=1; break;\r
+\r
// Test\r
case 't': decode=1; output_filename=nulmark; break;\r
\r
+ // Overwrite\r
+ case 'f': overwrite=1; break;\r
+\r
+ // Verbose mode\r
+ case 'v': displayLevel=4; break;\r
+\r
+ // Quiet mode\r
+ case 'q': displayLevel--; break;\r
+\r
+ // keep source file (default anyway, so useless) (for xz/lzma compatibility)\r
+ case 'k': break;\r
+\r
// Modify Block Properties\r
case 'B':\r
while (argument[1]!=0)\r
- switch(argument[1])\r
{\r
- case '4':\r
- case '5':\r
- case '6':\r
- case '7':\r
- { \r
- int B = argument[1] - '0'; \r
- int S = 1 << (8 + 2*B); \r
- BMK_SetBlocksize(S); \r
- blockSizeId = B;\r
- argument++;\r
- break;\r
- }\r
- case 'D': blockIndependence = 0, argument++; break;\r
- case 'X': blockChecksum = 1, argument ++; break;\r
- default : goto _exit_blockProperties;\r
+ int exitBlockProperties=0;\r
+ switch(argument[1])\r
+ {\r
+ case '4':\r
+ case '5':\r
+ case '6':\r
+ case '7':\r
+ { \r
+ int B = argument[1] - '0'; \r
+ int S = 1 << (8 + 2*B); \r
+ BMK_SetBlocksize(S); \r
+ blockSizeId = B;\r
+ argument++;\r
+ break;\r
+ }\r
+ case 'D': blockIndependence = 0, argument++; break;\r
+ case 'X': blockChecksum = 1, argument ++; break;\r
+ default : exitBlockProperties=1;\r
+ }\r
+ if (exitBlockProperties) break;\r
}\r
-_exit_blockProperties:\r
break;\r
\r
// Modify Stream properties\r
case 'S': if (argument[1]=='x') { streamChecksum=0; argument++; break; } else { badusage(); }\r
\r
- // Bench\r
- case 'b': bench=1; \r
- if ((argument[1] >='0') && (argument[1] <='1')) { cLevel=argument[1] - '0'; argument++; } \r
- break;\r
+ // Benchmark\r
+ case 'b': bench=1; break;\r
\r
// Modify Nb Iterations (benchmark only)\r
case 'i': \r
// Pause at the end (benchmark only) (hidden option)\r
case 'p': BMK_SetPause(); break;\r
\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();\r
}\r
}\r
}\r
\r
- if (verbose) DISPLAY( WELCOME_MESSAGE);\r
+ DISPLAYLEVEL(4, WELCOME_MESSAGE);\r
+ DISPLAYLEVEL(4, "Blocks size : %i KB\n", (1 << ((blockSizeId*2)-2)));\r
\r
// No input filename ==> use stdin\r
if(!input_filename) { input_filename=stdinmark; }\r
\r
- // Check if benchmark was required\r
+ // Check if benchmark is selected\r
if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, cLevel);\r
\r
// No output filename ==> select one automatically (when possible)\r
if (!output_filename) \r
{\r
- if (input_filename == stdinmark) { output_filename=stdoutmark; silence=1; }\r
+ if (!IS_CONSOLE(stdout)) { output_filename=stdoutmark; }\r
else if (!decode) // compression\r
{\r
int i=0, l=0;\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
+ DISPLAYLEVEL(2, "Compressed filename will be : %s \n", output_filename);\r
}\r
else // decompression (input file must respect format extension ".lz4")\r
{\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) { DISPLAY("Cannot automatically decide an output filename\n"); badusage(); }\r
+ if (outl != inl-5) { DISPLAYLEVEL(1, "Cannot automatically decide an output filename\n"); badusage(); }\r
+ DISPLAYLEVEL(2, "Decoding file %s \n", output_filename);\r
}\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
+ // No warning message in pure pipe mode (stdin + stdout)\r
+ if (!strcmp(input_filename, stdinmark) && !strcmp(output_filename,stdoutmark) && (displayLevel>1) && (displayLevel<4)) displayLevel=1;\r
\r
- if (verbose) silence=0;\r
+ // Check if input or output are defined as console; trigger an error in this case\r
+ if (!strcmp(input_filename, stdinmark) && IS_CONSOLE(stdin) ) badusage();\r
+ if (!strcmp(output_filename,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) badusage();\r
\r
+ // Decompress input if selected\r
if (decode) return decodeFile(input_filename, output_filename);\r
\r
// compression is default action\r
if (legacy_format)\r
{\r
- if (!silence) DISPLAY("! Generating compressed LZ4 using Legacy format (deprecated !) ! \n");\r
+ DISPLAYLEVEL(2, "! Generating compressed LZ4 using Legacy format (deprecated !) ! \n");\r
return legacy_compress_file(input_filename, output_filename, cLevel); \r
}\r
else\r