Rizin
unix-like reverse engineering framework and cli tools
lz4hc.c File Reference
#include "lz4hc.h"

Go to the source code of this file.

Classes

struct  LZ4HC_optimal_t
 
struct  LZ4HC_match_t
 

Macros

#define LZ4HC_HEAPMODE   1
 
#define LZ4_HC_STATIC_LINKING_ONLY
 
#define LZ4_COMMONDEFS_ONLY
 
#define OPTIMAL_ML   (int)((ML_MASK-1)+MINMATCH)
 
#define LZ4_OPT_NUM   (1<<12)
 
#define MIN(a, b)   ( (a) < (b) ? (a) : (b) )
 
#define MAX(a, b)   ( (a) > (b) ? (a) : (b) )
 
#define HASH_FUNCTION(i)   (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))
 
#define DELTANEXTMAXD(p)   chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */
 
#define DELTANEXTU16(table, pos)   table[(U16)(pos)] /* faster */
 
#define UPDATABLE(ip, op, anchor)   &ip, &op, &anchor
 
#define LZ4HC_rotl32(x, r)   ((x << r) | (x >> (32 - r)))
 
#define ip   (*_ip)
 
#define op   (*_op)
 
#define anchor   (*_anchor)
 
#define TRAILING_LITERALS   3
 

Enumerations

enum  dictCtx_directive { noDictCtx , usingDictCtxHc }
 
enum  repeat_state_e { rep_untested , rep_not , rep_confirmed }
 
enum  HCfavor_e { favorCompressionRatio =0 , favorDecompressionSpeed }
 

Functions

static U32 LZ4HC_hashPtr (const void *ptr)
 
static void LZ4HC_clearTables (LZ4HC_CCtx_internal *hc4)
 
static void LZ4HC_init_internal (LZ4HC_CCtx_internal *hc4, const BYTE *start)
 
LZ4_FORCE_INLINE void LZ4HC_Insert (LZ4HC_CCtx_internal *hc4, const BYTE *ip)
 
LZ4_FORCE_INLINE int LZ4HC_countBack (const BYTE *const ip, const BYTE *const match, const BYTE *const iMin, const BYTE *const mMin)
 
static U32 LZ4HC_rotatePattern (size_t const rotate, U32 const pattern)
 
static unsigned LZ4HC_countPattern (const BYTE *ip, const BYTE *const iEnd, U32 const pattern32)
 
static unsigned LZ4HC_reverseCountPattern (const BYTE *ip, const BYTE *const iLow, U32 pattern)
 
static int LZ4HC_protectDictEnd (U32 const dictLimit, U32 const matchIndex)
 
LZ4_FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (LZ4HC_CCtx_internal *hc4, const BYTE *const ip, const BYTE *const iLowLimit, const BYTE *const iHighLimit, int longest, const BYTE **matchpos, const BYTE **startpos, const int maxNbAttempts, const int patternAnalysis, const int chainSwap, const dictCtx_directive dict, const HCfavor_e favorDecSpeed)
 
LZ4_FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_CCtx_internal *const hc4, const BYTE *const ip, const BYTE *const iLimit, const BYTE **matchpos, const int maxNbAttempts, const int patternAnalysis, const dictCtx_directive dict)
 
LZ4_FORCE_INLINE int LZ4HC_encodeSequence (const BYTE **_ip, BYTE **_op, const BYTE **_anchor, int matchLength, const BYTE *const match, limitedOutput_directive limit, BYTE *oend)
 
LZ4_FORCE_INLINE int LZ4HC_compress_hashChain (LZ4HC_CCtx_internal *const ctx, const char *const source, char *const dest, int *srcSizePtr, int const maxOutputSize, int maxNbAttempts, const limitedOutput_directive limit, const dictCtx_directive dict)
 
static int LZ4HC_compress_optimal (LZ4HC_CCtx_internal *ctx, const char *const source, char *dst, int *srcSizePtr, int dstCapacity, int const nbSearches, size_t sufficient_len, const limitedOutput_directive limit, int const fullUpdate, const dictCtx_directive dict, const HCfavor_e favorDecSpeed)
 
LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal (LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, const limitedOutput_directive limit, const dictCtx_directive dict)
 
static void LZ4HC_setExternalDict (LZ4HC_CCtx_internal *ctxPtr, const BYTE *newBlock)
 
static int LZ4HC_compress_generic_noDictCtx (LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
 
static int LZ4HC_compress_generic_dictCtx (LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
 
static int LZ4HC_compress_generic (LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
 
int LZ4_sizeofStateHC (void)
 
static size_t LZ4_streamHC_t_alignment (void)
 
int LZ4_compress_HC_extStateHC_fastReset (void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
 
int LZ4_compress_HC_extStateHC (void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
 
int LZ4_compress_HC (const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
 
int LZ4_compress_HC_destSize (void *state, const char *source, char *dest, int *sourceSizePtr, int targetDestSize, int cLevel)
 
LZ4_streamHC_tLZ4_createStreamHC (void)
 
int LZ4_freeStreamHC (LZ4_streamHC_t *LZ4_streamHCPtr)
 
LZ4_streamHC_tLZ4_initStreamHC (void *buffer, size_t size)
 
void LZ4_resetStreamHC (LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
 
void LZ4_resetStreamHC_fast (LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
 
void LZ4_setCompressionLevel (LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
 
void LZ4_favorDecompressionSpeed (LZ4_streamHC_t *LZ4_streamHCPtr, int favor)
 
int LZ4_loadDictHC (LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
 
void LZ4_attach_HC_dictionary (LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream)
 
static int LZ4_compressHC_continue_generic (LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int dstCapacity, limitedOutput_directive limit)
 
int LZ4_compress_HC_continue (LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
 
int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int targetDestSize)
 
int LZ4_saveDictHC (LZ4_streamHC_t *LZ4_streamHCPtr, char *safeBuffer, int dictSize)
 
int LZ4_compressHC (const char *src, char *dst, int srcSize)
 
int LZ4_compressHC_limitedOutput (const char *src, char *dst, int srcSize, int maxDstSize)
 
int LZ4_compressHC2 (const char *src, char *dst, int srcSize, int cLevel)
 
int LZ4_compressHC2_limitedOutput (const char *src, char *dst, int srcSize, int maxDstSize, int cLevel)
 
int LZ4_compressHC_withStateHC (void *state, const char *src, char *dst, int srcSize)
 
int LZ4_compressHC_limitedOutput_withStateHC (void *state, const char *src, char *dst, int srcSize, int maxDstSize)
 
int LZ4_compressHC2_withStateHC (void *state, const char *src, char *dst, int srcSize, int cLevel)
 
int LZ4_compressHC2_limitedOutput_withStateHC (void *state, const char *src, char *dst, int srcSize, int maxDstSize, int cLevel)
 
int LZ4_compressHC_continue (LZ4_streamHC_t *ctx, const char *src, char *dst, int srcSize)
 
int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t *ctx, const char *src, char *dst, int srcSize, int maxDstSize)
 
int LZ4_sizeofStreamStateHC (void)
 
int LZ4_resetStreamStateHC (void *state, char *inputBuffer)
 
void * LZ4_createHC (const char *inputBuffer)
 
int LZ4_freeHC (void *LZ4HC_Data)
 
int LZ4_compressHC2_continue (void *LZ4HC_Data, const char *src, char *dst, int srcSize, int cLevel)
 
int LZ4_compressHC2_limitedOutput_continue (void *LZ4HC_Data, const char *src, char *dst, int srcSize, int dstCapacity, int cLevel)
 
char * LZ4_slideInputBufferHC (void *LZ4HC_Data)
 
LZ4_FORCE_INLINE int LZ4HC_literalsPrice (int const litlen)
 
LZ4_FORCE_INLINE int LZ4HC_sequencePrice (int litlen, int mlen)
 
LZ4_FORCE_INLINE LZ4HC_match_t LZ4HC_FindLongerMatch (LZ4HC_CCtx_internal *const ctx, const BYTE *ip, const BYTE *const iHighLimit, int minLen, int nbSearches, const dictCtx_directive dict, const HCfavor_e favorDecSpeed)
 

Macro Definition Documentation

◆ anchor

#define anchor   (*_anchor)

◆ DELTANEXTMAXD

#define DELTANEXTMAXD (   p)    chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */

Definition at line 83 of file lz4hc.c.

◆ DELTANEXTU16

#define DELTANEXTU16 (   table,
  pos 
)    table[(U16)(pos)] /* faster */

Definition at line 84 of file lz4hc.c.

◆ HASH_FUNCTION

#define HASH_FUNCTION (   i)    (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))

Definition at line 82 of file lz4hc.c.

◆ ip

#define ip   (*_ip)

◆ LZ4_COMMONDEFS_ONLY

#define LZ4_COMMONDEFS_ONLY

Definition at line 64 of file lz4hc.c.

◆ LZ4_HC_STATIC_LINKING_ONLY

#define LZ4_HC_STATIC_LINKING_ONLY

Definition at line 52 of file lz4hc.c.

◆ LZ4_OPT_NUM

#define LZ4_OPT_NUM   (1<<12)

Definition at line 76 of file lz4hc.c.

◆ LZ4HC_HEAPMODE

#define LZ4HC_HEAPMODE   1

HEAPMODE : Select how default compression function will allocate workplace memory, in stack (0:fastest), or in heap (1:requires malloc()). Since workplace is rather large, heap mode is recommended.

Definition at line 47 of file lz4hc.c.

◆ LZ4HC_rotl32

#define LZ4HC_rotl32 (   x,
  r 
)    ((x << r) | (x >> (32 - r)))

Definition at line 158 of file lz4hc.c.

◆ MAX

#define MAX (   a,
  b 
)    ( (a) > (b) ? (a) : (b) )

Definition at line 81 of file lz4hc.c.

◆ MIN

#define MIN (   a,
  b 
)    ( (a) < (b) ? (a) : (b) )

Definition at line 80 of file lz4hc.c.

◆ op

#define op   (*_op)

◆ OPTIMAL_ML

#define OPTIMAL_ML   (int)((ML_MASK-1)+MINMATCH)

Definition at line 75 of file lz4hc.c.

◆ TRAILING_LITERALS

#define TRAILING_LITERALS   3

◆ UPDATABLE

#define UPDATABLE (   ip,
  op,
  anchor 
)    &ip, &op, &anchor

Definition at line 86 of file lz4hc.c.

Enumeration Type Documentation

◆ dictCtx_directive

Enumerator
noDictCtx 
usingDictCtxHc 

Definition at line 71 of file lz4hc.c.

dictCtx_directive
Definition: lz4hc.c:71
@ noDictCtx
Definition: lz4hc.c:71
@ usingDictCtxHc
Definition: lz4hc.c:71

◆ HCfavor_e

enum HCfavor_e
Enumerator
favorCompressionRatio 
favorDecompressionSpeed 

Definition at line 233 of file lz4hc.c.

HCfavor_e
Definition: lz4hc.c:233
@ favorDecompressionSpeed
Definition: lz4hc.c:233
@ favorCompressionRatio
Definition: lz4hc.c:233

◆ repeat_state_e

Enumerator
rep_untested 
rep_not 
rep_confirmed 

Definition at line 232 of file lz4hc.c.

repeat_state_e
Definition: lz4hc.c:232
@ rep_untested
Definition: lz4hc.c:232
@ rep_confirmed
Definition: lz4hc.c:232
@ rep_not
Definition: lz4hc.c:232

Function Documentation

◆ LZ4_attach_HC_dictionary()

void LZ4_attach_HC_dictionary ( LZ4_streamHC_t working_stream,
const LZ4_streamHC_t dictionary_stream 
)

Definition at line 1077 of file lz4hc.c.

1077  {
1078  working_stream->internal_donotuse.dictCtx = dictionary_stream != NULL ? &(dictionary_stream->internal_donotuse) : NULL;
1079 }
#define NULL
Definition: cris-opc.c:27
const LZ4HC_CCtx_internal * dictCtx
Definition: lz4hc.h:216
LZ4HC_CCtx_internal internal_donotuse
Definition: lz4hc.h:227

References LZ4HC_CCtx_internal::dictCtx, LZ4_streamHC_u::internal_donotuse, and NULL.

Referenced by FUZ_test(), LZ4_compressResetStreamHC(), LZ4F_initStream(), and state_attachDictHCRoundTrip().

◆ LZ4_compress_HC()

int LZ4_compress_HC ( const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  compressionLevel 
)

LZ4_compress_HC() : Compress data from src into dst, using the powerful but slower "HC" algorithm. dst must be already allocated. Compression is guaranteed to succeed if dstCapacity >= LZ4_compressBound(srcSize) (see "lz4.h") Max supported srcSize value is LZ4_MAX_INPUT_SIZE (see "lz4.h") compressionLevel : any value between 1 and LZ4HC_CLEVEL_MAX will work. Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.

Returns
: the number of bytes written into 'dst' or 0 if compression fails.

Definition at line 954 of file lz4hc.c.

955 {
956 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
957  LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)ALLOC(sizeof(LZ4_streamHC_t));
958 #else
960  LZ4_streamHC_t* const statePtr = &state;
961 #endif
962  int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel);
963 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
964  FREEMEM(statePtr);
965 #endif
966  return cSize;
967 }
lzma_index * src
Definition: index.h:567
#define ALLOC(s)
Definition: lz4.c:202
#define FREEMEM(p)
Definition: lz4.c:204
char int srcSize
Definition: lz4.h:697
char * dst
Definition: lz4.h:724
int LZ4_compress_HC_extStateHC(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:947
char int int compressionLevel
Definition: lz4hc.h:258
Definition: dis.h:43

References ALLOC, compressionLevel, dst, FREEMEM, LZ4_compress_HC_extStateHC(), src, and srcSize.

Referenced by FUZ_test(), LLVMFuzzerTestOneInput(), local_LZ4_compress_HC(), LZ4_compressBlockNoStreamHC(), LZ4_compressHC(), LZ4_compressHC2(), LZ4_compressHC2_limitedOutput(), LZ4_compressHC_limitedOutput(), LZ4IO_compressFilename_Legacy(), and roundTripTest().

◆ LZ4_compress_HC_continue()

int LZ4_compress_HC_continue ( LZ4_streamHC_t LZ4_streamHCPtr,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity 
)

Definition at line 1138 of file lz4hc.c.

1139 {
1140  if (dstCapacity < LZ4_compressBound(srcSize))
1141  return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, limitedOutput);
1142  else
1143  return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, notLimited);
1144 }
int LZ4_compressBound(int isize)
Definition: lz4.c:674
@ limitedOutput
Definition: lz4.c:302
@ notLimited
Definition: lz4.c:301
static int LZ4_compressHC_continue_generic(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int dstCapacity, limitedOutput_directive limit)
Definition: lz4hc.c:1102

References dst, limitedOutput, LZ4_compressBound(), LZ4_compressHC_continue_generic(), notLimited, src, and srcSize.

Referenced by FUZ_test(), FUZ_unitTests(), local_LZ4_compress_HC_continue(), LZ4_compressBlockStreamHC(), LZ4_compressHC_continue(), LZ4_compressHC_limitedOutput_continue(), LZ4F_compressBlockHC(), LZ4F_compressBlockHC_continue(), state_extDictHCRoundTrip(), state_prefixHCRoundTrip(), and test_compress().

◆ LZ4_compress_HC_continue_destSize()

int LZ4_compress_HC_continue_destSize ( LZ4_streamHC_t LZ4_streamHCPtr,
const char *  src,
char *  dst,
int srcSizePtr,
int  targetDstSize 
)

LZ4_compress_HC_continue_destSize() : v1.9.0+ Similar to LZ4_compress_HC_continue(), but will read as much data as possible from src to fit into targetDstSize budget. Result is provided into 2 parts :

Returns
: the number of bytes written into 'dst' (necessarily <= targetDstSize) or 0 if compression fails. srcSizePtr : on success, *srcSizePtr will be updated to indicate how much bytes were read from src. Note that this function may not consume the entire input.

Definition at line 1146 of file lz4hc.c.

1147 {
1148  return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, srcSizePtr, targetDestSize, fillOutput);
1149 }
@ fillOutput
Definition: lz4.c:303

