LZ4 specification defines 2 byte offset length for 64 KB data.
But in case of ZRAM we compress data per page and in most of
architecture PAGE_SIZE is 4KB. So we can decide offset length based
on actual offset value. For this we can reserve 1 bit to decide offset
length (1 byte or 2 byte). 2 byte required only if ofsset is greater than 127,
else 1 byte is enough.

With this new implementation new offset value can be at MAX 32 KB.

Thus we can save more memory for compressed data.

results checked with new implementation:-
LZO
=======
orig_data_size: 78917632
compr_data_size: 15894668
mem_used_total: 17117184

LZ4
========
orig_data_size: 78917632
compr_data_size: 16310717
mem_used_total: 17592320

LZ4_DYN
=======
orig_data_size: 78917632
compr_data_size: 15520506
mem_used_total: 16748544

Signed-off-by: Maninder Singh <maninder...@samsung.com>
Signed-off-by: Vaneet Narang <v.nar...@samsung.com>
---
 crypto/lz4.c               |   64 ++++++++++++++++++++++++++++++++-
 drivers/block/zram/zcomp.c |    4 ++
 fs/pstore/platform.c       |    2 +-
 include/linux/lz4.h        |   15 ++++++--
 lib/decompress_unlz4.c     |    2 +-
 lib/lz4/lz4_compress.c     |   84 +++++++++++++++++++++++++++++++++++--------
 lib/lz4/lz4_decompress.c   |   56 ++++++++++++++++++++---------
 lib/lz4/lz4defs.h          |   11 ++++++
 8 files changed, 197 insertions(+), 41 deletions(-)

diff --git a/crypto/lz4.c b/crypto/lz4.c
index 2ce2660..f1a8a20 100644
--- a/crypto/lz4.c
+++ b/crypto/lz4.c
@@ -67,7 +67,20 @@ static int __lz4_compress_crypto(const u8 *src, unsigned int 
slen,
                                 u8 *dst, unsigned int *dlen, void *ctx)
 {
        int out_len = LZ4_compress_default(src, dst,
-               slen, *dlen, ctx);
+               slen, *dlen, ctx, false);
+
+       if (!out_len)
+               return -EINVAL;
+
+       *dlen = out_len;
+       return 0;
+}
+
+static int __lz4_compress_crypto_dynamic(const u8 *src, unsigned int slen,
+                                u8 *dst, unsigned int *dlen, void *ctx)
+{
+       int out_len = LZ4_compress_default(src, dst,
+               slen, *dlen, ctx, true);
 
        if (!out_len)
                return -EINVAL;
@@ -91,10 +104,30 @@ static int lz4_compress_crypto(struct crypto_tfm *tfm, 
const u8 *src,
        return __lz4_compress_crypto(src, slen, dst, dlen, ctx->lz4_comp_mem);
 }
 
+static int lz4_compress_crypto_dynamic(struct crypto_tfm *tfm, const u8 *src,
+                              unsigned int slen, u8 *dst, unsigned int *dlen)
+{
+       struct lz4_ctx *ctx = crypto_tfm_ctx(tfm);
+
+       return __lz4_compress_crypto_dynamic(src, slen, dst, dlen, 
ctx->lz4_comp_mem);
+}
+
 static int __lz4_decompress_crypto(const u8 *src, unsigned int slen,
                                   u8 *dst, unsigned int *dlen, void *ctx)
 {
-       int out_len = LZ4_decompress_safe(src, dst, slen, *dlen);
+       int out_len = LZ4_decompress_safe(src, dst, slen, *dlen, false);
+
+       if (out_len < 0)
+               return -EINVAL;
+
+       *dlen = out_len;
+       return 0;
+}
+
+static int __lz4_decompress_crypto_dynamic(const u8 *src, unsigned int slen,
+                                  u8 *dst, unsigned int *dlen, void *ctx)
+{
+       int out_len = LZ4_decompress_safe(src, dst, slen, *dlen, true);
 
        if (out_len < 0)
                return -EINVAL;
@@ -117,6 +150,13 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, 
const u8 *src,
        return __lz4_decompress_crypto(src, slen, dst, dlen, NULL);
 }
 
+static int lz4_decompress_crypto_dynamic(struct crypto_tfm *tfm, const u8 *src,
+                                unsigned int slen, u8 *dst,
+                                unsigned int *dlen)
+{
+       return __lz4_decompress_crypto_dynamic(src, slen, dst, dlen, NULL);
+}
+
 static struct crypto_alg alg_lz4 = {
        .cra_name               = "lz4",
        .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
@@ -130,6 +170,19 @@ static int lz4_decompress_crypto(struct crypto_tfm *tfm, 
const u8 *src,
        .coa_decompress         = lz4_decompress_crypto } }
 };
 
