00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 static const int LZ4HC_compressionLevel_default = 9;
00041
00042
00043
00044
00045
00046 #include "lz4hc.h"
00047
00048
00049
00050
00051
00052 #if defined(__GNUC__)
00053 # pragma GCC diagnostic ignored "-Wunused-function"
00054 #endif
00055
00056 #if defined (__clang__)
00057 # pragma clang diagnostic ignored "-Wunused-function"
00058 #endif
00059
00060
00061
00062
00063
00064 #define LZ4_COMMONDEFS_ONLY
00065 #include "lz4.c"
00066
00067
00068
00069
00070
00071 #define DICTIONARY_LOGSIZE 16
00072 #define MAXD (1<<DICTIONARY_LOGSIZE)
00073 #define MAXD_MASK (MAXD - 1)
00074
00075 #define HASH_LOG (DICTIONARY_LOGSIZE-1)
00076 #define HASHTABLESIZE (1 << HASH_LOG)
00077 #define HASH_MASK (HASHTABLESIZE - 1)
00078
00079 #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
00080
00081 static const int g_maxCompressionLevel = 16;
00082
00083
00084
00085
00086
00087 typedef struct
00088 {
00089 U32 hashTable[HASHTABLESIZE];
00090 U16 chainTable[MAXD];
00091 const BYTE* end;
00092 const BYTE* base;
00093 const BYTE* dictBase;
00094 BYTE* inputBuffer;
00095 U32 dictLimit;
00096 U32 lowLimit;
00097 U32 nextToUpdate;
00098 U32 compressionLevel;
00099 } LZ4HC_Data_Structure;
00100
00101
00102
00103
00104
00105 #define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
00106
00107 #define DELTANEXTU16(p) chainTable[(U16)(p)]
00108
00109 static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); }
00110
00111
00112
00113
00114
00115
00116 static void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* start)
00117 {
00118 MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
00119 MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
00120 hc4->nextToUpdate = 64 KB;
00121 hc4->base = start - 64 KB;
00122 hc4->end = start;
00123 hc4->dictBase = start - 64 KB;
00124 hc4->dictLimit = 64 KB;
00125 hc4->lowLimit = 64 KB;
00126 }
00127
00128
00129
00130 FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
00131 {
00132 U16* chainTable = hc4->chainTable;
00133 U32* HashTable = hc4->hashTable;
00134 const BYTE* const base = hc4->base;
00135 const U32 target = (U32)(ip - base);
00136 U32 idx = hc4->nextToUpdate;
00137
00138 while(idx < target)
00139 {
00140 U32 h = LZ4HC_hashPtr(base+idx);
00141 size_t delta = idx - HashTable[h];
00142 if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
00143 DELTANEXTU16(idx) = (U16)delta;
00144 HashTable[h] = idx;
00145 idx++;
00146 }
00147
00148 hc4->nextToUpdate = target;
00149 }
00150
00151
00152 FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,
00153 const BYTE* ip, const BYTE* const iLimit,
00154 const BYTE** matchpos,
00155 const int maxNbAttempts)
00156 {
00157 U16* const chainTable = hc4->chainTable;
00158 U32* const HashTable = hc4->hashTable;
00159 const BYTE* const base = hc4->base;
00160 const BYTE* const dictBase = hc4->dictBase;
00161 const U32 dictLimit = hc4->dictLimit;
00162 const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
00163 U32 matchIndex;
00164 const BYTE* match;
00165 int nbAttempts=maxNbAttempts;
00166 size_t ml=0;
00167
00168
00169 LZ4HC_Insert(hc4, ip);
00170 matchIndex = HashTable[LZ4HC_hashPtr(ip)];
00171
00172 while ((matchIndex>=lowLimit) && (nbAttempts))
00173 {
00174 nbAttempts--;
00175 if (matchIndex >= dictLimit)
00176 {
00177 match = base + matchIndex;
00178 if (*(match+ml) == *(ip+ml)
00179 && (LZ4_read32(match) == LZ4_read32(ip)))
00180 {
00181 size_t mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
00182 if (mlt > ml) { ml = mlt; *matchpos = match; }
00183 }
00184 }
00185 else
00186 {
00187 match = dictBase + matchIndex;
00188 if (LZ4_read32(match) == LZ4_read32(ip))
00189 {
00190 size_t mlt;
00191 const BYTE* vLimit = ip + (dictLimit - matchIndex);
00192 if (vLimit > iLimit) vLimit = iLimit;
00193 mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
00194 if ((ip+mlt == vLimit) && (vLimit < iLimit))
00195 mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit);
00196 if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; }
00197 }
00198 }
00199 matchIndex -= DELTANEXTU16(matchIndex);
00200 }
00201
00202 return (int)ml;
00203 }
00204
00205
00206 FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
00207 LZ4HC_Data_Structure* hc4,
00208 const BYTE* const ip,
00209 const BYTE* const iLowLimit,
00210 const BYTE* const iHighLimit,
00211 int longest,
00212 const BYTE** matchpos,
00213 const BYTE** startpos,
00214 const int maxNbAttempts)
00215 {
00216 U16* const chainTable = hc4->chainTable;
00217 U32* const HashTable = hc4->hashTable;
00218 const BYTE* const base = hc4->base;
00219 const U32 dictLimit = hc4->dictLimit;
00220 const BYTE* const lowPrefixPtr = base + dictLimit;
00221 const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
00222 const BYTE* const dictBase = hc4->dictBase;
00223 U32 matchIndex;
00224 int nbAttempts = maxNbAttempts;
00225 int delta = (int)(ip-iLowLimit);
00226
00227
00228
00229 LZ4HC_Insert(hc4, ip);
00230 matchIndex = HashTable[LZ4HC_hashPtr(ip)];
00231
00232 while ((matchIndex>=lowLimit) && (nbAttempts))
00233 {
00234 nbAttempts--;
00235 if (matchIndex >= dictLimit)
00236 {
00237 const BYTE* matchPtr = base + matchIndex;
00238 if (*(iLowLimit + longest) == *(matchPtr - delta + longest))
00239 if (LZ4_read32(matchPtr) == LZ4_read32(ip))
00240 {
00241 int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
00242 int back = 0;
00243
00244 while ((ip+back>iLowLimit)
00245 && (matchPtr+back > lowPrefixPtr)
00246 && (ip[back-1] == matchPtr[back-1]))
00247 back--;
00248
00249 mlt -= back;
00250
00251 if (mlt > longest)
00252 {
00253 longest = (int)mlt;
00254 *matchpos = matchPtr+back;
00255 *startpos = ip+back;
00256 }
00257 }
00258 }
00259 else
00260 {
00261 const BYTE* matchPtr = dictBase + matchIndex;
00262 if (LZ4_read32(matchPtr) == LZ4_read32(ip))
00263 {
00264 size_t mlt;
00265 int back=0;
00266 const BYTE* vLimit = ip + (dictLimit - matchIndex);
00267 if (vLimit > iHighLimit) vLimit = iHighLimit;
00268 mlt = LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
00269 if ((ip+mlt == vLimit) && (vLimit < iHighLimit))
00270 mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit);
00271 while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == matchPtr[back-1])) back--;
00272 mlt -= back;
00273 if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; }
00274 }
00275 }
00276 matchIndex -= DELTANEXTU16(matchIndex);
00277 }
00278
00279 return longest;
00280 }
00281
00282
00283 typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
00284
00285 #define LZ4HC_DEBUG 0
00286 #if LZ4HC_DEBUG
00287 static unsigned debug = 0;
00288 #endif
00289
00290 FORCE_INLINE int LZ4HC_encodeSequence (
00291 const BYTE** ip,
00292 BYTE** op,
00293 const BYTE** anchor,
00294 int matchLength,
00295 const BYTE* const match,
00296 limitedOutput_directive limitedOutputBuffer,
00297 BYTE* oend)
00298 {
00299 int length;
00300 BYTE* token;
00301
00302 #if LZ4HC_DEBUG
00303 if (debug) printf("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match));
00304 #endif
00305
00306
00307 length = (int)(*ip - *anchor);
00308 token = (*op)++;
00309 if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1;
00310 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; }
00311 else *token = (BYTE)(length<<ML_BITS);
00312
00313
00314 LZ4_wildCopy(*op, *anchor, (*op) + length);
00315 *op += length;
00316
00317
00318 LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2;
00319
00320
00321 length = (int)(matchLength-MINMATCH);
00322 if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1;
00323 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; }
00324 else *token += (BYTE)(length);
00325
00326
00327 *ip += matchLength;
00328 *anchor = *ip;
00329
00330 return 0;
00331 }
00332
00333
00334 static int LZ4HC_compress_generic (
00335 void* ctxvoid,
00336 const char* source,
00337 char* dest,
00338 int inputSize,
00339 int maxOutputSize,
00340 int compressionLevel,
00341 limitedOutput_directive limit
00342 )
00343 {
00344 LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
00345 const BYTE* ip = (const BYTE*) source;
00346 const BYTE* anchor = ip;
00347 const BYTE* const iend = ip + inputSize;
00348 const BYTE* const mflimit = iend - MFLIMIT;
00349 const BYTE* const matchlimit = (iend - LASTLITERALS);
00350
00351 BYTE* op = (BYTE*) dest;
00352 BYTE* const oend = op + maxOutputSize;
00353
00354 unsigned maxNbAttempts;
00355 int ml, ml2, ml3, ml0;
00356 const BYTE* ref=NULL;
00357 const BYTE* start2=NULL;
00358 const BYTE* ref2=NULL;
00359 const BYTE* start3=NULL;
00360 const BYTE* ref3=NULL;
00361 const BYTE* start0;
00362 const BYTE* ref0;
00363
00364
00365
00366 if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel;
00367 if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default;
00368 maxNbAttempts = 1 << (compressionLevel-1);
00369 ctx->end += inputSize;
00370
00371 ip++;
00372
00373
00374 while (ip < mflimit)
00375 {
00376 ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts);
00377 if (!ml) { ip++; continue; }
00378
00379
00380 start0 = ip;
00381 ref0 = ref;
00382 ml0 = ml;
00383
00384 _Search2:
00385 if (ip+ml < mflimit)
00386 ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts);
00387 else ml2 = ml;
00388
00389 if (ml2 == ml)
00390 {
00391 if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
00392 continue;
00393 }
00394
00395 if (start0 < ip)
00396 {
00397 if (start2 < ip + ml0)
00398 {
00399 ip = start0;
00400 ref = ref0;
00401 ml = ml0;
00402 }
00403 }
00404
00405
00406 if ((start2 - ip) < 3)
00407 {
00408 ml = ml2;
00409 ip = start2;
00410 ref =ref2;
00411 goto _Search2;
00412 }
00413
00414 _Search3:
00415
00416
00417
00418
00419
00420 if ((start2 - ip) < OPTIMAL_ML)
00421 {
00422 int correction;
00423 int new_ml = ml;
00424 if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
00425 if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
00426 correction = new_ml - (int)(start2 - ip);
00427 if (correction > 0)
00428 {
00429 start2 += correction;
00430 ref2 += correction;
00431 ml2 -= correction;
00432 }
00433 }
00434
00435
00436 if (start2 + ml2 < mflimit)
00437 ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts);
00438 else ml3 = ml2;
00439
00440 if (ml3 == ml2)
00441 {
00442
00443 if (start2 < ip+ml) ml = (int)(start2 - ip);
00444
00445 if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
00446 ip = start2;
00447 if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
00448 continue;
00449 }
00450
00451 if (start3 < ip+ml+3)
00452 {
00453 if (start3 >= (ip+ml))
00454 {
00455 if (start2 < ip+ml)
00456 {
00457 int correction = (int)(ip+ml - start2);
00458 start2 += correction;
00459 ref2 += correction;
00460 ml2 -= correction;
00461 if (ml2 < MINMATCH)
00462 {
00463 start2 = start3;
00464 ref2 = ref3;
00465 ml2 = ml3;
00466 }
00467 }
00468
00469 if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
00470 ip = start3;
00471 ref = ref3;
00472 ml = ml3;
00473
00474 start0 = start2;
00475 ref0 = ref2;
00476 ml0 = ml2;
00477 goto _Search2;
00478 }
00479
00480 start2 = start3;
00481 ref2 = ref3;
00482 ml2 = ml3;
00483 goto _Search3;
00484 }
00485
00486
00487
00488
00489
00490 if (start2 < ip+ml)
00491 {
00492 if ((start2 - ip) < (int)ML_MASK)
00493 {
00494 int correction;
00495 if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
00496 if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
00497 correction = ml - (int)(start2 - ip);
00498 if (correction > 0)
00499 {
00500 start2 += correction;
00501 ref2 += correction;
00502 ml2 -= correction;
00503 }
00504 }
00505 else
00506 {
00507 ml = (int)(start2 - ip);
00508 }
00509 }
00510 if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
00511
00512 ip = start2;
00513 ref = ref2;
00514 ml = ml2;
00515
00516 start2 = start3;
00517 ref2 = ref3;
00518 ml2 = ml3;
00519
00520 goto _Search3;
00521 }
00522
00523
00524 {
00525 int lastRun = (int)(iend - anchor);
00526 if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0;
00527 if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
00528 else *op++ = (BYTE)(lastRun<<ML_BITS);
00529 memcpy(op, anchor, iend - anchor);
00530 op += iend-anchor;
00531 }
00532
00533
00534 return (int) (((char*)op)-dest);
00535 }
00536
00537
00538 int LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_Data_Structure); }
00539
00540 int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel)
00541 {
00542 if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0;
00543 LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)src);
00544 if (maxDstSize < LZ4_compressBound(srcSize))
00545 return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, limitedOutput);
00546 else
00547 return LZ4HC_compress_generic (state, src, dst, srcSize, maxDstSize, compressionLevel, noLimit);
00548 }
00549
00550 int LZ4_compress_HC(const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel)
00551 {
00552 LZ4HC_Data_Structure state;
00553 return LZ4_compress_HC_extStateHC(&state, src, dst, srcSize, maxDstSize, compressionLevel);
00554 }
00555
00556
00557
00558
00559
00560
00561
00562 LZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); }
00563 int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; }
00564
00565
00566
00567 void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
00568 {
00569 LZ4_STATIC_ASSERT(sizeof(LZ4HC_Data_Structure) <= sizeof(LZ4_streamHC_t));
00570 ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->base = NULL;
00571 ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel;
00572 }
00573
00574 int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize)
00575 {
00576 LZ4HC_Data_Structure* ctxPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr;
00577 if (dictSize > 64 KB)
00578 {
00579 dictionary += dictSize - 64 KB;
00580 dictSize = 64 KB;
00581 }
00582 LZ4HC_init (ctxPtr, (const BYTE*)dictionary);
00583 if (dictSize >= 4) LZ4HC_Insert (ctxPtr, (const BYTE*)dictionary +(dictSize-3));
00584 ctxPtr->end = (const BYTE*)dictionary + dictSize;
00585 return dictSize;
00586 }
00587
00588
00589
00590
00591 static void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock)
00592 {
00593 if (ctxPtr->end >= ctxPtr->base + 4)
00594 LZ4HC_Insert (ctxPtr, ctxPtr->end-3);
00595
00596 ctxPtr->lowLimit = ctxPtr->dictLimit;
00597 ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
00598 ctxPtr->dictBase = ctxPtr->base;
00599 ctxPtr->base = newBlock - ctxPtr->dictLimit;
00600 ctxPtr->end = newBlock;
00601 ctxPtr->nextToUpdate = ctxPtr->dictLimit;
00602 }
00603
00604 static int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* ctxPtr,
00605 const char* source, char* dest,
00606 int inputSize, int maxOutputSize, limitedOutput_directive limit)
00607 {
00608
00609 if (ctxPtr->base == NULL)
00610 LZ4HC_init (ctxPtr, (const BYTE*) source);
00611
00612
00613 if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB)
00614 {
00615 size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
00616 if (dictSize > 64 KB) dictSize = 64 KB;
00617
00618 LZ4_loadDictHC((LZ4_streamHC_t*)ctxPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
00619 }
00620
00621
00622 if ((const BYTE*)source != ctxPtr->end)
00623 LZ4HC_setExternalDict(ctxPtr, (const BYTE*)source);
00624
00625
00626 {
00627 const BYTE* sourceEnd = (const BYTE*) source + inputSize;
00628 const BYTE* dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
00629 const BYTE* dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
00630 if ((sourceEnd > dictBegin) && ((const BYTE*)source < dictEnd))
00631 {
00632 if (sourceEnd > dictEnd) sourceEnd = dictEnd;
00633 ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
00634 if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
00635 }
00636 }
00637
00638 return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->compressionLevel, limit);
00639 }
00640
00641 int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize)
00642 {
00643 if (maxOutputSize < LZ4_compressBound(inputSize))
00644 return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput);
00645 else
00646 return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, noLimit);
00647 }
00648
00649
00650
00651
00652 int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
00653 {
00654 LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr;
00655 int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
00656 if (dictSize > 64 KB) dictSize = 64 KB;
00657 if (dictSize < 4) dictSize = 0;
00658 if (dictSize > prefixSize) dictSize = prefixSize;
00659 memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
00660 {
00661 U32 endIndex = (U32)(streamPtr->end - streamPtr->base);
00662 streamPtr->end = (const BYTE*)safeBuffer + dictSize;
00663 streamPtr->base = streamPtr->end - endIndex;
00664 streamPtr->dictLimit = endIndex - dictSize;
00665 streamPtr->lowLimit = endIndex - dictSize;
00666 if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit;
00667 }
00668 return dictSize;
00669 }
00670
00671
00672
00673
00674
00675
00676
00677 int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); }
00678 int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); }
00679 int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); }
00680 int LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); }
00681 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); }
00682 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); }
00683 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); }
00684 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); }
00685 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)); }
00686 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); }
00687
00688
00689
00690
00691 int LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
00692
00693 int LZ4_resetStreamStateHC(void* state, char* inputBuffer)
00694 {
00695 if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1;
00696 LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer);
00697 ((LZ4HC_Data_Structure*)state)->inputBuffer = (BYTE*)inputBuffer;
00698 return 0;
00699 }
00700
00701 void* LZ4_createHC (char* inputBuffer)
00702 {
00703 void* hc4 = ALLOCATOR(1, sizeof(LZ4HC_Data_Structure));
00704 if (hc4 == NULL) return NULL;
00705 LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer);
00706 ((LZ4HC_Data_Structure*)hc4)->inputBuffer = (BYTE*)inputBuffer;
00707 return hc4;
00708 }
00709
00710 int LZ4_freeHC (void* LZ4HC_Data)
00711 {
00712 FREEMEM(LZ4HC_Data);
00713 return (0);
00714 }
00715
00716 int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel)
00717 {
00718 return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit);
00719 }
00720
00721 int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
00722 {
00723 return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
00724 }
00725
00726 char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
00727 {
00728 LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data;
00729 int dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB);
00730 return (char*)(hc4->inputBuffer + dictSize);
00731 }