References dst, fillOutput, LZ4_compressHC_continue_generic(), and src.

Referenced by FUZ_test().

◆ LZ4_compress_HC_destSize()

int LZ4_compress_HC_destSize ( void *  stateHC,
const char *  src,
char *  dst,
int srcSizePtr,
int  targetDstSize,
int  compressionLevel 
)

LZ4_compress_HC_destSize() : v1.9.0+ Will compress as much data as possible from src to fit into targetDstSize budget. Result is provided in 2 parts :

Returns
: the number of bytes written into 'dst' (necessarily <= targetDstSize) or 0 if compression fails. srcSizePtr : on success, *srcSizePtr is updated to indicate how much bytes were read from src

Definition at line 970 of file lz4hc.c.

971 {
972  LZ4_streamHC_t* const ctx = LZ4_initStreamHC(state, sizeof(*ctx));
973  if (ctx==NULL) return 0; /* init failure */
974  LZ4HC_init_internal(&ctx->internal_donotuse, (const BYTE*) source);
975  LZ4_setCompressionLevel(ctx, cLevel);
976  return LZ4HC_compress_generic(&ctx->internal_donotuse, source, dest, sourceSizePtr, targetDestSize, cLevel, fillOutput);
977 }
unsigned char BYTE
Definition: lz4.c:286
const char * source
Definition: lz4.h:699
char * dest
Definition: lz4.h:697
LZ4_streamHC_t * LZ4_initStreamHC(void *buffer, size_t size)
Definition: lz4hc.c:1003
static void LZ4HC_init_internal(LZ4HC_CCtx_internal *hc4, const BYTE *start)
Definition: lz4hc.c:100
static int LZ4HC_compress_generic(LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
Definition: lz4hc.c:903
void LZ4_setCompressionLevel(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1041

References dest, fillOutput, LZ4_initStreamHC(), LZ4_setCompressionLevel(), LZ4HC_compress_generic(), LZ4HC_init_internal(), NULL, and source.

Referenced by FUZ_test(), FUZ_unitTests(), and LLVMFuzzerTestOneInput().

◆ LZ4_compress_HC_extStateHC()

int LZ4_compress_HC_extStateHC ( void *  state,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  compressionLevel 
)

Definition at line 947 of file lz4hc.c.

948 {
949  LZ4_streamHC_t* const ctx = LZ4_initStreamHC(state, sizeof(*ctx));
950  if (ctx==NULL) return 0; /* init failure */
952 }
int LZ4_compress_HC_extStateHC_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:935

References compressionLevel, dst, LZ4_compress_HC_extStateHC_fastReset(), LZ4_initStreamHC(), NULL, src, and srcSize.

Referenced by FUZ_test(), local_LZ4_compress_HC_extStateHC(), LZ4_compress_HC(), LZ4_compressHC2_limitedOutput_withStateHC(), LZ4_compressHC2_withStateHC(), LZ4_compressHC_limitedOutput_withStateHC(), and LZ4_compressHC_withStateHC().

◆ LZ4_compress_HC_extStateHC_fastReset()

int LZ4_compress_HC_extStateHC_fastReset ( void *  state,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  compressionLevel 
)

Definition at line 935 of file lz4hc.c.

936 {
937  LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
938  if (!LZ4_isAligned(state, LZ4_streamHC_t_alignment())) return 0;
940  LZ4HC_init_internal (ctx, (const BYTE*)src);
941  if (dstCapacity < LZ4_compressBound(srcSize))
943  else
945 }
static int LZ4_isAligned(const void *ptr, size_t alignment)
Definition: lz4.c:264
static size_t LZ4_streamHC_t_alignment(void)
Definition: lz4hc.c:923
void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1027

References compressionLevel, dst, limitedOutput, LZ4_compressBound(), LZ4_isAligned(), LZ4_resetStreamHC_fast(), LZ4_streamHC_t_alignment(), LZ4HC_compress_generic(), LZ4HC_init_internal(), notLimited, src, and srcSize.

Referenced by FUZ_test(), LZ4_compress_HC_extStateHC(), and LZ4F_compressBlockHC().

◆ LZ4_compressHC()

int LZ4_compressHC ( const char *  src,
char *  dst,
int  srcSize 
)

Definition at line 1189 of file lz4hc.c.

int LZ4_compress_HC(const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:954

References dst, LZ4_compress_HC(), LZ4_compressBound(), src, and srcSize.

◆ LZ4_compressHC2()

int LZ4_compressHC2 ( const char *  src,
char *  dst,
int  srcSize,
int  cLevel 
)

Definition at line 1191 of file lz4hc.c.

1191 { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); }

References dst, LZ4_compress_HC(), LZ4_compressBound(), src, and srcSize.

◆ LZ4_compressHC2_continue()

int LZ4_compressHC2_continue ( void *  LZ4HC_Data,
const char *  src,
char *  dst,
int  srcSize,
int  cLevel 
)

Definition at line 1229 of file lz4hc.c.

1230 {
1231  return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, 0, cLevel, notLimited);
1232 }

References dst, LZ4HC_compress_generic(), notLimited, src, and srcSize.

◆ LZ4_compressHC2_limitedOutput()

int LZ4_compressHC2_limitedOutput ( const char *  src,
char *  dst,
int  srcSize,
int  maxDstSize,
int  cLevel 
)

Definition at line 1192 of file lz4hc.c.

1192 { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); }
char int int maxDstSize
Definition: lz4.h:724

References dst, LZ4_compress_HC(), maxDstSize, src, and srcSize.

◆ LZ4_compressHC2_limitedOutput_continue()

int LZ4_compressHC2_limitedOutput_continue ( void *  LZ4HC_Data,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  cLevel 
)

Definition at line 1234 of file lz4hc.c.

1235 {
1236  return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, dstCapacity, cLevel, limitedOutput);
1237 }

References dst, limitedOutput, LZ4HC_compress_generic(), src, and srcSize.

◆ LZ4_compressHC2_limitedOutput_withStateHC()

int LZ4_compressHC2_limitedOutput_withStateHC ( void *  state,
const char *  src,
char *  dst,
int  srcSize,
int  maxDstSize,
int  cLevel 
)

Definition at line 1196 of file lz4hc.c.

1196 { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, maxDstSize, cLevel); }

References dst, LZ4_compress_HC_extStateHC(), maxDstSize, src, and srcSize.

◆ LZ4_compressHC2_withStateHC()

int LZ4_compressHC2_withStateHC ( void *  state,
const char *  src,
char *  dst,
int  srcSize,
int  cLevel 
)

Definition at line 1195 of file lz4hc.c.

References dst, LZ4_compress_HC_extStateHC(), LZ4_compressBound(), src, and srcSize.

◆ LZ4_compressHC_continue()

int LZ4_compressHC_continue ( LZ4_streamHC_t ctx,
const char *  src,
char *  dst,
int  srcSize 
)

Definition at line 1197 of file lz4hc.c.

int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
Definition: lz4hc.c:1138

References dst, LZ4_compress_HC_continue(), LZ4_compressBound(), src, and srcSize.

◆ LZ4_compressHC_continue_generic()

static int LZ4_compressHC_continue_generic ( LZ4_streamHC_t LZ4_streamHCPtr,
const char *  src,
char *  dst,
int srcSizePtr,
int  dstCapacity,
limitedOutput_directive  limit 
)
static

Definition at line 1102 of file lz4hc.c.

1106 {
1107  LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
1108  DEBUGLOG(5, "LZ4_compressHC_continue_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
1109  LZ4_streamHCPtr, src, *srcSizePtr, limit);
1110  assert(ctxPtr != NULL);
1111  /* auto-init if forgotten */
1112  if (ctxPtr->base == NULL) LZ4HC_init_internal (ctxPtr, (const BYTE*) src);
1113 
1114  /* Check overflow */
1115  if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) {
1116  size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
1117  if (dictSize > 64 KB) dictSize = 64 KB;
1118  LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
1119  }
1120 
1121  /* Check if blocks follow each other */
1122  if ((const BYTE*)src != ctxPtr->end)
1123  LZ4HC_setExternalDict(ctxPtr, (const BYTE*)src);
1124 
1125  /* Check overlapping input/dictionary space */
1126  { const BYTE* sourceEnd = (const BYTE*) src + *srcSizePtr;
1127  const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
1128  const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
1129  if ((sourceEnd > dictBegin) && ((const BYTE*)src < dictEnd)) {
1130  if (sourceEnd > dictEnd) sourceEnd = dictEnd;
1131  ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
1132  if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
1133  } }
1134 
1135  return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit);
1136 }
#define DEBUGLOG(l,...)
Definition: lz4.c:261
static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal *ctxPtr, const BYTE *newBlock)
Definition: lz4hc.c:1083
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
Definition: lz4hc.c:1056
assert(limit<=UINT32_MAX/2)
static uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45
#define U32(val)
int size_t
Definition: sftypes.h:40
LZ4_u32 dictLimit
Definition: lz4hc.h:209
const LZ4_byte * dictBase
Definition: lz4hc.h:208
short compressionLevel
Definition: lz4hc.h:212
const LZ4_byte * end
Definition: lz4hc.h:206
const LZ4_byte * base
Definition: lz4hc.h:207
LZ4_u32 lowLimit
Definition: lz4hc.h:210
#define KB
Definition: unum.c:91
#define GB
Definition: unum.c:93

References assert(), LZ4HC_CCtx_internal::base, LZ4HC_CCtx_internal::compressionLevel, DEBUGLOG, LZ4HC_CCtx_internal::dictBase, LZ4HC_CCtx_internal::dictLimit, dst, LZ4HC_CCtx_internal::end, GB, LZ4_streamHC_u::internal_donotuse, KB, limit, LZ4HC_CCtx_internal::lowLimit, LZ4_loadDictHC(), LZ4HC_compress_generic(), LZ4HC_init_internal(), LZ4HC_setExternalDict(), NULL, src, and U32.

Referenced by LZ4_compress_HC_continue(), and LZ4_compress_HC_continue_destSize().

◆ LZ4_compressHC_limitedOutput()

int LZ4_compressHC_limitedOutput ( const char *  src,
char *  dst,
int  srcSize,
int  maxDstSize 
)

Definition at line 1190 of file lz4hc.c.

1190 { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); }

References dst, LZ4_compress_HC(), maxDstSize, src, and srcSize.

◆ LZ4_compressHC_limitedOutput_continue()

int LZ4_compressHC_limitedOutput_continue ( LZ4_streamHC_t ctx,
const char *  src,
char *  dst,
int  srcSize,
int  maxDstSize 
)

Definition at line 1198 of file lz4hc.c.

References dst, LZ4_compress_HC_continue(), maxDstSize, src, and srcSize.

◆ LZ4_compressHC_limitedOutput_withStateHC()

int LZ4_compressHC_limitedOutput_withStateHC ( void *  state,
const char *  src,
char *  dst,
int  srcSize,
int  maxDstSize 
)