+static struct crypto_alg alg_lz4_dyn = {
+       .cra_name               = "lz4_dyn",
+       .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
+       .cra_ctxsize            = sizeof(struct lz4_ctx),
+       .cra_module             = THIS_MODULE,
+       .cra_list               = LIST_HEAD_INIT(alg_lz4_dyn.cra_list),
+       .cra_init               = lz4_init,
+       .cra_exit               = lz4_exit,
+       .cra_u                  = { .compress = {
+       .coa_compress           = lz4_compress_crypto_dynamic,
+       .coa_decompress         = lz4_decompress_crypto_dynamic } }
+};
+
 static struct scomp_alg scomp = {
        .alloc_ctx              = lz4_alloc_ctx,
        .free_ctx               = lz4_free_ctx,
@@ -150,9 +203,16 @@ static int __init lz4_mod_init(void)
        if (ret)
                return ret;
 
+       ret = crypto_register_alg(&alg_lz4_dyn);
+       if (ret) {
+               crypto_unregister_alg(&alg_lz4);
+               return ret;
+       }
+
        ret = crypto_register_scomp(&scomp);
        if (ret) {
                crypto_unregister_alg(&alg_lz4);
+               crypto_unregister_alg(&alg_lz4_dyn);
                return ret;
        }
 
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index 4ed0a78..5bc5aab 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -17,11 +17,15 @@
 #include <linux/crypto.h>
 
 #include "zcomp.h"
+#define KB     (1 << 10)
 
 static const char * const backends[] = {
        "lzo",
 #if IS_ENABLED(CONFIG_CRYPTO_LZ4)
        "lz4",
+#if (PAGE_SIZE < (32 * KB))
+       "lz4_dyn",
+#endif
 #endif
 #if IS_ENABLED(CONFIG_CRYPTO_LZ4HC)
        "lz4hc",
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 6910321..2b03449 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -342,7 +342,7 @@ static int compress_lz4(const void *in, void *out, size_t 
inlen, size_t outlen)
 {
        int ret;
 
-       ret = LZ4_compress_default(in, out, inlen, outlen, workspace);
+       ret = LZ4_compress_default(in, out, inlen, outlen, workspace, false);
        if (!ret) {
                pr_err("LZ4_compress_default error; compression failed!\n");
                return -EIO;
diff --git a/include/linux/lz4.h b/include/linux/lz4.h
index 394e3d9..08bb95d 100644
--- a/include/linux/lz4.h
+++ b/include/linux/lz4.h
@@ -181,6 +181,9 @@ static inline int LZ4_compressBound(size_t isize)
  *     which must be already allocated
  * @wrkmem: address of the working memory.
  *     This requires 'workmem' of LZ4_MEM_COMPRESS.
+ * @dynoffset: 1 or 0.
+ *  1 specifies dynamic offset. (1 byte or 2 byte based on offset value),
+ *  0 specifies normal offset.  (2 bytes for each offset value).
  *
  * Compresses 'sourceSize' bytes from buffer 'source'
  * into already allocated 'dest' buffer of size 'maxOutputSize'.
@@ -195,7 +198,7 @@ static inline int LZ4_compressBound(size_t isize)
  *     (necessarily <= maxOutputSize) or 0 if compression fails
  */
 int LZ4_compress_default(const char *source, char *dest, int inputSize,
-       int maxOutputSize, void *wrkmem);
+       int maxOutputSize, void *wrkmem, bool dynOffset);
 
 /**
  * LZ4_compress_fast() - As LZ4_compress_default providing an acceleration 
param
@@ -207,6 +210,9 @@ int LZ4_compress_default(const char *source, char *dest, 
int inputSize,
  * @acceleration: acceleration factor
  * @wrkmem: address of the working memory.
  *     This requires 'workmem' of LZ4_MEM_COMPRESS.
+ * @dynoffset: 1 or 0.
+ *  1 specifies dynamic offset. (1 byte or 2 byte based on offset value),
+ *  0 specifies normal offset.  (2 bytes for each offset value).
  *
  * Same as LZ4_compress_default(), but allows to select an "acceleration"
  * factor. The larger the acceleration value, the faster the algorithm,
@@ -219,7 +225,7 @@ int LZ4_compress_default(const char *source, char *dest, 
int inputSize,
  *     (necessarily <= maxOutputSize) or 0 if compression fails
  */
 int LZ4_compress_fast(const char *source, char *dest, int inputSize,
-       int maxOutputSize, int acceleration, void *wrkmem);
+       int maxOutputSize, int acceleration, void *wrkmem, bool dynOffset);
 
 /**
  * LZ4_compress_destSize() - Compress as much data as possible
@@ -277,6 +283,9 @@ int LZ4_compress_destSize(const char *source, char *dest, 
int *sourceSizePtr,
  *     which must be already allocated
  * @compressedSize: is the precise full size of the compressed block
  * @maxDecompressedSize: is the size of 'dest' buffer
+ * @dynoffset: 1 or 0.
+ *  1 specifies dynamic offset. (1 byte or 2 byte based on offset value),
+ *  0 specifies normal offset.  (2 bytes for each offset value).
  *
  * Decompresses data fom 'source' into 'dest'.
  * If the source stream is detected malformed, the function will
@@ -290,7 +299,7 @@ int LZ4_compress_destSize(const char *source, char *dest, 
int *sourceSizePtr,
  *     or a negative result in case of error
  */
 int LZ4_decompress_safe(const char *source, char *dest, int compressedSize,
-       int maxDecompressedSize);
+       int maxDecompressedSize, bool dynOffset);
 
 /**
  * LZ4_decompress_safe_partial() - Decompress a block of size 'compressedSize'
diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c
index 1b0baf3..8be2faa 100644
--- a/lib/decompress_unlz4.c
+++ b/lib/decompress_unlz4.c
@@ -158,7 +158,7 @@ STATIC inline int INIT unlz4(u8 *input, long in_len,
 #else
                dest_len = uncomp_chunksize;
 
-               ret = LZ4_decompress_safe(inp, outp, chunksize, dest_len);
+               ret = LZ4_decompress_safe(inp, outp, chunksize, dest_len, 
false);
                dest_len = ret;
 #endif
                if (ret < 0) {
diff --git a/lib/lz4/lz4_compress.c b/lib/lz4/lz4_compress.c
index cc7b6d4..185c358 100644
--- a/lib/lz4/lz4_compress.c
+++ b/lib/lz4/lz4_compress.c
@@ -183,7 +183,8 @@ static FORCE_INLINE int LZ4_compress_generic(
        const tableType_t tableType,
        const dict_directive dict,
        const dictIssue_directive dictIssue,
-       const U32 acceleration)
+       const U32 acceleration,
+       const Dynamic_Offset dynOffset)
 {
        const BYTE *ip = (const BYTE *) source;
        const BYTE *base;
@@ -199,6 +200,7 @@ static FORCE_INLINE int LZ4_compress_generic(
 
        BYTE *op = (BYTE *) dest;
        BYTE * const olimit = op + maxOutputSize;
+       int max_distance = dynOffset ? MAX_DISTANCE_DYN : MAX_DISTANCE;
 
        U32 forwardH;
        size_t refDelta = 0;
@@ -245,6 +247,7 @@ static FORCE_INLINE int LZ4_compress_generic(
        for ( ; ; ) {
                const BYTE *match;
                BYTE *token;
+               int curr_offset;
 
                /* Find a match */
                {
@@ -285,7 +288,7 @@ static FORCE_INLINE int LZ4_compress_generic(
                                        : 0)
                                || ((tableType == byU16)
                                        ? 0
-                                       : (match + MAX_DISTANCE < ip))
+                                       : (match + max_distance < ip))
                                || (LZ4_read32(match + refDelta)
                                        != LZ4_read32(ip)));
                }
