Rizin
unix-like reverse engineering framework and cli tools
lz4frame.c File Reference
#include <stdlib.h>
#include <string.h>
#include "lz4frame.h"
#include "lz4.h"
#include "lz4hc.h"
#include "xxhash.h"

Go to the source code of this file.

Classes

struct  LZ4F_cctx_s
 
struct  LZ4F_CDict_s
 
struct  LZ4F_dctx_s
 

Macros

#define LZ4F_HEAPMODE   0
 
#define ALLOC(s)   malloc(s)
 
#define ALLOC_AND_ZERO(s)   calloc(1,(s))
 
#define FREEMEM(p)   free(p)
 
#define MEM_INIT(p, v, s)   memset((p),(v),(s))
 
#define LZ4F_STATIC_LINKING_ONLY
 
#define LZ4_STATIC_LINKING_ONLY
 
#define LZ4_HC_STATIC_LINKING_ONLY
 
#define XXH_STATIC_LINKING_ONLY
 
#define assert(condition)   ((void)0)
 
#define LZ4F_STATIC_ASSERT(c)   { enum { LZ4F_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
 
#define DEBUGLOG(l, ...)   {} /* disabled */
 
#define _1BIT   0x01
 
#define _2BITS   0x03
 
#define _3BITS   0x07
 
#define _4BITS   0x0F
 
#define _8BITS   0xFF
 
#define LZ4F_MAGIC_SKIPPABLE_START   0x184D2A50U
 
#define LZ4F_MAGICNUMBER   0x184D2204U
 
#define LZ4F_BLOCKUNCOMPRESSED_FLAG   0x80000000U
 
#define LZ4F_BLOCKSIZEID_DEFAULT   LZ4F_max64KB
 
#define LZ4F_GENERATE_STRING(STRING)   #STRING,
 
#define MIN(a, b)   ( (a) < (b) ? (a) : (b) )
 

Typedefs

typedef unsigned char BYTE
 
typedef unsigned short U16
 
typedef unsigned int U32
 
typedef signed int S32
 
typedef unsigned long long U64
 
typedef struct LZ4F_cctx_s LZ4F_cctx_t
 
typedef int(* compressFunc_t) (void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level, const LZ4F_CDict *cdict)
 

Enumerations

enum  LZ4F_lastBlockStatus { notDone , fromTmpBuffer , fromSrcBuffer }
 
enum  dStage_t {
  dstage_getFrameHeader =0 , dstage_storeFrameHeader , dstage_init , dstage_getBlockHeader ,
  dstage_storeBlockHeader , dstage_copyDirect , dstage_getBlockChecksum , dstage_getCBlock ,
  dstage_storeCBlock , dstage_flushOut , dstage_getSuffix , dstage_storeSuffix ,
  dstage_getSFrameSize , dstage_storeSFrameSize , dstage_skipSkippable
}
 

Functions

static U32 LZ4F_readLE32 (const void *src)
 
static void LZ4F_writeLE32 (void *dst, U32 value32)
 
static U64 LZ4F_readLE64 (const void *src)
 
static void LZ4F_writeLE64 (void *dst, U64 value64)
 
unsigned LZ4F_isError (LZ4F_errorCode_t code)
 
const char * LZ4F_getErrorName (LZ4F_errorCode_t code)
 
LZ4F_errorCodes LZ4F_getErrorCode (size_t functionResult)
 
static LZ4F_errorCode_t err0r (LZ4F_errorCodes code)
 
unsigned LZ4F_getVersion (void)
 
int LZ4F_compressionLevel_max (void)
 
size_t LZ4F_getBlockSize (unsigned blockSizeID)
 
static BYTE LZ4F_headerChecksum (const void *header, size_t length)
 
static LZ4F_blockSizeID_t LZ4F_optimalBSID (const LZ4F_blockSizeID_t requestedBSID, const size_t srcSize)
 
static size_t LZ4F_compressBound_internal (size_t srcSize, const LZ4F_preferences_t *preferencesPtr, size_t alreadyBuffered)
 
