2013-12-30 17:16:52 +00:00
/*
2015-05-02 14:44:43 +00:00
LZ4 HC - High Compression Mode of LZ4
2016-11-21 23:51:39 +00:00
Copyright ( C ) 2011 - 2016 , Yann Collet .
2015-05-02 14:44:43 +00:00
BSD 2 - Clause License ( http : //www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions are
met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above
copyright notice , this list of conditions and the following disclaimer
in the documentation and / or other materials provided with the
distribution .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
" AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
You can contact the author at :
2016-11-03 14:12:57 +00:00
- LZ4 source repository : https : //github.com/lz4/lz4
2015-05-02 14:44:43 +00:00
- LZ4 public forum : https : //groups.google.com/forum/#!forum/lz4c
2013-12-30 17:16:52 +00:00
*/
2016-11-12 23:50:29 +00:00
/* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */
2014-02-04 14:11:10 +00:00
2015-10-21 14:00:48 +00:00
/* *************************************
2015-05-02 14:44:43 +00:00
* Tuning Parameter
2015-10-21 14:00:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-02-04 14:11:10 +00:00
2015-10-21 14:00:48 +00:00
/*!
* HEAPMODE :
* Select how default compression function will allocate workplace memory ,
* in stack ( 0 : fastest ) , or in heap ( 1 : requires malloc ( ) ) .
* Since workplace is rather large , heap mode is recommended .
*/
2016-11-12 23:50:29 +00:00
# ifndef LZ4HC_HEAPMODE
# define LZ4HC_HEAPMODE 1
# endif
2014-02-04 14:11:10 +00:00
2015-10-21 14:00:48 +00:00
/* *************************************
2016-11-12 23:50:29 +00:00
* Dependency
2015-10-21 14:00:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-11-29 16:12:26 +00:00
# include "lz4hc.h"
2013-12-30 17:16:52 +00:00
2015-10-21 14:00:48 +00:00
/* *************************************
2015-05-02 14:44:43 +00:00
* Local Compiler Options
2015-10-21 14:00:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-11-29 19:19:39 +00:00
# if defined(__GNUC__)
# pragma GCC diagnostic ignored "-Wunused-function"
2013-12-30 17:16:52 +00:00
# endif
2014-11-29 19:19:39 +00:00
# if defined (__clang__)
# pragma clang diagnostic ignored "-Wunused-function"
2013-12-30 17:16:52 +00:00
# endif
2015-10-21 14:00:48 +00:00
/* *************************************
2015-05-02 14:44:43 +00:00
* Common LZ4 definition
2015-10-21 14:00:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-11-29 19:19:39 +00:00
# define LZ4_COMMONDEFS_ONLY
# include "lz4.c"
2013-12-30 17:16:52 +00:00
2015-10-21 14:00:48 +00:00
/* *************************************
2015-05-02 14:44:43 +00:00
* Local Constants
2015-10-21 14:00:48 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-12-30 17:16:52 +00:00
# define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
2014-02-04 14:11:10 +00:00
/**************************************
2015-05-02 14:44:43 +00:00
* Local Macros
2014-02-04 14:11:10 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-11 21:00:02 +00:00
# define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))
2016-12-07 11:59:05 +00:00
# define DELTANEXTMAXD(p) chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */
2015-05-02 14:44:43 +00:00
# define DELTANEXTU16(p) chainTable[(U16)(p)] /* faster */
2013-12-30 17:16:52 +00:00
2014-11-29 19:19:39 +00:00
static U32 LZ4HC_hashPtr ( const void * ptr ) { return HASH_FUNCTION ( LZ4_read32 ( ptr ) ) ; }
2013-12-30 17:16:52 +00:00
2014-11-29 19:19:39 +00:00
/**************************************
2015-05-02 14:44:43 +00:00
* HC Compression
2014-11-29 19:19:39 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-12 15:29:54 +00:00
static void LZ4HC_init ( LZ4HC_CCtx_internal * hc4 , const BYTE * start )
2013-12-30 17:16:52 +00:00
{
MEM_INIT ( ( void * ) hc4 - > hashTable , 0 , sizeof ( hc4 - > hashTable ) ) ;
MEM_INIT ( hc4 - > chainTable , 0xFF , sizeof ( hc4 - > chainTable ) ) ;
2016-12-28 14:38:59 +00:00
hc4 - > nextToUpdate = 64 KB ;
2014-12-03 18:17:10 +00:00
hc4 - > base = start - 64 KB ;
hc4 - > end = start ;
hc4 - > dictBase = start - 64 KB ;
2014-10-20 23:12:55 +00:00
hc4 - > dictLimit = 64 KB ;
hc4 - > lowLimit = 64 KB ;
2013-12-30 17:16:52 +00:00
}
2014-02-04 14:11:10 +00:00
/* Update chains up to ip (excluded) */
2016-11-12 15:29:54 +00:00
FORCE_INLINE void LZ4HC_Insert ( LZ4HC_CCtx_internal * hc4 , const BYTE * ip )
2013-12-30 17:16:52 +00:00
{
2016-09-03 02:06:01 +00:00
U16 * const chainTable = hc4 - > chainTable ;
U32 * const hashTable = hc4 - > hashTable ;
2014-10-18 10:18:14 +00:00
const BYTE * const base = hc4 - > base ;
2016-09-03 02:06:01 +00:00
U32 const target = ( U32 ) ( ip - base ) ;
2014-10-18 10:18:14 +00:00
U32 idx = hc4 - > nextToUpdate ;
2013-12-30 17:16:52 +00:00
2016-09-03 02:06:01 +00:00
while ( idx < target ) {
U32 const h = LZ4HC_hashPtr ( base + idx ) ;
size_t delta = idx - hashTable [ h ] ;
2013-12-30 17:16:52 +00:00
if ( delta > MAX_DISTANCE ) delta = MAX_DISTANCE ;
2015-05-02 14:44:43 +00:00
DELTANEXTU16 ( idx ) = ( U16 ) delta ;
2016-09-03 02:06:01 +00:00
hashTable [ h ] = idx ;
2014-10-18 10:18:14 +00:00
idx + + ;
2013-12-30 17:16:52 +00:00
}
2014-08-01 18:10:21 +00:00
2014-10-18 10:18:14 +00:00
hc4 - > nextToUpdate = target ;
2013-12-30 17:16:52 +00:00
}
2016-11-12 15:29:54 +00:00
FORCE_INLINE int LZ4HC_InsertAndFindBestMatch ( LZ4HC_CCtx_internal * hc4 , /* Index table will be updated */
2014-10-26 10:22:15 +00:00
const BYTE * ip , const BYTE * const iLimit ,
const BYTE * * matchpos ,
const int maxNbAttempts )
2013-12-30 17:16:52 +00:00
{
U16 * const chainTable = hc4 - > chainTable ;
2014-10-18 10:18:14 +00:00
U32 * const HashTable = hc4 - > hashTable ;
const BYTE * const base = hc4 - > base ;
2014-10-19 16:41:42 +00:00
const BYTE * const dictBase = hc4 - > dictBase ;
const U32 dictLimit = hc4 - > dictLimit ;
2014-10-26 10:22:15 +00:00
const U32 lowLimit = ( hc4 - > lowLimit + 64 KB > ( U32 ) ( ip - base ) ) ? hc4 - > lowLimit : ( U32 ) ( ip - base ) - ( 64 KB - 1 ) ;
2014-10-19 16:41:42 +00:00
U32 matchIndex ;
2014-02-04 14:11:10 +00:00
int nbAttempts = maxNbAttempts ;
2014-10-18 10:18:14 +00:00
size_t ml = 0 ;
2013-12-30 17:16:52 +00:00
2014-10-26 10:22:15 +00:00
/* HC4 match finder */
2013-12-30 17:16:52 +00:00
LZ4HC_Insert ( hc4 , ip ) ;
2014-10-20 00:08:21 +00:00
matchIndex = HashTable [ LZ4HC_hashPtr ( ip ) ] ;
2013-12-30 17:16:52 +00:00
2016-09-03 02:06:01 +00:00
while ( ( matchIndex > = lowLimit ) & & ( nbAttempts ) ) {
2013-12-30 17:16:52 +00:00
nbAttempts - - ;
2016-09-03 02:06:01 +00:00
if ( matchIndex > = dictLimit ) {
2016-11-12 23:50:29 +00:00
const BYTE * const match = base + matchIndex ;
2014-10-20 00:08:21 +00:00
if ( * ( match + ml ) = = * ( ip + ml )
2014-11-29 19:19:39 +00:00
& & ( LZ4_read32 ( match ) = = LZ4_read32 ( ip ) ) )
2014-10-20 00:08:21 +00:00
{
2016-09-03 02:06:01 +00:00
size_t const mlt = LZ4_count ( ip + MINMATCH , match + MINMATCH , iLimit ) + MINMATCH ;
2014-10-20 00:08:21 +00:00
if ( mlt > ml ) { ml = mlt ; * matchpos = match ; }
}
2016-09-03 02:06:01 +00:00
} else {
2016-11-12 23:50:29 +00:00
const BYTE * const match = dictBase + matchIndex ;
2016-09-03 02:06:01 +00:00
if ( LZ4_read32 ( match ) = = LZ4_read32 ( ip ) ) {
2014-10-20 00:08:21 +00:00
size_t mlt ;
const BYTE * vLimit = ip + ( dictLimit - matchIndex ) ;
if ( vLimit > iLimit ) vLimit = iLimit ;
2014-11-29 19:19:39 +00:00
mlt = LZ4_count ( ip + MINMATCH , match + MINMATCH , vLimit ) + MINMATCH ;
2014-10-20 00:08:21 +00:00
if ( ( ip + mlt = = vLimit ) & & ( vLimit < iLimit ) )
2014-11-29 19:19:39 +00:00
mlt + = LZ4_count ( ip + mlt , base + dictLimit , iLimit ) ;
2014-12-16 21:03:16 +00:00
if ( mlt > ml ) { ml = mlt ; * matchpos = base + matchIndex ; } /* virtual matchpos */
2014-10-20 00:08:21 +00:00
}
2013-12-30 17:16:52 +00:00
}
2015-05-02 14:44:43 +00:00
matchIndex - = DELTANEXTU16 ( matchIndex ) ;
2013-12-30 17:16:52 +00:00
}
return ( int ) ml ;
}
2014-10-18 10:18:14 +00:00
FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * hc4 ,
2015-03-30 14:57:26 +00:00
const BYTE * const ip ,
const BYTE * const iLowLimit ,
const BYTE * const iHighLimit ,
2014-10-26 10:22:15 +00:00
int longest ,
const BYTE * * matchpos ,
const BYTE * * startpos ,
const int maxNbAttempts )
2013-12-30 17:16:52 +00:00
{
2014-10-18 10:18:14 +00:00
U16 * const chainTable = hc4 - > chainTable ;
U32 * const HashTable = hc4 - > hashTable ;
const BYTE * const base = hc4 - > base ;
2014-10-20 00:08:21 +00:00
const U32 dictLimit = hc4 - > dictLimit ;
2015-03-30 14:57:26 +00:00
const BYTE * const lowPrefixPtr = base + dictLimit ;
2014-10-26 10:22:15 +00:00
const U32 lowLimit = ( hc4 - > lowLimit + 64 KB > ( U32 ) ( ip - base ) ) ? hc4 - > lowLimit : ( U32 ) ( ip - base ) - ( 64 KB - 1 ) ;
2014-10-20 00:08:21 +00:00
const BYTE * const dictBase = hc4 - > dictBase ;
U32 matchIndex ;
2014-02-04 14:11:10 +00:00
int nbAttempts = maxNbAttempts ;
2014-10-20 00:08:21 +00:00
int delta = ( int ) ( ip - iLowLimit ) ;
2013-12-30 17:16:52 +00:00
2014-10-20 23:12:55 +00:00
2014-10-26 10:22:15 +00:00
/* First Match */
2013-12-30 17:16:52 +00:00
LZ4HC_Insert ( hc4 , ip ) ;
2014-10-20 00:08:21 +00:00
matchIndex = HashTable [ LZ4HC_hashPtr ( ip ) ] ;
2013-12-30 17:16:52 +00:00
2016-09-03 02:06:01 +00:00
while ( ( matchIndex > = lowLimit ) & & ( nbAttempts ) ) {
2013-12-30 17:16:52 +00:00
nbAttempts - - ;
2016-09-03 02:06:01 +00:00
if ( matchIndex > = dictLimit ) {
2015-03-30 14:57:26 +00:00
const BYTE * matchPtr = base + matchIndex ;
2016-09-03 02:06:01 +00:00
if ( * ( iLowLimit + longest ) = = * ( matchPtr - delta + longest ) ) {
if ( LZ4_read32 ( matchPtr ) = = LZ4_read32 ( ip ) ) {
2015-03-30 14:57:26 +00:00
int mlt = MINMATCH + LZ4_count ( ip + MINMATCH , matchPtr + MINMATCH , iHighLimit ) ;
int back = 0 ;
2016-09-03 02:06:01 +00:00
while ( ( ip + back > iLowLimit )
2015-03-30 14:57:26 +00:00
& & ( matchPtr + back > lowPrefixPtr )
& & ( ip [ back - 1 ] = = matchPtr [ back - 1 ] ) )
back - - ;
2013-12-30 17:16:52 +00:00
2015-03-30 14:57:26 +00:00
mlt - = back ;
2013-12-30 17:16:52 +00:00
2016-09-03 02:06:01 +00:00
if ( mlt > longest ) {
2015-03-30 14:57:26 +00:00
longest = ( int ) mlt ;
* matchpos = matchPtr + back ;
* startpos = ip + back ;
2014-10-26 10:22:15 +00:00
}
2014-10-20 00:08:21 +00:00
}
2016-09-03 02:06:01 +00:00
}
} else {
2016-11-04 00:14:25 +00:00
const BYTE * const matchPtr = dictBase + matchIndex ;
2016-09-03 02:06:01 +00:00
if ( LZ4_read32 ( matchPtr ) = = LZ4_read32 ( ip ) ) {
2014-10-20 00:08:21 +00:00
size_t mlt ;
2014-10-26 10:22:15 +00:00
int back = 0 ;
2014-10-20 00:08:21 +00:00
const BYTE * vLimit = ip + ( dictLimit - matchIndex ) ;
if ( vLimit > iHighLimit ) vLimit = iHighLimit ;
2015-03-30 14:57:26 +00:00
mlt = LZ4_count ( ip + MINMATCH , matchPtr + MINMATCH , vLimit ) + MINMATCH ;
2014-10-20 00:08:21 +00:00
if ( ( ip + mlt = = vLimit ) & & ( vLimit < iHighLimit ) )
2014-11-29 19:19:39 +00:00
mlt + = LZ4_count ( ip + mlt , base + dictLimit , iHighLimit ) ;
2015-03-30 14:57:26 +00:00
while ( ( ip + back > iLowLimit ) & & ( matchIndex + back > lowLimit ) & & ( ip [ back - 1 ] = = matchPtr [ back - 1 ] ) ) back - - ;
2014-10-26 10:22:15 +00:00
mlt - = back ;
2014-10-20 00:08:21 +00:00
if ( ( int ) mlt > longest ) { longest = ( int ) mlt ; * matchpos = base + matchIndex + back ; * startpos = ip + back ; }
2013-12-30 17:16:52 +00:00
}
}
2015-05-02 14:44:43 +00:00
matchIndex - = DELTANEXTU16 ( matchIndex ) ;
2013-12-30 17:16:52 +00:00
}
return longest ;
}
typedef enum { noLimit = 0 , limitedOutput = 1 } limitedOutput_directive ;
2014-12-16 21:03:16 +00:00
# define LZ4HC_DEBUG 0
# if LZ4HC_DEBUG
static unsigned debug = 0 ;
# endif
2014-10-26 10:22:15 +00:00
2013-12-30 17:16:52 +00:00
FORCE_INLINE int LZ4HC_encodeSequence (
2014-10-26 10:22:15 +00:00
const BYTE * * ip ,
BYTE * * op ,
const BYTE * * anchor ,
int matchLength ,
const BYTE * const match ,
limitedOutput_directive limitedOutputBuffer ,
BYTE * oend )
2013-12-30 17:16:52 +00:00
{
int length ;
BYTE * token ;
2014-12-16 21:03:16 +00:00
# if LZ4HC_DEBUG
if ( debug ) printf ( " literal : %u -- match : %u -- offset : %u \n " , ( U32 ) ( * ip - * anchor ) , ( U32 ) matchLength , ( U32 ) ( * ip - match ) ) ;
# endif
2014-10-19 16:41:42 +00:00
2014-02-04 14:11:10 +00:00
/* Encode Literal length */
2013-12-30 17:16:52 +00:00
length = ( int ) ( * ip - * anchor ) ;
token = ( * op ) + + ;
2014-10-19 16:41:42 +00:00
if ( ( limitedOutputBuffer ) & & ( ( * op + ( length > > 8 ) + length + ( 2 + 1 + LASTLITERALS ) ) > oend ) ) return 1 ; /* Check output limit */
2013-12-30 17:16:52 +00:00
if ( length > = ( int ) RUN_MASK ) { int len ; * token = ( RUN_MASK < < ML_BITS ) ; len = length - RUN_MASK ; for ( ; len > 254 ; len - = 255 ) * ( * op ) + + = 255 ; * ( * op ) + + = ( BYTE ) len ; }
else * token = ( BYTE ) ( length < < ML_BITS ) ;
2014-02-04 14:11:10 +00:00
/* Copy Literals */
2014-11-29 19:19:39 +00:00
LZ4_wildCopy ( * op , * anchor , ( * op ) + length ) ;
* op + = length ;
2013-12-30 17:16:52 +00:00
2014-02-04 14:11:10 +00:00
/* Encode Offset */
2014-11-29 19:19:39 +00:00
LZ4_writeLE16 ( * op , ( U16 ) ( * ip - match ) ) ; * op + = 2 ;
2013-12-30 17:16:52 +00:00
2014-02-04 14:11:10 +00:00
/* Encode MatchLength */
2013-12-30 17:16:52 +00:00
length = ( int ) ( matchLength - MINMATCH ) ;
2014-10-19 16:41:42 +00:00
if ( ( limitedOutputBuffer ) & & ( * op + ( length > > 8 ) + ( 1 + LASTLITERALS ) > oend ) ) return 1 ; /* Check output limit */
2016-09-03 02:32:06 +00:00
if ( length > = ( int ) ML_MASK ) {
* token + = ML_MASK ;
length - = ML_MASK ;
for ( ; length > 509 ; length - = 510 ) { * ( * op ) + + = 255 ; * ( * op ) + + = 255 ; }
if ( length > 254 ) { length - = 255 ; * ( * op ) + + = 255 ; }
* ( * op ) + + = ( BYTE ) length ;
} else {
* token + = ( BYTE ) ( length ) ;
}
2013-12-30 17:16:52 +00:00
2014-02-04 14:11:10 +00:00
/* Prepare next loop */
2013-12-30 17:16:52 +00:00
* ip + = matchLength ;
* anchor = * ip ;
return 0 ;
}
2016-12-06 14:21:28 +00:00
# include "lz4opt.h"
2013-12-30 17:16:52 +00:00
2016-12-06 14:21:28 +00:00
static int LZ4HC_compress_hashChain (
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * const ctx ,
2016-11-08 03:32:24 +00:00
const char * const source ,
char * const dest ,
int const inputSize ,
int const maxOutputSize ,
2016-12-07 11:16:33 +00:00
unsigned maxNbAttempts ,
2014-10-26 10:22:15 +00:00
limitedOutput_directive limit
)
2013-12-30 17:16:52 +00:00
{
const BYTE * ip = ( const BYTE * ) source ;
const BYTE * anchor = ip ;
const BYTE * const iend = ip + inputSize ;
const BYTE * const mflimit = iend - MFLIMIT ;
const BYTE * const matchlimit = ( iend - LASTLITERALS ) ;
BYTE * op = ( BYTE * ) dest ;
BYTE * const oend = op + maxOutputSize ;
int ml , ml2 , ml3 , ml0 ;
2016-09-03 02:06:01 +00:00
const BYTE * ref = NULL ;
const BYTE * start2 = NULL ;
const BYTE * ref2 = NULL ;
const BYTE * start3 = NULL ;
const BYTE * ref3 = NULL ;
2013-12-30 17:16:52 +00:00
const BYTE * start0 ;
const BYTE * ref0 ;
2014-10-18 10:18:14 +00:00
/* init */
2013-12-30 17:16:52 +00:00
ctx - > end + = inputSize ;
ip + + ;
2014-02-04 14:11:10 +00:00
/* Main Loop */
2016-09-03 02:06:01 +00:00
while ( ip < mflimit ) {
2014-02-04 14:11:10 +00:00
ml = LZ4HC_InsertAndFindBestMatch ( ctx , ip , matchlimit , ( & ref ) , maxNbAttempts ) ;
2013-12-30 17:16:52 +00:00
if ( ! ml ) { ip + + ; continue ; }
2014-02-04 14:11:10 +00:00
/* saved, in case we would skip too much */
2013-12-30 17:16:52 +00:00
start0 = ip ;
ref0 = ref ;
ml0 = ml ;
_Search2 :
if ( ip + ml < mflimit )
2016-11-08 03:32:24 +00:00
ml2 = LZ4HC_InsertAndGetWiderMatch ( ctx , ip + ml - 2 , ip + 0 , matchlimit , ml , & ref2 , & start2 , maxNbAttempts ) ;
2013-12-30 17:16:52 +00:00
else ml2 = ml ;
2016-09-03 02:06:01 +00:00
if ( ml2 = = ml ) { /* No better match */
2013-12-30 17:16:52 +00:00
if ( LZ4HC_encodeSequence ( & ip , & op , & anchor , ml , ref , limit , oend ) ) return 0 ;
continue ;
}
2016-09-03 02:06:01 +00:00
if ( start0 < ip ) {
if ( start2 < ip + ml0 ) { /* empirical */
2013-12-30 17:16:52 +00:00
ip = start0 ;
ref = ref0 ;
ml = ml0 ;
}
}
2014-02-04 14:11:10 +00:00
/* Here, start0==ip */
2016-09-03 02:06:01 +00:00
if ( ( start2 - ip ) < 3 ) { /* First Match too small : removed */
2013-12-30 17:16:52 +00:00
ml = ml2 ;
ip = start2 ;
ref = ref2 ;
goto _Search2 ;
}
_Search3 :
2014-02-04 14:11:10 +00:00
/*
2014-10-26 10:22:15 +00:00
* Currently we have :
* ml2 > ml1 , and
* ip1 + 3 < = ip2 ( usually < ip1 + ml1 )
*/
2016-09-03 02:06:01 +00:00
if ( ( start2 - ip ) < OPTIMAL_ML ) {
2013-12-30 17:16:52 +00:00
int correction ;
int new_ml = ml ;
if ( new_ml > OPTIMAL_ML ) new_ml = OPTIMAL_ML ;
if ( ip + new_ml > start2 + ml2 - MINMATCH ) new_ml = ( int ) ( start2 - ip ) + ml2 - MINMATCH ;
correction = new_ml - ( int ) ( start2 - ip ) ;
2016-09-03 02:06:01 +00:00
if ( correction > 0 ) {
2013-12-30 17:16:52 +00:00
start2 + = correction ;
ref2 + = correction ;
ml2 - = correction ;
}
}
2014-02-04 14:11:10 +00:00
/* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */
2013-12-30 17:16:52 +00:00
if ( start2 + ml2 < mflimit )
2014-02-04 14:11:10 +00:00
ml3 = LZ4HC_InsertAndGetWiderMatch ( ctx , start2 + ml2 - 3 , start2 , matchlimit , ml2 , & ref3 , & start3 , maxNbAttempts ) ;
2017-03-07 14:11:48 +00:00
else
ml3 = ml2 ;
2013-12-30 17:16:52 +00:00
2016-09-03 02:06:01 +00:00
if ( ml3 = = ml2 ) { /* No better match : 2 sequences to encode */
2014-02-04 14:11:10 +00:00
/* ip & ref are known; Now for ml */
2013-12-30 17:16:52 +00:00
if ( start2 < ip + ml ) ml = ( int ) ( start2 - ip ) ;
2014-02-04 14:11:10 +00:00
/* Now, encode 2 sequences */
2013-12-30 17:16:52 +00:00
if ( LZ4HC_encodeSequence ( & ip , & op , & anchor , ml , ref , limit , oend ) ) return 0 ;
ip = start2 ;
if ( LZ4HC_encodeSequence ( & ip , & op , & anchor , ml2 , ref2 , limit , oend ) ) return 0 ;
continue ;
}
2016-09-03 02:06:01 +00:00
if ( start3 < ip + ml + 3 ) { /* Not enough space for match 2 : remove it */
if ( start3 > = ( ip + ml ) ) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
if ( start2 < ip + ml ) {
2013-12-30 17:16:52 +00:00
int correction = ( int ) ( ip + ml - start2 ) ;
start2 + = correction ;
ref2 + = correction ;
ml2 - = correction ;
2016-09-03 02:06:01 +00:00
if ( ml2 < MINMATCH ) {
2013-12-30 17:16:52 +00:00
start2 = start3 ;
ref2 = ref3 ;
ml2 = ml3 ;
}
}
if ( LZ4HC_encodeSequence ( & ip , & op , & anchor , ml , ref , limit , oend ) ) return 0 ;
ip = start3 ;
ref = ref3 ;
ml = ml3 ;
start0 = start2 ;
ref0 = ref2 ;
ml0 = ml2 ;
goto _Search2 ;
}
start2 = start3 ;
ref2 = ref3 ;
ml2 = ml3 ;
goto _Search3 ;
}
2014-02-04 14:11:10 +00:00
/*
2014-10-26 10:22:15 +00:00
* OK , now we have 3 ascending matches ; let ' s write at least the first one
* ip & ref are known ; Now for ml
*/
2016-09-03 02:06:01 +00:00
if ( start2 < ip + ml ) {
if ( ( start2 - ip ) < ( int ) ML_MASK ) {
2013-12-30 17:16:52 +00:00
int correction ;
if ( ml > OPTIMAL_ML ) ml = OPTIMAL_ML ;
if ( ip + ml > start2 + ml2 - MINMATCH ) ml = ( int ) ( start2 - ip ) + ml2 - MINMATCH ;
correction = ml - ( int ) ( start2 - ip ) ;
2016-09-03 02:06:01 +00:00
if ( correction > 0 ) {
2013-12-30 17:16:52 +00:00
start2 + = correction ;
ref2 + = correction ;
ml2 - = correction ;
}
2016-09-03 02:06:01 +00:00
} else {
2013-12-30 17:16:52 +00:00
ml = ( int ) ( start2 - ip ) ;
}
}
if ( LZ4HC_encodeSequence ( & ip , & op , & anchor , ml , ref , limit , oend ) ) return 0 ;
ip = start2 ;
ref = ref2 ;
ml = ml2 ;
start2 = start3 ;
ref2 = ref3 ;
ml2 = ml3 ;
goto _Search3 ;
}
2014-02-04 14:11:10 +00:00
/* Encode Last Literals */
2017-03-07 14:11:48 +00:00
{ size_t lastRunSize , litLength , totalSize ;
lastRunSize = ( size_t ) ( iend - anchor ) ; /* literals */
litLength = ( lastRunSize + 255 - RUN_MASK ) / 255 ;
totalSize = 1 + litLength + lastRunSize ;
if ( ( limit = = limitedOutput ) & & ( op + totalSize > oend ) ) return 0 ; /* Check output limit */
if ( lastRunSize > = RUN_MASK ) {
size_t accumulator = lastRunSize - RUN_MASK ;
* op + + = ( RUN_MASK < < ML_BITS ) ;
for ( ; accumulator > = 255 ; accumulator - = 255 ) * op + + = 255 ;
* op + + = ( BYTE ) accumulator ;
} else {
* op + + = ( BYTE ) ( lastRunSize < < ML_BITS ) ;
}
memcpy ( op , anchor , lastRunSize ) ;
op + = lastRunSize ;
2013-12-30 17:16:52 +00:00
}
2014-02-04 14:11:10 +00:00
/* End */
2013-12-30 17:16:52 +00:00
return ( int ) ( ( ( char * ) op ) - dest ) ;
}
2016-12-28 14:18:19 +00:00
static int LZ4HC_getSearchNum ( int compressionLevel )
{
switch ( compressionLevel ) {
default : return 0 ; /* unused */
case 11 : return 128 ;
case 12 : return 1 < < 10 ;
}
}
2013-12-30 17:16:52 +00:00
2016-12-06 14:21:28 +00:00
static int LZ4HC_compress_generic (
LZ4HC_CCtx_internal * const ctx ,
const char * const source ,
char * const dest ,
int const inputSize ,
int const maxOutputSize ,
int compressionLevel ,
limitedOutput_directive limit
)
{
2016-12-22 10:41:05 +00:00
if ( compressionLevel < 1 ) compressionLevel = LZ4HC_CLEVEL_DEFAULT ;
2016-12-07 11:16:33 +00:00
if ( compressionLevel > 9 ) {
2016-12-06 14:21:28 +00:00
switch ( compressionLevel ) {
2016-12-07 11:16:33 +00:00
case 10 : return LZ4HC_compress_hashChain ( ctx , source , dest , inputSize , maxOutputSize , 1 < < ( 16 - 1 ) , limit ) ;
2016-12-28 14:18:19 +00:00
case 11 : ctx - > searchNum = LZ4HC_getSearchNum ( compressionLevel ) ; return LZ4HC_compress_optimal ( ctx , source , dest , inputSize , maxOutputSize , limit , 128 , 0 ) ;
2016-12-06 18:11:53 +00:00
default :
2016-12-28 14:18:19 +00:00
case 12 : ctx - > searchNum = LZ4HC_getSearchNum ( compressionLevel ) ; return LZ4HC_compress_optimal ( ctx , source , dest , inputSize , maxOutputSize , limit , LZ4_OPT_NUM , 1 ) ;
2016-12-06 14:21:28 +00:00
}
}
2016-12-07 11:16:33 +00:00
return LZ4HC_compress_hashChain ( ctx , source , dest , inputSize , maxOutputSize , 1 < < ( compressionLevel - 1 ) , limit ) ;
2016-12-06 14:21:28 +00:00
}
2016-11-12 23:50:29 +00:00
int LZ4_sizeofStateHC ( void ) { return sizeof ( LZ4_streamHC_t ) ; }
2013-12-30 17:16:52 +00:00
2015-05-03 19:57:21 +00:00
int LZ4_compress_HC_extStateHC ( void * state , const char * src , char * dst , int srcSize , int maxDstSize , int compressionLevel )
2013-12-30 17:16:52 +00:00
{
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * ctx = & ( ( LZ4_streamHC_t * ) state ) - > internal_donotuse ;
2014-02-04 14:11:10 +00:00
if ( ( ( size_t ) ( state ) & ( sizeof ( void * ) - 1 ) ) ! = 0 ) return 0 ; /* Error : state is not aligned for pointers (32 or 64 bits) */
2016-11-11 21:00:02 +00:00
LZ4HC_init ( ctx , ( const BYTE * ) src ) ;
2015-05-03 19:57:21 +00:00
if ( maxDstSize < LZ4_compressBound ( srcSize ) )
2016-11-11 21:00:02 +00:00
return LZ4HC_compress_generic ( ctx , src , dst , srcSize , maxDstSize , compressionLevel , limitedOutput ) ;
2015-04-11 11:28:09 +00:00
else
2016-11-11 21:00:02 +00:00
return LZ4HC_compress_generic ( ctx , src , dst , srcSize , maxDstSize , compressionLevel , noLimit ) ;
2013-12-30 17:16:52 +00:00
}
2015-05-03 19:57:21 +00:00
int LZ4_compress_HC ( const char * src , char * dst , int srcSize , int maxDstSize , int compressionLevel )
2013-12-30 17:16:52 +00:00
{
2016-11-12 23:50:29 +00:00
# if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
2016-11-13 01:14:57 +00:00
LZ4_streamHC_t * const statePtr = ( LZ4_streamHC_t * ) malloc ( sizeof ( LZ4_streamHC_t ) ) ;
2015-10-21 14:00:48 +00:00
# else
2016-11-11 21:00:02 +00:00
LZ4_streamHC_t state ;
LZ4_streamHC_t * const statePtr = & state ;
2015-10-21 14:00:48 +00:00
# endif
2016-11-12 23:50:29 +00:00
int const cSize = LZ4_compress_HC_extStateHC ( statePtr , src , dst , srcSize , maxDstSize , compressionLevel ) ;
# if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
2015-10-21 14:00:48 +00:00
free ( statePtr ) ;
# endif
return cSize ;
2013-12-30 17:16:52 +00:00
}
2014-12-03 18:17:10 +00:00
2014-10-18 10:18:14 +00:00
/**************************************
2015-05-02 14:44:43 +00:00
* Streaming Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-10-18 10:18:14 +00:00
/* allocation */
LZ4_streamHC_t * LZ4_createStreamHC ( void ) { return ( LZ4_streamHC_t * ) malloc ( sizeof ( LZ4_streamHC_t ) ) ; }
2015-04-11 11:28:09 +00:00
int LZ4_freeStreamHC ( LZ4_streamHC_t * LZ4_streamHCPtr ) { free ( LZ4_streamHCPtr ) ; return 0 ; }
2013-12-30 17:16:52 +00:00
2014-10-18 10:18:14 +00:00
/* initialization */
void LZ4_resetStreamHC ( LZ4_streamHC_t * LZ4_streamHCPtr , int compressionLevel )
2013-12-30 17:16:52 +00:00
{
2016-11-12 15:29:54 +00:00
LZ4_STATIC_ASSERT ( sizeof ( LZ4HC_CCtx_internal ) < = sizeof ( size_t ) * LZ4_STREAMHCSIZE_SIZET ) ; /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
2016-11-11 21:00:02 +00:00
LZ4_streamHCPtr - > internal_donotuse . base = NULL ;
LZ4_streamHCPtr - > internal_donotuse . compressionLevel = ( unsigned ) compressionLevel ;
2016-12-28 14:18:19 +00:00
LZ4_streamHCPtr - > internal_donotuse . searchNum = LZ4HC_getSearchNum ( compressionLevel ) ;
2014-02-04 14:11:10 +00:00
}
2014-10-18 10:18:14 +00:00
int LZ4_loadDictHC ( LZ4_streamHC_t * LZ4_streamHCPtr , const char * dictionary , int dictSize )
2014-02-04 14:11:10 +00:00
{
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * ctxPtr = & LZ4_streamHCPtr - > internal_donotuse ;
2016-09-03 02:06:01 +00:00
if ( dictSize > 64 KB ) {
2014-11-02 21:32:12 +00:00
dictionary + = dictSize - 64 KB ;
dictSize = 64 KB ;
}
2014-12-03 18:17:10 +00:00
LZ4HC_init ( ctxPtr , ( const BYTE * ) dictionary ) ;
ctxPtr - > end = ( const BYTE * ) dictionary + dictSize ;
2016-12-28 12:19:11 +00:00
if ( ctxPtr - > compressionLevel > = LZ4HC_CLEVEL_OPT_MIN )
LZ4HC_updateBinTree ( ctxPtr , ctxPtr - > end - MFLIMIT , ctxPtr - > end - LASTLITERALS ) ;
else
if ( dictSize > = 4 ) LZ4HC_Insert ( ctxPtr , ctxPtr - > end - 3 ) ;
2014-11-02 21:32:12 +00:00
return dictSize ;
2014-10-18 10:18:14 +00:00
}
/* compression */
2016-11-12 15:29:54 +00:00
static void LZ4HC_setExternalDict ( LZ4HC_CCtx_internal * ctxPtr , const BYTE * newBlock )
2014-12-03 18:17:10 +00:00
{
2016-12-22 10:41:05 +00:00
if ( ctxPtr - > compressionLevel > = LZ4HC_CLEVEL_OPT_MIN )
2016-12-09 17:17:46 +00:00
LZ4HC_updateBinTree ( ctxPtr , ctxPtr - > end - MFLIMIT , ctxPtr - > end - LASTLITERALS ) ;
else
if ( ctxPtr - > end > = ctxPtr - > base + 4 ) LZ4HC_Insert ( ctxPtr , ctxPtr - > end - 3 ) ; /* Referencing remaining dictionary content */
2016-12-09 16:16:35 +00:00
2014-12-03 18:17:10 +00:00
/* Only one memory segment for extDict, so any previous extDict is lost at this stage */
ctxPtr - > lowLimit = ctxPtr - > dictLimit ;
ctxPtr - > dictLimit = ( U32 ) ( ctxPtr - > end - ctxPtr - > base ) ;
ctxPtr - > dictBase = ctxPtr - > base ;
ctxPtr - > base = newBlock - ctxPtr - > dictLimit ;
ctxPtr - > end = newBlock ;
2016-12-28 14:38:59 +00:00
ctxPtr - > nextToUpdate = ctxPtr - > dictLimit ; /* match referencing will resume from there */
2014-12-03 18:17:10 +00:00
}
2016-11-11 21:00:02 +00:00
static int LZ4_compressHC_continue_generic ( LZ4_streamHC_t * LZ4_streamHCPtr ,
2014-10-22 07:07:56 +00:00
const char * source , char * dest ,
int inputSize , int maxOutputSize , limitedOutput_directive limit )
{
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * ctxPtr = & LZ4_streamHCPtr - > internal_donotuse ;
2014-10-22 07:07:56 +00:00
/* auto-init if forgotten */
2016-09-03 02:06:01 +00:00
if ( ctxPtr - > base = = NULL ) LZ4HC_init ( ctxPtr , ( const BYTE * ) source ) ;
2014-10-22 07:07:56 +00:00
2014-10-26 10:22:15 +00:00
/* Check overflow */
2016-09-03 02:06:01 +00:00
if ( ( size_t ) ( ctxPtr - > end - ctxPtr - > base ) > 2 GB ) {
2014-12-03 18:17:10 +00:00
size_t dictSize = ( size_t ) ( ctxPtr - > end - ctxPtr - > base ) - ctxPtr - > dictLimit ;
2014-10-26 10:22:15 +00:00
if ( dictSize > 64 KB ) dictSize = 64 KB ;
2016-11-11 21:00:02 +00:00
LZ4_loadDictHC ( LZ4_streamHCPtr , ( const char * ) ( ctxPtr - > end ) - dictSize , ( int ) dictSize ) ;
2014-10-26 10:22:15 +00:00
}
/* Check if blocks follow each other */
2016-09-03 02:06:01 +00:00
if ( ( const BYTE * ) source ! = ctxPtr - > end ) LZ4HC_setExternalDict ( ctxPtr , ( const BYTE * ) source ) ;
2014-10-22 07:07:56 +00:00
2014-10-26 10:22:15 +00:00
/* Check overlapping input/dictionary space */
2016-09-03 02:06:01 +00:00
{ const BYTE * sourceEnd = ( const BYTE * ) source + inputSize ;
const BYTE * const dictBegin = ctxPtr - > dictBase + ctxPtr - > lowLimit ;
const BYTE * const dictEnd = ctxPtr - > dictBase + ctxPtr - > dictLimit ;
if ( ( sourceEnd > dictBegin ) & & ( ( const BYTE * ) source < dictEnd ) ) {
2014-10-25 19:52:10 +00:00
if ( sourceEnd > dictEnd ) sourceEnd = dictEnd ;
2014-12-03 18:17:10 +00:00
ctxPtr - > lowLimit = ( U32 ) ( sourceEnd - ctxPtr - > dictBase ) ;
if ( ctxPtr - > dictLimit - ctxPtr - > lowLimit < 4 ) ctxPtr - > lowLimit = ctxPtr - > dictLimit ;
2014-10-22 07:07:56 +00:00
}
}
2014-12-03 18:17:10 +00:00
return LZ4HC_compress_generic ( ctxPtr , source , dest , inputSize , maxOutputSize , ctxPtr - > compressionLevel , limit ) ;
2014-10-22 07:07:56 +00:00
}
2015-05-03 19:57:21 +00:00
int LZ4_compress_HC_continue ( LZ4_streamHC_t * LZ4_streamHCPtr , const char * source , char * dest , int inputSize , int maxOutputSize )
2014-10-18 10:18:14 +00:00
{
2015-04-11 11:28:09 +00:00
if ( maxOutputSize < LZ4_compressBound ( inputSize ) )
2016-11-11 21:00:02 +00:00
return LZ4_compressHC_continue_generic ( LZ4_streamHCPtr , source , dest , inputSize , maxOutputSize , limitedOutput ) ;
2015-04-11 11:28:09 +00:00
else
2016-11-11 21:00:02 +00:00
return LZ4_compressHC_continue_generic ( LZ4_streamHCPtr , source , dest , inputSize , maxOutputSize , noLimit ) ;
2014-10-18 10:18:14 +00:00
}
/* dictionary saving */
int LZ4_saveDictHC ( LZ4_streamHC_t * LZ4_streamHCPtr , char * safeBuffer , int dictSize )
{
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * const streamPtr = & LZ4_streamHCPtr - > internal_donotuse ;
2016-09-03 02:06:01 +00:00
int const prefixSize = ( int ) ( streamPtr - > end - ( streamPtr - > base + streamPtr - > dictLimit ) ) ;
2014-10-18 10:18:14 +00:00
if ( dictSize > 64 KB ) dictSize = 64 KB ;
2014-11-02 21:32:12 +00:00
if ( dictSize < 4 ) dictSize = 0 ;
if ( dictSize > prefixSize ) dictSize = prefixSize ;
2015-04-12 08:29:52 +00:00
memmove ( safeBuffer , streamPtr - > end - dictSize , dictSize ) ;
2016-09-03 02:06:01 +00:00
{ U32 const endIndex = ( U32 ) ( streamPtr - > end - streamPtr - > base ) ;
2014-11-02 21:32:12 +00:00
streamPtr - > end = ( const BYTE * ) safeBuffer + dictSize ;
streamPtr - > base = streamPtr - > end - endIndex ;
streamPtr - > dictLimit = endIndex - dictSize ;
streamPtr - > lowLimit = endIndex - dictSize ;
2014-12-16 01:13:19 +00:00
if ( streamPtr - > nextToUpdate < streamPtr - > dictLimit ) streamPtr - > nextToUpdate = streamPtr - > dictLimit ;
2014-11-02 21:32:12 +00:00
}
2014-10-18 10:18:14 +00:00
return dictSize ;
2013-12-30 17:16:52 +00:00
}
2014-10-18 10:18:14 +00:00
/***********************************
2015-05-02 14:44:43 +00:00
* Deprecated Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-11-12 23:50:29 +00:00
/* These functions currently generate deprecation warnings */
2015-04-11 11:28:09 +00:00
/* Deprecated compression functions */
2015-05-03 19:57:21 +00:00
int LZ4_compressHC ( const char * src , char * dst , int srcSize ) { return LZ4_compress_HC ( src , dst , srcSize , LZ4_compressBound ( srcSize ) , 0 ) ; }
int LZ4_compressHC_limitedOutput ( const char * src , char * dst , int srcSize , int maxDstSize ) { return LZ4_compress_HC ( src , dst , srcSize , maxDstSize , 0 ) ; }
int LZ4_compressHC2 ( const char * src , char * dst , int srcSize , int cLevel ) { return LZ4_compress_HC ( src , dst , srcSize , LZ4_compressBound ( srcSize ) , cLevel ) ; }
int LZ4_compressHC2_limitedOutput ( const char * src , char * dst , int srcSize , int maxDstSize , int cLevel ) { return LZ4_compress_HC ( src , dst , srcSize , maxDstSize , cLevel ) ; }
int LZ4_compressHC_withStateHC ( void * state , const char * src , char * dst , int srcSize ) { return LZ4_compress_HC_extStateHC ( state , src , dst , srcSize , LZ4_compressBound ( srcSize ) , 0 ) ; }
int LZ4_compressHC_limitedOutput_withStateHC ( void * state , const char * src , char * dst , int srcSize , int maxDstSize ) { return LZ4_compress_HC_extStateHC ( state , src , dst , srcSize , maxDstSize , 0 ) ; }
int LZ4_compressHC2_withStateHC ( void * state , const char * src , char * dst , int srcSize , int cLevel ) { return LZ4_compress_HC_extStateHC ( state , src , dst , srcSize , LZ4_compressBound ( srcSize ) , cLevel ) ; }
int LZ4_compressHC2_limitedOutput_withStateHC ( void * state , const char * src , char * dst , int srcSize , int maxDstSize , int cLevel ) { return LZ4_compress_HC_extStateHC ( state , src , dst , srcSize , maxDstSize , cLevel ) ; }
int LZ4_compressHC_continue ( LZ4_streamHC_t * ctx , const char * src , char * dst , int srcSize ) { return LZ4_compress_HC_continue ( ctx , src , dst , srcSize , LZ4_compressBound ( srcSize ) ) ; }
int LZ4_compressHC_limitedOutput_continue ( LZ4_streamHC_t * ctx , const char * src , char * dst , int srcSize , int maxDstSize ) { return LZ4_compress_HC_continue ( ctx , src , dst , srcSize , maxDstSize ) ; }
2015-04-11 11:28:09 +00:00
/* Deprecated streaming functions */
2014-10-18 10:18:14 +00:00
int LZ4_sizeofStreamStateHC ( void ) { return LZ4_STREAMHCSIZE ; }
2015-05-06 00:58:24 +00:00
int LZ4_resetStreamStateHC ( void * state , char * inputBuffer )
2014-10-18 10:18:14 +00:00
{
2016-11-12 15:29:54 +00:00
LZ4HC_CCtx_internal * ctx = & ( ( LZ4_streamHC_t * ) state ) - > internal_donotuse ;
2014-10-18 10:18:14 +00:00
if ( ( ( ( size_t ) state ) & ( sizeof ( void * ) - 1 ) ) ! = 0 ) return 1 ; /* Error : pointer is not aligned for pointer (32 or 64 bits) */
2016-11-11 21:00:02 +00:00
LZ4HC_init ( ctx , ( const BYTE * ) inputBuffer ) ;
ctx - > inputBuffer = ( BYTE * ) inputBuffer ;
2014-10-18 10:18:14 +00:00
return 0 ;
}
2015-05-06 00:58:24 +00:00
void * LZ4_createHC ( char * inputBuffer )
2014-10-18 10:18:14 +00:00
{
2016-11-11 21:00:02 +00:00
LZ4_streamHC_t * hc4 = ( LZ4_streamHC_t * ) ALLOCATOR ( 1 , sizeof ( LZ4_streamHC_t ) ) ;
2015-06-29 03:51:11 +00:00
if ( hc4 = = NULL ) return NULL ; /* not enough memory */
2016-11-11 21:00:02 +00:00
LZ4HC_init ( & hc4 - > internal_donotuse , ( const BYTE * ) inputBuffer ) ;
hc4 - > internal_donotuse . inputBuffer = ( BYTE * ) inputBuffer ;
2014-10-18 10:18:14 +00:00
return hc4 ;
}
2016-11-12 23:50:29 +00:00
int LZ4_freeHC ( void * LZ4HC_Data ) { FREEMEM ( LZ4HC_Data ) ; return 0 ; }
2014-10-18 10:18:14 +00:00
int LZ4_compressHC2_continue ( void * LZ4HC_Data , const char * source , char * dest , int inputSize , int compressionLevel )
{
2016-11-11 21:00:02 +00:00
return LZ4HC_compress_generic ( & ( ( LZ4_streamHC_t * ) LZ4HC_Data ) - > internal_donotuse , source , dest , inputSize , 0 , compressionLevel , noLimit ) ;
2014-10-18 10:18:14 +00:00
}
2013-12-30 17:16:52 +00:00
2014-02-04 14:11:10 +00:00
int LZ4_compressHC2_limitedOutput_continue ( void * LZ4HC_Data , const char * source , char * dest , int inputSize , int maxOutputSize , int compressionLevel )
{
2016-11-11 21:00:02 +00:00
return LZ4HC_compress_generic ( & ( ( LZ4_streamHC_t * ) LZ4HC_Data ) - > internal_donotuse , source , dest , inputSize , maxOutputSize , compressionLevel , limitedOutput ) ;
2014-02-04 14:11:10 +00:00
}
2014-10-18 10:18:14 +00:00
char * LZ4_slideInputBufferHC ( void * LZ4HC_Data )
{
2016-11-12 23:50:29 +00:00
LZ4HC_CCtx_internal * const hc4 = & ( ( LZ4_streamHC_t * ) LZ4HC_Data ) - > internal_donotuse ;
int const dictSize = LZ4_saveDictHC ( ( LZ4_streamHC_t * ) LZ4HC_Data , ( char * ) ( hc4 - > inputBuffer ) , 64 KB ) ;
2014-12-03 18:17:10 +00:00
return ( char * ) ( hc4 - > inputBuffer + dictSize ) ;
2014-10-18 10:18:14 +00:00
}