while(BMK_GetMilliSpan(milliTime) < TIMELOOP)\r
{\r
for (chunkNb=0; chunkNb<nbChunks; chunkNb++)\r
- chunkP[chunkNb].outputSize = compP.decompressionFunction(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].inputSize);\r
+ chunkP[chunkNb].outputSize = LZ4_uncompress(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].inputSize);\r
+ //chunkP[chunkNb].inputSize = LZ4_uncompress_unknownOutputSize(chunkP[chunkNb].outputBuffer, chunkP[chunkNb].inputBuffer, chunkP[chunkNb].outputSize, chunkSize);\r
nb_loops++;\r
}\r
milliTime = BMK_GetMilliSpan(milliTime);\r
set(CPACK_PACKAGE_VERSION_MINOR 0)\r
set(CPACK_PACKAGE_VERSION_PATCH r51)\r
#set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/COPYING_LGPL)\r
- set(VERSION_STRING " \"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}\" ")\r
+set(VERSION_STRING " \"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}\" ")\r
include(CPack)\r
\r
\r
MESSAGE( STATUS "64 bit architecture detected size of void * is " ${SIZEOF_VOID_P})\r
ENDIF()\r
\r
+set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries")\r
+\r
+if (BUILD_SHARED_LIBS)\r
+ message(STATUS "Enable shared library building")\r
+else(BUILD_SHARED_LIBS)\r
+ message(STATUS "Disable shared library building")\r
+endif(BUILD_SHARED_LIBS)\r
+\r
+if(UNIX AND BUILD_SHARED_LIBS)\r
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")\r
+ add_definitions(-fPIC)\r
+ endif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")\r
+endif()\r
\r
set(SRC_DIR ../)\r
set(LZ4_SRCS_LIB ${SRC_DIR}lz4.c ${SRC_DIR}lz4hc.c ${SRC_DIR}lz4.h )\r
-set(LZ4_SRCS ${LZ4_SRCS_LIB} ${SRC_DIR}bench.c ${SRC_DIR}lz4demo.c )\r
+set(LZ4_SRCS ${SRC_DIR}bench.c ${SRC_DIR}lz4demo.c)\r
\r
-# EXECUTABLES FOR 32 Bit and 64 versions\r
-if(CMAKE_SYSTEM_PROCESSOR STREQUAL "64bit")\r
- add_executable(lz4demo64 ${LZ4_SRCS})\r
- install(TARGETS lz4demo64 RUNTIME DESTINATION "./")\r
+if(NOT BUILD_SHARED_LIBS)\r
+ set(LZ4_SRCS ${LZ4_SRCS} ${LZ4_SRCS_LIB})\r
endif()\r
\r
- add_executable(lz4demo32 ${LZ4_SRCS})\r
+if (CMAKE_SYSTEM_PROCESSOR STREQUAL "64bit")\r
+ message(STATUS "Build 64bit executable binary")\r
+ add_executable(lz4demo64 ${LZ4_SRCS})\r
+ install(TARGETS lz4demo64 RUNTIME DESTINATION "./")\r
+ if(NOT BUILD_SHARED_LIBS)\r
+ message(STATUS "Build 32bit executable binary")\r
+ add_executable(lz4demo32 ${LZ4_SRCS})\r
install(TARGETS lz4demo32 RUNTIME DESTINATION "./")\r
\r
-if(CMAKE_SYSTEM_PROCESSOR STREQUAL "64bit")\r
-SET_TARGET_PROPERTIES(lz4demo32 PROPERTIES\r
- COMPILE_FLAGS PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")\r
+ SET_TARGET_PROPERTIES(lz4demo32 PROPERTIES\r
+ COMPILE_FLAGS PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")\r
+ endif()\r
+else()\r
+ message(STATUS "Build 32bit executable binary")\r
+ add_executable(lz4demo32 ${LZ4_SRCS})\r
+ install(TARGETS lz4demo32 RUNTIME DESTINATION "./")\r
endif()\r
\r
+if(BUILD_SHARED_LIBS)\r
+ set(LZ4_SOVERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")\r
+ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "64bit")\r
+ target_link_libraries(lz4demo64 liblz4)\r
+ else()\r
+ target_link_libraries(lz4demo32 liblz4)\r
+ endif()\r
+ \r
+ # for static library\r
+ add_library(liblz4_static STATIC ${LZ4_SRCS_LIB})\r
+ set_target_properties(liblz4_static PROPERTIES OUTPUT_NAME lz4)\r
+\r
+ install(TARGETS liblz4_static\r
+ LIBRARY DESTINATION lib\r
+ ARCHIVE DESTINATION lib\r
+ )\r
+\r
+ # for shared library o\r
+ add_library(liblz4 ${LZ4_SRCS_LIB})\r
+ set_target_properties(liblz4 PROPERTIES\r
+ OUTPUT_NAME lz4\r
+ SOVERSION ${LZ4_SOVERSION})\r
+\r
+ install(TARGETS liblz4\r
+ LIBRARY DESTINATION lib\r
+ ARCHIVE DESTINATION lib\r
+ )\r
+endif(BUILD_SHARED_LIBS)\r
+\r
\r
#warnings\r
\r
INCLUDE_DIRECTORIES (${SRC_DIR})\r
\r
\r
-#target_link_libraries(lz4 ${LZ4_SRCS_LIB})\r
-\r
\r
--- /dev/null
+\r
+ lz4demo and fuzzer is an open-source demo compression algorithm LZ4 programs\r
+ Copyright (C) Yann Collet 2012\r
+\r
+ This program is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ This program is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License along\r
+ with this program; if not, write to the Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+\r
+ You can contact the author at :\r
+ - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html\r
+ - LZ4 source repository : http://code.google.com/p/lz4/\r
for (i = 0; i < 2048; i++)\r
cbuf[FUZ_avail + i] = cbuf[FUZ_avail + 2048 + i] = FUZ_rand(&seed) >> 16;\r
\r
- for (i = 0; i < NB_ATTEMPTS; i++) {\r
+ for (i = 0; i < NB_ATTEMPTS; i++) \r
+ {\r
printf("\r%7i /%7i\r", i, NB_ATTEMPTS);\r
\r
FUZ_rand(&seed);\r
\r
// Test decoding with output size being exactly what's necessary => must work\r
ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN);\r
- if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
+ if (ret<0) { printf("decompression failed despite correct space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
\r
// Test decoding with one byte missing => must fail\r
ret = LZ4_uncompress((char*)&cbuf[off_full], (char*)testOut, LEN-1);\r
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN+1);\r
if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
\r
- // Test decoding with output size being exactly what's necessary => should work\r
+ // Test decoding with output size being exactly what's necessary => must work\r
ret = LZ4_uncompress_unknownOutputSize((char*)&cbuf[off_full], (char*)testOut, len, LEN);\r
if (ret<0) { printf("decompression failed despite sufficient space: seed %u, len %d\n", seed, LEN); goto _output_error; }\r
\r
// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache\r
#define MEMORY_USAGE 14\r
\r
-// NOTCOMPRESSIBLE_DETECTIONLEVEL :\r
-// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"\r
-// This may decrease compression ratio dramatically, but will be faster on incompressible data\r
-// Increasing this value will make the algorithm search more before declaring a segment "incompressible"\r
-// This could improve compression a bit, but will be slower on incompressible data\r
-// The default value (6) is recommended\r
-#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6\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
#define HASHTABLESIZE (1 << HASH_LOG)\r
#define HASH_MASK (HASHTABLESIZE - 1)\r
\r
+// NOTCOMPRESSIBLE_DETECTIONLEVEL :\r
+// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"\r
+// This may decrease compression ratio dramatically, but will be faster on incompressible data\r
+// Increasing this value will make the algorithm search more before declaring a segment "incompressible"\r
+// This could improve compression a bit, but will be slower on incompressible data\r
+// The default value (6) is recommended\r
+#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6\r
#define SKIPSTRENGTH (NOTCOMPRESSIBLE_DETECTIONLEVEL>2?NOTCOMPRESSIBLE_DETECTIONLEVEL:2)\r
#define STACKLIMIT 13\r
#define HEAPMODE (HASH_LOG>STACKLIMIT) // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).\r
#endif\r
#else\r
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)\r
- unsigned long r = 0;\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
BYTE* op = (BYTE*) dest;\r
BYTE* const oend = op + maxOutputSize;\r
\r
- int len, length;\r
+ int length;\r
const int skipStrength = SKIPSTRENGTH;\r
U32 forwardH;\r
\r
}\r
else *token = (length<<ML_BITS);\r
#else\r
- if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }\r
+ if (length>=(int)RUN_MASK) \r
+ { \r
+ int len;\r
+ *token=(RUN_MASK<<ML_BITS); \r
+ len = length-RUN_MASK; \r
+ for(; len > 254 ; len-=255) *op++ = 255; \r
+ *op++ = (BYTE)len; \r
+ }\r
else *token = (length<<ML_BITS);\r
#endif\r
\r
LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));\r
\r
// Start Counting\r
- ip+=MINMATCH; ref+=MINMATCH; // MinMatch verified\r
+ ip+=MINMATCH; ref+=MINMATCH; // MinMatch already verified\r
anchor = ip;\r
while likely(ip<matchlimit-(STEPSIZE-1))\r
{\r
_endCount:\r
\r
// Encode MatchLength\r
- len = (int)(ip - anchor);\r
- if unlikely(op + (1 + LASTLITERALS) + (len>>8) > oend) return 0; // Check output limit\r
- if (len>=(int)ML_MASK) { *token+=ML_MASK; len-=ML_MASK; for(; len > 509 ; len-=510) { *op++ = 255; *op++ = 255; } if (len > 254) { len-=255; *op++ = 255; } *op++ = (BYTE)len; }\r
- else *token += len;\r
+ length = (int)(ip - anchor);\r
+ if unlikely(op + (1 + LASTLITERALS) + (length>>8) > oend) return 0; // Check output limit\r
+ if (length>=(int)ML_MASK) \r
+ { \r
+ *token += ML_MASK; \r
+ length -= ML_MASK; \r
+ for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; } \r
+ if (length > 254) { length-=255; *op++ = 255; } \r
+ *op++ = (BYTE)length; \r
+ }\r
+ else *token += length;\r
\r
// Test end of chunk\r
if (ip > mflimit) { anchor = ip; break; }\r
\r
unsigned token;\r
\r
- size_t length;\r
size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};\r
#if LZ4_ARCH64\r
size_t dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};\r
// Main Loop\r
while (1)\r
{\r
+ size_t length;\r
+\r
// get runlength\r
token = *ip++;\r
if ((length=(token>>ML_BITS)) == RUN_MASK) { size_t len; for (;(len=*ip++)==255;length+=255){} length += len; }\r
\r
// copy literals\r
cpy = op+length;\r
- if unlikely(cpy>oend-COPYLENGTH)\r
+ if (cpy>oend-COPYLENGTH)\r
{\r
if (cpy != oend) goto _output_error; // Error : not enough place for another match (min 4) + 5 literals\r
memcpy(op, ip, length);\r
\r
// get offset\r
LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;\r
- if unlikely(ref < (BYTE* const)dest) goto _output_error; // Error : offset create reference outside destination buffer\r
+ if unlikely(ref < (BYTE* const)dest) goto _output_error; // Error : offset outside destination buffer\r
\r
// get matchlength\r
if ((length=(token&ML_MASK)) == ML_MASK) { for (;*ip==255;length+=255) {ip++;} length += *ip++; }\r
op += STEPSIZE-4; ref -= dec64;\r
} else { LZ4_COPYSTEP(ref,op); }\r
cpy = op + length - (STEPSIZE-4);\r
- if (cpy>oend-COPYLENGTH)\r
+\r
+ if unlikely(cpy>oend-(COPYLENGTH)-(STEPSIZE-4))\r
{\r
- if (cpy > oend) goto _output_error; // Error : request to write beyond destination buffer\r
+ if (cpy > oend-LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals\r
LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));\r
while(op<cpy) *op++=*ref++;\r
op=cpy;\r
- if (op == oend) goto _output_error; // Check EOF (should never happen, since last 5 bytes are supposed to be literals)\r
continue;\r
}\r
- LZ4_SECURECOPY(ref, op, cpy);\r
+ \r
+ LZ4_WILDCOPY(ref, op, cpy);\r
op=cpy; // correction\r
}\r
\r
#endif\r
\r
\r
+ // Special case\r
+ if unlikely(ip==iend) goto _output_error; // A correctly formed null-compressed LZ4 must have at least one byte (token=0)\r
+\r
// Main Loop\r
- while (ip<iend)\r
+ while (1) \r
{\r
unsigned token;\r
size_t length;\r
\r
// get runlength\r
token = *ip++;\r
- if ((length=(token>>ML_BITS)) == RUN_MASK) { int s=255; while ((ip<iend) && (s==255)) { s=*ip++; length += s; } }\r
+ if ((length=(token>>ML_BITS)) == RUN_MASK) \r
+ { \r
+ int s=255; \r
+ while (likely(ip<iend) && (s==255)) { s=*ip++; length += s; } \r
+ }\r
\r
// copy literals\r
cpy = op+length;\r
- if ((cpy>oend-COPYLENGTH) || (ip+length>iend-COPYLENGTH))\r
+ if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS)))\r
{\r
if (cpy > oend) goto _output_error; // Error : writes beyond output buffer\r
- if (ip+length != iend) goto _output_error; // Error : LZ4 format requires to consume all input at this stage\r
+ if (ip+length != iend) goto _output_error; // Error : LZ4 format requires to consume all input at this stage (no match within the last 11 bytes, and at least 8 remaining input bytes for another match+literals)\r
memcpy(op, ip, length);\r
op += length;\r
break; // Necessarily EOF, due to parsing restrictions\r
\r
// get offset\r
LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;\r
- if (ref < (BYTE* const)dest) goto _output_error; // Error : offset creates reference outside of destination buffer\r
+ if unlikely(ref < (BYTE* const)dest) goto _output_error; // Error : offset outside of destination buffer\r
\r
// get matchlength\r
- if ((length=(token&ML_MASK)) == ML_MASK) { while (ip<iend) { int s = *ip++; length +=s; if (s==255) continue; break; } }\r
+ if ((length=(token&ML_MASK)) == ML_MASK) \r
+ { \r
+ while likely(ip<iend-(LASTLITERALS+1)) // Error : a minimum input bytes must remain for LASTLITERALS + token\r
+ { \r
+ int s = *ip++; \r
+ length +=s; \r
+ if (s==255) continue; \r
+ break; \r
+ } \r
+ }\r
\r
// copy repeated sequence\r
if unlikely(op-ref<STEPSIZE)\r
op += STEPSIZE-4; ref -= dec64;\r
} else { LZ4_COPYSTEP(ref,op); }\r
cpy = op + length - (STEPSIZE-4);\r
- if (cpy>oend-COPYLENGTH)\r
+\r
+ if unlikely(cpy>oend-(COPYLENGTH+(STEPSIZE-4)))\r
{\r
- if (cpy > oend) goto _output_error; // Error : request to write outside of destination buffer\r
+ if (cpy > oend-LASTLITERALS) goto _output_error; // Error : last 5 bytes must be literals\r
LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));\r
while(op<cpy) *op++=*ref++;\r
op=cpy;\r
- if (op == oend) goto _output_error; // Check EOF (should never happen, since last 5 bytes are supposed to be literals)\r
continue;\r
}\r
- LZ4_SECURECOPY(ref, op, cpy);\r
+\r
+ LZ4_WILDCOPY(ref, op, cpy);\r
op=cpy; // correction\r
}\r
\r
const BYTE* ref;\r
INITBASE(base,hc4->base);\r
int nbAttempts=MAX_NB_ATTEMPTS;\r
- size_t ml=0;\r
+ size_t repl=0, ml=0;\r
+ U16 delta;\r
\r
// HC4 match finder\r
LZ4HC_Insert(hc4, ip);\r
ref = HASH_POINTER(ip);\r
\r
-#if 1\r
+#define REPEAT_OPTIMIZATION\r
+#ifdef REPEAT_OPTIMIZATION\r
+ // Detect repetitive sequences of length <= 4\r
if (ref >= ip-4) // potential repetition\r
{\r
if (A32(ref) == A32(ip)) // confirmed\r
{\r
- const U16 delta = (U16)(ip-ref);\r
- const BYTE* ptr = ip;\r
- const BYTE* end;\r
- ml = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;\r
- end = ip + ml - (MINMATCH-1);\r
- while(ptr < end-delta)\r
- {\r
- DELTANEXT(ptr) = delta; // Pre-Load\r
- ptr++;\r
- }\r
- do\r
- {\r
- DELTANEXT(ptr) = delta; \r
- HashTable[HASH_VALUE(ptr)] = (ptr) - base; // Head of chain\r
- ptr++;\r
- } while(ptr < end);\r
- hc4->nextToUpdate = end;\r
+ delta = (U16)(ip-ref);\r
+ repl = ml = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;\r
*matchpos = ref;\r
}\r
ref = GETNEXT(ref);\r
}\r
#endif\r
\r
- while ((ref >= ip-MAX_DISTANCE) && (ref >= hc4->base) && (nbAttempts))\r
+ while ((ref >= ip-MAX_DISTANCE) && (nbAttempts))\r
{\r
nbAttempts--;\r
if (*(ref+ml) == *(ip+ml))\r
ref = GETNEXT(ref);\r
}\r
\r
+#ifdef REPEAT_OPTIMIZATION\r
+ // Complete table\r
+ if (repl)\r
+ {\r
+ const BYTE* ptr = ip;\r
+ const BYTE* end;\r
+\r
+ end = ip + repl - (MINMATCH-1);\r
+ while(ptr < end-delta)\r
+ {\r
+ DELTANEXT(ptr) = delta; // Pre-Load\r
+ ptr++;\r
+ }\r
+ do\r
+ {\r
+ DELTANEXT(ptr) = delta; \r
+ HashTable[HASH_VALUE(ptr)] = (ptr) - base; // Head of chain\r
+ ptr++;\r
+ } while(ptr < end);\r
+ hc4->nextToUpdate = end;\r
+ }\r
+#endif \r
+\r
return (int)ml;\r
}\r
\r
LZ4HC_Insert(hc4, ip);\r
ref = HASH_POINTER(ip);\r
\r
- while ((ref >= ip-MAX_DISTANCE) && (ref >= hc4->base) && (nbAttempts))\r
+ while ((ref >= ip-MAX_DISTANCE) && (nbAttempts))\r
{\r
nbAttempts--;\r
if (*(startLimit + longest) == *(ref - delta + longest))\r