@@ -328,8 +331,26 @@ static FORCE_INLINE int LZ4_compress_generic(
 
 _next_match:
                /* Encode Offset */
-               LZ4_writeLE16(op, (U16)(ip - match));
-               op += 2;
+               if (dynOffset) {
+                       curr_offset = (U16)(ip - match);
+
+                       /*
+                        * If Ofsset is greater than 127, we need 2 bytes
+                        * to store it. Otherwise 1 byte is enough.
+                        */
+                       if (curr_offset > 127) {
+                               curr_offset = (curr_offset << 1) | DYN_BIT;
+                               LZ4_writeLE16(op, (U16)curr_offset);
+                               op += 2;
+                       } else {
+                               curr_offset = curr_offset << 1;
+                               *op = (BYTE)curr_offset;
+                               op++;
+                       }
+               } else {
+                       LZ4_writeLE16(op, (U16)(ip - match));
+                       op += 2;
+               }
 
                /* Encode MatchLength */
                {
@@ -480,39 +501,70 @@ static int LZ4_compress_fast_extState(
                        return LZ4_compress_generic(ctx, source,
                                dest, inputSize, 0,
                                noLimit, byU16, noDict,
-                               noDictIssue, acceleration);
+                               noDictIssue, acceleration, NoDynOffset);
                else
                        return LZ4_compress_generic(ctx, source,
                                dest, inputSize, 0,
                                noLimit, tableType, noDict,
-                               noDictIssue, acceleration);
+                               noDictIssue, acceleration, NoDynOffset);
        } else {
                if (inputSize < LZ4_64Klimit)
                        return LZ4_compress_generic(ctx, source,
                                dest, inputSize,
                                maxOutputSize, limitedOutput, byU16, noDict,
-                               noDictIssue, acceleration);
+                               noDictIssue, acceleration, NoDynOffset);
                else
                        return LZ4_compress_generic(ctx, source,
                                dest, inputSize,
                                maxOutputSize, limitedOutput, tableType, noDict,
-                               noDictIssue, acceleration);
+                               noDictIssue, acceleration, NoDynOffset);
        }
 }
 