size_t LZ4F_compressFrameBound (size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
 
size_t LZ4F_compressFrame_usingCDict (LZ4F_cctx *cctx, void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_CDict *cdict, const LZ4F_preferences_t *preferencesPtr)
 
size_t LZ4F_compressFrame (void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
 
LZ4F_CDict * LZ4F_createCDict (const void *dictBuffer, size_t dictSize)
 
void LZ4F_freeCDict (LZ4F_CDict *cdict)
 
LZ4F_errorCode_t LZ4F_createCompressionContext (LZ4F_cctx **LZ4F_compressionContextPtr, unsigned version)
 
LZ4F_errorCode_t LZ4F_freeCompressionContext (LZ4F_cctx *cctxPtr)
 
static void LZ4F_initStream (void *ctx, const LZ4F_CDict *cdict, int level, LZ4F_blockMode_t blockMode)
 
size_t LZ4F_compressBegin_usingCDict (LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_CDict *cdict, const LZ4F_preferences_t *preferencesPtr)
 
size_t LZ4F_compressBegin (LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_preferences_t *preferencesPtr)
 
size_t LZ4F_compressBound (size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
 
static size_t LZ4F_makeBlock (void *dst, const void *src, size_t srcSize, compressFunc_t compress, void *lz4ctx, int level, const LZ4F_CDict *cdict, LZ4F_blockChecksum_t crcFlag)
 
static int LZ4F_compressBlock (void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
 
static int LZ4F_compressBlock_continue (void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
 
static int LZ4F_compressBlockHC (void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
 
static int LZ4F_compressBlockHC_continue (void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
 
static compressFunc_t LZ4F_selectCompression (LZ4F_blockMode_t blockMode, int level)
 
static int LZ4F_localSaveDict (LZ4F_cctx_t *cctxPtr)
 
size_t LZ4F_compressUpdate (LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_compressOptions_t *compressOptionsPtr)
 
size_t LZ4F_flush (LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t *compressOptionsPtr)
 
size_t LZ4F_compressEnd (LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t *compressOptionsPtr)
 
LZ4F_errorCode_t LZ4F_createDecompressionContext (LZ4F_dctx **LZ4F_decompressionContextPtr, unsigned versionNumber)
 
LZ4F_errorCode_t LZ4F_freeDecompressionContext (LZ4F_dctx *dctx)
 
void LZ4F_resetDecompressionContext (LZ4F_dctx *dctx)
 
static size_t LZ4F_decodeHeader (LZ4F_dctx *dctx, const void *src, size_t srcSize)
 
size_t LZ4F_headerSize (const void *src, size_t srcSize)
 
LZ4F_errorCode_t LZ4F_getFrameInfo (LZ4F_dctx *dctx, LZ4F_frameInfo_t *frameInfoPtr, const void *srcBuffer, size_t *srcSizePtr)
 
static void LZ4F_updateDict (LZ4F_dctx *dctx, const BYTE *dstPtr, size_t dstSize, const BYTE *dstBufferStart, unsigned withinTmp)
 
size_t LZ4F_decompress (LZ4F_dctx *dctx, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const LZ4F_decompressOptions_t *decompressOptionsPtr)
 
size_t LZ4F_decompress_usingDict (LZ4F_dctx *dctx, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const void *dict, size_t dictSize, const LZ4F_decompressOptions_t *decompressOptionsPtr)
 

Variables

static const size_t minFHSize = LZ4F_HEADER_SIZE_MIN
 
static const size_t maxFHSize = LZ4F_HEADER_SIZE_MAX
 
static const size_t BHSize = LZ4F_BLOCK_HEADER_SIZE
 
static const size_t BFSize = LZ4F_BLOCK_CHECKSUM_SIZE
 
static const char * LZ4F_errorStrings [] = { LZ4F_LIST_ERRORS(LZ4F_GENERATE_STRING) }
 

Macro Definition Documentation

◆ _1BIT

#define _1BIT   0x01

Definition at line 203 of file lz4frame.c.

◆ _2BITS

#define _2BITS   0x03

Definition at line 204 of file lz4frame.c.

◆ _3BITS

#define _3BITS   0x07

Definition at line 205 of file lz4frame.c.

◆ _4BITS

#define _4BITS   0x0F

Definition at line 206 of file lz4frame.c.

◆ _8BITS

#define _8BITS   0xFF

Definition at line 207 of file lz4frame.c.

◆ ALLOC

#define ALLOC (   s)    malloc(s)

Definition at line 76 of file lz4frame.c.

◆ ALLOC_AND_ZERO

#define ALLOC_AND_ZERO (   s)    calloc(1,(s))

Definition at line 77 of file lz4frame.c.

◆ assert

#define assert (   condition)    ((void)0)

Definition at line 107 of file lz4frame.c.

◆ DEBUGLOG

#define DEBUGLOG (   l,
  ... 
)    {} /* disabled */

Definition at line 123 of file lz4frame.c.

◆ FREEMEM

#define FREEMEM (   p)    free(p)

Definition at line 78 of file lz4frame.c.

◆ LZ4_HC_STATIC_LINKING_ONLY

#define LZ4_HC_STATIC_LINKING_ONLY

Definition at line 94 of file lz4frame.c.

◆ LZ4_STATIC_LINKING_ONLY

#define LZ4_STATIC_LINKING_ONLY

Definition at line 92 of file lz4frame.c.

◆ LZ4F_BLOCKSIZEID_DEFAULT

#define LZ4F_BLOCKSIZEID_DEFAULT   LZ4F_max64KB

Definition at line 212 of file lz4frame.c.

◆ LZ4F_BLOCKUNCOMPRESSED_FLAG

#define LZ4F_BLOCKUNCOMPRESSED_FLAG   0x80000000U

Definition at line 211 of file lz4frame.c.

◆ LZ4F_GENERATE_STRING

#define LZ4F_GENERATE_STRING (   STRING)    #STRING,

Definition at line 245 of file lz4frame.c.

◆ LZ4F_HEAPMODE

#define LZ4F_HEAPMODE   0

Definition at line 61 of file lz4frame.c.

◆ LZ4F_MAGIC_SKIPPABLE_START

#define LZ4F_MAGIC_SKIPPABLE_START   0x184D2A50U

Definition at line 209 of file lz4frame.c.

◆ LZ4F_MAGICNUMBER

#define LZ4F_MAGICNUMBER   0x184D2204U

Definition at line 210 of file lz4frame.c.

◆ LZ4F_STATIC_ASSERT

#define LZ4F_STATIC_ASSERT (   c)    { enum { LZ4F_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */

Definition at line 111 of file lz4frame.c.

◆ LZ4F_STATIC_LINKING_ONLY

#define LZ4F_STATIC_LINKING_ONLY

Definition at line 90 of file lz4frame.c.

◆ MEM_INIT

#define MEM_INIT (   p,
  v,
  s 
)    memset((p),(v),(s))

Definition at line 83 of file lz4frame.c.

◆ MIN

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

Definition at line 292 of file lz4frame.c.

◆ XXH_STATIC_LINKING_ONLY

#define XXH_STATIC_LINKING_ONLY

Definition at line 96 of file lz4frame.c.

Typedef Documentation

◆ BYTE

typedef unsigned char BYTE

Definition at line 138 of file lz4frame.c.

◆ compressFunc_t

typedef int(* compressFunc_t) (void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level, const LZ4F_CDict *cdict)

Definition at line 733 of file lz4frame.c.

◆ LZ4F_cctx_t

typedef struct LZ4F_cctx_s LZ4F_cctx_t

◆ S32

typedef signed int S32

Definition at line 141 of file lz4frame.c.

◆ U16

typedef unsigned short U16

Definition at line 139 of file lz4frame.c.

◆ U32

typedef unsigned int U32

Definition at line 140 of file lz4frame.c.

◆ U64

typedef unsigned long long U64

Definition at line 142 of file lz4frame.c.

Enumeration Type Documentation

◆ dStage_t

enum dStage_t
Enumerator
dstage_getFrameHeader 
dstage_storeFrameHeader 
dstage_init 
dstage_getBlockHeader 
dstage_storeBlockHeader 
dstage_copyDirect 
dstage_getBlockChecksum 
dstage_getCBlock 
dstage_storeCBlock 
dstage_flushOut 
dstage_getSuffix 
dstage_storeSuffix 
dstage_getSFrameSize 
dstage_storeSFrameSize 
dstage_skipSkippable 

Definition at line 1029 of file lz4frame.c.

1029  {
1031  dstage_init,
1039 } dStage_t;
dStage_t
Definition: lz4frame.c:1029
@ dstage_skipSkippable
Definition: lz4frame.c:1038
@ dstage_getCBlock
Definition: lz4frame.c:1034
@ dstage_getSuffix
Definition: lz4frame.c:1036
@ dstage_getFrameHeader
Definition: lz4frame.c:1030
@ dstage_getSFrameSize
Definition: lz4frame.c:1037
@ dstage_storeSFrameSize
Definition: lz4frame.c:1037
@ dstage_storeSuffix
Definition: lz4frame.c:1036
@ dstage_getBlockChecksum
Definition: lz4frame.c:1033
@ dstage_init
Definition: lz4frame.c:1031
@ dstage_storeBlockHeader
Definition: lz4frame.c:1032
@ dstage_storeCBlock
Definition: lz4frame.c:1034
@ dstage_storeFrameHeader
Definition: lz4frame.c:1030
@ dstage_copyDirect
Definition: lz4frame.c:1033
@ dstage_flushOut
Definition: lz4frame.c:1035
@ dstage_getBlockHeader
Definition: lz4frame.c:1032

◆ LZ4F_lastBlockStatus

Enumerator
notDone 
fromTmpBuffer 
fromSrcBuffer 

Definition at line 816 of file lz4frame.c.

LZ4F_lastBlockStatus
Definition: lz4frame.c:816
@ fromSrcBuffer
Definition: lz4frame.c:816
@ notDone
Definition: lz4frame.c:816
@ fromTmpBuffer
Definition: lz4frame.c:816

Function Documentation

◆ err0r()

static LZ4F_errorCode_t err0r ( LZ4F_errorCodes  code)
static

Definition at line 267 of file lz4frame.c.

268 {
269  /* A compilation error here means sizeof(ptrdiff_t) is not large enough */
270  LZ4F_STATIC_ASSERT(sizeof(ptrdiff_t) >= sizeof(size_t));
271  return (LZ4F_errorCode_t)-(ptrdiff_t)code;
272 }
#define LZ4F_STATIC_ASSERT(c)
Definition: lz4frame.c:111
size_t LZ4F_errorCode_t
Definition: lz4frame.h:103
int ptrdiff_t
Definition: sftypes.h:68
Definition: inftree9.h:24

References LZ4F_STATIC_ASSERT.

Referenced by LZ4F_compressBegin_usingCDict(), LZ4F_compressEnd(), LZ4F_compressFrame_usingCDict(), LZ4F_compressUpdate(), LZ4F_createCompressionContext(), LZ4F_createDecompressionContext(), LZ4F_decodeHeader(), LZ4F_decompress(), LZ4F_flush(), LZ4F_getBlockSize(), LZ4F_getFrameInfo(), and LZ4F_headerSize().

◆ LZ4F_compressBegin()

size_t LZ4F_compressBegin ( LZ4F_cctx cctxPtr,
void *  dstBuffer,
size_t  dstCapacity,
const LZ4F_preferences_t preferencesPtr 
)

LZ4F_compressBegin() : init streaming compression and writes frame header into dstBuffer. dstBuffer must be >= LZ4F_HEADER_SIZE_MAX bytes. preferencesPtr can be NULL, in which case default parameters are selected.

Returns
: number of bytes written into dstBuffer for the header or an error code (can be tested using LZ4F_isError())

Definition at line 710 of file lz4frame.c.

713 {
714  return LZ4F_compressBegin_usingCDict(cctxPtr, dstBuffer, dstCapacity,
715  NULL, preferencesPtr);
716 }
#define NULL
Definition: cris-opc.c:27
size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_CDict *cdict, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:598

References LZ4F_compressBegin_usingCDict(), and NULL.

Referenced by basicTests(), compress_file_internal(), and fuzzerTests().

◆ LZ4F_compressBegin_usingCDict()

size_t LZ4F_compressBegin_usingCDict ( LZ4F_cctx cctxPtr,
void *  dstBuffer,
size_t  dstCapacity,
const LZ4F_CDict *  cdict,
const LZ4F_preferences_t preferencesPtr 
)

LZ4F_compressBegin_usingCDict() : init streaming compression and writes frame header into dstBuffer. dstBuffer must be >= LZ4F_HEADER_SIZE_MAX bytes.

Returns
: number of bytes written into dstBuffer for the header or an error code (can be tested using LZ4F_isError())

Definition at line 598 of file lz4frame.c.

602 {
603  LZ4F_preferences_t prefNull;
604  BYTE* const dstStart = (BYTE*)dstBuffer;
605  BYTE* dstPtr = dstStart;
606  BYTE* headerStart;
607 
608  if (dstCapacity < maxFHSize) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
609  MEM_INIT(&prefNull, 0, sizeof(prefNull));
610  if (preferencesPtr == NULL) preferencesPtr = &prefNull;
611  cctxPtr->prefs = *preferencesPtr;
612 
613  /* Ctx Management */
614  { U16 const ctxTypeID = (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ? 1 : 2;
615  if (cctxPtr->lz4CtxAlloc < ctxTypeID) {
616  FREEMEM(cctxPtr->lz4CtxPtr);
617  if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
618  cctxPtr->lz4CtxPtr = LZ4_createStream();
619  } else {
620  cctxPtr->lz4CtxPtr = LZ4_createStreamHC();
621  }
622  if (cctxPtr->lz4CtxPtr == NULL)
623  return err0r(LZ4F_ERROR_allocation_failed);
624  cctxPtr->lz4CtxAlloc = ctxTypeID;
625  cctxPtr->lz4CtxState = ctxTypeID;
626  } else if (cctxPtr->lz4CtxState != ctxTypeID) {
627  /* otherwise, a sufficient buffer is allocated, but we need to
628  * reset it to the correct context type */
629  if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
630  LZ4_initStream((LZ4_stream_t *) cctxPtr->lz4CtxPtr, sizeof (LZ4_stream_t));
631  } else {
634  }
635  cctxPtr->lz4CtxState = ctxTypeID;
636  }
637  }
638 
639  /* Buffer Management */
640  if (cctxPtr->prefs.frameInfo.blockSizeID == 0)
643 
644  { size_t const requiredBuffSize = preferencesPtr->autoFlush ?
645  ((cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 64 KB : 0) : /* only needs past data up to window size */
646  cctxPtr->maxBlockSize + ((cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 128 KB : 0);
647 
648  if (cctxPtr->maxBufferSize < requiredBuffSize) {
649  cctxPtr->maxBufferSize = 0;
650  FREEMEM(cctxPtr->tmpBuff);
651  cctxPtr->tmpBuff = (BYTE*)ALLOC_AND_ZERO(requiredBuffSize);
652  if (cctxPtr->tmpBuff == NULL) return err0r(LZ4F_ERROR_allocation_failed);
653  cctxPtr->maxBufferSize = requiredBuffSize;
654  } }
655  cctxPtr->tmpIn = cctxPtr->tmpBuff;
656  cctxPtr->tmpInSize = 0;
657  (void)XXH32_reset(&(cctxPtr->xxh), 0);
658 
659  /* context init */
660  cctxPtr->cdict = cdict;
661  if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
662  /* frame init only for blockLinked : blockIndependent will be init at each block */
664  }
665  if (preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN) {
666  LZ4_favorDecompressionSpeed((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, (int)preferencesPtr->favorDecSpeed);
667  }
668 
669  /* Magic Number */
671  dstPtr += 4;
672  headerStart = dstPtr;
673 
674  /* FLG Byte */
675  *dstPtr++ = (BYTE)(((1 & _2BITS) << 6) /* Version('01') */
676  + ((cctxPtr->prefs.frameInfo.blockMode & _1BIT ) << 5)
677  + ((cctxPtr->prefs.frameInfo.blockChecksumFlag & _1BIT ) << 4)
678  + ((unsigned)(cctxPtr->prefs.frameInfo.contentSize > 0) << 3)
679  + ((cctxPtr->prefs.frameInfo.contentChecksumFlag & _1BIT ) << 2)
680  + (cctxPtr->prefs.frameInfo.dictID > 0) );
681  /* BD Byte */
682  *dstPtr++ = (BYTE)((cctxPtr->prefs.frameInfo.blockSizeID & _3BITS) << 4);
683  /* Optional Frame content size field */
684  if (cctxPtr->prefs.frameInfo.contentSize) {
685  LZ4F_writeLE64(dstPtr, cctxPtr->prefs.frameInfo.contentSize);
686  dstPtr += 8;
687  cctxPtr->totalInSize = 0;
688  }
689  /* Optional dictionary ID field */
690  if (cctxPtr->prefs.frameInfo.dictID) {
691  LZ4F_writeLE32(dstPtr, cctxPtr->prefs.frameInfo.dictID);
692  dstPtr += 4;
693  }
694  /* Header CRC Byte */
695  *dstPtr = LZ4F_headerChecksum(headerStart, (size_t)(dstPtr - headerStart));
696  dstPtr++;
697 
698  cctxPtr->cStage = 1; /* header written, now request input data block */
699  return (size_t)(dstPtr - dstStart);
700 }
static void struct sockaddr socklen_t static fromlen static backlog static fork char char char static envp int struct rusage static rusage struct utsname static buf struct sembuf unsigned
Definition: sflib.h:97
XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed)
Definition: xxhash.c:437
LZ4_stream_t * LZ4_createStream(void)
Definition: lz4.c:1423
LZ4_stream_t * LZ4_initStream(void *buffer, size_t size)
Definition: lz4.c:1443
unsigned char BYTE
Definition: lz4.c:286
unsigned short U16
Definition: lz4.c:287
#define _2BITS
Definition: lz4frame.c:204
static void LZ4F_writeLE32(void *dst, U32 value32)
Definition: lz4frame.c:157
#define _3BITS
Definition: lz4frame.c:205
size_t LZ4F_getBlockSize(unsigned blockSizeID)
Definition: lz4frame.c:278
unsigned char BYTE
Definition: lz4frame.c:138
static const size_t maxFHSize
Definition: lz4frame.c:215
static LZ4F_errorCode_t err0r(LZ4F_errorCodes code)
Definition: lz4frame.c:267
#define LZ4F_BLOCKSIZEID_DEFAULT
Definition: lz4frame.c:212
#define FREEMEM(p)
Definition: lz4frame.c:78
#define LZ4F_MAGICNUMBER
Definition: lz4frame.c:210
#define ALLOC_AND_ZERO(s)
Definition: lz4frame.c:77
#define MEM_INIT(p, v, s)
Definition: lz4frame.c:83
static void LZ4F_writeLE64(void *dst, U64 value64)
Definition: lz4frame.c:180
static BYTE LZ4F_headerChecksum(const void *header, size_t length)
Definition: lz4frame.c:294
#define _1BIT
Definition: lz4frame.c:203
static void LZ4F_initStream(void *ctx, const LZ4F_CDict *cdict, int level, LZ4F_blockMode_t blockMode)
Definition: lz4frame.c:570
@ LZ4F_blockLinked
Definition: lz4frame.h:139
void LZ4_favorDecompressionSpeed(LZ4_streamHC_t *LZ4_streamHCPtr, int favor)
Definition: lz4hc.c:1049
LZ4_streamHC_t * LZ4_initStreamHC(void *buffer, size_t size)
Definition: lz4hc.c:1003
LZ4_streamHC_t * LZ4_createStreamHC(void)
Definition: lz4hc.c:985
void LZ4_setCompressionLevel(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1041
#define LZ4HC_CLEVEL_MIN
Definition: lz4hc.h:47
BYTE * tmpBuff
Definition: lz4frame.c:231
U16 lz4CtxState
Definition: lz4frame.c:238
size_t tmpInSize
Definition: lz4frame.c:233
U32 cStage
Definition: lz4frame.c:227
U16 lz4CtxAlloc
Definition: lz4frame.c:237
const LZ4F_CDict * cdict
Definition: lz4frame.c:228
U64 totalInSize
Definition: lz4frame.c:234
size_t maxBufferSize
Definition: lz4frame.c:230
LZ4F_preferences_t prefs
Definition: lz4frame.c:225
size_t maxBlockSize
Definition: lz4frame.c:229
void * lz4CtxPtr
Definition: lz4frame.c:236
BYTE * tmpIn
Definition: lz4frame.c:232
XXH32_state_t xxh
Definition: lz4frame.c:235
LZ4F_contentChecksum_t contentChecksumFlag
Definition: lz4frame.h:178
unsigned dictID
Definition: lz4frame.h:181
unsigned long long contentSize
Definition: lz4frame.h:180
LZ4F_blockChecksum_t blockChecksumFlag
Definition: lz4frame.h:182
LZ4F_blockMode_t blockMode
Definition: lz4frame.h:177
LZ4F_blockSizeID_t blockSizeID
Definition: lz4frame.h:176
LZ4F_frameInfo_t frameInfo
Definition: lz4frame.h:193
unsigned favorDecSpeed
Definition: lz4frame.h:196
unsigned autoFlush
Definition: lz4frame.h:195
#define KB
Definition: unum.c:91

References _1BIT, _2BITS, _3BITS, ALLOC_AND_ZERO, LZ4F_preferences_t::autoFlush, LZ4F_frameInfo_t::blockChecksumFlag, LZ4F_frameInfo_t::blockMode, LZ4F_frameInfo_t::blockSizeID, LZ4F_cctx_s::cdict, LZ4F_preferences_t::compressionLevel, LZ4F_frameInfo_t::contentChecksumFlag, LZ4F_frameInfo_t::contentSize, LZ4F_cctx_s::cStage, LZ4F_frameInfo_t::dictID, err0r(), LZ4F_preferences_t::favorDecSpeed, LZ4F_preferences_t::frameInfo, FREEMEM, KB, LZ4_createStream(), LZ4_createStreamHC(), LZ4_favorDecompressionSpeed(), LZ4_initStream(), LZ4_initStreamHC(), LZ4_setCompressionLevel(), LZ4F_cctx_s::lz4CtxAlloc, LZ4F_cctx_s::lz4CtxPtr, LZ4F_cctx_s::lz4CtxState, LZ4F_blockLinked, LZ4F_BLOCKSIZEID_DEFAULT, LZ4F_getBlockSize(), LZ4F_headerChecksum(), LZ4F_initStream(), LZ4F_MAGICNUMBER, LZ4F_writeLE32(), LZ4F_writeLE64(), LZ4HC_CLEVEL_MIN, LZ4F_cctx_s::maxBlockSize, LZ4F_cctx_s::maxBufferSize, maxFHSize, MEM_INIT, NULL, LZ4F_cctx_s::prefs, LZ4F_cctx_s::tmpBuff, LZ4F_cctx_s::tmpIn, LZ4F_cctx_s::tmpInSize, LZ4F_cctx_s::totalInSize, unsigned, LZ4F_cctx_s::xxh, and XXH32_reset().

Referenced by LZ4F_compressBegin(), LZ4F_compressFrame_usingCDict(), and LZ4IO_compressFilename_extRess().

◆ LZ4F_compressBlock()

static int LZ4F_compressBlock ( void *  ctx,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  level,
const LZ4F_CDict *  cdict 
)
static

Definition at line 766 of file lz4frame.c.

767 {
768  int const acceleration = (level < 0) ? -level + 1 : 1;
770  if (cdict) {
771  return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
772  } else {
773  return LZ4_compress_fast_extState_fastReset(ctx, src, dst, srcSize, dstCapacity, acceleration);
774  }
775 }
lzma_index * src
Definition: index.h:567
int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
Definition: lz4.c:1565
int LZ4_compress_fast_extState_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration)
Definition: lz4.c:1316
char int srcSize
Definition: lz4.h:697
char * dst
Definition: lz4.h:724
@ LZ4F_blockIndependent
Definition: lz4frame.h:140
static int level
Definition: vmenus.c:2424

References dst, level, LZ4_compress_fast_continue(), LZ4_compress_fast_extState_fastReset(), LZ4F_blockIndependent, LZ4F_initStream(), src, and srcSize.

Referenced by LZ4F_selectCompression().

◆ LZ4F_compressBlock_continue()

static int LZ4F_compressBlock_continue ( void *  ctx,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  level,
const LZ4F_CDict *  cdict 
)
static

Definition at line 777 of file lz4frame.c.

778 {
779  int const acceleration = (level < 0) ? -level + 1 : 1;
780  (void)cdict; /* init once at beginning of frame */
781  return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
782 }

References dst, level, LZ4_compress_fast_continue(), src, and srcSize.

Referenced by LZ4F_selectCompression().

◆ LZ4F_compressBlockHC()

static int LZ4F_compressBlockHC ( void *  ctx,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  level,
const LZ4F_CDict *  cdict 
)
static

Definition at line 784 of file lz4frame.c.

785 {
787  if (cdict) {
788  return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
789  }
790  return LZ4_compress_HC_extStateHC_fastReset(ctx, src, dst, srcSize, dstCapacity, level);
791 }
int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
Definition: lz4hc.c:1138
int LZ4_compress_HC_extStateHC_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:935

References dst, level, LZ4_compress_HC_continue(), LZ4_compress_HC_extStateHC_fastReset(), LZ4F_blockIndependent, LZ4F_initStream(), src, and srcSize.

Referenced by LZ4F_selectCompression().

◆ LZ4F_compressBlockHC_continue()

static int LZ4F_compressBlockHC_continue ( void *  ctx,
const char *  src,
char *  dst,
int  srcSize,
int  dstCapacity,
int  level,
const LZ4F_CDict *  cdict 
)
static

Definition at line 793 of file lz4frame.c.

794 {
795  (void)level; (void)cdict; /* init once at beginning of frame */
796  return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
797 }

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

Referenced by LZ4F_selectCompression().

◆ LZ4F_compressBound()

size_t LZ4F_compressBound ( size_t  srcSize,
const LZ4F_preferences_t prefsPtr 
)

LZ4F_compressBound() : Provides minimum dstCapacity required to guarantee success of LZ4F_compressUpdate(), given a srcSize and preferences, for a worst case scenario. When srcSize==0, LZ4F_compressBound() provides an upper bound for LZ4F_flush() and LZ4F_compressEnd() instead. Note that the result is only valid for a single invocation of LZ4F_compressUpdate(). When invoking LZ4F_compressUpdate() multiple times, if the output buffer is gradually filled up instead of emptied and re-used from its start, one must check if there is enough remaining capacity before each invocation, using LZ4F_compressBound().

Returns
is always the same for a srcSize and prefsPtr. prefsPtr is optional : when NULL is provided, preferences will be set to cover worst case scenario. tech details :
if automatic flushing is not enabled, includes the possibility that internal buffer might already be filled by up to (blockSize-1) bytes. It also includes frame footer (ending + checksum), since it might be generated by LZ4F_compressEnd().
doesn't include frame header, as it was already generated by LZ4F_compressBegin().

Definition at line 724 of file lz4frame.c.

725 {
726  if (preferencesPtr && preferencesPtr->autoFlush) {
727  return LZ4F_compressBound_internal(srcSize, preferencesPtr, 0);
728  }
729  return LZ4F_compressBound_internal(srcSize, preferencesPtr, (size_t)-1);
730 }
static size_t LZ4F_compressBound_internal(size_t srcSize, const LZ4F_preferences_t *preferencesPtr, size_t alreadyBuffered)
Definition: lz4frame.c:324

References LZ4F_preferences_t::autoFlush, LZ4F_compressBound_internal(), and srcSize.

Referenced by basicTests(), compress_file(), compress_file_internal(), and fuzzerTests().

◆ LZ4F_compressBound_internal()

static size_t LZ4F_compressBound_internal ( size_t  srcSize,
const LZ4F_preferences_t preferencesPtr,
size_t  alreadyBuffered 
)
static

LZ4F_compressBound_internal() : Provides dstCapacity given a srcSize to guarantee operation success in worst case situations. prefsPtr is optional : if NULL is provided, preferences will be set to cover worst case scenario.

Returns
is always the same for a srcSize and prefsPtr, so it can be relied upon to size reusable buffers. When srcSize==0, LZ4F_compressBound() provides an upper bound for LZ4F_flush() and LZ4F_compressEnd() operations.

Definition at line 324 of file lz4frame.c.

327 {
329  prefsNull.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled; /* worst case */
330  prefsNull.frameInfo.blockChecksumFlag = LZ4F_blockChecksumEnabled; /* worst case */
331  { const LZ4F_preferences_t* const prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
332  U32 const flush = prefsPtr->autoFlush | (srcSize==0);
333  LZ4F_blockSizeID_t const blockID = prefsPtr->frameInfo.blockSizeID;
334  size_t const blockSize = LZ4F_getBlockSize(blockID);
335  size_t const maxBuffered = blockSize - 1;
336  size_t const bufferedSize = MIN(alreadyBuffered, maxBuffered);
337  size_t const maxSrcSize = srcSize + bufferedSize;
338  unsigned const nbFullBlocks = (unsigned)(maxSrcSize / blockSize);
339  size_t const partialBlockSize = maxSrcSize & (blockSize-1);
340  size_t const lastBlockSize = flush ? partialBlockSize : 0;
341  unsigned const nbBlocks = nbFullBlocks + (lastBlockSize>0);
342 
343  size_t const blockCRCSize = BFSize * prefsPtr->frameInfo.blockChecksumFlag;
344  size_t const frameEnd = BHSize + (prefsPtr->frameInfo.contentChecksumFlag*BFSize);
345 
346  return ((BHSize + blockCRCSize) * nbBlocks) +
347  (blockSize * nbFullBlocks) + lastBlockSize + frameEnd;
348  }
349 }
unsigned int U32
Definition: lz4.c:288
#define MIN(a, b)
Definition: lz4frame.c:292
static const size_t BHSize
Definition: lz4frame.c:216
static const size_t BFSize
Definition: lz4frame.c:217
LZ4F_blockSizeID_t
Definition: lz4frame.h:123
#define LZ4F_INIT_PREFERENCES
Definition: lz4frame.h:200
@ LZ4F_contentChecksumEnabled
Definition: lz4frame.h:147
@ LZ4F_blockChecksumEnabled
Definition: lz4frame.h:154

References LZ4F_preferences_t::autoFlush, BFSize, BHSize, LZ4F_frameInfo_t::blockChecksumFlag, LZ4F_frameInfo_t::blockSizeID, LZ4F_frameInfo_t::contentChecksumFlag, LZ4F_preferences_t::frameInfo, LZ4F_blockChecksumEnabled, LZ4F_contentChecksumEnabled, LZ4F_getBlockSize(), LZ4F_INIT_PREFERENCES, MIN, NULL, srcSize, and unsigned.

Referenced by LZ4F_compressBound(), LZ4F_compressFrameBound(), and LZ4F_compressUpdate().

◆ LZ4F_compressEnd()

size_t LZ4F_compressEnd ( LZ4F_cctx cctxPtr,
void *  dstBuffer,
size_t  dstCapacity,
const LZ4F_compressOptions_t compressOptionsPtr 
)

LZ4F_compressEnd() : When you want to properly finish the compressed frame, just call LZ4F_compressEnd(). It will flush whatever data remained within compressionContext (like LZ4_flush()) but also properly finalize the frame, with an endMark and an (optional) checksum. LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.

Returns
: the number of bytes written into dstBuffer (necessarily >= 4 (endMark size)) or an error code if it fails (can be tested using LZ4F_isError()) The context can then be used again to compress a new frame, starting with LZ4F_compressBegin().

Definition at line 986 of file lz4frame.c.

989 {
990  BYTE* const dstStart = (BYTE*)dstBuffer;
991  BYTE* dstPtr = dstStart;
992 
993  size_t const flushSize = LZ4F_flush(cctxPtr, dstBuffer, dstCapacity, compressOptionsPtr);
994  DEBUGLOG(5,"LZ4F_compressEnd: dstCapacity=%u", (unsigned)dstCapacity);
995  if (LZ4F_isError(flushSize)) return flushSize;
996  dstPtr += flushSize;
997 
998  assert(flushSize <= dstCapacity);
999  dstCapacity -= flushSize;
1000 
1001  if (dstCapacity < 4) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
1002  LZ4F_writeLE32(dstPtr, 0);
1003  dstPtr += 4; /* endMark */
1004 
1006  U32 const xxh = XXH32_digest(&(cctxPtr->xxh));
1007  if (dstCapacity < 8) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
1008  DEBUGLOG(5,"Writing 32-bit content checksum");
1009  LZ4F_writeLE32(dstPtr, xxh);
1010  dstPtr+=4; /* content Checksum */
1011  }
1012 
1013  cctxPtr->cStage = 0; /* state is now re-usable (with identical preferences) */
1014  cctxPtr->maxBufferSize = 0; /* reuse HC context */
1015 
1016  if (cctxPtr->prefs.frameInfo.contentSize) {
1017  if (cctxPtr->prefs.frameInfo.contentSize != cctxPtr->totalInSize)
1018  return err0r(LZ4F_ERROR_frameSize_wrong);
1019  }
1020 
1021  return (size_t)(dstPtr - dstStart);
1022 }
XXH_PUBLIC_API unsigned int XXH32_digest(const XXH32_state_t *state_in)
Definition: xxhash.c:546
size_t LZ4F_flush(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t *compressOptionsPtr)
Definition: lz4frame.c:938
#define DEBUGLOG(l,...)
Definition: lz4frame.c:123
unsigned LZ4F_isError(LZ4F_errorCode_t code)
Definition: lz4frame.c:249
#define assert(condition)
Definition: lz4frame.c:107

References assert, LZ4F_frameInfo_t::contentChecksumFlag, LZ4F_frameInfo_t::contentSize, LZ4F_cctx_s::cStage, DEBUGLOG, err0r(), LZ4F_preferences_t::frameInfo, LZ4F_contentChecksumEnabled, LZ4F_flush(), LZ4F_isError(), LZ4F_writeLE32(), LZ4F_cctx_s::maxBufferSize, LZ4F_cctx_s::prefs, LZ4F_cctx_s::totalInSize, LZ4F_cctx_s::xxh, and XXH32_digest().

Referenced by basicTests(), compress_file_internal(), fuzzerTests(), LZ4F_compressFrame_usingCDict(), and LZ4IO_compressFilename_extRess().

◆ LZ4F_compressFrame()

size_t LZ4F_compressFrame ( void *  dstBuffer,
size_t  dstCapacity,
const void *  srcBuffer,
size_t  srcSize,
const LZ4F_preferences_t preferencesPtr 
)

LZ4F_compressFrame() : Compress an entire srcBuffer into a valid LZ4 frame, in a single step. dstBuffer MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr). The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default.

Returns
: number of bytes written into dstBuffer. or an error code if it fails (can be tested using LZ4F_isError())

Definition at line 429 of file lz4frame.c.

432 {
433  size_t result;
434 #if (LZ4F_HEAPMODE)
435  LZ4F_cctx_t *cctxPtr;
436  result = LZ4F_createCompressionContext(&cctxPtr, LZ4F_VERSION);
437  if (LZ4F_isError(result)) return result;
438 #else
439  LZ4F_cctx_t cctx;
440  LZ4_stream_t lz4ctx;
441  LZ4F_cctx_t *cctxPtr = &cctx;
442 
443  DEBUGLOG(4, "LZ4F_compressFrame");
444  MEM_INIT(&cctx, 0, sizeof(cctx));
445  cctx.version = LZ4F_VERSION;
446  cctx.maxBufferSize = 5 MB; /* mess with real buffer size to prevent dynamic allocation; works only because autoflush==1 & stableSrc==1 */
447  if (preferencesPtr == NULL ||
448  preferencesPtr->compressionLevel < LZ4HC_CLEVEL_MIN)
449  {
450  LZ4_initStream(&lz4ctx, sizeof(lz4ctx));
451  cctxPtr->lz4CtxPtr = &lz4ctx;
452  cctxPtr->lz4CtxAlloc = 1;
453  cctxPtr->lz4CtxState = 1;
454  }
455 #endif
456 
457  result = LZ4F_compressFrame_usingCDict(cctxPtr, dstBuffer, dstCapacity,
458  srcBuffer, srcSize,
459  NULL, preferencesPtr);
460 
461 #if (LZ4F_HEAPMODE)
463 #else
464  if (preferencesPtr != NULL &&
465  preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN)
466  {
467  FREEMEM(cctxPtr->lz4CtxPtr);
468  }
469 #endif
470  return result;
471 }
size_t LZ4F_compressFrame_usingCDict(LZ4F_cctx *cctx, void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_CDict *cdict, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:373
LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx *cctxPtr)
Definition: lz4frame.c:550
LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx **LZ4F_compressionContextPtr, unsigned version)
Definition: lz4frame.c:536
#define LZ4F_VERSION
Definition: lz4frame.h:242
U32 version
Definition: lz4frame.c:226
#define MB
Definition: unum.c:92

References LZ4F_preferences_t::compressionLevel, DEBUGLOG, FREEMEM, LZ4_initStream(), LZ4F_cctx_s::lz4CtxAlloc, LZ4F_cctx_s::lz4CtxPtr, LZ4F_cctx_s::lz4CtxState, LZ4F_compressFrame_usingCDict(), LZ4F_createCompressionContext(), LZ4F_freeCompressionContext(), LZ4F_isError(), LZ4F_VERSION, LZ4HC_CLEVEL_MIN, LZ4F_cctx_s::maxBufferSize, MB, MEM_INIT, NULL, srcSize, and LZ4F_cctx_s::version.

Referenced by basicTests(), fullSpeedBench(), fuzzerTests(), LLVMFuzzerTestOneInput(), and local_LZ4F_compressFrame().

◆ LZ4F_compressFrame_usingCDict()

size_t LZ4F_compressFrame_usingCDict ( LZ4F_cctx cctx,
void *  dstBuffer,
size_t  dstCapacity,
const void *  srcBuffer,
size_t  srcSize,
const LZ4F_CDict *  cdict,
const LZ4F_preferences_t preferencesPtr 
)

LZ4F_compressFrame_usingCDict() : Compress srcBuffer using a dictionary, in a single step. cdict can be NULL, in which case, no dictionary is used. dstBuffer MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr). The LZ4F_preferences_t structure is optional : you may provide NULL as argument, however, it's the only way to provide a dictID, so it's not recommended.

Returns
: number of bytes written into dstBuffer, or an error code if it fails (can be tested using LZ4F_isError())

Definition at line 373 of file lz4frame.c.

378 {
379  LZ4F_preferences_t prefs;
381  BYTE* const dstStart = (BYTE*) dstBuffer;
382  BYTE* dstPtr = dstStart;
383  BYTE* const dstEnd = dstStart + dstCapacity;
384 
385  if (preferencesPtr!=NULL)
386  prefs = *preferencesPtr;
387  else
388  MEM_INIT(&prefs, 0, sizeof(prefs));
389  if (prefs.frameInfo.contentSize != 0)
390  prefs.frameInfo.contentSize = (U64)srcSize; /* auto-correct content size if selected (!=0) */
391 
393  prefs.autoFlush = 1;
395  prefs.frameInfo.blockMode = LZ4F_blockIndependent; /* only one block => no need for inter-block link */
396 
397  MEM_INIT(&options, 0, sizeof(options));
398  options.stableSrc = 1;
399 
400  if (dstCapacity < LZ4F_compressFrameBound(srcSize, &prefs)) /* condition to guarantee success */
401  return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
402 
403  { size_t const headerSize = LZ4F_compressBegin_usingCDict(cctx, dstBuffer, dstCapacity, cdict, &prefs); /* write header */
404  if (LZ4F_isError(headerSize)) return headerSize;
405  dstPtr += headerSize; /* header size */ }
406 
407  assert(dstEnd >= dstPtr);
408  { size_t const cSize = LZ4F_compressUpdate(cctx, dstPtr, (size_t)(dstEnd-dstPtr), srcBuffer, srcSize, &options);
409  if (LZ4F_isError(cSize)) return cSize;
410  dstPtr += cSize; }
411 
412  assert(dstEnd >= dstPtr);
413  { size_t const tailSize = LZ4F_compressEnd(cctx, dstPtr, (size_t)(dstEnd-dstPtr), &options); /* flush last block, and generate suffix */
414  if (LZ4F_isError(tailSize)) return tailSize;
415  dstPtr += tailSize; }
416 
417  assert(dstEnd >= dstStart);
418  return (size_t)(dstPtr - dstStart);
419 }
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
static LZ4F_blockSizeID_t LZ4F_optimalBSID(const LZ4F_blockSizeID_t requestedBSID, const size_t srcSize)
Definition: lz4frame.c:304
unsigned long long U64
Definition: lz4frame.c:142
size_t LZ4F_compressUpdate(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_compressOptions_t *compressOptionsPtr)
Definition: lz4frame.c:825
size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:351
size_t LZ4F_compressEnd(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t *compressOptionsPtr)
Definition: lz4frame.c:986

References assert, LZ4F_preferences_t::autoFlush, LZ4F_frameInfo_t::blockMode, LZ4F_frameInfo_t::blockSizeID, LZ4F_frameInfo_t::contentSize, err0r(), LZ4F_preferences_t::frameInfo, LZ4F_blockIndependent, LZ4F_compressBegin_usingCDict(), LZ4F_compressEnd(), LZ4F_compressFrameBound(), LZ4F_compressUpdate(), LZ4F_getBlockSize(), LZ4F_isError(), LZ4F_optimalBSID(), MEM_INIT, NULL, options, and srcSize.

Referenced by basicTests(), LZ4F_compressFrame(), and LZ4IO_compressFilename_extRess().

◆ LZ4F_compressFrameBound()

size_t LZ4F_compressFrameBound ( size_t  srcSize,
const LZ4F_preferences_t preferencesPtr 
)

LZ4F_compressFrameBound() : Returns the maximum possible compressed size with LZ4F_compressFrame() given srcSize and preferences. preferencesPtr is optional. It can be replaced by NULL, in which case, the function will assume default preferences. Note : this result is only usable with LZ4F_compressFrame(). It may also be used with LZ4F_compressUpdate() if no flush() operation is performed.

Definition at line 351 of file lz4frame.c.

352 {
353  LZ4F_preferences_t prefs;
354  size_t const headerSize = maxFHSize; /* max header size, including optional fields */
355 
356  if (preferencesPtr!=NULL) prefs = *preferencesPtr;
357  else MEM_INIT(&prefs, 0, sizeof(prefs));
358  prefs.autoFlush = 1;
359 
360  return headerSize + LZ4F_compressBound_internal(srcSize, &prefs, 0);;
361 }

References LZ4F_preferences_t::autoFlush, LZ4F_compressBound_internal(), maxFHSize, MEM_INIT, NULL, and srcSize.

Referenced by basicTests(), fuzzerTests(), LLVMFuzzerTestOneInput(), local_LZ4F_compressFrame(), LZ4F_compressFrame_usingCDict(), and LZ4IO_createCResources().

◆ LZ4F_compressionLevel_max()

int LZ4F_compressionLevel_max ( void  )

Definition at line 276 of file lz4frame.c.

276 { return LZ4HC_CLEVEL_MAX; }
#define LZ4HC_CLEVEL_MAX
Definition: lz4hc.h:50

References LZ4HC_CLEVEL_MAX.

Referenced by basicTests().

◆ LZ4F_compressUpdate()

size_t LZ4F_compressUpdate ( LZ4F_cctx cctxPtr,
void *  dstBuffer,
size_t  dstCapacity,
const void *  srcBuffer,
size_t  srcSize,
const LZ4F_compressOptions_t compressOptionsPtr 
)

LZ4F_compressUpdate() : LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary. dstBuffer MUST be >= LZ4F_compressBound(srcSize, preferencesPtr). LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.

Returns
: the number of bytes written into dstBuffer. It can be zero, meaning input data was just buffered. or an error code if it fails (which can be tested using LZ4F_isError())

Definition at line 825 of file lz4frame.c.

829 {
830  LZ4F_compressOptions_t cOptionsNull;
831  size_t const blockSize = cctxPtr->maxBlockSize;
832  const BYTE* srcPtr = (const BYTE*)srcBuffer;
833  const BYTE* const srcEnd = srcPtr + srcSize;
834  BYTE* const dstStart = (BYTE*)dstBuffer;
835  BYTE* dstPtr = dstStart;
836  LZ4F_lastBlockStatus lastBlockCompressed = notDone;
838 
839  DEBUGLOG(4, "LZ4F_compressUpdate (srcSize=%zu)", srcSize);
840 
841  if (cctxPtr->cStage != 1) return err0r(LZ4F_ERROR_GENERIC);
842  if (dstCapacity < LZ4F_compressBound_internal(srcSize, &(cctxPtr->prefs), cctxPtr->tmpInSize))
843  return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
844  MEM_INIT(&cOptionsNull, 0, sizeof(cOptionsNull));
845  if (compressOptionsPtr == NULL) compressOptionsPtr = &cOptionsNull;
846 
847  /* complete tmp buffer */
848  if (cctxPtr->tmpInSize > 0) { /* some data already within tmp buffer */
849  size_t const sizeToCopy = blockSize - cctxPtr->tmpInSize;
850  if (sizeToCopy > srcSize) {
851  /* add src to tmpIn buffer */
852  memcpy(cctxPtr->tmpIn + cctxPtr->tmpInSize, srcBuffer, srcSize);
853  srcPtr = srcEnd;
854  cctxPtr->tmpInSize += srcSize;
855  /* still needs some CRC */
856  } else {
857  /* complete tmpIn block and then compress it */
858  lastBlockCompressed = fromTmpBuffer;
859  memcpy(cctxPtr->tmpIn + cctxPtr->tmpInSize, srcBuffer, sizeToCopy);
860  srcPtr += sizeToCopy;
861 
862  dstPtr += LZ4F_makeBlock(dstPtr,
863  cctxPtr->tmpIn, blockSize,
864  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
865  cctxPtr->cdict,
867 
868  if (cctxPtr->prefs.frameInfo.blockMode==LZ4F_blockLinked) cctxPtr->tmpIn += blockSize;
869  cctxPtr->tmpInSize = 0;
870  }
871  }
872 
873  while ((size_t)(srcEnd - srcPtr) >= blockSize) {
874  /* compress full blocks */
875  lastBlockCompressed = fromSrcBuffer;
876  dstPtr += LZ4F_makeBlock(dstPtr,
877  srcPtr, blockSize,
878  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
879  cctxPtr->cdict,
881  srcPtr += blockSize;
882  }
883 
884  if ((cctxPtr->prefs.autoFlush) && (srcPtr < srcEnd)) {
885  /* compress remaining input < blockSize */
886  lastBlockCompressed = fromSrcBuffer;
887  dstPtr += LZ4F_makeBlock(dstPtr,
888  srcPtr, (size_t)(srcEnd - srcPtr),
889  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
890  cctxPtr->cdict,
892  srcPtr = srcEnd;
893  }
894 
895  /* preserve dictionary if necessary */
896  if ((cctxPtr->prefs.frameInfo.blockMode==LZ4F_blockLinked) && (lastBlockCompressed==fromSrcBuffer)) {
897  if (compressOptionsPtr->stableSrc) {
898  cctxPtr->tmpIn = cctxPtr->tmpBuff;
899  } else {
900  int const realDictSize = LZ4F_localSaveDict(cctxPtr);
901  if (realDictSize==0) return err0r(LZ4F_ERROR_GENERIC);
902  cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
903  }
904  }
905 
906  /* keep tmpIn within limits */
907  if ((cctxPtr->tmpIn + blockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize) /* necessarily LZ4F_blockLinked && lastBlockCompressed==fromTmpBuffer */
908  && !(cctxPtr->prefs.autoFlush))
909  {
910  int const realDictSize = LZ4F_localSaveDict(cctxPtr);
911  cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
912  }
913 
914  /* some input data left, necessarily < blockSize */
915  if (srcPtr < srcEnd) {
916  /* fill tmp buffer */
917  size_t const sizeToCopy = (size_t)(srcEnd - srcPtr);
918  memcpy(cctxPtr->tmpIn, srcPtr, sizeToCopy);
919  cctxPtr->tmpInSize = sizeToCopy;
920  }
921 
923  (void)XXH32_update(&(cctxPtr->xxh), srcBuffer, srcSize);
924 
925  cctxPtr->totalInSize += srcSize;
926  return (size_t)(dstPtr - dstStart);
927 }
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *state_in, const void *input, size_t len)
Definition: xxhash.c:515
static size_t LZ4F_makeBlock(void *dst, const void *src, size_t srcSize, compressFunc_t compress, void *lz4ctx, int level, const LZ4F_CDict *cdict, LZ4F_blockChecksum_t crcFlag)
Definition: lz4frame.c:740
static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode, int level)
Definition: lz4frame.c:799
static int LZ4F_localSaveDict(LZ4F_cctx_t *cctxPtr)
Definition: lz4frame.c:809
int(* compressFunc_t)(void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:733
int size_t
Definition: sftypes.h:40

References LZ4F_preferences_t::autoFlush, LZ4F_frameInfo_t::blockChecksumFlag, LZ4F_frameInfo_t::blockMode, LZ4F_cctx_s::cdict, compress(), LZ4F_preferences_t::compressionLevel, LZ4F_frameInfo_t::contentChecksumFlag, LZ4F_cctx_s::cStage, DEBUGLOG, err0r(), LZ4F_preferences_t::frameInfo, fromSrcBuffer, fromTmpBuffer, LZ4F_cctx_s::lz4CtxPtr, LZ4F_blockLinked, LZ4F_compressBound_internal(), LZ4F_contentChecksumEnabled, LZ4F_localSaveDict(), LZ4F_makeBlock(), LZ4F_selectCompression(), LZ4F_cctx_s::maxBlockSize, LZ4F_cctx_s::maxBufferSize, MEM_INIT, memcpy(), notDone, NULL, LZ4F_cctx_s::prefs, srcSize, LZ4F_compressOptions_t::stableSrc, LZ4F_cctx_s::tmpBuff, LZ4F_cctx_s::tmpIn, LZ4F_cctx_s::tmpInSize, LZ4F_cctx_s::totalInSize, LZ4F_cctx_s::xxh, and XXH32_update().

Referenced by basicTests(), compress_file_internal(), fuzzerTests(), LZ4F_compressFrame_usingCDict(), and LZ4IO_compressFilename_extRess().

◆ LZ4F_createCDict()

LZ4F_CDict* LZ4F_createCDict ( const void *  dictBuffer,
size_t  dictSize 
)

LZ4F_createCDict() : When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. LZ4F_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. LZ4F_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. dictBuffer can be released after LZ4F_CDict creation, since its content is copied within CDict

Returns
: digested dictionary for compression, or NULL if failed

Definition at line 490 of file lz4frame.c.

491 {
492  const char* dictStart = (const char*)dictBuffer;
493  LZ4F_CDict* cdict = (LZ4F_CDict*) ALLOC(sizeof(*cdict));
494  DEBUGLOG(4, "LZ4F_createCDict");
495  if (!cdict) return NULL;
496  if (dictSize > 64 KB) {
497  dictStart += dictSize - 64 KB;
498  dictSize = 64 KB;
499  }
500  cdict->dictContent = ALLOC(dictSize);
501  cdict->fastCtx = LZ4_createStream();
502  cdict->HCCtx = LZ4_createStreamHC();
503  if (!cdict->dictContent || !cdict->fastCtx || !cdict->HCCtx) {
504  LZ4F_freeCDict(cdict);
505  return NULL;
506  }
507  memcpy(cdict->dictContent, dictStart, dictSize);
508  LZ4_loadDict (cdict->fastCtx, (const char*)cdict->dictContent, (int)dictSize);
510  LZ4_loadDictHC(cdict->HCCtx, (const char*)cdict->dictContent, (int)dictSize);
511  return cdict;
512 }
int LZ4_loadDict(LZ4_stream_t *LZ4_dict, const char *dictionary, int dictSize)
Definition: lz4.c:1475
#define ALLOC(s)
Definition: lz4frame.c:76
void LZ4F_freeCDict(LZ4F_CDict *cdict)
Definition: lz4frame.c:514
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
Definition: lz4hc.c:1056
#define LZ4HC_CLEVEL_DEFAULT
Definition: lz4hc.h:48

References ALLOC, DEBUGLOG, KB, LZ4_createStream(), LZ4_createStreamHC(), LZ4_loadDict(), LZ4_loadDictHC(), LZ4_setCompressionLevel(), LZ4F_freeCDict(), LZ4HC_CLEVEL_DEFAULT, memcpy(), and NULL.

Referenced by basicTests(), and LZ4IO_createCDict().

◆ LZ4F_createCompressionContext()

LZ4F_errorCode_t LZ4F_createCompressionContext ( LZ4F_cctx **  LZ4F_compressionContextPtr,
unsigned  version 
)

LZ4F_createCompressionContext() : The first thing to do is to create a compressionContext object, which will be used in all compression operations. This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure. The version provided MUST be LZ4F_VERSION. It is intended to track potential incompatible differences between different binaries. The function will provide a pointer to an allocated LZ4F_compressionContext_t object. If the result LZ4F_errorCode_t is not OK_NoError, there was an error during context creation. Object can release its memory using LZ4F_freeCompressionContext();

Definition at line 536 of file lz4frame.c.

537 {
538  LZ4F_cctx_t* const cctxPtr = (LZ4F_cctx_t*)ALLOC_AND_ZERO(sizeof(LZ4F_cctx_t));
539  if (cctxPtr==NULL) return err0r(LZ4F_ERROR_allocation_failed);
540 
541  cctxPtr->version = version;
542  cctxPtr->cStage = 0; /* Next stage : init stream */
543 
544  *LZ4F_compressionContextPtr = cctxPtr;
545 
546  return LZ4F_OK_NoError;
547 }
static char * version
Definition: acr.h:4

References ALLOC_AND_ZERO, LZ4F_cctx_s::cStage, err0r(), NULL, LZ4F_cctx_s::version, and version.

Referenced by basicTests(), compress_file(), fuzzerTests(), LZ4F_compressFrame(), and LZ4IO_createCResources().

◆ LZ4F_createDecompressionContext()

LZ4F_errorCode_t LZ4F_createDecompressionContext ( LZ4F_dctx **  LZ4F_decompressionContextPtr,
unsigned  versionNumber 
)

LZ4F_createDecompressionContext() : Create a decompressionContext object, which will track all decompression operations. Provides a pointer to a fully allocated and initialized LZ4F_decompressionContext object. Object can later be released using LZ4F_freeDecompressionContext().

Returns
: if != 0, there was an error during context creation.

Definition at line 1069 of file lz4frame.c.

1070 {
1071  LZ4F_dctx* const dctx = (LZ4F_dctx*)ALLOC_AND_ZERO(sizeof(LZ4F_dctx));
1072  if (dctx == NULL) { /* failed allocation */
1073  *LZ4F_decompressionContextPtr = NULL;
1074  return err0r(LZ4F_ERROR_allocation_failed);
1075  }
1076 
1077  dctx->version = versionNumber;
1078  *LZ4F_decompressionContextPtr = dctx;
1079  return LZ4F_OK_NoError;
1080 }

References ALLOC_AND_ZERO, err0r(), NULL, and LZ4F_dctx_s::version.

Referenced by basicTests(), createCResources(), decompress_file(), fullSpeedBench(), FUZZ_decompressFrame(), fuzzerTests(), LLVMFuzzerTestOneInput(), LZ4IO_createDResources(), and LZ4IO_getCompressedFileInfo().

◆ LZ4F_decodeHeader()

static size_t LZ4F_decodeHeader ( LZ4F_dctx dctx,
const void *  src,
size_t  srcSize 
)
static

LZ4F_decodeHeader() : input : src points at the beginning of the frame output : set internal values of dctx, such as dctx->frameInfo and dctx->dStage. Also allocates internal buffers.

Returns
: nb Bytes read from src (necessarily <= srcSize) or an error code (testable with LZ4F_isError())

Definition at line 1113 of file lz4frame.c.

1114 {
1115  unsigned blockMode, blockChecksumFlag, contentSizeFlag, contentChecksumFlag, dictIDFlag, blockSizeID;
1116  size_t frameHeaderSize;
1117  const BYTE* srcPtr = (const BYTE*)src;
1118 
1119  DEBUGLOG(5, "LZ4F_decodeHeader");
1120  /* need to decode header to get frameInfo */
1121  if (srcSize < minFHSize) return err0r(LZ4F_ERROR_frameHeader_incomplete); /* minimal frame header size */
1122  MEM_INIT(&(dctx->frameInfo), 0, sizeof(dctx->frameInfo));
1123 
1124  /* special case : skippable frames */
1125  if ((LZ4F_readLE32(srcPtr) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START) {
1127  if (src == (void*)(dctx->header)) {
1128  dctx->tmpInSize = srcSize;
1129  dctx->tmpInTarget = 8;
1131  return srcSize;
1132  } else {
1133  dctx->dStage = dstage_getSFrameSize;
1134  return 4;
1135  }
1136  }
1137 
1138  /* control magic number */
1139 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1140  if (LZ4F_readLE32(srcPtr) != LZ4F_MAGICNUMBER) {
1141  DEBUGLOG(4, "frame header error : unknown magic number");
1142  return err0r(LZ4F_ERROR_frameType_unknown);
1143  }
1144 #endif
1145  dctx->frameInfo.frameType = LZ4F_frame;
1146 
1147  /* Flags */
1148  { U32 const FLG = srcPtr[4];
1149  U32 const version = (FLG>>6) & _2BITS;
1150  blockChecksumFlag = (FLG>>4) & _1BIT;
1151  blockMode = (FLG>>5) & _1BIT;
1152  contentSizeFlag = (FLG>>3) & _1BIT;
1153  contentChecksumFlag = (FLG>>2) & _1BIT;
1154  dictIDFlag = FLG & _1BIT;
1155  /* validate */
1156  if (((FLG>>1)&_1BIT) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bit */
1157  if (version != 1) return err0r(LZ4F_ERROR_headerVersion_wrong); /* Version Number, only supported value */
1158  }
1159 
1160  /* Frame Header Size */
1161  frameHeaderSize = minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
1162 
1163  if (srcSize < frameHeaderSize) {
1164  /* not enough input to fully decode frame header */
1165  if (srcPtr != dctx->header)
1166  memcpy(dctx->header, srcPtr, srcSize);
1167  dctx->tmpInSize = srcSize;
1168  dctx->tmpInTarget = frameHeaderSize;
1170  return srcSize;
1171  }
1172 
1173  { U32 const BD = srcPtr[5];
1174  blockSizeID = (BD>>4) & _3BITS;
1175  /* validate */
1176  if (((BD>>7)&_1BIT) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bit */
1177  if (blockSizeID < 4) return err0r(LZ4F_ERROR_maxBlockSize_invalid); /* 4-7 only supported values for the time being */
1178  if (((BD>>0)&_4BITS) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bits */
1179  }
1180 
1181  /* check header */
1182  assert(frameHeaderSize > 5);
1183 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1184  { BYTE const HC = LZ4F_headerChecksum(srcPtr+4, frameHeaderSize-5);
1185  if (HC != srcPtr[frameHeaderSize-1])
1186  return err0r(LZ4F_ERROR_headerChecksum_invalid);
1187  }
1188 #endif
1189 
1190  /* save */
1191  dctx->frameInfo.blockMode = (LZ4F_blockMode_t)blockMode;
1192  dctx->frameInfo.blockChecksumFlag = (LZ4F_blockChecksum_t)blockChecksumFlag;
1193  dctx->frameInfo.contentChecksumFlag = (LZ4F_contentChecksum_t)contentChecksumFlag;
1194  dctx->frameInfo.blockSizeID = (LZ4F_blockSizeID_t)blockSizeID;
1195  dctx->maxBlockSize = LZ4F_getBlockSize(blockSizeID);
1196  if (contentSizeFlag)
1197  dctx->frameRemainingSize =
1198  dctx->frameInfo.contentSize = LZ4F_readLE64(srcPtr+6);
1199  if (dictIDFlag)
1200  dctx->frameInfo.dictID = LZ4F_readLE32(srcPtr + frameHeaderSize - 5);
1201 
1202  dctx->dStage = dstage_init;
1203 
1204  return frameHeaderSize;
1205 }
#define FLG(x)
Definition: esil.c:10
static U32 LZ4F_readLE32(const void *src)
Definition: lz4frame.c:147
static const size_t minFHSize
Definition: lz4frame.c:214
#define LZ4F_MAGIC_SKIPPABLE_START
Definition: lz4frame.c:209
static U64 LZ4F_readLE64(const void *src)
Definition: lz4frame.c:166
#define _4BITS
Definition: lz4frame.c:206
LZ4F_blockMode_t
Definition: lz4frame.h:138
LZ4F_contentChecksum_t
Definition: lz4frame.h:145
@ LZ4F_skippableFrame
Definition: lz4frame.h:159
@ LZ4F_frame
Definition: lz4frame.h:158
LZ4F_blockChecksum_t
Definition: lz4frame.h:152
#define BD(a, b)
Definition: print.c:1148
size_t maxBlockSize
Definition: lz4frame.c:1046
dStage_t dStage
Definition: lz4frame.c:1044
size_t tmpInSize
Definition: lz4frame.c:1049
BYTE header[LZ4F_HEADER_SIZE_MAX]
Definition: lz4frame.c:1059
LZ4F_frameInfo_t frameInfo
Definition: lz4frame.c:1042
size_t tmpInTarget
Definition: lz4frame.c:1050
U64 frameRemainingSize
Definition: lz4frame.c:1045
LZ4F_frameType_t frameType
Definition: lz4frame.h:179

References _1BIT, _2BITS, _3BITS, _4BITS, assert, BD, LZ4F_frameInfo_t::blockChecksumFlag, LZ4F_frameInfo_t::blockMode, LZ4F_frameInfo_t::blockSizeID, LZ4F_frameInfo_t::contentChecksumFlag, LZ4F_frameInfo_t::contentSize, DEBUGLOG, LZ4F_frameInfo_t::dictID, LZ4F_dctx_s::dStage, dstage_getSFrameSize, dstage_init, dstage_storeFrameHeader, dstage_storeSFrameSize, err0r(), FLG, LZ4F_dctx_s::frameInfo, LZ4F_dctx_s::frameRemainingSize, LZ4F_frameInfo_t::frameType, LZ4F_dctx_s::header, LZ4F_frame, LZ4F_getBlockSize(), LZ4F_headerChecksum(), LZ4F_MAGIC_SKIPPABLE_START, LZ4F_MAGICNUMBER, LZ4F_readLE32(), LZ4F_readLE64(), LZ4F_skippableFrame, LZ4F_dctx_s::maxBlockSize, MEM_INIT, memcpy(), minFHSize, src, srcSize, LZ4F_dctx_s::tmpInSize, and LZ4F_dctx_s::tmpInTarget.

Referenced by LZ4F_decompress(), and LZ4F_getFrameInfo().

◆ LZ4F_decompress()

size_t LZ4F_decompress ( LZ4F_dctx dctx,
void *  dstBuffer,
size_t dstSizePtr,
const void *  srcBuffer,
size_t srcSizePtr,
const LZ4F_decompressOptions_t decompressOptionsPtr 
)

LZ4F_decompress() : Call this function repetitively to regenerate compressed data in srcBuffer. The function will attempt to decode up to *srcSizePtr bytes from srcBuffer into dstBuffer of capacity *dstSizePtr.

The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr (necessarily <= original value).

The number of bytes effectively read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). If number of bytes read is < number of bytes provided, then decompression operation is not complete. Remaining data will have to be presented again in a subsequent invocation.

The function result is an hint of the better srcSize to use for next call to LZ4F_decompress. Schematically, it's the size of the current (or remaining) compressed block + header of next block. Respecting the hint provides a small boost to performance, since it allows less buffer shuffling. Note that this is just a hint, and it's always possible to any srcSize value. When a frame is fully decoded,

Returns
will be 0. If decompression failed,
is an error code which can be tested using LZ4F_isError().

Definition at line 1384 of file lz4frame.c.

1388 {
1389  LZ4F_decompressOptions_t optionsNull;
1390  const BYTE* const srcStart = (const BYTE*)srcBuffer;
1391  const BYTE* const srcEnd = srcStart + *srcSizePtr;
1392  const BYTE* srcPtr = srcStart;
1393  BYTE* const dstStart = (BYTE*)dstBuffer;
1394  BYTE* const dstEnd = dstStart ? dstStart + *dstSizePtr : NULL;
1395  BYTE* dstPtr = dstStart;
1396  const BYTE* selectedIn = NULL;
1397  unsigned doAnotherStage = 1;
1398  size_t nextSrcSizeHint = 1;
1399 
1400 
1401  DEBUGLOG(5, "LZ4F_decompress : %p,%u => %p,%u",
1402  srcBuffer, (unsigned)*srcSizePtr, dstBuffer, (unsigned)*dstSizePtr);
1403  if (dstBuffer == NULL) assert(*dstSizePtr == 0);
1404  MEM_INIT(&optionsNull, 0, sizeof(optionsNull));
1405  if (decompressOptionsPtr==NULL) decompressOptionsPtr = &optionsNull;
1406  *srcSizePtr = 0;
1407  *dstSizePtr = 0;
1408  assert(dctx != NULL);
1409 
1410  /* behaves as a state machine */
1411 
1412  while (doAnotherStage) {
1413 
1414  switch(dctx->dStage)
1415  {
1416 
1417  case dstage_getFrameHeader:
1418  DEBUGLOG(6, "dstage_getFrameHeader");
1419  if ((size_t)(srcEnd-srcPtr) >= maxFHSize) { /* enough to decode - shortcut */
1420  size_t const hSize = LZ4F_decodeHeader(dctx, srcPtr, (size_t)(srcEnd-srcPtr)); /* will update dStage appropriately */
1421  if (LZ4F_isError(hSize)) return hSize;
1422  srcPtr += hSize;
1423  break;
1424  }
1425  dctx->tmpInSize = 0;
1426  if (srcEnd-srcPtr == 0) return minFHSize; /* 0-size input */
1427  dctx->tmpInTarget = minFHSize; /* minimum size to decode header */
1429  /* fall-through */
1430 
1432  DEBUGLOG(6, "dstage_storeFrameHeader");
1433  { size_t const sizeToCopy = MIN(dctx->tmpInTarget - dctx->tmpInSize, (size_t)(srcEnd - srcPtr));
1434  memcpy(dctx->header + dctx->tmpInSize, srcPtr, sizeToCopy);
1435  dctx->tmpInSize += sizeToCopy;
1436  srcPtr += sizeToCopy;
1437  }
1438  if (dctx->tmpInSize < dctx->tmpInTarget) {
1439  nextSrcSizeHint = (dctx->tmpInTarget - dctx->tmpInSize) + BHSize; /* rest of header + nextBlockHeader */
1440  doAnotherStage = 0; /* not enough src data, ask for some more */
1441  break;
1442  }
1443  { size_t const hSize = LZ4F_decodeHeader(dctx, dctx->header, dctx->tmpInTarget); /* will update dStage appropriately */
1444  if (LZ4F_isError(hSize)) return hSize;
1445  }
1446  break;
1447 
1448  case dstage_init:
1449  DEBUGLOG(6, "dstage_init");
1450  if (dctx->frameInfo.contentChecksumFlag) (void)XXH32_reset(&(dctx->xxh), 0);
1451  /* internal buffers allocation */
1452  { size_t const bufferNeeded = dctx->maxBlockSize
1453  + ((dctx->frameInfo.blockMode==LZ4F_blockLinked) ? 128 KB : 0);
1454  if (bufferNeeded > dctx->maxBufferSize) { /* tmp buffers too small */
1455  dctx->maxBufferSize = 0; /* ensure allocation will be re-attempted on next entry*/
1456  FREEMEM(dctx->tmpIn);
1457  dctx->tmpIn = (BYTE*)ALLOC(dctx->maxBlockSize + BFSize /* block checksum */);
1458  if (dctx->tmpIn == NULL)
1459  return err0r(LZ4F_ERROR_allocation_failed);
1460  FREEMEM(dctx->tmpOutBuffer);
1461  dctx->tmpOutBuffer= (BYTE*)ALLOC(bufferNeeded);
1462  if (dctx->tmpOutBuffer== NULL)
1463  return err0r(LZ4F_ERROR_allocation_failed);
1464  dctx->maxBufferSize = bufferNeeded;
1465  } }
1466  dctx->tmpInSize = 0;
1467  dctx->tmpInTarget = 0;
1468  dctx->tmpOut = dctx->tmpOutBuffer;
1469  dctx->tmpOutStart = 0;
1470  dctx->tmpOutSize = 0;
1471 
1472  dctx->dStage = dstage_getBlockHeader;
1473  /* fall-through */
1474 
1475  case dstage_getBlockHeader:
1476  if ((size_t)(srcEnd - srcPtr) >= BHSize) {
1477  selectedIn = srcPtr;
1478  srcPtr += BHSize;
1479  } else {
1480  /* not enough input to read cBlockSize field */
1481  dctx->tmpInSize = 0;
1483  }
1484 
1485  if (dctx->dStage == dstage_storeBlockHeader) /* can be skipped */
1487  { size_t const remainingInput = (size_t)(srcEnd - srcPtr);
1488  size_t const wantedData = BHSize - dctx->tmpInSize;
1489  size_t const sizeToCopy = MIN(wantedData, remainingInput);
1490  memcpy(dctx->tmpIn + dctx->tmpInSize, srcPtr, sizeToCopy);
1491  srcPtr += sizeToCopy;
1492  dctx->tmpInSize += sizeToCopy;
1493 
1494  if (dctx->tmpInSize < BHSize) { /* not enough input for cBlockSize */
1495  nextSrcSizeHint = BHSize - dctx->tmpInSize;
1496  doAnotherStage = 0;
1497  break;
1498  }
1499  selectedIn = dctx->tmpIn;
1500  } /* if (dctx->dStage == dstage_storeBlockHeader) */
1501 
1502  /* decode block header */
1503  { U32 const blockHeader = LZ4F_readLE32(selectedIn);
1504  size_t const nextCBlockSize = blockHeader & 0x7FFFFFFFU;
1505  size_t const crcSize = dctx->frameInfo.blockChecksumFlag * BFSize;
1506  if (blockHeader==0) { /* frameEnd signal, no more block */
1507  DEBUGLOG(5, "end of frame");
1508  dctx->dStage = dstage_getSuffix;
1509  break;
1510  }
1511  if (nextCBlockSize > dctx->maxBlockSize) {
1512  return err0r(LZ4F_ERROR_maxBlockSize_invalid);
1513  }
1514  if (blockHeader & LZ4F_BLOCKUNCOMPRESSED_FLAG) {
1515  /* next block is uncompressed */
1516  dctx->tmpInTarget = nextCBlockSize;
1517  DEBUGLOG(5, "next block is uncompressed (size %u)", (U32)nextCBlockSize);
1518  if (dctx->frameInfo.blockChecksumFlag) {
1519  (void)XXH32_reset(&dctx->blockChecksum, 0);
1520  }
1521  dctx->dStage = dstage_copyDirect;
1522  break;
1523  }
1524  /* next block is a compressed block */
1525  dctx->tmpInTarget = nextCBlockSize + crcSize;
1526  dctx->dStage = dstage_getCBlock;
1527  if (dstPtr==dstEnd || srcPtr==srcEnd) {
1528  nextSrcSizeHint = BHSize + nextCBlockSize + crcSize;
1529  doAnotherStage = 0;
1530  }
1531  break;
1532  }
1533 
1534  case dstage_copyDirect: /* uncompressed block */
1535  DEBUGLOG(6, "dstage_copyDirect");
1536  { size_t sizeToCopy;
1537  if (dstPtr == NULL) {
1538  sizeToCopy = 0;
1539  } else {
1540  size_t const minBuffSize = MIN((size_t)(srcEnd-srcPtr), (size_t)(dstEnd-dstPtr));
1541  sizeToCopy = MIN(dctx->tmpInTarget, minBuffSize);
1542  memcpy(dstPtr, srcPtr, sizeToCopy);
1543  if (dctx->frameInfo.blockChecksumFlag) {
1544  (void)XXH32_update(&dctx->blockChecksum, srcPtr, sizeToCopy);
1545  }
1546  if (dctx->frameInfo.contentChecksumFlag)
1547  (void)XXH32_update(&dctx->xxh, srcPtr, sizeToCopy);
1548  if (dctx->frameInfo.contentSize)
1549  dctx->frameRemainingSize -= sizeToCopy;
1550 
1551  /* history management (linked blocks only)*/
1552  if (dctx->frameInfo.blockMode == LZ4F_blockLinked) {
1553  LZ4F_updateDict(dctx, dstPtr, sizeToCopy, dstStart, 0);
1554  } }
1555 
1556  srcPtr += sizeToCopy;
1557  dstPtr += sizeToCopy;
1558  if (sizeToCopy == dctx->tmpInTarget) { /* all done */
1559  if (dctx->frameInfo.blockChecksumFlag) {
1560  dctx->tmpInSize = 0;
1562  } else
1563  dctx->dStage = dstage_getBlockHeader; /* new block */
1564  break;
1565  }
1566  dctx->tmpInTarget -= sizeToCopy; /* need to copy more */
1567  }
1568  nextSrcSizeHint = dctx->tmpInTarget +
1569  +(dctx->frameInfo.blockChecksumFlag ? BFSize : 0)
1570  + BHSize /* next header size */;
1571  doAnotherStage = 0;
1572  break;
1573 
1574  /* check block checksum for recently transferred uncompressed block */
1576  DEBUGLOG(6, "dstage_getBlockChecksum");
1577  { const void* crcSrc;
1578  if ((srcEnd-srcPtr >= 4) && (dctx->tmpInSize==0)) {
1579  crcSrc = srcPtr;
1580  srcPtr += 4;
1581  } else {
1582  size_t const stillToCopy = 4 - dctx->tmpInSize;
1583  size_t const sizeToCopy = MIN(stillToCopy, (size_t)(srcEnd-srcPtr));
1584  memcpy(dctx->header + dctx->tmpInSize, srcPtr, sizeToCopy);
1585  dctx->tmpInSize += sizeToCopy;
1586  srcPtr += sizeToCopy;
1587  if (dctx->tmpInSize < 4) { /* all input consumed */
1588  doAnotherStage = 0;
1589  break;
1590  }
1591  crcSrc = dctx->header;
1592  }
1593  { U32 const readCRC = LZ4F_readLE32(crcSrc);
1594  U32 const calcCRC = XXH32_digest(&dctx->blockChecksum);
1595 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1596  DEBUGLOG(6, "compare block checksum");
1597  if (readCRC != calcCRC) {
1598  DEBUGLOG(4, "incorrect block checksum: %08X != %08X",
1599  readCRC, calcCRC);
1600  return err0r(LZ4F_ERROR_blockChecksum_invalid);
1601  }
1602 #else
1603  (void)readCRC;
1604  (void)calcCRC;
1605 #endif
1606  } }
1607  dctx->dStage = dstage_getBlockHeader; /* new block */
1608  break;
1609 
1610  case dstage_getCBlock:
1611  DEBUGLOG(6, "dstage_getCBlock");
1612  if ((size_t)(srcEnd-srcPtr) < dctx->tmpInTarget) {
1613  dctx->tmpInSize = 0;
1614  dctx->dStage = dstage_storeCBlock;
1615  break;
1616  }
1617  /* input large enough to read full block directly */
1618  selectedIn = srcPtr;
1619  srcPtr += dctx->tmpInTarget;
1620 
1621  if (0) /* always jump over next block */
1622  case dstage_storeCBlock:
1623  { size_t const wantedData = dctx->tmpInTarget - dctx->tmpInSize;
1624  size_t const inputLeft = (size_t)(srcEnd-srcPtr);
1625  size_t const sizeToCopy = MIN(wantedData, inputLeft);
1626  memcpy(dctx->tmpIn + dctx->tmpInSize, srcPtr, sizeToCopy);
1627  dctx->tmpInSize += sizeToCopy;
1628  srcPtr += sizeToCopy;
1629  if (dctx->tmpInSize < dctx->tmpInTarget) { /* need more input */
1630  nextSrcSizeHint = (dctx->tmpInTarget - dctx->tmpInSize)
1631  + (dctx->frameInfo.blockChecksumFlag ? BFSize : 0)
1632  + BHSize /* next header size */;
1633  doAnotherStage = 0;
1634  break;
1635  }
1636  selectedIn = dctx->tmpIn;
1637  }
1638 
1639  /* At this stage, input is large enough to decode a block */
1640  if (dctx->frameInfo.blockChecksumFlag) {
1641  dctx->tmpInTarget -= 4;
1642  assert(selectedIn != NULL); /* selectedIn is defined at this stage (either srcPtr, or dctx->tmpIn) */
1643  { U32 const readBlockCrc = LZ4F_readLE32(selectedIn + dctx->tmpInTarget);
1644  U32 const calcBlockCrc = XXH32(selectedIn, dctx->tmpInTarget, 0);
1645 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1646  if (readBlockCrc != calcBlockCrc)
1647  return err0r(LZ4F_ERROR_blockChecksum_invalid);
1648 #else
1649  (void)readBlockCrc;
1650  (void)calcBlockCrc;
1651 #endif
1652  } }
1653 
1654  if ((size_t)(dstEnd-dstPtr) >= dctx->maxBlockSize) {
1655  const char* dict = (const char*)dctx->dict;
1656  size_t dictSize = dctx->dictSize;
1657  int decodedSize;
1658  assert(dstPtr != NULL);
1659  if (dict && dictSize > 1 GB) {
1660  /* the dictSize param is an int, avoid truncation / sign issues */
1661  dict += dictSize - 64 KB;
1662  dictSize = 64 KB;
1663  }
1664  /* enough capacity in `dst` to decompress directly there */
1665  decodedSize = LZ4_decompress_safe_usingDict(
1666  (const char*)selectedIn, (char*)dstPtr,
1667  (int)dctx->tmpInTarget, (int)dctx->maxBlockSize,
1668  dict, (int)dictSize);
1669  if (decodedSize < 0) return err0r(LZ4F_ERROR_GENERIC); /* decompression failed */
1670  if (dctx->frameInfo.contentChecksumFlag)
1671  XXH32_update(&(dctx->xxh), dstPtr, (size_t)decodedSize);
1672  if (dctx->frameInfo.contentSize)
1673  dctx->frameRemainingSize -= (size_t)decodedSize;
1674 
1675  /* dictionary management */
1676  if (dctx->frameInfo.blockMode==LZ4F_blockLinked) {
1677  LZ4F_updateDict(dctx, dstPtr, (size_t)decodedSize, dstStart, 0);
1678  }
1679 
1680  dstPtr += decodedSize;
1681  dctx->dStage = dstage_getBlockHeader;
1682  break;
1683  }
1684 
1685  /* not enough place into dst : decode into tmpOut */
1686  /* ensure enough place for tmpOut */
1687  if (dctx->frameInfo.blockMode == LZ4F_blockLinked) {
1688  if (dctx->dict == dctx->tmpOutBuffer) {
1689  if (dctx->dictSize > 128 KB) {
1690  memcpy(dctx->tmpOutBuffer, dctx->dict + dctx->dictSize - 64 KB, 64 KB);
1691  dctx->dictSize = 64 KB;
1692  }
1693  dctx->tmpOut = dctx->tmpOutBuffer + dctx->dictSize;
1694  } else { /* dict not within tmp */
1695  size_t const reservedDictSpace = MIN(dctx->dictSize, 64 KB);
1696  dctx->tmpOut = dctx->tmpOutBuffer + reservedDictSpace;
1697  } }
1698 
1699  /* Decode block */
1700  { const char* dict = (const char*)dctx->dict;
1701  size_t dictSize = dctx->dictSize;
1702  int decodedSize;
1703  if (dict && dictSize > 1 GB) {
1704  /* the dictSize param is an int, avoid truncation / sign issues */
1705  dict += dictSize - 64 KB;
1706  dictSize = 64 KB;
1707  }
1708  decodedSize = LZ4_decompress_safe_usingDict(
1709  (const char*)selectedIn, (char*)dctx->tmpOut,
1710  (int)dctx->tmpInTarget, (int)dctx->maxBlockSize,
1711  dict, (int)dictSize);
1712  if (decodedSize < 0) /* decompression failed */
1713  return err0r(LZ4F_ERROR_decompressionFailed);
1714  if (dctx->frameInfo.contentChecksumFlag)
1715  XXH32_update(&(dctx->xxh), dctx->tmpOut, (size_t)decodedSize);
1716  if (dctx->frameInfo.contentSize)
1717  dctx->frameRemainingSize -= (size_t)decodedSize;
1718  dctx->tmpOutSize = (size_t)decodedSize;
1719  dctx->tmpOutStart = 0;
1720  dctx->dStage = dstage_flushOut;
1721  }
1722  /* fall-through */
1723 
1724  case dstage_flushOut: /* flush decoded data from tmpOut to dstBuffer */
1725  DEBUGLOG(6, "dstage_flushOut");
1726  if (dstPtr != NULL) {
1727  size_t const sizeToCopy = MIN(dctx->tmpOutSize - dctx->tmpOutStart, (size_t)(dstEnd-dstPtr));
1728  memcpy(dstPtr, dctx->tmpOut + dctx->tmpOutStart, sizeToCopy);
1729 
1730  /* dictionary management */
1731  if (dctx->frameInfo.blockMode == LZ4F_blockLinked)
1732  LZ4F_updateDict(dctx, dstPtr, sizeToCopy, dstStart, 1 /*withinTmp*/);
1733 
1734  dctx->tmpOutStart += sizeToCopy;
1735  dstPtr += sizeToCopy;
1736  }
1737  if (dctx->tmpOutStart == dctx->tmpOutSize) { /* all flushed */
1738  dctx->dStage = dstage_getBlockHeader; /* get next block */
1739  break;
1740  }
1741  /* could not flush everything : stop there, just request a block header */
1742  doAnotherStage = 0;
1743  nextSrcSizeHint = BHSize;
1744  break;
1745 
1746  case dstage_getSuffix:
1747  if (dctx->frameRemainingSize)
1748  return err0r(LZ4F_ERROR_frameSize_wrong); /* incorrect frame size decoded */
1749  if (!dctx->frameInfo.contentChecksumFlag) { /* no checksum, frame is completed */
1750  nextSrcSizeHint = 0;
1752  doAnotherStage = 0;
1753  break;
1754  }
1755  if ((srcEnd - srcPtr) < 4) { /* not enough size for entire CRC */
1756  dctx->tmpInSize = 0;
1757  dctx->dStage = dstage_storeSuffix;
1758  } else {
1759  selectedIn = srcPtr;
1760  srcPtr += 4;
1761  }
1762 
1763  if (dctx->dStage == dstage_storeSuffix) /* can be skipped */
1764  case dstage_storeSuffix:
1765  { size_t const remainingInput = (size_t)(srcEnd - srcPtr);
1766  size_t const wantedData = 4 - dctx->tmpInSize;
1767  size_t const sizeToCopy = MIN(wantedData, remainingInput);
1768  memcpy(dctx->tmpIn + dctx->tmpInSize, srcPtr, sizeToCopy);
1769  srcPtr += sizeToCopy;
1770  dctx->tmpInSize += sizeToCopy;
1771  if (dctx->tmpInSize < 4) { /* not enough input to read complete suffix */
1772  nextSrcSizeHint = 4 - dctx->tmpInSize;
1773  doAnotherStage=0;
1774  break;
1775  }
1776  selectedIn = dctx->tmpIn;
1777  } /* if (dctx->dStage == dstage_storeSuffix) */
1778 
1779  /* case dstage_checkSuffix: */ /* no direct entry, avoid initialization risks */
1780  { U32 const readCRC = LZ4F_readLE32(selectedIn);
1781  U32 const resultCRC = XXH32_digest(&(dctx->xxh));
1782 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1783  if (readCRC != resultCRC)
1784  return err0r(LZ4F_ERROR_contentChecksum_invalid);
1785 #else
1786  (void)readCRC;
1787  (void)resultCRC;
1788 #endif
1789  nextSrcSizeHint = 0;
1791  doAnotherStage = 0;
1792  break;
1793  }
1794 
1795  case dstage_getSFrameSize:
1796  if ((srcEnd - srcPtr) >= 4) {
1797  selectedIn = srcPtr;
1798  srcPtr += 4;
1799  } else {
1800  /* not enough input to read cBlockSize field */
1801  dctx->tmpInSize = 4;
1802  dctx->tmpInTarget = 8;
1804  }
1805 
1806  if (dctx->dStage == dstage_storeSFrameSize)
1808  { size_t const sizeToCopy = MIN(dctx->tmpInTarget - dctx->tmpInSize,
1809  (size_t)(srcEnd - srcPtr) );
1810  memcpy(dctx->header + dctx->tmpInSize, srcPtr, sizeToCopy);
1811  srcPtr += sizeToCopy;
1812  dctx->tmpInSize += sizeToCopy;
1813  if (dctx->tmpInSize < dctx->tmpInTarget) {
1814  /* not enough input to get full sBlockSize; wait for more */
1815  nextSrcSizeHint = dctx->tmpInTarget - dctx->tmpInSize;
1816  doAnotherStage = 0;
1817  break;
1818  }
1819  selectedIn = dctx->header + 4;
1820  } /* if (dctx->dStage == dstage_storeSFrameSize) */
1821 
1822  /* case dstage_decodeSFrameSize: */ /* no direct entry */
1823  { size_t const SFrameSize = LZ4F_readLE32(selectedIn);
1824  dctx->frameInfo.contentSize = SFrameSize;
1825  dctx->tmpInTarget = SFrameSize;
1826  dctx->dStage = dstage_skipSkippable;
1827  break;
1828  }
1829 
1830  case dstage_skipSkippable:
1831  { size_t const skipSize = MIN(dctx->tmpInTarget, (size_t)(srcEnd-srcPtr));
1832  srcPtr += skipSize;
1833  dctx->tmpInTarget -= skipSize;
1834  doAnotherStage = 0;
1835  nextSrcSizeHint = dctx->tmpInTarget;
1836  if (nextSrcSizeHint) break; /* still more to skip */
1837  /* frame fully skipped : prepare context for a new frame */
1839  break;
1840  }
1841  } /* switch (dctx->dStage) */
1842  } /* while (doAnotherStage) */
1843 
1844  /* preserve history within tmp whenever necessary */
1845  LZ4F_STATIC_ASSERT((unsigned)dstage_init == 2);
1846  if ( (dctx->frameInfo.blockMode==LZ4F_blockLinked) /* next block will use up to 64KB from previous ones */
1847  && (dctx->dict != dctx->tmpOutBuffer) /* dictionary is not already within tmp */
1848  && (dctx->dict != NULL) /* dictionary exists */
1849  && (!decompressOptionsPtr->stableDst) /* cannot rely on dst data to remain there for next call */
1850  && ((unsigned)(dctx->dStage)-2 < (unsigned)(dstage_getSuffix)-2) ) /* valid stages : [init ... getSuffix[ */
1851  {
1852  if (dctx->dStage == dstage_flushOut) {
1853  size_t const preserveSize = (size_t)(dctx->tmpOut - dctx->tmpOutBuffer);
1854  size_t copySize = 64 KB - dctx->tmpOutSize;
1855  const BYTE* oldDictEnd = dctx->dict + dctx->dictSize - dctx->tmpOutStart;
1856  if (dctx->tmpOutSize > 64 KB) copySize = 0;
1857  if (copySize > preserveSize) copySize = preserveSize;
1858  assert(dctx->tmpOutBuffer != NULL);
1859 
1860  memcpy(dctx->tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1861 
1862  dctx->dict = dctx->tmpOutBuffer;
1863  dctx->dictSize = preserveSize + dctx->tmpOutStart;
1864  } else {
1865  const BYTE* const oldDictEnd = dctx->dict + dctx->dictSize;
1866  size_t const newDictSize = MIN(dctx->dictSize, 64 KB);
1867 
1868  memcpy(dctx->tmpOutBuffer, oldDictEnd - newDictSize, newDictSize);
1869 
1870  dctx->dict = dctx->tmpOutBuffer;
1871  dctx->dictSize = newDictSize;
1872  dctx->tmpOut = dctx->tmpOutBuffer + newDictSize;
1873  }
1874  }
1875 
1876  *srcSizePtr = (size_t)(srcPtr - srcStart);
1877  *dstSizePtr = (size_t)(dstPtr - dstStart);
1878  return nextSrcSizeHint;
1879 }
XXH_PUBLIC_API unsigned int XXH32(const void *input, size_t len, unsigned int seed)
Definition: xxhash.c:392
int LZ4_decompress_safe_usingDict(const char *source, char *dest, int compressedSize, int maxOutputSize, const char *dictStart, int dictSize)
Definition: lz4.c:2404
static void LZ4F_updateDict(LZ4F_dctx *dctx, const BYTE *dstPtr, size_t dstSize, const BYTE *dstBufferStart, unsigned withinTmp)
Definition: lz4frame.c:1295
#define LZ4F_BLOCKUNCOMPRESSED_FLAG
Definition: lz4frame.c:211
static size_t LZ4F_decodeHeader(LZ4F_dctx *dctx, const void *src, size_t srcSize)
Definition: lz4frame.c:1113
void LZ4F_resetDecompressionContext(LZ4F_dctx *dctx)
Definition: lz4frame.c:1097
size_t dictSize
Definition: lz4frame.c:1053
const BYTE * dict
Definition: lz4frame.c:1052
size_t maxBufferSize
Definition: lz4frame.c:1047
BYTE * tmpIn
Definition: lz4frame.c:1048
size_t tmpOutSize
Definition: lz4frame.c:1055
XXH32_state_t blockChecksum
Definition: lz4frame.c:1058
size_t tmpOutStart
Definition: lz4frame.c:1056
BYTE * tmpOutBuffer
Definition: lz4frame.c:1051
XXH32_state_t xxh
Definition: lz4frame.c:1057
BYTE * tmpOut
Definition: lz4frame.c:1054
#define GB
Definition: unum.c:93
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References ALLOC, assert, BFSize, BHSize, LZ4F_dctx_s::blockChecksum, LZ4F_frameInfo_t::blockChecksumFlag, LZ4F_frameInfo_t::blockMode, LZ4F_frameInfo_t::contentChecksumFlag, LZ4F_frameInfo_t::contentSize, DEBUGLOG, LZ4F_dctx_s::dict, LZ4F_dctx_s::dictSize, LZ4F_dctx_s::dStage, dstage_copyDirect, dstage_flushOut, dstage_getBlockChecksum, dstage_getBlockHeader, dstage_getCBlock, dstage_getFrameHeader, dstage_getSFrameSize, dstage_getSuffix, dstage_init, dstage_skipSkippable, dstage_storeBlockHeader, dstage_storeCBlock, dstage_storeFrameHeader, dstage_storeSFrameSize, dstage_storeSuffix, err0r(), LZ4F_dctx_s::frameInfo, LZ4F_dctx_s::frameRemainingSize, FREEMEM, GB, LZ4F_dctx_s::header, if(), KB, LZ4_decompress_safe_usingDict(), LZ4F_blockLinked, LZ4F_BLOCKUNCOMPRESSED_FLAG, LZ4F_decodeHeader(), LZ4F_isError(), LZ4F_readLE32(), LZ4F_resetDecompressionContext(), LZ4F_STATIC_ASSERT, LZ4F_updateDict(), LZ4F_dctx_s::maxBlockSize, LZ4F_dctx_s::maxBufferSize, maxFHSize, MEM_INIT, memcpy(), MIN, minFHSize, NULL, LZ4F_decompressOptions_t::stableDst, LZ4F_dctx_s::tmpIn, LZ4F_dctx_s::tmpInSize, LZ4F_dctx_s::tmpInTarget, LZ4F_dctx_s::tmpOut, LZ4F_dctx_s::tmpOutBuffer, LZ4F_dctx_s::tmpOutSize, LZ4F_dctx_s::tmpOutStart, LZ4F_dctx_s::xxh, XXH32(), XXH32_digest(), XXH32_reset(), and XXH32_update().

Referenced by basicTests(), decompress(), decompress_file_internal(), frameCheck(), FUZZ_decompressFrame(), local_LZ4F_decompress(), local_LZ4F_decompress_followHint(), local_LZ4F_decompress_noHint(), LZ4F_decompress_usingDict(), LZ4F_getFrameInfo(), and test_lz4f_decompression_wBuffers().

◆ LZ4F_decompress_usingDict()

size_t LZ4F_decompress_usingDict ( LZ4F_dctx dctx,
void *  dstBuffer,
size_t dstSizePtr,
const void *  srcBuffer,
size_t srcSizePtr,
const void *  dict,
size_t  dictSize,
const LZ4F_decompressOptions_t decompressOptionsPtr 
)

LZ4F_decompress_usingDict() : Same as LZ4F_decompress(), using a predefined dictionary. Dictionary is used "in place", without any preprocessing. It must remain accessible throughout the entire frame decoding.

Definition at line 1886 of file lz4frame.c.

1891 {
1892  if (dctx->dStage <= dstage_init) {
1893  dctx->dict = (const BYTE*)dict;
1894  dctx->dictSize = dictSize;
1895  }
1896  return LZ4F_decompress(dctx, dstBuffer, dstSizePtr,
1897  srcBuffer, srcSizePtr,
1898  decompressOptionsPtr);
1899 }
size_t LZ4F_decompress(LZ4F_dctx *dctx, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const LZ4F_decompressOptions_t *decompressOptionsPtr)
Definition: lz4frame.c:1384

References LZ4F_dctx_s::dict, LZ4F_dctx_s::dictSize, LZ4F_dctx_s::dStage, dstage_init, and LZ4F_decompress().

Referenced by basicTests(), decompress(), and LZ4IO_decompressLZ4F().

◆ LZ4F_flush()

size_t LZ4F_flush ( LZ4F_cctx cctxPtr,
void *  dstBuffer,
size_t  dstCapacity,
const LZ4F_compressOptions_t compressOptionsPtr 
)

LZ4F_flush() : When compressed data must be sent immediately, without waiting for a block to be filled, invoke LZ4_flush(), which will immediately compress any remaining data stored within LZ4F_cctx. The result of the function is the number of bytes written into dstBuffer. It can be zero, this means there was no data left within LZ4F_cctx. The function outputs an error code if it fails (can be tested using LZ4F_isError()) LZ4F_compressOptions_t* is optional. NULL is a valid argument.

Definition at line 938 of file lz4frame.c.

941 {
942  BYTE* const dstStart = (BYTE*)dstBuffer;
943  BYTE* dstPtr = dstStart;
945 
946  if (cctxPtr->tmpInSize == 0) return 0; /* nothing to flush */
947  if (cctxPtr->cStage != 1) return err0r(LZ4F_ERROR_GENERIC);
948  if (dstCapacity < (cctxPtr->tmpInSize + BHSize + BFSize))
949  return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
950  (void)compressOptionsPtr; /* not yet useful */
951 
952  /* select compression function */
954 
955  /* compress tmp buffer */
956  dstPtr += LZ4F_makeBlock(dstPtr,
957  cctxPtr->tmpIn, cctxPtr->tmpInSize,
958  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
959  cctxPtr->cdict,
961  assert(((void)"flush overflows dstBuffer!", (size_t)(dstPtr - dstStart) <= dstCapacity));
962 
963  if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked)
964  cctxPtr->tmpIn += cctxPtr->tmpInSize;
965  cctxPtr->tmpInSize = 0;
966 
967  /* keep tmpIn within limits */
968  if ((cctxPtr->tmpIn + cctxPtr->maxBlockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize)) { /* necessarily LZ4F_blockLinked */
969  int const realDictSize = LZ4F_localSaveDict(cctxPtr);
970  cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
971  }
972 
973  return (size_t)(dstPtr - dstStart);
974 }

References assert, BFSize, BHSize, LZ4F_frameInfo_t::blockChecksumFlag, LZ4F_frameInfo_t::blockMode, LZ4F_cctx_s::cdict, compress(), LZ4F_preferences_t::compressionLevel, LZ4F_cctx_s::cStage, err0r(), LZ4F_preferences_t::frameInfo, LZ4F_cctx_s::lz4CtxPtr, LZ4F_blockLinked, LZ4F_localSaveDict(), LZ4F_makeBlock(), LZ4F_selectCompression(), LZ4F_cctx_s::maxBlockSize, LZ4F_cctx_s::maxBufferSize, LZ4F_cctx_s::prefs, LZ4F_cctx_s::tmpBuff, LZ4F_cctx_s::tmpIn, and LZ4F_cctx_s::tmpInSize.

Referenced by fuzzerTests(), and LZ4F_compressEnd().

◆ LZ4F_freeCDict()

void LZ4F_freeCDict ( LZ4F_CDict *  cdict)

Definition at line 514 of file lz4frame.c.

515 {
516  if (cdict==NULL) return; /* support free on NULL */
517  FREEMEM(cdict->dictContent);
518  LZ4_freeStream(cdict->fastCtx);
519  LZ4_freeStreamHC(cdict->HCCtx);
520  FREEMEM(cdict);
521 }
int LZ4_freeStream(LZ4_stream_t *LZ4_stream)
Definition: lz4.c:1465
int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr)
Definition: lz4hc.c:994

References FREEMEM, LZ4_freeStream(), LZ4_freeStreamHC(), and NULL.

Referenced by basicTests(), LZ4F_createCDict(), and LZ4IO_freeCResources().

◆ LZ4F_freeCompressionContext()

LZ4F_errorCode_t LZ4F_freeCompressionContext ( LZ4F_cctx cctxPtr)

Definition at line 550 of file lz4frame.c.

551 {
552  if (cctxPtr != NULL) { /* support free on NULL */
553  FREEMEM(cctxPtr->lz4CtxPtr); /* note: LZ4_streamHC_t and LZ4_stream_t are simple POD types */
554  FREEMEM(cctxPtr->tmpBuff);
555  FREEMEM(cctxPtr);
556  }
557 
558  return LZ4F_OK_NoError;
559 }

References FREEMEM, LZ4F_cctx_s::lz4CtxPtr, NULL, and LZ4F_cctx_s::tmpBuff.

Referenced by basicTests(), compress_file(), fuzzerTests(), LZ4F_compressFrame(), and LZ4IO_freeCResources().

◆ LZ4F_freeDecompressionContext()

LZ4F_errorCode_t LZ4F_freeDecompressionContext ( LZ4F_dctx dctx)

Definition at line 1082 of file lz4frame.c.

1083 {
1084  LZ4F_errorCode_t result = LZ4F_OK_NoError;
1085  if (dctx != NULL) { /* can accept NULL input, like free() */
1086  result = (LZ4F_errorCode_t)dctx->dStage;
1087  FREEMEM(dctx->tmpIn);
1088  FREEMEM(dctx->tmpOutBuffer);
1089  FREEMEM(dctx);
1090  }
1091  return result;
1092 }

References LZ4F_dctx_s::dStage, FREEMEM, NULL, LZ4F_dctx_s::tmpIn, and LZ4F_dctx_s::tmpOutBuffer.

Referenced by basicTests(), decompress_file(), freeCResources(), fullSpeedBench(), FUZZ_decompressFrame(), fuzzerTests(), LLVMFuzzerTestOneInput(), LZ4IO_freeDResources(), and LZ4IO_getCompressedFileInfo().

◆ LZ4F_getBlockSize()

size_t LZ4F_getBlockSize ( unsigned  blockSizeID)

Definition at line 278 of file lz4frame.c.

279 {
280  static const size_t blockSizes[4] = { 64 KB, 256 KB, 1 MB, 4 MB };
281 
282  if (blockSizeID == 0) blockSizeID = LZ4F_BLOCKSIZEID_DEFAULT;
283  if (blockSizeID < LZ4F_max64KB || blockSizeID > LZ4F_max4MB)
284  return err0r(LZ4F_ERROR_maxBlockSize_invalid);
285  blockSizeID -= LZ4F_max64KB;
286  return blockSizes[blockSizeID];
287 }
@ LZ4F_max64KB
Definition: lz4frame.h:125
@ LZ4F_max4MB
Definition: lz4frame.h:128

References err0r(), KB, LZ4F_BLOCKSIZEID_DEFAULT, LZ4F_max4MB, LZ4F_max64KB, and MB.

Referenced by basicTests(), LZ4F_compressBegin_usingCDict(), LZ4F_compressBound_internal(), LZ4F_compressFrame_usingCDict(), and LZ4F_decodeHeader().

◆ LZ4F_getErrorCode()

LZ4F_errorCodes LZ4F_getErrorCode ( size_t  functionResult)

Definition at line 261 of file lz4frame.c.

262 {
263  if (!LZ4F_isError(functionResult)) return LZ4F_OK_NoError;
264  return (LZ4F_errorCodes)(-(ptrdiff_t)functionResult);
265 }

References LZ4F_isError().

Referenced by basicTests(), and test_lz4f_decompression_wBuffers().

◆ LZ4F_getErrorName()

const char* LZ4F_getErrorName ( LZ4F_errorCode_t  code)

return error code string; for debugging

Definition at line 254 of file lz4frame.c.

255 {
256  static const char* codeError = "Unspecified error code";
257  if (LZ4F_isError(code)) return LZ4F_errorStrings[-(int)(code)];
258  return codeError;
259 }
static const char * LZ4F_errorStrings[]
Definition: lz4frame.c:246
static int
Definition: sfsocketcall.h:114

References int, LZ4F_errorStrings, and LZ4F_isError().

Referenced by basicTests(), decompress_file(), decompress_file_allocDst(), decompress_file_internal(), frameCheck(), fuzzerTests(), LZ4IO_compressFilename_extRess(), LZ4IO_createCResources(), LZ4IO_createDResources(), LZ4IO_decompressLZ4F(), LZ4IO_freeCResources(), and LZ4IO_freeDResources().

◆ LZ4F_getFrameInfo()

LZ4F_errorCode_t LZ4F_getFrameInfo ( LZ4F_dctx dctx,
LZ4F_frameInfo_t frameInfoPtr,
const void *  srcBuffer,
size_t srcSizePtr 
)

LZ4F_getFrameInfo() : This function extracts frame parameters (max blockSize, frame checksum, etc.). Usage is optional. Objective is to provide relevant information for allocation purposes. This function works in 2 situations :

  • At the beginning of a new frame, in which case it will decode this information from srcBuffer, and start the decoding process. Amount of input data provided must be large enough to successfully decode the frame header. A header size is variable, but is guaranteed to be <= LZ4F_HEADER_SIZE_MAX bytes. It's possible to provide more input data than this minimum.
  • After decoding has been started. In which case, no input is read, frame parameters are extracted from dctx. The number of bytes consumed from srcBuffer will be updated within *srcSizePtr (necessarily <= original value). Decompression must resume from (srcBuffer + *srcSizePtr).
    Returns
    : an hint about how many srcSize bytes LZ4F_decompress() expects for next call, or an error code which can be tested using LZ4F_isError() note 1 : in case of error, dctx is not modified. Decoding operations can resume from where they stopped. note 2 : frame parameters are copied into an already allocated LZ4F_frameInfo_t structure.

Definition at line 1253 of file lz4frame.c.

1256 {
1258  if (dctx->dStage > dstage_storeFrameHeader) {
1259  /* frameInfo already decoded */
1260  size_t o=0, i=0;
1261  *srcSizePtr = 0;
1262  *frameInfoPtr = dctx->frameInfo;
1263  /* returns : recommended nb of bytes for LZ4F_decompress() */
1264  return LZ4F_decompress(dctx, NULL, &o, NULL, &i, NULL);
1265  } else {
1266  if (dctx->dStage == dstage_storeFrameHeader) {
1267  /* frame decoding already started, in the middle of header => automatic fail */
1268  *srcSizePtr = 0;
1269  return err0r(LZ4F_ERROR_frameDecoding_alreadyStarted);
1270  } else {
1271  size_t const hSize = LZ4F_headerSize(srcBuffer, *srcSizePtr);
1272  if (LZ4F_isError(hSize)) { *srcSizePtr=0; return hSize; }
1273  if (*srcSizePtr < hSize) {
1274  *srcSizePtr=0;
1275  return err0r(LZ4F_ERROR_frameHeader_incomplete);
1276  }
1277 
1278  { size_t decodeResult = LZ4F_decodeHeader(dctx, srcBuffer, hSize);
1279  if (LZ4F_isError(decodeResult)) {
1280  *srcSizePtr = 0;
1281  } else {
1282  *srcSizePtr = decodeResult;
1283  decodeResult = BHSize; /* block header size */
1284  }
1285  *frameInfoPtr = dctx->frameInfo;
1286  return decodeResult;
1287  } } }
1288 }
lzma_index ** i
Definition: index.h:629
size_t LZ4F_headerSize(const void *src, size_t srcSize)
Definition: lz4frame.c:1212

References BHSize, LZ4F_dctx_s::dStage, dstage_getFrameHeader, dstage_storeFrameHeader, err0r(), LZ4F_dctx_s::frameInfo, i, LZ4F_decodeHeader(), LZ4F_decompress(), LZ4F_headerSize(), LZ4F_isError(), LZ4F_STATIC_ASSERT, and NULL.

Referenced by basicTests(), decompress_file_allocDst(), frameCheck(), and LZ4IO_getCompressedFileInfo().

◆ LZ4F_getVersion()

unsigned LZ4F_getVersion ( void  )

Definition at line 274 of file lz4frame.c.

274 { return LZ4F_VERSION; }

References LZ4F_VERSION.

◆ LZ4F_headerChecksum()

static BYTE LZ4F_headerChecksum ( const void *  header,
size_t  length 
)
static

Definition at line 294 of file lz4frame.c.

295 {
296  U32 const xxh = XXH32(header, length, 0);
297  return (BYTE)(xxh >> 8);
298 }
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
#define header(is_bt, len_min, ret_op)

References header, length, and XXH32().

Referenced by LZ4F_compressBegin_usingCDict(), and LZ4F_decodeHeader().

◆ LZ4F_headerSize()

size_t LZ4F_headerSize ( const void *  src,
size_t  srcSize 
)

LZ4F_headerSize() :

Returns
: size of frame header or an error code, which can be tested using LZ4F_isError()

Definition at line 1212 of file lz4frame.c.

1213 {
1214  if (src == NULL) return err0r(LZ4F_ERROR_srcPtr_wrong);
1215 
1216  /* minimal srcSize to determine header size */
1218  return err0r(LZ4F_ERROR_frameHeader_incomplete);
1219 
1220  /* special case : skippable frames */
1221  if ((LZ4F_readLE32(src) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START)
1222  return 8;
1223 
1224  /* control magic number */
1225 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1227  return err0r(LZ4F_ERROR_frameType_unknown);
1228 #endif
1229 
1230  /* Frame Header Size */
1231  { BYTE const FLG = ((const BYTE*)src)[4];
1232  U32 const contentSizeFlag = (FLG>>3) & _1BIT;
1233  U32 const dictIDFlag = FLG & _1BIT;
1234  return minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
1235  }
1236 }
#define LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH
Definition: lz4frame.h:374

References _1BIT, err0r(), FLG, LZ4F_MAGIC_SKIPPABLE_START, LZ4F_MAGICNUMBER, LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH, LZ4F_readLE32(), minFHSize, NULL, src, and srcSize.

Referenced by basicTests(), LZ4F_getFrameInfo(), and LZ4IO_getCompressedFileInfo().

◆ LZ4F_initStream()

static void LZ4F_initStream ( void *  ctx,
const LZ4F_CDict *  cdict,
int  level,
LZ4F_blockMode_t  blockMode 
)
static

This function prepares the internal LZ4(HC) stream for a new compression, resetting the context and attaching the dictionary, if there is one.

It needs to be called at the beginning of each independent compression stream (i.e., at the beginning of a frame in blockLinked mode, or at the beginning of each block in blockIndependent mode).

Definition at line 570 of file lz4frame.c.

573  {
574  if (level < LZ4HC_CLEVEL_MIN) {
575  if (cdict != NULL || blockMode == LZ4F_blockLinked) {
576  /* In these cases, we will call LZ4_compress_fast_continue(),
577  * which needs an already reset context. Otherwise, we'll call a
578  * one-shot API. The non-continued APIs internally perform their own
579  * resets at the beginning of their calls, where they know what
580  * tableType they need the context to be in. So in that case this
581  * would be misguided / wasted work. */
583  }
584  LZ4_attach_dictionary((LZ4_stream_t *)ctx, cdict ? cdict->fastCtx : NULL);
585  } else {
587  LZ4_attach_HC_dictionary((LZ4_streamHC_t *)ctx, cdict ? cdict->HCCtx : NULL);
588  }
589 }
void LZ4_resetStream_fast(LZ4_stream_t *ctx)
Definition: lz4.c:1461
void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream)
Definition: lz4.c:1517
void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream)
Definition: lz4hc.c:1077
void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1027

References level, LZ4_attach_dictionary(), LZ4_attach_HC_dictionary(), LZ4_resetStream_fast(), LZ4_resetStreamHC_fast(), LZ4F_blockLinked, LZ4HC_CLEVEL_MIN, and NULL.

Referenced by LZ4F_compressBegin_usingCDict(), LZ4F_compressBlock(), and LZ4F_compressBlockHC().

◆ LZ4F_isError()

◆ LZ4F_localSaveDict()

static int LZ4F_localSaveDict ( LZ4F_cctx_t cctxPtr)
static

Definition at line 809 of file lz4frame.c.

810 {
811  if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN)
812  return LZ4_saveDict ((LZ4_stream_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
813  return LZ4_saveDictHC ((LZ4_streamHC_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
814 }
int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char *safeBuffer, int dictSize)
Definition: lz4.c:1668
int LZ4_saveDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, char *safeBuffer, int dictSize)
Definition: lz4hc.c:1158

References LZ4F_preferences_t::compressionLevel, KB, LZ4_saveDict(), LZ4_saveDictHC(), LZ4F_cctx_s::lz4CtxPtr, LZ4HC_CLEVEL_MIN, LZ4F_cctx_s::prefs, and LZ4F_cctx_s::tmpBuff.

Referenced by LZ4F_compressUpdate(), and LZ4F_flush().

◆ LZ4F_makeBlock()

static size_t LZ4F_makeBlock ( void *  dst,
const void *  src,
size_t  srcSize,
compressFunc_t  compress,
void *  lz4ctx,
int  level,
const LZ4F_CDict *  cdict,
LZ4F_blockChecksum_t  crcFlag 
)
static

LZ4F_makeBlock(): compress a single block, add header and optional checksum. assumption : dst buffer capacity is >= BHSize + srcSize + crcSize

Definition at line 740 of file lz4frame.c.

745 {
746  BYTE* const cSizePtr = (BYTE*)dst;
747  U32 cSize = (U32)compress(lz4ctx, (const char*)src, (char*)(cSizePtr+BHSize),
748  (int)(srcSize), (int)(srcSize-1),
749  level, cdict);
750  if (cSize == 0) { /* compression failed */
751  DEBUGLOG(5, "LZ4F_makeBlock: compression failed, creating a raw block (size %u)", (U32)srcSize);
752  cSize = (U32)srcSize;
753  LZ4F_writeLE32(cSizePtr, cSize | LZ4F_BLOCKUNCOMPRESSED_FLAG);
754  memcpy(cSizePtr+BHSize, src, srcSize);
755  } else {
756  LZ4F_writeLE32(cSizePtr, cSize);
757  }
758  if (crcFlag) {
759  U32 const crc32 = XXH32(cSizePtr+BHSize, cSize, 0); /* checksum of compressed data */
760  LZ4F_writeLE32(cSizePtr+BHSize+cSize, crc32);
761  }
762  return BHSize + cSize + ((U32)crcFlag)*BFSize;
763 }
unsigned int U32
Definition: lz4frame.c:140
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition: crc32.c:1063

References BFSize, BHSize, compress(), crc32(), DEBUGLOG, dst, int, level, LZ4F_BLOCKUNCOMPRESSED_FLAG, LZ4F_writeLE32(), memcpy(), src, srcSize, and XXH32().

Referenced by LZ4F_compressUpdate(), and LZ4F_flush().

◆ LZ4F_optimalBSID()

static LZ4F_blockSizeID_t LZ4F_optimalBSID ( const LZ4F_blockSizeID_t  requestedBSID,
const size_t  srcSize 
)
static

Definition at line 304 of file lz4frame.c.

306 {
307  LZ4F_blockSizeID_t proposedBSID = LZ4F_max64KB;
308  size_t maxBlockSize = 64 KB;
309  while (requestedBSID > proposedBSID) {
310  if (srcSize <= maxBlockSize)
311  return proposedBSID;
312  proposedBSID = (LZ4F_blockSizeID_t)((int)proposedBSID + 1);
313  maxBlockSize <<= 2;
314  }
315  return requestedBSID;
316 }

References KB, LZ4F_max64KB, and srcSize.

Referenced by LZ4F_compressFrame_usingCDict().

◆ LZ4F_readLE32()

static U32 LZ4F_readLE32 ( const void *  src)
static

Definition at line 147 of file lz4frame.c.

148 {
149  const BYTE* const srcPtr = (const BYTE*)src;
150  U32 value32 = srcPtr[0];
151  value32 += ((U32)srcPtr[1])<< 8;
152  value32 += ((U32)srcPtr[2])<<16;
153  value32 += ((U32)srcPtr[3])<<24;
154  return value32;
155 }

References src.

Referenced by LZ4F_decodeHeader(), LZ4F_decompress(), and LZ4F_headerSize().

◆ LZ4F_readLE64()

static U64 LZ4F_readLE64 ( const void *  src)
static

Definition at line 166 of file lz4frame.c.

167 {
168  const BYTE* const srcPtr = (const BYTE*)src;
169  U64 value64 = srcPtr[0];
170  value64 += ((U64)srcPtr[1]<<8);
171  value64 += ((U64)srcPtr[2]<<16);
172  value64 += ((U64)srcPtr[3]<<24);
173  value64 += ((U64)srcPtr[4]<<32);
174  value64 += ((U64)srcPtr[5]<<40);
175  value64 += ((U64)srcPtr[6]<<48);
176  value64 += ((U64)srcPtr[7]<<56);
177  return value64;
178 }
unsigned long long U64
Definition: lz4.c:290

References src.

Referenced by LZ4F_decodeHeader().

◆ LZ4F_resetDecompressionContext()

void LZ4F_resetDecompressionContext ( LZ4F_dctx dctx)

LZ4F_resetDecompressionContext() : added in v1.8.0 In case of an error, the context is left in "undefined" state. In which case, it's necessary to reset it, before re-using it. This method can also be used to abruptly stop any unfinished decompression, and start a new one using same context resources.

Definition at line 1097 of file lz4frame.c.

1098 {
1099  dctx->dStage = dstage_getFrameHeader;
1100  dctx->dict = NULL;
1101  dctx->dictSize = 0;
1102 }

References LZ4F_dctx_s::dict, LZ4F_dctx_s::dictSize, LZ4F_dctx_s::dStage, dstage_getFrameHeader, and NULL.

Referenced by basicTests(), decompress(), fuzzerTests(), and LZ4F_decompress().

◆ LZ4F_selectCompression()

static compressFunc_t LZ4F_selectCompression ( LZ4F_blockMode_t  blockMode,
int  level 
)
static

Definition at line 799 of file lz4frame.c.

800 {
801  if (level < LZ4HC_CLEVEL_MIN) {
802  if (blockMode == LZ4F_blockIndependent) return LZ4F_compressBlock;
804  }
805  if (blockMode == LZ4F_blockIndependent) return LZ4F_compressBlockHC;
807 }
static int LZ4F_compressBlockHC(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:784
static int LZ4F_compressBlock(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:766
static int LZ4F_compressBlockHC_continue(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:793
static int LZ4F_compressBlock_continue(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:777

References level, LZ4F_blockIndependent, LZ4F_compressBlock(), LZ4F_compressBlock_continue(), LZ4F_compressBlockHC(), LZ4F_compressBlockHC_continue(), and LZ4HC_CLEVEL_MIN.

Referenced by LZ4F_compressUpdate(), and LZ4F_flush().

◆ LZ4F_updateDict()

static void LZ4F_updateDict ( LZ4F_dctx dctx,
const BYTE dstPtr,
size_t  dstSize,
const BYTE dstBufferStart,
unsigned  withinTmp 
)
static

Definition at line 1295 of file lz4frame.c.

1298 {
1299  assert(dstPtr != NULL);
1300  if (dctx->dictSize==0) {
1301  dctx->dict = (const BYTE*)dstPtr; /* priority to prefix mode */
1302  }
1303  assert(dctx->dict != NULL);
1304 
1305  if (dctx->dict + dctx->dictSize == dstPtr) { /* prefix mode, everything within dstBuffer */
1306  dctx->dictSize += dstSize;
1307  return;
1308  }
1309 
1310  assert(dstPtr >= dstBufferStart);
1311  if ((size_t)(dstPtr - dstBufferStart) + dstSize >= 64 KB) { /* history in dstBuffer becomes large enough to become dictionary */
1312  dctx->dict = (const BYTE*)dstBufferStart;
1313  dctx->dictSize = (size_t)(dstPtr - dstBufferStart) + dstSize;
1314  return;
1315  }
1316 
1317  assert(dstSize < 64 KB); /* if dstSize >= 64 KB, dictionary would be set into dstBuffer directly */
1318 
1319  /* dstBuffer does not contain whole useful history (64 KB), so it must be saved within tmpOutBuffer */
1320  assert(dctx->tmpOutBuffer != NULL);
1321 
1322  if (withinTmp && (dctx->dict == dctx->tmpOutBuffer)) { /* continue history within tmpOutBuffer */
1323  /* withinTmp expectation : content of [dstPtr,dstSize] is same as [dict+dictSize,dstSize], so we just extend it */
1324  assert(dctx->dict + dctx->dictSize == dctx->tmpOut + dctx->tmpOutStart);
1325  dctx->dictSize += dstSize;
1326  return;
1327  }
1328 
1329  if (withinTmp) { /* copy relevant dict portion in front of tmpOut within tmpOutBuffer */
1330  size_t const preserveSize = (size_t)(dctx->tmpOut - dctx->tmpOutBuffer);
1331  size_t copySize = 64 KB - dctx->tmpOutSize;
1332  const BYTE* const oldDictEnd = dctx->dict + dctx->dictSize - dctx->tmpOutStart;
1333  if (dctx->tmpOutSize > 64 KB) copySize = 0;
1334  if (copySize > preserveSize) copySize = preserveSize;
1335 
1336  memcpy(dctx->tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1337 
1338  dctx->dict = dctx->tmpOutBuffer;
1339  dctx->dictSize = preserveSize + dctx->tmpOutStart + dstSize;
1340  return;
1341  }
1342 
1343  if (dctx->dict == dctx->tmpOutBuffer) { /* copy dst into tmp to complete dict */
1344  if (dctx->dictSize + dstSize > dctx->maxBufferSize) { /* tmp buffer not large enough */
1345  size_t const preserveSize = 64 KB - dstSize;
1346  memcpy(dctx->tmpOutBuffer, dctx->dict + dctx->dictSize - preserveSize, preserveSize);
1347  dctx->dictSize = preserveSize;
1348  }
1349  memcpy(dctx->tmpOutBuffer + dctx->dictSize, dstPtr, dstSize);
1350  dctx->dictSize += dstSize;
1351  return;
1352  }
1353 
1354  /* join dict & dest into tmp */
1355  { size_t preserveSize = 64 KB - dstSize;
1356  if (preserveSize > dctx->dictSize) preserveSize = dctx->dictSize;
1357  memcpy(dctx->tmpOutBuffer, dctx->dict + dctx->dictSize - preserveSize, preserveSize);
1358  memcpy(dctx->tmpOutBuffer + preserveSize, dstPtr, dstSize);
1359  dctx->dict = dctx->tmpOutBuffer;
1360  dctx->dictSize = preserveSize + dstSize;
1361  }
1362 }

References assert, LZ4F_dctx_s::dict, LZ4F_dctx_s::dictSize, KB, LZ4F_dctx_s::maxBufferSize, memcpy(), NULL, LZ4F_dctx_s::tmpOut, LZ4F_dctx_s::tmpOutBuffer, LZ4F_dctx_s::tmpOutSize, and LZ4F_dctx_s::tmpOutStart.

Referenced by LZ4F_decompress().

◆ LZ4F_writeLE32()

static void LZ4F_writeLE32 ( void *  dst,
U32  value32 
)
static

Definition at line 157 of file lz4frame.c.

158 {
159  BYTE* const dstPtr = (BYTE*)dst;
160  dstPtr[0] = (BYTE)value32;
161  dstPtr[1] = (BYTE)(value32 >> 8);
162  dstPtr[2] = (BYTE)(value32 >> 16);
163  dstPtr[3] = (BYTE)(value32 >> 24);
164 }

References dst.

Referenced by LZ4F_compressBegin_usingCDict(), LZ4F_compressEnd(), and LZ4F_makeBlock().

◆ LZ4F_writeLE64()

static void LZ4F_writeLE64 ( void *  dst,
U64  value64 
)
static

Definition at line 180 of file lz4frame.c.

181 {
182  BYTE* const dstPtr = (BYTE*)dst;
183  dstPtr[0] = (BYTE)value64;
184  dstPtr[1] = (BYTE)(value64 >> 8);
185  dstPtr[2] = (BYTE)(value64 >> 16);
186  dstPtr[3] = (BYTE)(value64 >> 24);
187  dstPtr[4] = (BYTE)(value64 >> 32);
188  dstPtr[5] = (BYTE)(value64 >> 40);
189  dstPtr[6] = (BYTE)(value64 >> 48);
190  dstPtr[7] = (BYTE)(value64 >> 56);
191 }

References dst.

Referenced by LZ4F_compressBegin_usingCDict().

Variable Documentation

◆ BFSize

◆ BHSize

◆ LZ4F_errorStrings

const char* LZ4F_errorStrings[] = { LZ4F_LIST_ERRORS(LZ4F_GENERATE_STRING) }
static

Definition at line 246 of file lz4frame.c.

Referenced by LZ4F_getErrorName().

◆ maxFHSize

◆ minFHSize

const size_t minFHSize = LZ4F_HEADER_SIZE_MIN
static

Definition at line 214 of file lz4frame.c.

Referenced by LZ4F_decodeHeader(), LZ4F_decompress(), and LZ4F_headerSize().