Definition at line 1194 of file lz4hc.c.

References dst, LZ4_compress_HC_extStateHC(), maxDstSize, src, and srcSize.

◆ LZ4_compressHC_withStateHC()

int LZ4_compressHC_withStateHC ( void *  state,
const char *  src,
char *  dst,
int  srcSize 
)

◆ LZ4_createHC()

void* LZ4_createHC ( const char *  inputBuffer)

Definition at line 1214 of file lz4hc.c.

1215 {
1216  LZ4_streamHC_t* const hc4 = LZ4_createStreamHC();
1217  if (hc4 == NULL) return NULL; /* not enough memory */
1219  return hc4;
1220 }
char * inputBuffer
Definition: lz4.h:720
LZ4_streamHC_t * LZ4_createStreamHC(void)
Definition: lz4hc.c:985

References inputBuffer, LZ4_streamHC_u::internal_donotuse, LZ4_createStreamHC(), LZ4HC_init_internal(), and NULL.

Referenced by FUZ_test().

◆ LZ4_createStreamHC()

LZ4_streamHC_t* LZ4_createStreamHC ( void  )

LZ4_createStreamHC() and LZ4_freeStreamHC() : These functions create and release memory for LZ4 HC streaming state. Newly created states are automatically initialized. A same state can be used multiple times consecutively, starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.

Definition at line 985 of file lz4hc.c.

986 {
987  LZ4_streamHC_t* const state =
989  if (state == NULL) return NULL;
991  return state;
992 }
#define ALLOC_AND_ZERO(s)
Definition: lz4.c:203
#define LZ4HC_CLEVEL_DEFAULT
Definition: lz4hc.h:48

References ALLOC_AND_ZERO, LZ4_setCompressionLevel(), LZ4HC_CLEVEL_DEFAULT, and NULL.

Referenced by FUZ_test(), FUZ_unitTests(), LZ4_compressInitStreamHC(), LZ4_createHC(), LZ4F_compressBegin_usingCDict(), LZ4F_createCDict(), state_attachDictHCRoundTrip(), and state_create().

◆ LZ4_favorDecompressionSpeed()

void LZ4_favorDecompressionSpeed ( LZ4_streamHC_t LZ4_streamHCPtr,
int  favor 
)

Definition at line 1049 of file lz4hc.c.

1050 {
1051  LZ4_streamHCPtr->internal_donotuse.favorDecSpeed = (favor!=0);
1052 }
LZ4_i8 favorDecSpeed
Definition: lz4hc.h:213

References LZ4HC_CCtx_internal::favorDecSpeed, and LZ4_streamHC_u::internal_donotuse.

Referenced by LZ4F_compressBegin_usingCDict().

◆ LZ4_freeHC()

int LZ4_freeHC ( void *  LZ4HC_Data)

Definition at line 1222 of file lz4hc.c.

1223 {
1224  if (!LZ4HC_Data) return 0; /* support free on NULL */
1225  FREEMEM(LZ4HC_Data);
1226  return 0;
1227 }

References FREEMEM.

Referenced by FUZ_test().

◆ LZ4_freeStreamHC()

int LZ4_freeStreamHC ( LZ4_streamHC_t LZ4_streamHCPtr)

Definition at line 994 of file lz4hc.c.

995 {
996  DEBUGLOG(4, "LZ4_freeStreamHC(%p)", LZ4_streamHCPtr);
997  if (!LZ4_streamHCPtr) return 0; /* support free on NULL */
998  FREEMEM(LZ4_streamHCPtr);
999  return 0;
1000 }

References DEBUGLOG, and FREEMEM.

Referenced by FUZ_test(), FUZ_unitTests(), LZ4_compressCleanupStreamHC(), LZ4F_freeCDict(), state_attachDictHCRoundTrip(), and state_free().

◆ LZ4_initStreamHC()

LZ4_streamHC_t* LZ4_initStreamHC ( void *  buffer,
size_t  size 
)

Definition at line 1003 of file lz4hc.c.

1004 {
1005  LZ4_streamHC_t* const LZ4_streamHCPtr = (LZ4_streamHC_t*)buffer;
1006  /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
1008  DEBUGLOG(4, "LZ4_initStreamHC(%p, %u)", buffer, (unsigned)size);
1009  /* check conditions */
1010  if (buffer == NULL) return NULL;
1011  if (size < sizeof(LZ4_streamHC_t)) return NULL;
1013  /* init */
1014  { LZ4HC_CCtx_internal* const hcstate = &(LZ4_streamHCPtr->internal_donotuse);
1015  MEM_INIT(hcstate, 0, sizeof(*hcstate)); }
1017  return LZ4_streamHCPtr;
1018 }
voidpf void uLong size
Definition: ioapi.h:138
#define LZ4_STATIC_ASSERT(c)
Definition: lz4.c:249
#define MEM_INIT(p, v, s)
Definition: lz4.c:208
#define LZ4_STREAMHCSIZE
Definition: lz4hc.h:223
Definition: buffer.h:15

References DEBUGLOG, LZ4_streamHC_u::internal_donotuse, LZ4_isAligned(), LZ4_setCompressionLevel(), LZ4_STATIC_ASSERT, LZ4_streamHC_t_alignment(), LZ4_STREAMHCSIZE, LZ4HC_CLEVEL_DEFAULT, MEM_INIT, and NULL.

Referenced by FUZ_unitTests(), local_LZ4_resetStreamHC(), LZ4_compress_HC_destSize(), LZ4_compress_HC_extStateHC(), LZ4_loadDictHC(), LZ4_resetStreamHC(), LZ4_resetStreamHC_fast(), LZ4_resetStreamStateHC(), and LZ4F_compressBegin_usingCDict().

◆ LZ4_loadDictHC()

int LZ4_loadDictHC ( LZ4_streamHC_t LZ4_streamHCPtr,
const char *  dictionary,
int  dictSize 
)

Definition at line 1056 of file lz4hc.c.

1058 {
1059  LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
1060  DEBUGLOG(4, "LZ4_loadDictHC(ctx:%p, dict:%p, dictSize:%d)", LZ4_streamHCPtr, dictionary, dictSize);
1061  assert(LZ4_streamHCPtr != NULL);
1062  if (dictSize > 64 KB) {
1063  dictionary += (size_t)dictSize - 64 KB;
1064  dictSize = 64 KB;
1065  }
1066  /* need a full initialization, there are bad side-effects when using resetFast() */
1067  { int const cLevel = ctxPtr->compressionLevel;
1068  LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr));
1069  LZ4_setCompressionLevel(LZ4_streamHCPtr, cLevel);
1070  }
1071  LZ4HC_init_internal (ctxPtr, (const BYTE*)dictionary);
1072  ctxPtr->end = (const BYTE*)dictionary + dictSize;
1073  if (dictSize >= 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3);
1074  return dictSize;
1075 }
LZ4_FORCE_INLINE void LZ4HC_Insert(LZ4HC_CCtx_internal *hc4, const BYTE *ip)
Definition: lz4hc.c:118

References assert(), LZ4HC_CCtx_internal::compressionLevel, DEBUGLOG, LZ4HC_CCtx_internal::end, LZ4_streamHC_u::internal_donotuse, KB, LZ4_initStreamHC(), LZ4_setCompressionLevel(), LZ4HC_init_internal(), LZ4HC_Insert(), and NULL.

Referenced by fullSpeedBench(), FUZ_test(), FUZ_unitTests(), LZ4_compressHC_continue_generic(), LZ4_compressInitStreamHC(), LZ4F_createCDict(), state_attachDictHCRoundTrip(), and state_loadDictHCRoundTrip().

◆ LZ4_resetStreamHC()

void LZ4_resetStreamHC ( LZ4_streamHC_t LZ4_streamHCPtr,
int  compressionLevel 
)

Definition at line 1021 of file lz4hc.c.

1022 {
1023  LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr));
1024  LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel);
1025 }

References compressionLevel, LZ4_initStreamHC(), and LZ4_setCompressionLevel().

Referenced by FUZ_unitTests().

◆ LZ4_resetStreamHC_fast()

void LZ4_resetStreamHC_fast ( LZ4_streamHC_t LZ4_streamHCPtr,
int  compressionLevel 
)

Definition at line 1027 of file lz4hc.c.

1028 {
1029  DEBUGLOG(4, "LZ4_resetStreamHC_fast(%p, %d)", LZ4_streamHCPtr, compressionLevel);
1030  if (LZ4_streamHCPtr->internal_donotuse.dirty) {
1031  LZ4_initStreamHC(LZ4_streamHCPtr, sizeof(*LZ4_streamHCPtr));
1032  } else {
1033  /* preserve end - base : can trigger clearTable's threshold */
1034  LZ4_streamHCPtr->internal_donotuse.end -= (uptrval)LZ4_streamHCPtr->internal_donotuse.base;
1035  LZ4_streamHCPtr->internal_donotuse.base = NULL;
1036  LZ4_streamHCPtr->internal_donotuse.dictCtx = NULL;
1037  }
1038  LZ4_setCompressionLevel(LZ4_streamHCPtr, compressionLevel);
1039 }
size_t uptrval
Definition: lz4.c:291

References LZ4HC_CCtx_internal::base, compressionLevel, DEBUGLOG, LZ4HC_CCtx_internal::dictCtx, LZ4HC_CCtx_internal::dirty, LZ4HC_CCtx_internal::end, LZ4_streamHC_u::internal_donotuse, LZ4_initStreamHC(), LZ4_setCompressionLevel(), and NULL.

Referenced by FUZ_test(), FUZ_unitTests(), LZ4_compress_HC_extStateHC_fastReset(), LZ4_compressResetStreamHC(), LZ4_slideInputBufferHC(), LZ4F_initStream(), and state_reset().

◆ LZ4_resetStreamStateHC()

int LZ4_resetStreamStateHC ( void *  state,
char *  inputBuffer 
)

Definition at line 1206 of file lz4hc.c.

1207 {
1208  LZ4_streamHC_t* const hc4 = LZ4_initStreamHC(state, sizeof(*hc4));
1209  if (hc4 == NULL) return 1; /* init failed */
1211  return 0;
1212 }

References inputBuffer, LZ4_streamHC_u::internal_donotuse, LZ4_initStreamHC(), LZ4HC_init_internal(), and NULL.

◆ LZ4_saveDictHC()

int LZ4_saveDictHC ( LZ4_streamHC_t LZ4_streamHCPtr,
char *  safeBuffer,
int  dictSize 
)

Definition at line 1158 of file lz4hc.c.

1159 {
1160  LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
1161  int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
1162  DEBUGLOG(5, "LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
1163  assert(prefixSize >= 0);
1164  if (dictSize > 64 KB) dictSize = 64 KB;
1165  if (dictSize < 4) dictSize = 0;
1166  if (dictSize > prefixSize) dictSize = prefixSize;
1167  if (safeBuffer == NULL) assert(dictSize == 0);
1168  if (dictSize > 0)
1169  memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
1170  { U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
1171  streamPtr->end = (const BYTE*)safeBuffer + dictSize;
1172  streamPtr->base = streamPtr->end - endIndex;
1173  streamPtr->dictLimit = endIndex - (U32)dictSize;
1174  streamPtr->lowLimit = endIndex - (U32)dictSize;
1175  if (streamPtr->nextToUpdate < streamPtr->dictLimit)
1176  streamPtr->nextToUpdate = streamPtr->dictLimit;
1177  }
1178  return dictSize;
1179 }
unsigned int U32
Definition: lz4.c:288
static int
Definition: sfsocketcall.h:114
LZ4_u32 nextToUpdate
Definition: lz4hc.h:211

References assert(), LZ4HC_CCtx_internal::base, DEBUGLOG, LZ4HC_CCtx_internal::dictLimit, LZ4HC_CCtx_internal::end, int, LZ4_streamHC_u::internal_donotuse, KB, LZ4HC_CCtx_internal::lowLimit, LZ4HC_CCtx_internal::nextToUpdate, NULL, and U32.

Referenced by FUZ_unitTests(), local_LZ4_saveDictHC(), and LZ4F_localSaveDict().

◆ LZ4_setCompressionLevel()

◆ LZ4_sizeofStateHC()

int LZ4_sizeofStateHC ( void  )

LZ4_compress_HC_extStateHC() : Same as LZ4_compress_HC(), but using an externally allocated memory segment for state. state size is provided by LZ4_sizeofStateHC(). Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).

Definition at line 921 of file lz4hc.c.

921 { return (int)sizeof(LZ4_streamHC_t); }
union LZ4_streamHC_u LZ4_streamHC_t
Definition: lz4hc.h:101

Referenced by FUZ_test(), and LLVMFuzzerTestOneInput().

◆ LZ4_sizeofStreamStateHC()

int LZ4_sizeofStreamStateHC ( void  )

Definition at line 1202 of file lz4hc.c.

1202 { return LZ4_STREAMHCSIZE; }

References LZ4_STREAMHCSIZE.

◆ LZ4_slideInputBufferHC()

char* LZ4_slideInputBufferHC ( void *  LZ4HC_Data)

Definition at line 1239 of file lz4hc.c.

1240 {
1241  LZ4_streamHC_t *ctx = (LZ4_streamHC_t*)LZ4HC_Data;
1242  const BYTE *bufferStart = ctx->internal_donotuse.base + ctx->internal_donotuse.lowLimit;
1243  LZ4_resetStreamHC_fast(ctx, ctx->internal_donotuse.compressionLevel);
1244  /* avoid const char * -> char * conversion warning :( */
1245  return (char *)(uptrval)bufferStart;
1246 }