+static int LZ4_compress_fast_extState_dynamic(
+       void *state,
+       const char *source,
+       char *dest,
+       int inputSize,
+       int maxOutputSize,
+       int acceleration)
+{
+       LZ4_stream_t_internal *ctx = &((LZ4_stream_t 
*)state)->internal_donotuse;
+
+       LZ4_resetStream((LZ4_stream_t *)state);
+
+       if (acceleration < 1)
+               acceleration = LZ4_ACCELERATION_DEFAULT;
+
+       if (maxOutputSize >= LZ4_COMPRESSBOUND(inputSize))
+               return LZ4_compress_generic(ctx, source,
+                       dest, inputSize, 0,
+                       noLimit, byU16, noDict,
+                       noDictIssue, acceleration, DynOffset);
+       else
+               return LZ4_compress_generic(ctx, source,
+                       dest, inputSize,
+                       maxOutputSize, limitedOutput, byU16, noDict,
+                       noDictIssue, acceleration, DynOffset);
+}
+
 int LZ4_compress_fast(const char *source, char *dest, int inputSize,
-       int maxOutputSize, int acceleration, void *wrkmem)
+       int maxOutputSize, int acceleration, void *wrkmem, bool dynOffset)
 {
-       return LZ4_compress_fast_extState(wrkmem, source, dest, inputSize,
+       if (!dynOffset)
+               return LZ4_compress_fast_extState(wrkmem, source, dest, 
inputSize,
+                       maxOutputSize, acceleration);
+
+       return LZ4_compress_fast_extState_dynamic(wrkmem, source, dest, 
inputSize,
                maxOutputSize, acceleration);
 }
 EXPORT_SYMBOL(LZ4_compress_fast);
 
 int LZ4_compress_default(const char *source, char *dest, int inputSize,
-       int maxOutputSize, void *wrkmem)
+       int maxOutputSize, void *wrkmem, bool dynOffset)
 {
        return LZ4_compress_fast(source, dest, inputSize,
-               maxOutputSize, LZ4_ACCELERATION_DEFAULT, wrkmem);
+               maxOutputSize, LZ4_ACCELERATION_DEFAULT, wrkmem, dynOffset);
 }
 EXPORT_SYMBOL(LZ4_compress_default);
 
