summaryrefslogtreecommitdiffstats
path: root/lz4frame.c
diff options
context:
space:
mode:
authorYann Collet <yann.collet.73@gmail.com>2014-08-29 15:35:13 (GMT)
committerYann Collet <yann.collet.73@gmail.com>2014-08-29 15:35:13 (GMT)
commit47b70f4956528d2dbcaf25e4fd04a4f8844bcbf7 (patch)
tree25d657709856dc11820d73c1d58a0509691d22a4 /lz4frame.c
parent2050756f0f8f2cb0d12229ed4a09095f74ddff21 (diff)
downloadlz4-47b70f4956528d2dbcaf25e4fd04a4f8844bcbf7.zip
lz4-47b70f4956528d2dbcaf25e4fd04a4f8844bcbf7.tar.gz
lz4-47b70f4956528d2dbcaf25e4fd04a4f8844bcbf7.tar.bz2
lz4frame minor API fixes (pointers)
lz4frame.c first example code (incomplete)
Diffstat (limited to 'lz4frame.c')
-rw-r--r--lz4frame.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/lz4frame.c b/lz4frame.c
new file mode 100644
index 0000000..8af9c28
--- /dev/null
+++ b/lz4frame.c
@@ -0,0 +1,265 @@
+/*
+ LZ4 auto-framing library
+ Copyright (C) 2011-2014, Yann Collet.
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - LZ4 source repository : http://code.google.com/p/lz4/
+ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
+*/
+
+/* LZ4F is a stand-alone API to create LZ4-compressed frames
+ * fully conformant to specification v1.4.1.
+ * All related operations, including memory management, are handled by the library.
+ * You don't need lz4.h when using lz4frame.h.
+ * */
+
+
+/**************************************
+ CPU Feature Detection
+**************************************/
+/* 32 or 64 bits ? */
+static const int LZ4F_32bits = (sizeof(void*)==4);
+static const int LZ4F_64bits = (sizeof(void*)==8);
+
+/* Little Endian or Big Endian ? */
+typedef union {
+ int num;
+ char bytes[4];
+ } endian_t;
+static const endian_t endianTest = { .num = 1 };
+#define LZ4F_isLittleEndian (endianTest.bytes[0])
+
+
+/**************************************
+ Compiler Options
+**************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+#endif
+
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+
+/**************************************
+ Memory routines
+**************************************/
+#include <stdlib.h> /* malloc, calloc, free */
+#define ALLOCATOR(n,s) calloc(n,s)
+#define FREEMEM free
+#include <string.h> /* memset, memcpy */
+#define MEM_INIT memset
+
+
+/**************************************
+ Includes
+**************************************/
+#include "lz4frame.h"
+#include "lz4.h"
+#include "lz4hc.h"
+#include "xxhash.h"
+
+
+/**************************************
+ Basic Types
+**************************************/
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+ typedef int32_t S32;
+ typedef uint64_t U64;
+#else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+ typedef signed int S32;
+ typedef unsigned long long U64;
+#endif
+
+#if defined(__GNUC__)
+# define _PACKED __attribute__ ((packed))
+#else
+# define _PACKED
+#endif
+
+#if !defined(__GNUC__)
+# if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# pragma pack(1)
+# else
+# pragma pack(push, 1)
+# endif
+#endif
+
+typedef struct { U16 v; } _PACKED U16_S;
+typedef struct { U32 v; } _PACKED U32_S;
+typedef struct { U64 v; } _PACKED U64_S;
+typedef struct {size_t v;} _PACKED size_t_S;
+
+#if !defined(__GNUC__)
+# if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# pragma pack(0)
+# else
+# pragma pack(pop)
+# endif
+#endif
+
+#define A16(x) (((U16_S *)(x))->v)
+#define A32(x) (((U32_S *)(x))->v)
+#define A64(x) (((U64_S *)(x))->v)
+#define AARCH(x) (((size_t_S *)(x))->v)
+
+
+/**************************************
+ Constants
+**************************************/
+#define KB *(1<<10)
+#define MB *(1<<20)
+#define GB *(1<<30)
+
+
+/**************************************
+ Structures and local types
+**************************************/
+
+
+/**************************************
+ Macros
+**************************************/
+
+
+/**************************************
+ Private functions
+**************************************/
+static size_t LZ4F_getBlockSize(unsigned blockSizeID)
+{
+ static const size_t blockSizes[4] = { 64 KB, 256 KB, 1 MB, 4 MB };
+
+ blockSizeID -= 4;
+ if (blockSizeID > 3) return ERROR_maxBlockSize_invalid;
+ return blockSizes[blockSizeID];
+}
+
+
+/**************************************
+ Error management
+**************************************/
+int LZ4F_isError(LZ4F_errorCode_t code)
+{
+ return (code > (LZ4F_errorCode_t)(-ERROR_maxCode));
+}
+
+
+/**************************************
+ Compression functions
+**************************************/
+size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_frameInfo_t* frameInfoPtr)
+{
+ const LZ4F_frameInfo_t frameInfoNull = { 0 };
+ size_t headerSize;
+ size_t blockInfoSize;
+ size_t blockSize;
+ unsigned nbBlocks;
+ size_t frameSuffixSize;
+ size_t totalBound;
+
+ if (frameInfoPtr==NULL) frameInfoPtr = &frameInfoNull; /* all parameters set to default */
+
+ headerSize = 7; /* basic header size (no option) including magic number */
+ blockInfoSize = 4; /* basic blockInfo size (no option) for one block */
+
+ blockSize = LZ4F_getBlockSize(frameInfoPtr->maxBlockSizeID);
+ nbBlocks = (srcSize + (blockSize-1)) / blockSize;
+ blockInfoSize *= nbBlocks; /* total block info size */
+
+ frameSuffixSize = 4; /* basic frameSuffixSize (no option) */
+ if (frameInfoPtr->contentChecksumFlag == contentChecksumEnabled) frameSuffixSize += 4;
+
+ totalBound = headerSize + srcSize + blockInfoSize + frameSuffixSize;
+ if (totalBound < srcSize) return ERROR_srcSize_tooLarge; /* overflow error */
+
+ return totalBound;
+}
+
+
+/* LZ4F_compressFrame()
+ * Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.4.1, in a single step.
+ * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case.
+ * You can get the minimum value of dstMaxSize by using LZ4F_compressFrameBound()
+ * If this condition is not respected, LZ4F_compressFrame() will fail (result is an errorCode)
+ * The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default.
+ * The result of the function is the number of bytes written into dstBuffer.
+ * The function outputs an error code if it fails (can be tested using LZ4F_isError())
+ */
+size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_preferences_t* preferencesPtr)
+{
+ const LZ4F_frameInfo_t frameInfoNull = { 0 };
+ const LZ4F_frameInfo_t* const frameInfoPtr = (preferencesPtr==NULL) ? &frameInfoNull : &(preferencesPtr->frameInfo);
+ LZ4F_compressionContext_t cctx;
+ LZ4F_errorCode_t errorCode;
+ BYTE* const dstStart = (BYTE*) dstBuffer;
+ BYTE* dstPtr = dstStart;
+ size_t blockSize = LZ4F_getBlockSize(frameInfoPtr->maxBlockSizeID);
+ unsigned nbBlocks = (srcSize + (blockSize-1)) / blockSize;
+ unsigned blockNb;
+ const BYTE* srcPtr = (const BYTE*) srcBuffer;
+ const size_t dstBlockSize = LZ4F_compressBound(blockSize, frameInfoPtr);
+
+
+ if (dstMaxSize < LZ4F_compressFrameBound(srcSize, frameInfoPtr))
+ return ERROR_maxDstSize_tooSmall;
+
+ errorCode = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION, preferencesPtr);
+ if (LZ4F_isError(errorCode)) return errorCode;
+
+ errorCode = LZ4F_compressBegin(cctx, dstBuffer, dstMaxSize); /* write header */
+ if (LZ4F_isError(errorCode)) return errorCode;
+ dstPtr += errorCode; /* header size */
+
+ for (blockNb=1; blockNb<nbBlocks; blockNb++)
+ {
+ errorCode = LZ4F_compress(cctx, dstPtr, dstBlockSize, srcPtr, blockSize, NULL);
+ if (LZ4F_isError(errorCode)) return errorCode;
+ srcPtr += blockSize;
+ dstPtr += errorCode;
+ }
+
+ /* last block */
+ blockSize = srcSize % blockSize;
+ errorCode = LZ4F_compress(cctx, dstPtr, dstBlockSize, srcPtr, blockSize, NULL);
+ if (LZ4F_isError(errorCode)) return errorCode;
+ dstPtr += errorCode;
+
+ errorCode = LZ4F_compressEnd(cctx, dstPtr, dstMaxSize, NULL); /* flush last block, and generate suffix */
+ if (LZ4F_isError(errorCode)) return errorCode;
+ dstPtr += errorCode;
+
+ errorCode = LZ4F_freeCompressionContext(cctx);
+ if (LZ4F_isError(errorCode)) return errorCode;
+
+ return (dstPtr - dstStart);
+}