References LZ4_resetStreamHC_fast().

◆ LZ4_streamHC_t_alignment()

static size_t LZ4_streamHC_t_alignment ( void  )
static

Definition at line 923 of file lz4hc.c.

924 {
925 #if LZ4_ALIGN_TEST
926  typedef struct { char c; LZ4_streamHC_t t; } t_a;
927  return sizeof(t_a) - sizeof(LZ4_streamHC_t);
928 #else
929  return 1; /* effectively disabled */
930 #endif
931 }
#define c(i)
Definition: sha256.c:43

References c.

Referenced by LZ4_compress_HC_extStateHC_fastReset(), and LZ4_initStreamHC().

◆ LZ4HC_clearTables()

static void LZ4HC_clearTables ( LZ4HC_CCtx_internal hc4)
static

Definition at line 94 of file lz4hc.c.

95 {
96  MEM_INIT(hc4->hashTable, 0, sizeof(hc4->hashTable));
97  MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
98 }
LZ4_u32 hashTable[LZ4HC_HASHTABLESIZE]
Definition: lz4hc.h:204
LZ4_u16 chainTable[LZ4HC_MAXD]
Definition: lz4hc.h:205

References LZ4HC_CCtx_internal::chainTable, LZ4HC_CCtx_internal::hashTable, and MEM_INIT.

Referenced by LZ4HC_init_internal().

◆ LZ4HC_compress_generic()

static int LZ4HC_compress_generic ( LZ4HC_CCtx_internal *const  ctx,
const char *const  src,
char *const  dst,
int *const  srcSizePtr,
int const  dstCapacity,
int  cLevel,
limitedOutput_directive  limit 
)
static

Definition at line 903 of file lz4hc.c.

912 {
913  if (ctx->dictCtx == NULL) {
914  return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
915  } else {
916  return LZ4HC_compress_generic_dictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
917  }
918 }
static int LZ4HC_compress_generic_noDictCtx(LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
Definition: lz4hc.c:862
static int LZ4HC_compress_generic_dictCtx(LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
Definition: lz4hc.c:877

References dst, limit, LZ4HC_compress_generic_dictCtx(), LZ4HC_compress_generic_noDictCtx(), NULL, and src.

Referenced by LZ4_compress_HC_destSize(), LZ4_compress_HC_extStateHC_fastReset(), LZ4_compressHC2_continue(), LZ4_compressHC2_limitedOutput_continue(), and LZ4_compressHC_continue_generic().

◆ LZ4HC_compress_generic_dictCtx()

static int LZ4HC_compress_generic_dictCtx ( LZ4HC_CCtx_internal *const  ctx,
const char *const  src,
char *const  dst,
int *const  srcSizePtr,
int const  dstCapacity,
int  cLevel,
limitedOutput_directive  limit 
)
static

Definition at line 877 of file lz4hc.c.

886 {
887  const size_t position = (size_t)(ctx->end - ctx->base) - ctx->lowLimit;
888  assert(ctx->dictCtx != NULL);
889  if (position >= 64 KB) {
890  ctx->dictCtx = NULL;
891  return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
892  } else if (position == 0 && *srcSizePtr > 4 KB) {
893  memcpy(ctx, ctx->dictCtx, sizeof(LZ4HC_CCtx_internal));
894  LZ4HC_setExternalDict(ctx, (const BYTE *)src);
895  ctx->compressionLevel = (short)cLevel;
896  return LZ4HC_compress_generic_noDictCtx(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit);
897  } else {
898  return LZ4HC_compress_generic_internal(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit, usingDictCtxHc);
899  }
900 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal(LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, const limitedOutput_directive limit, const dictCtx_directive dict)
Definition: lz4hc.c:796

References assert(), dst, KB, limit, LZ4HC_compress_generic_internal(), LZ4HC_compress_generic_noDictCtx(), LZ4HC_setExternalDict(), memcpy(), NULL, src, and usingDictCtxHc.

Referenced by LZ4HC_compress_generic().

◆ LZ4HC_compress_generic_internal()

LZ4_FORCE_INLINE int LZ4HC_compress_generic_internal ( LZ4HC_CCtx_internal *const  ctx,
const char *const  src,
char *const  dst,
int *const  srcSizePtr,
int const  dstCapacity,
int  cLevel,
const limitedOutput_directive  limit,
const dictCtx_directive  dict 
)

Definition at line 796 of file lz4hc.c.

806 {
807  typedef enum { lz4hc, lz4opt } lz4hc_strat_e;
808  typedef struct {
809  lz4hc_strat_e strat;
810  int nbSearches;
811  U32 targetLength;
812  } cParams_t;
813  static const cParams_t clTable[LZ4HC_CLEVEL_MAX+1] = {
814  { lz4hc, 2, 16 }, /* 0, unused */
815  { lz4hc, 2, 16 }, /* 1, unused */
816  { lz4hc, 2, 16 }, /* 2, unused */
817  { lz4hc, 4, 16 }, /* 3 */
818  { lz4hc, 8, 16 }, /* 4 */
819  { lz4hc, 16, 16 }, /* 5 */
820  { lz4hc, 32, 16 }, /* 6 */
821  { lz4hc, 64, 16 }, /* 7 */
822  { lz4hc, 128, 16 }, /* 8 */
823  { lz4hc, 256, 16 }, /* 9 */
824  { lz4opt, 96, 64 }, /*10==LZ4HC_CLEVEL_OPT_MIN*/
825  { lz4opt, 512,128 }, /*11 */
826  { lz4opt,16384,LZ4_OPT_NUM }, /* 12==LZ4HC_CLEVEL_MAX */
827  };
828 
829  DEBUGLOG(4, "LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
830  ctx, src, *srcSizePtr, limit);
831 
832  if (limit == fillOutput && dstCapacity < 1) return 0; /* Impossible to store anything */
833  if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size (too large or negative) */
834 
835  ctx->end += *srcSizePtr;
836  if (cLevel < 1) cLevel = LZ4HC_CLEVEL_DEFAULT; /* note : convention is different from lz4frame, maybe something to review */
837  cLevel = MIN(LZ4HC_CLEVEL_MAX, cLevel);
838  { cParams_t const cParam = clTable[cLevel];
839  HCfavor_e const favor = ctx->favorDecSpeed ? favorDecompressionSpeed : favorCompressionRatio;
840  int result;
841 
842  if (cParam.strat == lz4hc) {
843  result = LZ4HC_compress_hashChain(ctx,
844  src, dst, srcSizePtr, dstCapacity,
845  cParam.nbSearches, limit, dict);
846  } else {
847  assert(cParam.strat == lz4opt);
848  result = LZ4HC_compress_optimal(ctx,
849  src, dst, srcSizePtr, dstCapacity,
850  cParam.nbSearches, cParam.targetLength, limit,
851  cLevel == LZ4HC_CLEVEL_MAX, /* ultra mode */
852  dict, favor);
853  }
854  if (result <= 0) ctx->dirty = 1;
855  return result;
856  }
857 }
#define LZ4_MAX_INPUT_SIZE
Definition: lz4.h:170
#define MIN(a, b)
Definition: lz4hc.c:80
#define LZ4_OPT_NUM
Definition: lz4hc.c:76
LZ4_FORCE_INLINE int LZ4HC_compress_hashChain(LZ4HC_CCtx_internal *const ctx, const char *const source, char *const dest, int *srcSizePtr, int const maxOutputSize, int maxNbAttempts, const limitedOutput_directive limit, const dictCtx_directive dict)
Definition: lz4hc.c:549
static int LZ4HC_compress_optimal(LZ4HC_CCtx_internal *ctx, const char *const source, char *dst, int *srcSizePtr, int dstCapacity, int const nbSearches, size_t sufficient_len, const limitedOutput_directive limit, int const fullUpdate, const dictCtx_directive dict, const HCfavor_e favorDecSpeed)
Definition: lz4hc.c:1314

References assert(), DEBUGLOG, dst, favorCompressionRatio, favorDecompressionSpeed, fillOutput, limit, LZ4_MAX_INPUT_SIZE, LZ4_OPT_NUM, LZ4HC_CLEVEL_DEFAULT, LZ4HC_CLEVEL_MAX, LZ4HC_compress_hashChain(), LZ4HC_compress_optimal(), MIN, and src.

Referenced by LZ4HC_compress_generic_dictCtx(), and LZ4HC_compress_generic_noDictCtx().

◆ LZ4HC_compress_generic_noDictCtx()

static int LZ4HC_compress_generic_noDictCtx ( LZ4HC_CCtx_internal *const  ctx,
const char *const  src,
char *const  dst,
int *const  srcSizePtr,
int const  dstCapacity,
int  cLevel,
limitedOutput_directive  limit 
)
static

Definition at line 862 of file lz4hc.c.

871 {
872  assert(ctx->dictCtx == NULL);
873  return LZ4HC_compress_generic_internal(ctx, src, dst, srcSizePtr, dstCapacity, cLevel, limit, noDictCtx);
874 }

References assert(), dst, limit, LZ4HC_compress_generic_internal(), noDictCtx, NULL, and src.

Referenced by LZ4HC_compress_generic(), and LZ4HC_compress_generic_dictCtx().

◆ LZ4HC_compress_hashChain()

LZ4_FORCE_INLINE int LZ4HC_compress_hashChain ( LZ4HC_CCtx_internal *const  ctx,
const char *const  source,
char *const  dest,
int srcSizePtr,
int const  maxOutputSize,
int  maxNbAttempts,
const limitedOutput_directive  limit,
const dictCtx_directive  dict 
)

Definition at line 549 of file lz4hc.c.

559 {
560  const int inputSize = *srcSizePtr;
561  const int patternAnalysis = (maxNbAttempts > 128); /* levels 9+ */
562 
563  const BYTE* ip = (const BYTE*) source;
564  const BYTE* anchor = ip;
565  const BYTE* const iend = ip + inputSize;
566  const BYTE* const mflimit = iend - MFLIMIT;
567  const BYTE* const matchlimit = (iend - LASTLITERALS);
568 
569  BYTE* optr = (BYTE*) dest;
570  BYTE* op = (BYTE*) dest;
571  BYTE* oend = op + maxOutputSize;
572 
573  int ml0, ml, ml2, ml3;
574  const BYTE* start0;
575  const BYTE* ref0;
576  const BYTE* ref = NULL;
577  const BYTE* start2 = NULL;
578  const BYTE* ref2 = NULL;
579  const BYTE* start3 = NULL;
580  const BYTE* ref3 = NULL;
581 
582  /* init */
583  *srcSizePtr = 0;
584  if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */
585  if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
586 
587  /* Main Loop */
588  while (ip <= mflimit) {
589  ml = LZ4HC_InsertAndFindBestMatch(ctx, ip, matchlimit, &ref, maxNbAttempts, patternAnalysis, dict);
590  if (ml<MINMATCH) { ip++; continue; }
591 
592  /* saved, in case we would skip too much */
593  start0 = ip; ref0 = ref; ml0 = ml;
594 
595 _Search2:
596  if (ip+ml <= mflimit) {
598  ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2,
599  maxNbAttempts, patternAnalysis, 0, dict, favorCompressionRatio);
600  } else {
601  ml2 = ml;
602  }
603 
604  if (ml2 == ml) { /* No better match => encode ML1 */
605  optr = op;
606  if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow;
607  continue;
608  }
609 
610  if (start0 < ip) { /* first match was skipped at least once */
611  if (start2 < ip + ml0) { /* squeezing ML1 between ML0(original ML1) and ML2 */
612  ip = start0; ref = ref0; ml = ml0; /* restore initial ML1 */
613  } }
614 
615  /* Here, start0==ip */
616  if ((start2 - ip) < 3) { /* First Match too small : removed */
617  ml = ml2;
618  ip = start2;
619  ref =ref2;
620  goto _Search2;
621  }
622 
623 _Search3:
624  /* At this stage, we have :
625  * ml2 > ml1, and
626  * ip1+3 <= ip2 (usually < ip1+ml1) */
627  if ((start2 - ip) < OPTIMAL_ML) {
628  int correction;
629  int new_ml = ml;
630  if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
631  if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
632  correction = new_ml - (int)(start2 - ip);
633  if (correction > 0) {
634  start2 += correction;
635  ref2 += correction;
636  ml2 -= correction;
637  }
638  }
639  /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */
640 
641  if (start2 + ml2 <= mflimit) {
643  start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3,
644  maxNbAttempts, patternAnalysis, 0, dict, favorCompressionRatio);
645  } else {
646  ml3 = ml2;
647  }
648 
649  if (ml3 == ml2) { /* No better match => encode ML1 and ML2 */
650  /* ip & ref are known; Now for ml */
651  if (start2 < ip+ml) ml = (int)(start2 - ip);
652  /* Now, encode 2 sequences */
653  optr = op;
654  if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow;
655  ip = start2;
656  optr = op;
657  if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml2, ref2, limit, oend)) {
658  ml = ml2;
659  ref = ref2;
660  goto _dest_overflow;
661  }
662  continue;
663  }
664 
665  if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */
666  if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
667  if (start2 < ip+ml) {
668  int correction = (int)(ip+ml - start2);
669  start2 += correction;
670  ref2 += correction;
671  ml2 -= correction;
672  if (ml2 < MINMATCH) {
673  start2 = start3;
674  ref2 = ref3;
675  ml2 = ml3;
676  }
677  }
678 
679  optr = op;
680  if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow;
681  ip = start3;
682  ref = ref3;
683  ml = ml3;
684 
685  start0 = start2;
686  ref0 = ref2;
687  ml0 = ml2;
688  goto _Search2;
689  }
690 
691  start2 = start3;
692  ref2 = ref3;
693  ml2 = ml3;
694  goto _Search3;
695  }
696 
697  /*
698  * OK, now we have 3 ascending matches;
699  * let's write the first one ML1.
700  * ip & ref are known; Now decide ml.
701  */
702  if (start2 < ip+ml) {
703  if ((start2 - ip) < OPTIMAL_ML) {
704  int correction;
705  if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
706  if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
707  correction = ml - (int)(start2 - ip);
708  if (correction > 0) {
709  start2 += correction;
710  ref2 += correction;
711  ml2 -= correction;
712  }
713  } else {
714  ml = (int)(start2 - ip);
715  }
716  }
717  optr = op;
718  if (LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, limit, oend)) goto _dest_overflow;
719 
720  /* ML2 becomes ML1 */
721  ip = start2; ref = ref2; ml = ml2;
722 
723  /* ML3 becomes ML2 */
724  start2 = start3; ref2 = ref3; ml2 = ml3;
725 
726  /* let's find a new ML3 */
727  goto _Search3;
728  }
729 
730 _last_literals:
731  /* Encode Last Literals */
732  { size_t lastRunSize = (size_t)(iend - anchor); /* literals */
733  size_t llAdd = (lastRunSize + 255 - RUN_MASK) / 255;
734  size_t const totalSize = 1 + llAdd + lastRunSize;
735  if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */
736  if (limit && (op + totalSize > oend)) {
737  if (limit == limitedOutput) return 0;
738  /* adapt lastRunSize to fill 'dest' */
739  lastRunSize = (size_t)(oend - op) - 1 /*token*/;
740  llAdd = (lastRunSize + 256 - RUN_MASK) / 256;
741  lastRunSize -= llAdd;
742  }
743  DEBUGLOG(6, "Final literal run : %i literals", (int)lastRunSize);
744  ip = anchor + lastRunSize; /* can be != iend if limit==fillOutput */
745 
746  if (lastRunSize >= RUN_MASK) {
747  size_t accumulator = lastRunSize - RUN_MASK;
748  *op++ = (RUN_MASK << ML_BITS);
749  for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255;
750  *op++ = (BYTE) accumulator;
751  } else {
752  *op++ = (BYTE)(lastRunSize << ML_BITS);
753  }
754  memcpy(op, anchor, lastRunSize);
755  op += lastRunSize;
756  }
757 
758  /* End */
759  *srcSizePtr = (int) (((const char*)ip) - source);
760  return (int) (((char*)op)-dest);
761 
762 _dest_overflow:
763  if (limit == fillOutput) {
764  /* Assumption : ip, anchor, ml and ref must be set correctly */
765  size_t const ll = (size_t)(ip - anchor);
766  size_t const ll_addbytes = (ll + 240) / 255;
767  size_t const ll_totalCost = 1 + ll_addbytes + ll;
768  BYTE* const maxLitPos = oend - 3; /* 2 for offset, 1 for token */
769  DEBUGLOG(6, "Last sequence overflowing");
770  op = optr; /* restore correct out pointer */
771  if (op + ll_totalCost <= maxLitPos) {
772  /* ll validated; now adjust match length */
773  size_t const bytesLeftForMl = (size_t)(maxLitPos - (op+ll_totalCost));
774  size_t const maxMlSize = MINMATCH + (ML_MASK-1) + (bytesLeftForMl * 255);
775  assert(maxMlSize < INT_MAX); assert(ml >= 0);
776  if ((size_t)ml > maxMlSize) ml = (int)maxMlSize;
777  if ((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1 + ml >= MFLIMIT) {
778  LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ref, notLimited, oend);
779  } }
780  goto _last_literals;
781  }
782  /* compression failed */
783  return 0;
784 }
#define INT_MAX
Definition: cp-demangle.c:131
static const int LZ4_minLength
Definition: lz4.c:221
#define MINMATCH
Definition: lz4.c:214
#define MFLIMIT
Definition: lz4.c:218
#define LASTLITERALS
Definition: lz4.c:217
#define ML_BITS
Definition: lz4.c:232
#define ML_MASK
Definition: lz4.c:233
#define RUN_MASK
Definition: lz4.c:235
char int int maxOutputSize
Definition: lz4.h:698
const char char int inputSize
Definition: lz4.h:699
#define UPDATABLE(ip, op, anchor)
Definition: lz4hc.c:86
#define OPTIMAL_ML
Definition: lz4hc.c:75
LZ4_FORCE_INLINE int LZ4HC_encodeSequence(const BYTE **_ip, BYTE **_op, const BYTE **_anchor, int matchLength, const BYTE *const match, limitedOutput_directive limit, BYTE *oend)
Definition: lz4hc.c:463
#define op
#define anchor
#define ip
LZ4_FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch(LZ4HC_CCtx_internal *hc4, const BYTE *const ip, const BYTE *const iLowLimit, const BYTE *const iHighLimit, int longest, const BYTE **matchpos, const BYTE **startpos, const int maxNbAttempts, const int patternAnalysis, const int chainSwap, const dictCtx_directive dict, const HCfavor_e favorDecSpeed)
Definition: lz4hc.c:236
LZ4_FORCE_INLINE int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal *const hc4, const BYTE *const ip, const BYTE *const iLimit, const BYTE **matchpos, const int maxNbAttempts, const int patternAnalysis, const dictCtx_directive dict)
Definition: lz4hc.c:446
Definition: dis.c:32