@@ -900,12 +952,12 @@ int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, 
const char *source,
                        result = LZ4_compress_generic(
                                streamPtr, source, dest, inputSize,
                                maxOutputSize, limitedOutput, byU32,
-                               withPrefix64k, dictSmall, acceleration);
+                               withPrefix64k, dictSmall, acceleration, 
NoDynOffset);
                } else {
                        result = LZ4_compress_generic(
                                streamPtr, source, dest, inputSize,
                                maxOutputSize, limitedOutput, byU32,
-                               withPrefix64k, noDictIssue, acceleration);
+                               withPrefix64k, noDictIssue, acceleration, 
NoDynOffset);
                }
                streamPtr->dictSize += (U32)inputSize;
                streamPtr->currentOffset += (U32)inputSize;
@@ -921,12 +973,12 @@ int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, 
const char *source,
                        result = LZ4_compress_generic(
                                streamPtr, source, dest, inputSize,
                                maxOutputSize, limitedOutput, byU32,
-                               usingExtDict, dictSmall, acceleration);
+                               usingExtDict, dictSmall, acceleration, 
NoDynOffset);
                } else {
                        result = LZ4_compress_generic(
                                streamPtr, source, dest, inputSize,
                                maxOutputSize, limitedOutput, byU32,
-                               usingExtDict, noDictIssue, acceleration);
+                               usingExtDict, noDictIssue, acceleration, 
NoDynOffset);
                }
                streamPtr->dictionary = (const BYTE *)source;
                streamPtr->dictSize = (U32)inputSize;
diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c
index 141734d..337a828 100644
--- a/lib/lz4/lz4_decompress.c
+++ b/lib/lz4/lz4_decompress.c
@@ -71,7 +71,9 @@ static FORCE_INLINE int LZ4_decompress_generic(
         /* only if dict == usingExtDict */
         const BYTE * const dictStart,
         /* note : = 0 if noDict */
-        const size_t dictSize
+        const size_t dictSize,
+        /* offset == 1; dynamic offset */
+        const Dynamic_Offset dynOffset
         )
 {
        /* Local Variables */
@@ -141,8 +143,8 @@ static FORCE_INLINE int LZ4_decompress_generic(
                /* copy literals */
                cpy = op + length;
                if (((endOnInput) && ((cpy > (partialDecoding ? oexit : oend - 
MFLIMIT))
-                       || (ip + length > iend - (2 + 1 + LASTLITERALS))))
-                       || ((!endOnInput) && (cpy > oend - WILDCOPYLENGTH))) {
+                       || (ip + length > iend - (2 + LASTLITERALS))))
+                       || ((!endOnInput) && (cpy > oend - WILDCOPYLENGTH - 
1))) {
                        if (partialDecoding) {
                                if (cpy > oend) {
                                        /*
@@ -188,13 +190,31 @@ static FORCE_INLINE int LZ4_decompress_generic(
                        break;
                }
 
-               LZ4_wildCopy(op, ip, cpy);
+               if (dynOffset && length < 4)
+                       LZ4_copy4(op, ip);
+               else
+                       LZ4_wildCopy(op, ip, cpy);
+
                ip += length;
                op = cpy;
 
                /* get offset */
-               offset = LZ4_readLE16(ip);
-               ip += 2;
+               if (dynOffset) {
+                       /*
+                        * Check if DYN_BIT is set, means 2 Byte Offset,
+                        * else 1 Byte Offset.
+                        */
+                       if (*ip & DYN_BIT) {
+                               offset = LZ4_readLE16(ip) >> 1;
+                               ip += 2;
+                       } else {
+                               offset = *ip >> 1;
+                               ip += 1;
+                       }
+               } else {
+                       offset = LZ4_readLE16(ip);
+                       ip += 2;
+               }
                match = op - offset;
 
                if ((checkOffset) && (unlikely(match < lowLimit))) {
@@ -335,11 +355,11 @@ static FORCE_INLINE int LZ4_decompress_generic(
 }
 
 int LZ4_decompress_safe(const char *source, char *dest,
-       int compressedSize, int maxDecompressedSize)
+       int compressedSize, int maxDecompressedSize, bool dynOffset)
 {
        return LZ4_decompress_generic(source, dest, compressedSize,
                maxDecompressedSize, endOnInputSize, full, 0,
-               noDict, (BYTE *)dest, NULL, 0);
+               noDict, (BYTE *)dest, NULL, 0, dynOffset);
 }
 
 int LZ4_decompress_safe_partial(const char *source, char *dest,
@@ -347,14 +367,14 @@ int LZ4_decompress_safe_partial(const char *source, char 
*dest,
 {
        return LZ4_decompress_generic(source, dest, compressedSize,
                maxDecompressedSize, endOnInputSize, partial,
-               targetOutputSize, noDict, (BYTE *)dest, NULL, 0);
+               targetOutputSize, noDict, (BYTE *)dest, NULL, 0, NoDynOffset);
 }
 
 int LZ4_decompress_fast(const char *source, char *dest, int originalSize)
 {
        return LZ4_decompress_generic(source, dest, 0, originalSize,
                endOnOutputSize, full, 0, withPrefix64k,
-               (BYTE *)(dest - 64 * KB), NULL, 64 * KB);
+               (BYTE *)(dest - 64 * KB), NULL, 64 * KB, NoDynOffset);
 }
 
 int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode,
@@ -392,7 +412,7 @@ int LZ4_decompress_safe_continue(LZ4_streamDecode_t 
*LZ4_streamDecode,
                        endOnInputSize, full, 0,
                        usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize,
                        lz4sd->externalDict,
-                       lz4sd->extDictSize);
+                       lz4sd->extDictSize, NoDynOffset);
 
                if (result <= 0)
                        return result;
@@ -406,7 +426,7 @@ int LZ4_decompress_safe_continue(LZ4_streamDecode_t 
*LZ4_streamDecode,
                        compressedSize, maxOutputSize,
                        endOnInputSize, full, 0,
                        usingExtDict, (BYTE *)dest,
-                       lz4sd->externalDict, lz4sd->extDictSize);
+                       lz4sd->externalDict, lz4sd->extDictSize, NoDynOffset);
                if (result <= 0)
                        return result;
                lz4sd->prefixSize = result;
@@ -427,7 +447,7 @@ int LZ4_decompress_fast_continue(LZ4_streamDecode_t 
*LZ4_streamDecode,
                        endOnOutputSize, full, 0,
                        usingExtDict,
                        lz4sd->prefixEnd - lz4sd->prefixSize,
-                       lz4sd->externalDict, lz4sd->extDictSize);
+                       lz4sd->externalDict, lz4sd->extDictSize, NoDynOffset);
 
                if (result <= 0)
                        return result;