References anchor, assert(), DEBUGLOG, dest, favorCompressionRatio, fillOutput, inputSize, int, INT_MAX, ip, LASTLITERALS, limit, limitedOutput, LZ4_minLength, LZ4HC_encodeSequence(), LZ4HC_InsertAndFindBestMatch(), LZ4HC_InsertAndGetWiderMatch(), maxOutputSize, memcpy(), MFLIMIT, MINMATCH, ML_BITS, ML_MASK, notLimited, NULL, op, OPTIMAL_ML, RUN_MASK, source, and UPDATABLE.

Referenced by LZ4HC_compress_generic_internal().

◆ LZ4HC_compress_optimal()

static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal ctx,
const char *const  source,
char *  dst,
int srcSizePtr,
int  dstCapacity,
int const  nbSearches,
size_t  sufficient_len,
const limitedOutput_directive  limit,
int const  fullUpdate,
const dictCtx_directive  dict,
const HCfavor_e  favorDecSpeed 
)
static

Definition at line 1314 of file lz4hc.c.

1325 {
1326  int retval = 0;
1327 #define TRAILING_LITERALS 3
1328 #ifdef LZ4HC_HEAPMODE
1330 #else
1331  LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS]; /* ~64 KB, which is a bit large for stack... */
1332 #endif
1333 
1334  const BYTE* ip = (const BYTE*) source;
1335  const BYTE* anchor = ip;
1336  const BYTE* const iend = ip + *srcSizePtr;
1337  const BYTE* const mflimit = iend - MFLIMIT;
1338  const BYTE* const matchlimit = iend - LASTLITERALS;
1339  BYTE* op = (BYTE*) dst;
1340  BYTE* opSaved = (BYTE*) dst;
1341  BYTE* oend = op + dstCapacity;
1342  int ovml = MINMATCH; /* overflow - last sequence */
1343  const BYTE* ovref = NULL;
1344 
1345  /* init */
1346 #ifdef LZ4HC_HEAPMODE
1347  if (opt == NULL) goto _return_label;
1348 #endif
1349  DEBUGLOG(5, "LZ4HC_compress_optimal(dst=%p, dstCapa=%u)", dst, (unsigned)dstCapacity);
1350  *srcSizePtr = 0;
1351  if (limit == fillOutput) oend -= LASTLITERALS; /* Hack for support LZ4 format restriction */
1352  if (sufficient_len >= LZ4_OPT_NUM) sufficient_len = LZ4_OPT_NUM-1;
1353 
1354  /* Main Loop */
1355  while (ip <= mflimit) {
1356  int const llen = (int)(ip - anchor);
1357  int best_mlen, best_off;
1358  int cur, last_match_pos = 0;
1359 
1360  LZ4HC_match_t const firstMatch = LZ4HC_FindLongerMatch(ctx, ip, matchlimit, MINMATCH-1, nbSearches, dict, favorDecSpeed);
1361  if (firstMatch.len==0) { ip++; continue; }
1362 
1363  if ((size_t)firstMatch.len > sufficient_len) {
1364  /* good enough solution : immediate encoding */
1365  int const firstML = firstMatch.len;
1366  const BYTE* const matchPos = ip - firstMatch.off;
1367  opSaved = op;
1368  if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), firstML, matchPos, limit, oend) ) { /* updates ip, op and anchor */
1369  ovml = firstML;
1370  ovref = matchPos;
1371  goto _dest_overflow;
1372  }
1373  continue;
1374  }
1375 
1376  /* set prices for first positions (literals) */
1377  { int rPos;
1378  for (rPos = 0 ; rPos < MINMATCH ; rPos++) {
1379  int const cost = LZ4HC_literalsPrice(llen + rPos);
1380  opt[rPos].mlen = 1;
1381  opt[rPos].off = 0;
1382  opt[rPos].litlen = llen + rPos;
1383  opt[rPos].price = cost;
1384  DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup",
1385  rPos, cost, opt[rPos].litlen);
1386  } }
1387  /* set prices using initial match */
1388  { int mlen = MINMATCH;
1389  int const matchML = firstMatch.len; /* necessarily < sufficient_len < LZ4_OPT_NUM */
1390  int const offset = firstMatch.off;
1391  assert(matchML < LZ4_OPT_NUM);
1392  for ( ; mlen <= matchML ; mlen++) {
1393  int const cost = LZ4HC_sequencePrice(llen, mlen);
1394  opt[mlen].mlen = mlen;
1395  opt[mlen].off = offset;
1396  opt[mlen].litlen = llen;
1397  opt[mlen].price = cost;
1398  DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i) -- initial setup",
1399  mlen, cost, mlen);
1400  } }
1401  last_match_pos = firstMatch.len;
1402  { int addLit;
1403  for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) {
1404  opt[last_match_pos+addLit].mlen = 1; /* literal */
1405  opt[last_match_pos+addLit].off = 0;
1406  opt[last_match_pos+addLit].litlen = addLit;
1407  opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit);
1408  DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i) -- initial setup",
1409  last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit);
1410  } }
1411 
1412  /* check further positions */
1413  for (cur = 1; cur < last_match_pos; cur++) {
1414  const BYTE* const curPtr = ip + cur;
1415  LZ4HC_match_t newMatch;
1416 
1417  if (curPtr > mflimit) break;
1418  DEBUGLOG(7, "rPos:%u[%u] vs [%u]%u",
1419  cur, opt[cur].price, opt[cur+1].price, cur+1);
1420  if (fullUpdate) {
1421  /* not useful to search here if next position has same (or lower) cost */
1422  if ( (opt[cur+1].price <= opt[cur].price)
1423  /* in some cases, next position has same cost, but cost rises sharply after, so a small match would still be beneficial */
1424  && (opt[cur+MINMATCH].price < opt[cur].price + 3/*min seq price*/) )
1425  continue;
1426  } else {
1427  /* not useful to search here if next position has same (or lower) cost */
1428  if (opt[cur+1].price <= opt[cur].price) continue;
1429  }
1430 
1431  DEBUGLOG(7, "search at rPos:%u", cur);
1432  if (fullUpdate)
1433  newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, MINMATCH-1, nbSearches, dict, favorDecSpeed);
1434  else
1435  /* only test matches of minimum length; slightly faster, but misses a few bytes */
1436  newMatch = LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, last_match_pos - cur, nbSearches, dict, favorDecSpeed);
1437  if (!newMatch.len) continue;
1438 
1439  if ( ((size_t)newMatch.len > sufficient_len)
1440  || (newMatch.len + cur >= LZ4_OPT_NUM) ) {
1441  /* immediate encoding */
1442  best_mlen = newMatch.len;
1443  best_off = newMatch.off;
1444  last_match_pos = cur + 1;
1445  goto encode;
1446  }
1447 
1448  /* before match : set price with literals at beginning */
1449  { int const baseLitlen = opt[cur].litlen;
1450  int litlen;
1451  for (litlen = 1; litlen < MINMATCH; litlen++) {
1452  int const price = opt[cur].price - LZ4HC_literalsPrice(baseLitlen) + LZ4HC_literalsPrice(baseLitlen+litlen);
1453  int const pos = cur + litlen;
1454  if (price < opt[pos].price) {
1455  opt[pos].mlen = 1; /* literal */
1456  opt[pos].off = 0;
1457  opt[pos].litlen = baseLitlen+litlen;
1458  opt[pos].price = price;
1459  DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)",
1460  pos, price, opt[pos].litlen);
1461  } } }
1462 
1463  /* set prices using match at position = cur */
1464  { int const matchML = newMatch.len;
1465  int ml = MINMATCH;
1466 
1467  assert(cur + newMatch.len < LZ4_OPT_NUM);
1468  for ( ; ml <= matchML ; ml++) {
1469  int const pos = cur + ml;
1470  int const offset = newMatch.off;
1471  int price;
1472  int ll;
1473  DEBUGLOG(7, "testing price rPos %i (last_match_pos=%i)",
1474  pos, last_match_pos);
1475  if (opt[cur].mlen == 1) {
1476  ll = opt[cur].litlen;
1477  price = ((cur > ll) ? opt[cur - ll].price : 0)
1478  + LZ4HC_sequencePrice(ll, ml);
1479  } else {
1480  ll = 0;
1481  price = opt[cur].price + LZ4HC_sequencePrice(0, ml);
1482  }
1483 
1484  assert((U32)favorDecSpeed <= 1);
1485  if (pos > last_match_pos+TRAILING_LITERALS
1486  || price <= opt[pos].price - (int)favorDecSpeed) {
1487  DEBUGLOG(7, "rPos:%3i => price:%3i (matchlen=%i)",
1488  pos, price, ml);
1489  assert(pos < LZ4_OPT_NUM);
1490  if ( (ml == matchML) /* last pos of last match */
1491  && (last_match_pos < pos) )
1492  last_match_pos = pos;
1493  opt[pos].mlen = ml;
1494  opt[pos].off = offset;
1495  opt[pos].litlen = ll;
1496  opt[pos].price = price;
1497  } } }
1498  /* complete following positions with literals */
1499  { int addLit;
1500  for (addLit = 1; addLit <= TRAILING_LITERALS; addLit ++) {
1501  opt[last_match_pos+addLit].mlen = 1; /* literal */
1502  opt[last_match_pos+addLit].off = 0;
1503  opt[last_match_pos+addLit].litlen = addLit;
1504  opt[last_match_pos+addLit].price = opt[last_match_pos].price + LZ4HC_literalsPrice(addLit);
1505  DEBUGLOG(7, "rPos:%3i => price:%3i (litlen=%i)", last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit);
1506  } }
1507  } /* for (cur = 1; cur <= last_match_pos; cur++) */
1508 
1509  assert(last_match_pos < LZ4_OPT_NUM + TRAILING_LITERALS);
1510  best_mlen = opt[last_match_pos].mlen;
1511  best_off = opt[last_match_pos].off;
1512  cur = last_match_pos - best_mlen;
1513 
1514 encode: /* cur, last_match_pos, best_mlen, best_off must be set */
1515  assert(cur < LZ4_OPT_NUM);
1516  assert(last_match_pos >= 1); /* == 1 when only one candidate */
1517  DEBUGLOG(6, "reverse traversal, looking for shortest path (last_match_pos=%i)", last_match_pos);
1518  { int candidate_pos = cur;
1519  int selected_matchLength = best_mlen;
1520  int selected_offset = best_off;
1521  while (1) { /* from end to beginning */
1522  int const next_matchLength = opt[candidate_pos].mlen; /* can be 1, means literal */
1523  int const next_offset = opt[candidate_pos].off;
1524  DEBUGLOG(7, "pos %i: sequence length %i", candidate_pos, selected_matchLength);
1525  opt[candidate_pos].mlen = selected_matchLength;
1526  opt[candidate_pos].off = selected_offset;
1527  selected_matchLength = next_matchLength;
1528  selected_offset = next_offset;
1529  if (next_matchLength > candidate_pos) break; /* last match elected, first match to encode */
1530  assert(next_matchLength > 0); /* can be 1, means literal */
1531  candidate_pos -= next_matchLength;
1532  } }
1533 
1534  /* encode all recorded sequences in order */
1535  { int rPos = 0; /* relative position (to ip) */
1536  while (rPos < last_match_pos) {
1537  int const ml = opt[rPos].mlen;
1538  int const offset = opt[rPos].off;
1539  if (ml == 1) { ip++; rPos++; continue; } /* literal; note: can end up with several literals, in which case, skip them */
1540  rPos += ml;
1541  assert(ml >= MINMATCH);
1542  assert((offset >= 1) && (offset <= LZ4_DISTANCE_MAX));
1543  opSaved = op;
1544  if ( LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ml, ip - offset, limit, oend) ) { /* updates ip, op and anchor */
1545  ovml = ml;
1546  ovref = ip - offset;
1547  goto _dest_overflow;
1548  } } }
1549  } /* while (ip <= mflimit) */
1550 
1551 _last_literals:
1552  /* Encode Last Literals */
1553  { size_t lastRunSize = (size_t)(iend - anchor); /* literals */
1554  size_t llAdd = (lastRunSize + 255 - RUN_MASK) / 255;
1555  size_t const totalSize = 1 + llAdd + lastRunSize;
1556  if (limit == fillOutput) oend += LASTLITERALS; /* restore correct value */
1557  if (limit && (op + totalSize > oend)) {
1558  if (limit == limitedOutput) { /* Check output limit */
1559  retval = 0;
1560  goto _return_label;
1561  }
1562  /* adapt lastRunSize to fill 'dst' */
1563  lastRunSize = (size_t)(oend - op) - 1 /*token*/;
1564  llAdd = (lastRunSize + 256 - RUN_MASK) / 256;
1565  lastRunSize -= llAdd;
1566  }
1567  DEBUGLOG(6, "Final literal run : %i literals", (int)lastRunSize);
1568  ip = anchor + lastRunSize; /* can be != iend if limit==fillOutput */
1569 
1570  if (lastRunSize >= RUN_MASK) {
1571  size_t accumulator = lastRunSize - RUN_MASK;
1572  *op++ = (RUN_MASK << ML_BITS);
1573  for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255;
1574  *op++ = (BYTE) accumulator;
1575  } else {
1576  *op++ = (BYTE)(lastRunSize << ML_BITS);
1577  }
1578  memcpy(op, anchor, lastRunSize);
1579  op += lastRunSize;
1580  }
1581 
1582  /* End */
1583  *srcSizePtr = (int) (((const char*)ip) - source);
1584  retval = (int) ((char*)op-dst);
1585  goto _return_label;
1586 
1587 _dest_overflow:
1588 if (limit == fillOutput) {
1589  /* Assumption : ip, anchor, ovml and ovref must be set correctly */
1590  size_t const ll = (size_t)(ip - anchor);
1591  size_t const ll_addbytes = (ll + 240) / 255;
1592  size_t const ll_totalCost = 1 + ll_addbytes + ll;
1593  BYTE* const maxLitPos = oend - 3; /* 2 for offset, 1 for token */
1594  DEBUGLOG(6, "Last sequence overflowing (only %i bytes remaining)", (int)(oend-1-opSaved));
1595  op = opSaved; /* restore correct out pointer */
1596  if (op + ll_totalCost <= maxLitPos) {
1597  /* ll validated; now adjust match length */
1598  size_t const bytesLeftForMl = (size_t)(maxLitPos - (op+ll_totalCost));
1599  size_t const maxMlSize = MINMATCH + (ML_MASK-1) + (bytesLeftForMl * 255);
1600  assert(maxMlSize < INT_MAX); assert(ovml >= 0);
1601  if ((size_t)ovml > maxMlSize) ovml = (int)maxMlSize;
1602  if ((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1 + ovml >= MFLIMIT) {
1603  DEBUGLOG(6, "Space to end : %i + ml (%i)", (int)((oend + LASTLITERALS) - (op + ll_totalCost + 2) - 1), ovml);
1604  DEBUGLOG(6, "Before : ip = %p, anchor = %p", ip, anchor);
1605  LZ4HC_encodeSequence(UPDATABLE(ip, op, anchor), ovml, ovref, notLimited, oend);
1606  DEBUGLOG(6, "After : ip = %p, anchor = %p", ip, anchor);
1607  } }
1608  goto _last_literals;
1609 }
1610 _return_label:
1611 #ifdef LZ4HC_HEAPMODE
1612  FREEMEM(opt);
1613 #endif
1614  return retval;
1615 }
static void encode(size_t size, lzma_action action)
Definition: full_flush.c:25
voidpf uLong offset
Definition: ioapi.h:144
#define TRAILING_LITERALS
LZ4_FORCE_INLINE int LZ4HC_literalsPrice(int const litlen)
Definition: lz4hc.c:1260
LZ4_FORCE_INLINE LZ4HC_match_t LZ4HC_FindLongerMatch(LZ4HC_CCtx_internal *const ctx, const BYTE *ip, const BYTE *const iHighLimit, int minLen, int nbSearches, const dictCtx_directive dict, const HCfavor_e favorDecSpeed)
Definition: lz4hc.c:1292
LZ4_FORCE_INLINE int LZ4HC_sequencePrice(int litlen, int mlen)
Definition: lz4hc.c:1271
int pos
Definition: main.c:11