@@ -440,7 +460,7 @@ int LZ4_decompress_fast_continue(LZ4_streamDecode_t 
*LZ4_streamDecode,
                result = LZ4_decompress_generic(source, dest, 0, originalSize,
                        endOnOutputSize, full, 0,
                        usingExtDict, (BYTE *)dest,
-                       lz4sd->externalDict, lz4sd->extDictSize);
+                       lz4sd->externalDict, lz4sd->extDictSize, NoDynOffset);
                if (result <= 0)
                        return result;
                lz4sd->prefixSize = originalSize;
@@ -463,19 +483,19 @@ static FORCE_INLINE int 
LZ4_decompress_usingDict_generic(const char *source,
        if (dictSize == 0)
                return LZ4_decompress_generic(source, dest,
                        compressedSize, maxOutputSize, safe, full, 0,
-                       noDict, (BYTE *)dest, NULL, 0);
+                       noDict, (BYTE *)dest, NULL, 0, NoDynOffset);
        if (dictStart + dictSize == dest) {
                if (dictSize >= (int)(64 * KB - 1))
                        return LZ4_decompress_generic(source, dest,
                                compressedSize, maxOutputSize, safe, full, 0,
-                               withPrefix64k, (BYTE *)dest - 64 * KB, NULL, 0);
+                               withPrefix64k, (BYTE *)dest - 64 * KB, NULL, 0, 
NoDynOffset);
                return LZ4_decompress_generic(source, dest, compressedSize,
                        maxOutputSize, safe, full, 0, noDict,
-                       (BYTE *)dest - dictSize, NULL, 0);
+                       (BYTE *)dest - dictSize, NULL, 0, NoDynOffset);
        }
        return LZ4_decompress_generic(source, dest, compressedSize,
                maxOutputSize, safe, full, 0, usingExtDict,
-               (BYTE *)dest, (const BYTE *)dictStart, dictSize);
+               (BYTE *)dest, (const BYTE *)dictStart, dictSize, NoDynOffset);
 }
 
 int LZ4_decompress_safe_usingDict(const char *source, char *dest,
diff --git a/lib/lz4/lz4defs.h b/lib/lz4/lz4defs.h
index 00a0b58..9451a73 100644
--- a/lib/lz4/lz4defs.h
+++ b/lib/lz4/lz4defs.h
@@ -75,6 +75,7 @@
 #define WILDCOPYLENGTH 8
 #define LASTLITERALS 5
 #define MFLIMIT (WILDCOPYLENGTH + MINMATCH)
+#define DYN_BIT 0x1
 
 /* Increase this value ==> compression run slower on incompressible data */
 #define LZ4_SKIPTRIGGER 6
@@ -87,6 +88,7 @@
 
 #define MAXD_LOG 16
 #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
+#define MAX_DISTANCE_DYN ((1 << (MAXD_LOG - 1)) - 1)
 #define STEPSIZE sizeof(size_t)
 
 #define ML_BITS        4
@@ -147,6 +149,13 @@ static FORCE_INLINE void LZ4_copy8(void *dst, const void 
*src)
 #endif
 }
 
+static FORCE_INLINE void LZ4_copy4(void *dst, const void *src)
+{
+       U32 a = get_unaligned((const U32 *)src);
+
+       put_unaligned(a, (U32 *)dst);
+}
+
 /*
  * customized variant of memcpy,
  * which can overwrite up to 7 bytes beyond dstEnd
@@ -224,4 +233,6 @@ static FORCE_INLINE unsigned int LZ4_count(
 typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } 
endCondition_directive;
 typedef enum { full = 0, partial = 1 } earlyEnd_directive;
 
+typedef enum { NoDynOffset = 0, DynOffset = 1 } Dynamic_Offset;
+
 #endif
-- 
1.7.1

Reply via email to