References ALLOC, anchor, assert(), DEBUGLOG, dst, encode(), fillOutput, FREEMEM, int, INT_MAX, ip, LASTLITERALS, LZ4HC_match_t::len, limit, limitedOutput, LZ4HC_optimal_t::litlen, LZ4_OPT_NUM, LZ4HC_encodeSequence(), LZ4HC_FindLongerMatch(), LZ4HC_literalsPrice(), LZ4HC_sequencePrice(), memcpy(), MFLIMIT, MINMATCH, ML_BITS, ML_MASK, LZ4HC_optimal_t::mlen, notLimited, NULL, LZ4HC_optimal_t::off, LZ4HC_match_t::off, op, pos, LZ4HC_optimal_t::price, RUN_MASK, source, TRAILING_LITERALS, and UPDATABLE.

Referenced by LZ4HC_compress_generic_internal().

◆ LZ4HC_countBack()

LZ4_FORCE_INLINE int LZ4HC_countBack ( const BYTE *const  ip,
const BYTE *const  match,
const BYTE *const  iMin,
const BYTE *const  mMin 
)

LZ4HC_countBack() :

Returns
: negative value, nb of common bytes before ip/match

Definition at line 141 of file lz4hc.c.

143 {
144  int back = 0;
145  int const min = (int)MAX(iMin - ip, mMin - match);
146  assert(min <= 0);
147  assert(ip >= iMin); assert((size_t)(ip-iMin) < (1U<<31));
148  assert(match >= mMin); assert((size_t)(match - mMin) < (1U<<31));
149  while ( (back > min)
150  && (ip[back-1] == match[back-1]) )
151  back--;
152  return back;
153 }
#define MAX(a, b)
Definition: lz4hc.c:81
#define min(a, b)
Definition: qsort.h:83
Definition: engine.c:71

References assert(), int, ip, MAX, and min.

Referenced by LZ4HC_InsertAndGetWiderMatch().

◆ LZ4HC_countPattern()

static unsigned LZ4HC_countPattern ( const BYTE ip,
const BYTE *const  iEnd,
U32 const  pattern32 
)
static

Definition at line 172 of file lz4hc.c.

173 {
174  const BYTE* const iStart = ip;
175  reg_t const pattern = (sizeof(pattern)==8) ?
176  (reg_t)pattern32 + (((reg_t)pattern32) << (sizeof(pattern)*4)) : pattern32;
177 
178  while (likely(ip < iEnd-(sizeof(pattern)-1))) {
179  reg_t const diff = LZ4_read_ARCH(ip) ^ pattern;
180  if (!diff) { ip+=sizeof(pattern); continue; }
181  ip += LZ4_NbCommonBytes(diff);
182  return (unsigned)(ip - iStart);
183  }
184 
185  if (LZ4_isLittleEndian()) {
186  reg_t patternByte = pattern;
187  while ((ip<iEnd) && (*ip == (BYTE)patternByte)) {
188  ip++; patternByte >>= 8;
189  }
190  } else { /* big endian */
191  U32 bitOffset = (sizeof(pattern)*8) - 8;
192  while (ip < iEnd) {
193  BYTE const byte = (BYTE)(pattern >> bitOffset);
194  if (*ip != byte) break;
195  ip ++; bitOffset -= 8;
196  }
197  }
198 
199  return (unsigned)(ip - iStart);
200 }
size_t reg_t
Definition: lz4.c:297
static unsigned LZ4_NbCommonBytes(reg_t val)
Definition: lz4.c:513
static reg_t LZ4_read_ARCH(const void *memPtr)
Definition: lz4.c:367
#define likely(expr)
Definition: lz4.c:174
static unsigned LZ4_isLittleEndian(void)
Definition: lz4.c:325

References ip, likely, LZ4_isLittleEndian(), LZ4_NbCommonBytes(), and LZ4_read_ARCH().

Referenced by LZ4HC_InsertAndGetWiderMatch().

◆ LZ4HC_encodeSequence()

LZ4_FORCE_INLINE int LZ4HC_encodeSequence ( const BYTE **  _ip,
BYTE **  _op,
const BYTE **  _anchor,
int  matchLength,
const BYTE *const  match,
limitedOutput_directive  limit,
BYTE oend 
)

Definition at line 463 of file lz4hc.c.

471 {
472 #define ip (*_ip)
473 #define op (*_op)
474 #define anchor (*_anchor)
475 
476  size_t length;
477  BYTE* const token = op++;
478 
479 #if defined(LZ4_DEBUG) && (LZ4_DEBUG >= 6)
480  static const BYTE* start = NULL;
481  static U32 totalCost = 0;
482  U32 const pos = (start==NULL) ? 0 : (U32)(anchor - start);
483  U32 const ll = (U32)(ip - anchor);
484  U32 const llAdd = (ll>=15) ? ((ll-15) / 255) + 1 : 0;
485  U32 const mlAdd = (matchLength>=19) ? ((matchLength-19) / 255) + 1 : 0;
486  U32 const cost = 1 + llAdd + ll + 2 + mlAdd;
487  if (start==NULL) start = anchor; /* only works for single segment */
488  /* g_debuglog_enable = (pos >= 2228) & (pos <= 2262); */
489  DEBUGLOG(6, "pos:%7u -- literals:%4u, match:%4i, offset:%5u, cost:%4u + %5u",
490  pos,
491  (U32)(ip - anchor), matchLength, (U32)(ip-match),
492  cost, totalCost);
493  totalCost += cost;
494 #endif
495 
496  /* Encode Literal length */
497  length = (size_t)(ip - anchor);
499  /* Check output limit */
500  if (limit && ((op + (length / 255) + length + (2 + 1 + LASTLITERALS)) > oend)) {
501  DEBUGLOG(6, "Not enough room to write %i literals (%i bytes remaining)",
502  (int)length, (int)(oend - op));
503  return 1;
504  }
505  if (length >= RUN_MASK) {
506  size_t len = length - RUN_MASK;
507  *token = (RUN_MASK << ML_BITS);
508  for(; len >= 255 ; len -= 255) *op++ = 255;
509  *op++ = (BYTE)len;
510  } else {
511  *token = (BYTE)(length << ML_BITS);
512  }
513 
514  /* Copy Literals */
516  op += length;
517 
518  /* Encode Offset */
519  assert( (ip - match) <= LZ4_DISTANCE_MAX ); /* note : consider providing offset as a value, rather than as a pointer difference */
520  LZ4_writeLE16(op, (U16)(ip - match)); op += 2;
521 
522  /* Encode MatchLength */
523  assert(matchLength >= MINMATCH);
524  length = (size_t)matchLength - MINMATCH;
525  if (limit && (op + (length / 255) + (1 + LASTLITERALS) > oend)) {
526  DEBUGLOG(6, "Not enough room to write match length");
527  return 1; /* Check output limit */
528  }
529  if (length >= ML_MASK) {
530  *token += ML_MASK;
531  length -= ML_MASK;
532  for(; length >= 510 ; length -= 510) { *op++ = 255; *op++ = 255; }
533  if (length >= 255) { length -= 255; *op++ = 255; }
534  *op++ = (BYTE)length;
535  } else {
536  *token += (BYTE)(length);
537  }
538 
539  /* Prepare next loop */
540  ip += matchLength;
541  anchor = ip;
542 
543  return 0;
544 }
size_t len
Definition: 6502dis.c:15
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
LZ4_FORCE_INLINE void LZ4_wildCopy8(void *dstPtr, const void *srcPtr, void *dstEnd)
Definition: lz4.c:408
static void LZ4_writeLE16(void *memPtr, U16 value)
Definition: lz4.c:395
unsigned short U16
Definition: lz4.c:287

References anchor, assert(), DEBUGLOG, ip, LASTLITERALS, len, length, limit, LZ4_STATIC_ASSERT, LZ4_wildCopy8(), LZ4_writeLE16(), MINMATCH, ML_BITS, ML_MASK, notLimited, NULL, pos, RUN_MASK, start, and U32.

Referenced by LZ4HC_compress_hashChain(), and LZ4HC_compress_optimal().

◆ LZ4HC_FindLongerMatch()

LZ4_FORCE_INLINE LZ4HC_match_t LZ4HC_FindLongerMatch ( LZ4HC_CCtx_internal *const  ctx,
const BYTE ip,
const BYTE *const  iHighLimit,
int  minLen,
int  nbSearches,
const dictCtx_directive  dict,
const HCfavor_e  favorDecSpeed 
)

Definition at line 1292 of file lz4hc.c.

1297 {
1298  LZ4HC_match_t match = { 0 , 0 };
1299  const BYTE* matchPtr = NULL;
1300  /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos),
1301  * but this won't be the case here, as we define iLowLimit==ip,
1302  * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */
1303  int matchLength = LZ4HC_InsertAndGetWiderMatch(ctx, ip, ip, iHighLimit, minLen, &matchPtr, &ip, nbSearches, 1 /*patternAnalysis*/, 1 /*chainSwap*/, dict, favorDecSpeed);
1304  if (matchLength <= minLen) return match;
1305  if (favorDecSpeed) {
1306  if ((matchLength>18) & (matchLength<=36)) matchLength=18; /* favor shortcut */
1307  }
1308  match.len = matchLength;
1309  match.off = (int)(ip-matchPtr);
1310  return match;
1311 }
unsigned char match[65280+2]
Definition: gun.c:165

References int, ip, LZ4HC_InsertAndGetWiderMatch(), match, and NULL.

Referenced by LZ4HC_compress_optimal().

◆ LZ4HC_hashPtr()

static U32 LZ4HC_hashPtr ( const void *  ptr)
static

Definition at line 88 of file lz4hc.c.

88 { return HASH_FUNCTION(LZ4_read32(ptr)); }
static U32 LZ4_read32(const void *memPtr)
Definition: lz4.c:362
#define HASH_FUNCTION(i)
Definition: lz4hc.c:82

References HASH_FUNCTION, and LZ4_read32().

Referenced by LZ4HC_Insert(), and LZ4HC_InsertAndGetWiderMatch().

◆ LZ4HC_init_internal()

static void LZ4HC_init_internal ( LZ4HC_CCtx_internal hc4,
const BYTE start 
)
static

Definition at line 100 of file lz4hc.c.

101 {
102  uptrval startingOffset = (uptrval)(hc4->end - hc4->base);
103  if (startingOffset > 1 GB) {
104  LZ4HC_clearTables(hc4);
105  startingOffset = 0;
106  }
107  startingOffset += 64 KB;
108  hc4->nextToUpdate = (U32) startingOffset;
109  hc4->base = start - startingOffset;
110  hc4->end = start;
111  hc4->dictBase = start - startingOffset;
112  hc4->dictLimit = (U32) startingOffset;
113  hc4->lowLimit = (U32) startingOffset;
114 }
static void LZ4HC_clearTables(LZ4HC_CCtx_internal *hc4)
Definition: lz4hc.c:94

References LZ4HC_CCtx_internal::base, LZ4HC_CCtx_internal::dictBase, LZ4HC_CCtx_internal::dictLimit, LZ4HC_CCtx_internal::end, GB, KB, LZ4HC_CCtx_internal::lowLimit, LZ4HC_clearTables(), LZ4HC_CCtx_internal::nextToUpdate, start, and U32.

Referenced by LZ4_compress_HC_destSize(), LZ4_compress_HC_extStateHC_fastReset(), LZ4_compressHC_continue_generic(), LZ4_createHC(), LZ4_loadDictHC(), and LZ4_resetStreamStateHC().

◆ LZ4HC_Insert()

LZ4_FORCE_INLINE void LZ4HC_Insert ( LZ4HC_CCtx_internal hc4,
const BYTE ip 
)

Definition at line 118 of file lz4hc.c.

119 {
120  U16* const chainTable = hc4->chainTable;
121  U32* const hashTable = hc4->hashTable;
122  const BYTE* const base = hc4->base;
123  U32 const target = (U32)(ip - base);
124  U32 idx = hc4->nextToUpdate;
125 
126  while (idx < target) {
127  U32 const h = LZ4HC_hashPtr(base+idx);
128  size_t delta = idx - hashTable[h];
129  if (delta>LZ4_DISTANCE_MAX) delta = LZ4_DISTANCE_MAX;
130  DELTANEXTU16(chainTable, idx) = (U16)delta;
131  hashTable[h] = idx;
132  idx++;
133  }
134 
135  hc4->nextToUpdate = target;
136 }
#define DELTANEXTU16(table, pos)
Definition: lz4hc.c:84
static U32 LZ4HC_hashPtr(const void *ptr)
Definition: lz4hc.c:88
int idx
Definition: setup.py:197
#define U16(val)
#define h(i)
Definition: sha256.c:48
static st64 delta
Definition: vmenus.c:2425

References LZ4HC_CCtx_internal::base, LZ4HC_CCtx_internal::chainTable, delta, DELTANEXTU16, h, LZ4HC_CCtx_internal::hashTable, setup::idx, ip, LZ4HC_hashPtr(), LZ4HC_CCtx_internal::nextToUpdate, U16, and U32.

Referenced by LZ4_loadDictHC(), LZ4HC_InsertAndGetWiderMatch(), and LZ4HC_setExternalDict().

◆ LZ4HC_InsertAndFindBestMatch()

LZ4_FORCE_INLINE int LZ4HC_InsertAndFindBestMatch ( LZ4HC_CCtx_internal *const  hc4,
const BYTE *const  ip,
const BYTE *const  iLimit,
const BYTE **  matchpos,
const int  maxNbAttempts,
const int  patternAnalysis,
const dictCtx_directive  dict 
)

Definition at line 446 of file lz4hc.c.

452 {
453  const BYTE* uselessPtr = ip;
454  /* note : LZ4HC_InsertAndGetWiderMatch() is able to modify the starting position of a match (*startpos),
455  * but this won't be the case here, as we define iLowLimit==ip,
456  * so LZ4HC_InsertAndGetWiderMatch() won't be allowed to search past ip */
457  return LZ4HC_InsertAndGetWiderMatch(hc4, ip, ip, iLimit, MINMATCH-1, matchpos, &uselessPtr, maxNbAttempts, patternAnalysis, 0 /*chainSwap*/, dict, favorCompressionRatio);
458 }

References favorCompressionRatio, ip, LZ4HC_InsertAndGetWiderMatch(), and MINMATCH.

Referenced by LZ4HC_compress_hashChain().

◆ LZ4HC_InsertAndGetWiderMatch()

LZ4_FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch ( LZ4HC_CCtx_internal hc4,
const BYTE *const  ip,
const BYTE *const  iLowLimit,
const BYTE *const  iHighLimit,
int  longest,
const BYTE **  matchpos,
const BYTE **  startpos,
const int  maxNbAttempts,
const int  patternAnalysis,
const int  chainSwap,
const dictCtx_directive  dict,
const HCfavor_e  favorDecSpeed 
)

Definition at line 236 of file lz4hc.c.

249 {
250  U16* const chainTable = hc4->chainTable;
251  U32* const HashTable = hc4->hashTable;
252  const LZ4HC_CCtx_internal * const dictCtx = hc4->dictCtx;
253  const BYTE* const base = hc4->base;
254  const U32 dictLimit = hc4->dictLimit;
255  const BYTE* const lowPrefixPtr = base + dictLimit;
256  const U32 ipIndex = (U32)(ip - base);
257  const U32 lowestMatchIndex = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
258  const BYTE* const dictBase = hc4->dictBase;
259  int const lookBackLength = (int)(ip-iLowLimit);
260  int nbAttempts = maxNbAttempts;
261  U32 matchChainPos = 0;
262  U32 const pattern = LZ4_read32(ip);
263  U32 matchIndex;
265  size_t srcPatternLength = 0;
266 
267  DEBUGLOG(7, "LZ4HC_InsertAndGetWiderMatch");
268  /* First Match */
269  LZ4HC_Insert(hc4, ip);
270  matchIndex = HashTable[LZ4HC_hashPtr(ip)];
271  DEBUGLOG(7, "First match at index %u / %u (lowestMatchIndex)",
272  matchIndex, lowestMatchIndex);
273 
274  while ((matchIndex>=lowestMatchIndex) && (nbAttempts>0)) {
275  int matchLength=0;
276  nbAttempts--;
277  assert(matchIndex < ipIndex);
278  if (favorDecSpeed && (ipIndex - matchIndex < 8)) {
279  /* do nothing */
280  } else if (matchIndex >= dictLimit) { /* within current Prefix */
281  const BYTE* const matchPtr = base + matchIndex;
282  assert(matchPtr >= lowPrefixPtr);
283  assert(matchPtr < ip);
284  assert(longest >= 1);
285  if (LZ4_read16(iLowLimit + longest - 1) == LZ4_read16(matchPtr - lookBackLength + longest - 1)) {
286  if (LZ4_read32(matchPtr) == pattern) {
287  int const back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, lowPrefixPtr) : 0;
288  matchLength = MINMATCH + (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
289  matchLength -= back;
290  if (matchLength > longest) {
291  longest = matchLength;
292  *matchpos = matchPtr + back;
293  *startpos = ip + back;
294  } } }
295  } else { /* lowestMatchIndex <= matchIndex < dictLimit */
296  const BYTE* const matchPtr = dictBase + matchIndex;
297  if (LZ4_read32(matchPtr) == pattern) {
298  const BYTE* const dictStart = dictBase + hc4->lowLimit;
299  int back = 0;
300  const BYTE* vLimit = ip + (dictLimit - matchIndex);
301  if (vLimit > iHighLimit) vLimit = iHighLimit;
302  matchLength = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
303  if ((ip+matchLength == vLimit) && (vLimit < iHighLimit))
304  matchLength += LZ4_count(ip+matchLength, lowPrefixPtr, iHighLimit);
305  back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictStart) : 0;
306  matchLength -= back;
307  if (matchLength > longest) {
308  longest = matchLength;
309  *matchpos = base + matchIndex + back; /* virtual pos, relative to ip, to retrieve offset */
310  *startpos = ip + back;
311  } } }
312 
313  if (chainSwap && matchLength==longest) { /* better match => select a better chain */
314  assert(lookBackLength==0); /* search forward only */
315  if (matchIndex + (U32)longest <= ipIndex) {
316  int const kTrigger = 4;
317  U32 distanceToNextMatch = 1;
318  int const end = longest - MINMATCH + 1;
319  int step = 1;
320  int accel = 1 << kTrigger;
321  int pos;
322  for (pos = 0; pos < end; pos += step) {
323  U32 const candidateDist = DELTANEXTU16(chainTable, matchIndex + (U32)pos);
324  step = (accel++ >> kTrigger);
325  if (candidateDist > distanceToNextMatch) {
326  distanceToNextMatch = candidateDist;
327  matchChainPos = (U32)pos;
328  accel = 1 << kTrigger;
329  }
330  }
331  if (distanceToNextMatch > 1) {
332  if (distanceToNextMatch > matchIndex) break; /* avoid overflow */
333  matchIndex -= distanceToNextMatch;
334  continue;
335  } } }
336 
337  { U32 const distNextMatch = DELTANEXTU16(chainTable, matchIndex);
338  if (patternAnalysis && distNextMatch==1 && matchChainPos==0) {
339  U32 const matchCandidateIdx = matchIndex-1;
340  /* may be a repeated pattern */
341  if (repeat == rep_untested) {
342  if ( ((pattern & 0xFFFF) == (pattern >> 16))
343  & ((pattern & 0xFF) == (pattern >> 24)) ) {
345  srcPatternLength = LZ4HC_countPattern(ip+sizeof(pattern), iHighLimit, pattern) + sizeof(pattern);
346  } else {
347  repeat = rep_not;
348  } }
349  if ( (repeat == rep_confirmed) && (matchCandidateIdx >= lowestMatchIndex)
350  && LZ4HC_protectDictEnd(dictLimit, matchCandidateIdx) ) {
351  const int extDict = matchCandidateIdx < dictLimit;
352  const BYTE* const matchPtr = (extDict ? dictBase : base) + matchCandidateIdx;
353  if (LZ4_read32(matchPtr) == pattern) { /* good candidate */
354  const BYTE* const dictStart = dictBase + hc4->lowLimit;
355  const BYTE* const iLimit = extDict ? dictBase + dictLimit : iHighLimit;
356  size_t forwardPatternLength = LZ4HC_countPattern(matchPtr+sizeof(pattern), iLimit, pattern) + sizeof(pattern);
357  if (extDict && matchPtr + forwardPatternLength == iLimit) {
358  U32 const rotatedPattern = LZ4HC_rotatePattern(forwardPatternLength, pattern);
359  forwardPatternLength += LZ4HC_countPattern(lowPrefixPtr, iHighLimit, rotatedPattern);
360  }
361  { const BYTE* const lowestMatchPtr = extDict ? dictStart : lowPrefixPtr;
362  size_t backLength = LZ4HC_reverseCountPattern(matchPtr, lowestMatchPtr, pattern);
363  size_t currentSegmentLength;
364  if (!extDict && matchPtr - backLength == lowPrefixPtr && hc4->lowLimit < dictLimit) {
365  U32 const rotatedPattern = LZ4HC_rotatePattern((U32)(-(int)backLength), pattern);
366  backLength += LZ4HC_reverseCountPattern(dictBase + dictLimit, dictStart, rotatedPattern);
367  }
368  /* Limit backLength not go further than lowestMatchIndex */
369  backLength = matchCandidateIdx - MAX(matchCandidateIdx - (U32)backLength, lowestMatchIndex);
370  assert(matchCandidateIdx - backLength >= lowestMatchIndex);
371  currentSegmentLength = backLength + forwardPatternLength;
372  /* Adjust to end of pattern if the source pattern fits, otherwise the beginning of the pattern */
373  if ( (currentSegmentLength >= srcPatternLength) /* current pattern segment large enough to contain full srcPatternLength */
374  && (forwardPatternLength <= srcPatternLength) ) { /* haven't reached this position yet */
375  U32 const newMatchIndex = matchCandidateIdx + (U32)forwardPatternLength - (U32)srcPatternLength; /* best position, full pattern, might be followed by more match */
376  if (LZ4HC_protectDictEnd(dictLimit, newMatchIndex))
377  matchIndex = newMatchIndex;
378  else {
379  /* Can only happen if started in the prefix */
380  assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict);
381  matchIndex = dictLimit;
382  }
383  } else {
384  U32 const newMatchIndex = matchCandidateIdx - (U32)backLength; /* farthest position in current segment, will find a match of length currentSegmentLength + maybe some back */
385  if (!LZ4HC_protectDictEnd(dictLimit, newMatchIndex)) {
386  assert(newMatchIndex >= dictLimit - 3 && newMatchIndex < dictLimit && !extDict);
387  matchIndex = dictLimit;
388  } else {
389  matchIndex = newMatchIndex;
390  if (lookBackLength==0) { /* no back possible */
391  size_t const maxML = MIN(currentSegmentLength, srcPatternLength);
392  if ((size_t)longest < maxML) {
393  assert(base + matchIndex != ip);
394  if ((size_t)(ip - base) - matchIndex > LZ4_DISTANCE_MAX) break;
395  assert(maxML < 2 GB);
396  longest = (int)maxML;
397  *matchpos = base + matchIndex; /* virtual pos, relative to ip, to retrieve offset */
398  *startpos = ip;
399  }
400  { U32 const distToNextPattern = DELTANEXTU16(chainTable, matchIndex);
401  if (distToNextPattern > matchIndex) break; /* avoid overflow */
402  matchIndex -= distToNextPattern;
403  } } } } }
404  continue;
405  } }
406  } } /* PA optimization */
407 
408  /* follow current chain */
409  matchIndex -= DELTANEXTU16(chainTable, matchIndex + matchChainPos);
410 
411  } /* while ((matchIndex>=lowestMatchIndex) && (nbAttempts)) */
412 
413  if ( dict == usingDictCtxHc
414  && nbAttempts > 0
415  && ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) {
416  size_t const dictEndOffset = (size_t)(dictCtx->end - dictCtx->base);
417  U32 dictMatchIndex = dictCtx->hashTable[LZ4HC_hashPtr(ip)];
418  assert(dictEndOffset <= 1 GB);
419  matchIndex = dictMatchIndex + lowestMatchIndex - (U32)dictEndOffset;
420  while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) {
421  const BYTE* const matchPtr = dictCtx->base + dictMatchIndex;
422 
423  if (LZ4_read32(matchPtr) == pattern) {
424  int mlt;
425  int back = 0;
426  const BYTE* vLimit = ip + (dictEndOffset - dictMatchIndex);
427  if (vLimit > iHighLimit) vLimit = iHighLimit;
428  mlt = (int)LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
429  back = lookBackLength ? LZ4HC_countBack(ip, matchPtr, iLowLimit, dictCtx->base + dictCtx->dictLimit) : 0;
430  mlt -= back;
431  if (mlt > longest) {
432  longest = mlt;
433  *matchpos = base + matchIndex + back;
434  *startpos = ip + back;
435  } }
436 
437  { U32 const nextOffset = DELTANEXTU16(dictCtx->chainTable, dictMatchIndex);
438  dictMatchIndex -= nextOffset;
439  matchIndex -= nextOffset;
440  } } }
441 
442  return longest;
443 }
static states step(struct re_guts *, sopno, sopno, states, int, states)
Definition: engine.c:888
LZ4_FORCE_INLINE unsigned LZ4_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *pInLimit)
Definition: lz4.c:603
static U16 LZ4_read16(const void *memPtr)
Definition: lz4.c:357
static int LZ4HC_protectDictEnd(U32 const dictLimit, U32 const matchIndex)
Definition: lz4hc.c:227
static unsigned LZ4HC_reverseCountPattern(const BYTE *ip, const BYTE *const iLow, U32 pattern)
Definition: lz4hc.c:206
LZ4_FORCE_INLINE int LZ4HC_countBack(const BYTE *const ip, const BYTE *const match, const BYTE *const iMin, const BYTE *const mMin)
Definition: lz4hc.c:141
static unsigned LZ4HC_countPattern(const BYTE *ip, const BYTE *const iEnd, U32 const pattern32)
Definition: lz4hc.c:172
static U32 LZ4HC_rotatePattern(size_t const rotate, U32 const pattern)
Definition: lz4hc.c:162
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155

References assert(), LZ4HC_CCtx_internal::base, LZ4HC_CCtx_internal::chainTable, DEBUGLOG, DELTANEXTU16, LZ4HC_CCtx_internal::dictBase, LZ4HC_CCtx_internal::dictCtx, LZ4HC_CCtx_internal::dictLimit, test_evm::end, LZ4HC_CCtx_internal::end, GB, LZ4HC_CCtx_internal::hashTable, int, ip, LZ4HC_CCtx_internal::lowLimit, LZ4_count(), LZ4_read16(), LZ4_read32(), LZ4HC_countBack(), LZ4HC_countPattern(), LZ4HC_hashPtr(), LZ4HC_Insert(), LZ4HC_protectDictEnd(), LZ4HC_reverseCountPattern(), LZ4HC_rotatePattern(), MAX, MIN, MINMATCH, pos, rep_confirmed, rep_not, rep_untested, repeat(), step(), U32, and usingDictCtxHc.

Referenced by LZ4HC_compress_hashChain(), LZ4HC_FindLongerMatch(), and LZ4HC_InsertAndFindBestMatch().

◆ LZ4HC_literalsPrice()

LZ4_FORCE_INLINE int LZ4HC_literalsPrice ( int const  litlen)

Definition at line 1260 of file lz4hc.c.

1261 {
1262  int price = litlen;
1263  assert(litlen >= 0);
1264  if (litlen >= (int)RUN_MASK)
1265  price += 1 + ((litlen-(int)RUN_MASK) / 255);
1266  return price;
1267 }

References assert(), int, and RUN_MASK.

Referenced by LZ4HC_compress_optimal(), and LZ4HC_sequencePrice().

◆ LZ4HC_protectDictEnd()

static int LZ4HC_protectDictEnd ( U32 const  dictLimit,
U32 const  matchIndex 
)
static

Definition at line 227 of file lz4hc.c.

228 {
229  return ((U32)((dictLimit - 1) - matchIndex) >= 3);
230 }

Referenced by LZ4HC_InsertAndGetWiderMatch().

◆ LZ4HC_reverseCountPattern()

static unsigned LZ4HC_reverseCountPattern ( const BYTE ip,
const BYTE *const  iLow,
U32  pattern 
)
static

Definition at line 206 of file lz4hc.c.

207 {
208  const BYTE* const iStart = ip;
209 
210  while (likely(ip >= iLow+4)) {
211  if (LZ4_read32(ip-4) != pattern) break;
212  ip -= 4;
213  }
214  { const BYTE* bytePtr = (const BYTE*)(&pattern) + 3; /* works for any endianess */
215  while (likely(ip>iLow)) {
216  if (ip[-1] != *bytePtr) break;
217  ip--; bytePtr--;
218  } }
219  return (unsigned)(iStart - ip);
220 }

References ip, likely, and LZ4_read32().

Referenced by LZ4HC_InsertAndGetWiderMatch().

◆ LZ4HC_rotatePattern()

static U32 LZ4HC_rotatePattern ( size_t const  rotate,
U32 const  pattern 
)
static

Definition at line 162 of file lz4hc.c.

163 {
164  size_t const bitsToRotate = (rotate & (sizeof(pattern) - 1)) << 3;
165  if (bitsToRotate == 0) return pattern;
166  return LZ4HC_rotl32(pattern, (int)bitsToRotate);
167 }
void rotate(unsigned char *list, unsigned len, unsigned rot)
Definition: gzappend.c:123
#define LZ4HC_rotl32(x, r)
Definition: lz4hc.c:158

References LZ4HC_rotl32, and rotate().

Referenced by LZ4HC_InsertAndGetWiderMatch().

◆ LZ4HC_sequencePrice()

LZ4_FORCE_INLINE int LZ4HC_sequencePrice ( int  litlen,
int  mlen 
)

Definition at line 1271 of file lz4hc.c.

1272 {
1273  int price = 1 + 2 ; /* token + 16-bit offset */
1274  assert(litlen >= 0);
1275  assert(mlen >= MINMATCH);
1276 
1277  price += LZ4HC_literalsPrice(litlen);
1278 
1279  if (mlen >= (int)(ML_MASK+MINMATCH))
1280  price += 1 + ((mlen-(int)(ML_MASK+MINMATCH)) / 255);
1281 
1282  return price;
1283 }

References assert(), int, LZ4HC_literalsPrice(), MINMATCH, and ML_MASK.

Referenced by LZ4HC_compress_optimal().

◆ LZ4HC_setExternalDict()

static void LZ4HC_setExternalDict ( LZ4HC_CCtx_internal ctxPtr,
const BYTE newBlock 
)
static

Definition at line 1083 of file lz4hc.c.

1084 {
1085  DEBUGLOG(4, "LZ4HC_setExternalDict(%p, %p)", ctxPtr, newBlock);
1086  if (ctxPtr->end >= ctxPtr->base + ctxPtr->dictLimit + 4)
1087  LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */
1088 
1089  /* Only one memory segment for extDict, so any previous extDict is lost at this stage */
1090  ctxPtr->lowLimit = ctxPtr->dictLimit;
1091  ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
1092  ctxPtr->dictBase = ctxPtr->base;
1093  ctxPtr->base = newBlock - ctxPtr->dictLimit;
1094  ctxPtr->end = newBlock;
1095  ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */
1096 
1097  /* cannot reference an extDict and a dictCtx at the same time */
1098  ctxPtr->dictCtx = NULL;
1099 }

References LZ4HC_CCtx_internal::base, DEBUGLOG, LZ4HC_CCtx_internal::dictBase, LZ4HC_CCtx_internal::dictCtx, LZ4HC_CCtx_internal::dictLimit, LZ4HC_CCtx_internal::end, LZ4HC_CCtx_internal::lowLimit, LZ4HC_Insert(), LZ4HC_CCtx_internal::nextToUpdate, NULL, and U32.

Referenced by LZ4_compressHC_continue_generic(), and LZ4HC_compress_generic_dictCtx().