1 /* 2 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. 3 * All rights reserved. 4 * 5 * This source code is licensed under both the BSD-style license (found in the 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7 * in the COPYING file in the root directory of this source tree). 8 * You may select, at your option, one of the above-listed licenses. 9 */ 10 11 /* This header contains definitions 12 * that shall **only** be used by modules within lib/compress. 13 */ 14 15 #ifndef ZSTD_COMPRESS_H 16 #define ZSTD_COMPRESS_H 17 18 /*-************************************* 19 * Dependencies 20 ***************************************/ 21 #include "zstd_internal.h" 22 #ifdef ZSTD_MULTITHREAD 23 # include "zstdmt_compress.h" 24 #endif 25 26 #if defined (__cplusplus) 27 extern "C" { 28 #endif 29 30 /*-************************************* 31 * Constants 32 ***************************************/ 33 #define kSearchStrength 8 34 #define HASH_READ_SIZE 8 35 #define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index 1 now means "unsorted". 36 It could be confused for a real successor at index "1", if sorted as larger than its predecessor. 37 It's not a big deal though : candidate will just be sorted again. 38 Additionnally, candidate position 1 will be lost. 39 But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss. 40 The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be misdhandled after table re-use with a different strategy */ 41 42 43 /*-************************************* 44 * Context memory management 45 ***************************************/ 46 typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e; 47 typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage; 48 49 typedef struct ZSTD_prefixDict_s { 50 const void* dict; 51 size_t dictSize; 52 ZSTD_dictContentType_e dictContentType; 53 } ZSTD_prefixDict; 54 55 typedef struct { 56 U32 hufCTable[HUF_CTABLE_SIZE_U32(255)]; 57 FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; 58 FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; 59 FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; 60 HUF_repeat hufCTable_repeatMode; 61 FSE_repeat offcode_repeatMode; 62 FSE_repeat matchlength_repeatMode; 63 FSE_repeat litlength_repeatMode; 64 } ZSTD_entropyCTables_t; 65 66 typedef struct { 67 U32 off; 68 U32 len; 69 } ZSTD_match_t; 70 71 typedef struct { 72 int price; 73 U32 off; 74 U32 mlen; 75 U32 litlen; 76 U32 rep[ZSTD_REP_NUM]; 77 } ZSTD_optimal_t; 78 79 typedef struct { 80 /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */ 81 U32* litFreq; /* table of literals statistics, of size 256 */ 82 U32* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */ 83 U32* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */ 84 U32* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */ 85 ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_NUM+1 */ 86 ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_NUM+1 */ 87 88 U32 litSum; /* nb of literals */ 89 U32 litLengthSum; /* nb of litLength codes */ 90 U32 matchLengthSum; /* nb of matchLength codes */ 91 U32 offCodeSum; /* nb of offset codes */ 92 /* begin updated by ZSTD_setLog2Prices */ 93 U32 log2litSum; /* pow2 to compare log2(litfreq) to */ 94 U32 log2litLengthSum; /* pow2 to compare log2(llfreq) to */ 95 U32 log2matchLengthSum; /* pow2 to compare log2(mlfreq) to */ 96 U32 log2offCodeSum; /* pow2 to compare log2(offreq) to */ 97 /* end : updated by ZSTD_setLog2Prices */ 98 U32 staticPrices; /* prices follow a pre-defined cost structure, statistics are irrelevant */ 99 } optState_t; 100 101 typedef struct { 102 ZSTD_entropyCTables_t entropy; 103 U32 rep[ZSTD_REP_NUM]; 104 } ZSTD_compressedBlockState_t; 105 106 typedef struct { 107 BYTE const* nextSrc; /* next block here to continue on current prefix */ 108 BYTE const* base; /* All regular indexes relative to this position */ 109 BYTE const* dictBase; /* extDict indexes relative to this position */ 110 U32 dictLimit; /* below that point, need extDict */ 111 U32 lowLimit; /* below that point, no more data */ 112 } ZSTD_window_t; 113 114 typedef struct { 115 ZSTD_window_t window; /* State for window round buffer management */ 116 U32 loadedDictEnd; /* index of end of dictionary */ 117 U32 nextToUpdate; /* index from which to continue table update */ 118 U32 nextToUpdate3; /* index from which to continue table update */ 119 U32 hashLog3; /* dispatch table : larger == faster, more memory */ 120 U32* hashTable; 121 U32* hashTable3; 122 U32* chainTable; 123 optState_t opt; /* optimal parser state */ 124 } ZSTD_matchState_t; 125 126 typedef struct { 127 ZSTD_compressedBlockState_t* prevCBlock; 128 ZSTD_compressedBlockState_t* nextCBlock; 129 ZSTD_matchState_t matchState; 130 } ZSTD_blockState_t; 131 132 typedef struct { 133 U32 offset; 134 U32 checksum; 135 } ldmEntry_t; 136 137 typedef struct { 138 ZSTD_window_t window; /* State for the window round buffer management */ 139 ldmEntry_t* hashTable; 140 BYTE* bucketOffsets; /* Next position in bucket to insert entry */ 141 U64 hashPower; /* Used to compute the rolling hash. 142 * Depends on ldmParams.minMatchLength */ 143 } ldmState_t; 144 145 typedef struct { 146 U32 enableLdm; /* 1 if enable long distance matching */ 147 U32 hashLog; /* Log size of hashTable */ 148 U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */ 149 U32 minMatchLength; /* Minimum match length */ 150 U32 hashEveryLog; /* Log number of entries to skip */ 151 U32 windowLog; /* Window log for the LDM */ 152 } ldmParams_t; 153 154 typedef struct { 155 U32 offset; 156 U32 litLength; 157 U32 matchLength; 158 } rawSeq; 159 160 typedef struct { 161 rawSeq* seq; /* The start of the sequences */ 162 size_t pos; /* The position where reading stopped. <= size. */ 163 size_t size; /* The number of sequences. <= capacity. */ 164 size_t capacity; /* The capacity of the `seq` pointer */ 165 } rawSeqStore_t; 166 167 struct ZSTD_CCtx_params_s { 168 ZSTD_format_e format; 169 ZSTD_compressionParameters cParams; 170 ZSTD_frameParameters fParams; 171 172 int compressionLevel; 173 int disableLiteralCompression; 174 int forceWindow; /* force back-references to respect limit of 175 * 1<<wLog, even for dictionary */ 176 177 /* Multithreading: used to pass parameters to mtctx */ 178 unsigned nbWorkers; 179 unsigned jobSize; 180 unsigned overlapSizeLog; 181 182 /* Long distance matching parameters */ 183 ldmParams_t ldmParams; 184 185 /* Internal use, for createCCtxParams() and freeCCtxParams() only */ 186 ZSTD_customMem customMem; 187 }; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */ 188 189 struct ZSTD_CCtx_s { 190 ZSTD_compressionStage_e stage; 191 int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */ 192 int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ 193 ZSTD_CCtx_params requestedParams; 194 ZSTD_CCtx_params appliedParams; 195 U32 dictID; 196 void* workSpace; 197 size_t workSpaceSize; 198 size_t blockSize; 199 unsigned long long pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */ 200 unsigned long long consumedSrcSize; 201 unsigned long long producedCSize; 202 XXH64_state_t xxhState; 203 ZSTD_customMem customMem; 204 size_t staticSize; 205 206 seqStore_t seqStore; /* sequences storage ptrs */ 207 ldmState_t ldmState; /* long distance matching state */ 208 rawSeq* ldmSequences; /* Storage for the ldm output sequences */ 209 size_t maxNbLdmSequences; 210 rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */ 211 ZSTD_blockState_t blockState; 212 U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */ 213 214 /* streaming */ 215 char* inBuff; 216 size_t inBuffSize; 217 size_t inToCompress; 218 size_t inBuffPos; 219 size_t inBuffTarget; 220 char* outBuff; 221 size_t outBuffSize; 222 size_t outBuffContentSize; 223 size_t outBuffFlushedSize; 224 ZSTD_cStreamStage streamStage; 225 U32 frameEnded; 226 227 /* Dictionary */ 228 ZSTD_CDict* cdictLocal; 229 const ZSTD_CDict* cdict; 230 ZSTD_prefixDict prefixDict; /* single-usage dictionary */ 231 232 /* Multi-threading */ 233 #ifdef ZSTD_MULTITHREAD 234 ZSTDMT_CCtx* mtctx; 235 #endif 236 }; 237 238 239 typedef size_t (*ZSTD_blockCompressor) ( 240 ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], 241 ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize); 242 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict); 243 244 245 MEM_STATIC U32 ZSTD_LLcode(U32 litLength) 246 { 247 static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 248 8, 9, 10, 11, 12, 13, 14, 15, 249 16, 16, 17, 17, 18, 18, 19, 19, 250 20, 20, 20, 20, 21, 21, 21, 21, 251 22, 22, 22, 22, 22, 22, 22, 22, 252 23, 23, 23, 23, 23, 23, 23, 23, 253 24, 24, 24, 24, 24, 24, 24, 24, 254 24, 24, 24, 24, 24, 24, 24, 24 }; 255 static const U32 LL_deltaCode = 19; 256 return (litLength > 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength]; 257 } 258 259 /* ZSTD_MLcode() : 260 * note : mlBase = matchLength - MINMATCH; 261 * because it's the format it's stored in seqStore->sequences */ 262 MEM_STATIC U32 ZSTD_MLcode(U32 mlBase) 263 { 264 static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 265 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 266 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 267 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 268 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 269 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 270 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 271 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 }; 272 static const U32 ML_deltaCode = 36; 273 return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase]; 274 } 275 276 /*! ZSTD_storeSeq() : 277 * Store a sequence (literal length, literals, offset code and match length code) into seqStore_t. 278 * `offsetCode` : distance to match + 3 (values 1-3 are repCodes). 279 * `mlBase` : matchLength - MINMATCH 280 */ 281 MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t mlBase) 282 { 283 #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG >= 6) 284 static const BYTE* g_start = NULL; 285 if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */ 286 { U32 const pos = (U32)((const BYTE*)literals - g_start); 287 DEBUGLOG(6, "Cpos%7u :%3u literals, match%3u bytes at dist.code%7u", 288 pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offsetCode); 289 } 290 #endif 291 /* copy Literals */ 292 assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + 128 KB); 293 ZSTD_wildcopy(seqStorePtr->lit, literals, litLength); 294 seqStorePtr->lit += litLength; 295 296 /* literal Length */ 297 if (litLength>0xFFFF) { 298 assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */ 299 seqStorePtr->longLengthID = 1; 300 seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); 301 } 302 seqStorePtr->sequences[0].litLength = (U16)litLength; 303 304 /* match offset */ 305 seqStorePtr->sequences[0].offset = offsetCode + 1; 306 307 /* match Length */ 308 if (mlBase>0xFFFF) { 309 assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */ 310 seqStorePtr->longLengthID = 2; 311 seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); 312 } 313 seqStorePtr->sequences[0].matchLength = (U16)mlBase; 314 315 seqStorePtr->sequences++; 316 } 317 318 319 /*-************************************* 320 * Match length counter 321 ***************************************/ 322 static unsigned ZSTD_NbCommonBytes (size_t val) 323 { 324 if (MEM_isLittleEndian()) { 325 if (MEM_64bits()) { 326 # if defined(_MSC_VER) && defined(_WIN64) 327 unsigned long r = 0; 328 _BitScanForward64( &r, (U64)val ); 329 return (unsigned)(r>>3); 330 # elif defined(__GNUC__) && (__GNUC__ >= 4) 331 return (__builtin_ctzll((U64)val) >> 3); 332 # else 333 static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 334 0, 3, 1, 3, 1, 4, 2, 7, 335 0, 2, 3, 6, 1, 5, 3, 5, 336 1, 3, 4, 4, 2, 5, 6, 7, 337 7, 0, 1, 2, 3, 3, 4, 6, 338 2, 6, 5, 5, 3, 4, 5, 6, 339 7, 1, 2, 4, 6, 4, 4, 5, 340 7, 2, 6, 5, 7, 6, 7, 7 }; 341 return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; 342 # endif 343 } else { /* 32 bits */ 344 # if defined(_MSC_VER) 345 unsigned long r=0; 346 _BitScanForward( &r, (U32)val ); 347 return (unsigned)(r>>3); 348 # elif defined(__GNUC__) && (__GNUC__ >= 3) 349 return (__builtin_ctz((U32)val) >> 3); 350 # else 351 static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 352 3, 2, 2, 1, 3, 2, 0, 1, 353 3, 3, 1, 2, 2, 2, 2, 0, 354 3, 1, 2, 0, 1, 0, 1, 1 }; 355 return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; 356 # endif 357 } 358 } else { /* Big Endian CPU */ 359 if (MEM_64bits()) { 360 # if defined(_MSC_VER) && defined(_WIN64) 361 unsigned long r = 0; 362 _BitScanReverse64( &r, val ); 363 return (unsigned)(r>>3); 364 # elif defined(__GNUC__) && (__GNUC__ >= 4) && __has_builtin(__builtin_clzll) 365 return (__builtin_clzll(val) >> 3); 366 # else 367 unsigned r; 368 const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */ 369 if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; } 370 if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } 371 r += (!val); 372 return r; 373 # endif 374 } else { /* 32 bits */ 375 # if defined(_MSC_VER) 376 unsigned long r = 0; 377 _BitScanReverse( &r, (unsigned long)val ); 378 return (unsigned)(r>>3); 379 # elif defined(__GNUC__) && (__GNUC__ >= 3) && __has_builtin(__builtin_clz) 380 return (__builtin_clz((U32)val) >> 3); 381 # else 382 unsigned r; 383 if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } 384 r += (!val); 385 return r; 386 # endif 387 } } 388 } 389 390 391 MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit) 392 { 393 const BYTE* const pStart = pIn; 394 const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1); 395 396 if (pIn < pInLoopLimit) { 397 { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); 398 if (diff) return ZSTD_NbCommonBytes(diff); } 399 pIn+=sizeof(size_t); pMatch+=sizeof(size_t); 400 while (pIn < pInLoopLimit) { 401 size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); 402 if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; } 403 pIn += ZSTD_NbCommonBytes(diff); 404 return (size_t)(pIn - pStart); 405 } } 406 if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; } 407 if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; } 408 if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++; 409 return (size_t)(pIn - pStart); 410 } 411 412 /** ZSTD_count_2segments() : 413 * can count match length with `ip` & `match` in 2 different segments. 414 * convention : on reaching mEnd, match count continue starting from iStart 415 */ 416 MEM_STATIC size_t 417 ZSTD_count_2segments(const BYTE* ip, const BYTE* match, 418 const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart) 419 { 420 const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd); 421 size_t const matchLength = ZSTD_count(ip, match, vEnd); 422 if (match + matchLength != mEnd) return matchLength; 423 return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd); 424 } 425 426 427 /*-************************************* 428 * Hashes 429 ***************************************/ 430 static const U32 prime3bytes = 506832829U; 431 static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes) >> (32-h) ; } 432 MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */ 433 434 static const U32 prime4bytes = 2654435761U; 435 static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; } 436 static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); } 437 438 static const U64 prime5bytes = 889523592379ULL; 439 static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; } 440 static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); } 441 442 static const U64 prime6bytes = 227718039650203ULL; 443 static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; } 444 static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); } 445 446 static const U64 prime7bytes = 58295818150454627ULL; 447 static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; } 448 static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); } 449 450 static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; 451 static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; } 452 static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); } 453 454 MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) 455 { 456 switch(mls) 457 { 458 default: 459 case 4: return ZSTD_hash4Ptr(p, hBits); 460 case 5: return ZSTD_hash5Ptr(p, hBits); 461 case 6: return ZSTD_hash6Ptr(p, hBits); 462 case 7: return ZSTD_hash7Ptr(p, hBits); 463 case 8: return ZSTD_hash8Ptr(p, hBits); 464 } 465 } 466 467 /*-************************************* 468 * Round buffer management 469 ***************************************/ 470 /* Max current allowed */ 471 #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX)) 472 /* Maximum chunk size before overflow correction needs to be called again */ 473 #define ZSTD_CHUNKSIZE_MAX \ 474 ( ((U32)-1) /* Maximum ending current index */ \ 475 - ZSTD_CURRENT_MAX) /* Maximum beginning lowLimit */ 476 477 /** 478 * ZSTD_window_clear(): 479 * Clears the window containing the history by simply setting it to empty. 480 */ 481 MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window) 482 { 483 size_t const endT = (size_t)(window->nextSrc - window->base); 484 U32 const end = (U32)endT; 485 486 window->lowLimit = end; 487 window->dictLimit = end; 488 } 489 490 /** 491 * ZSTD_window_hasExtDict(): 492 * Returns non-zero if the window has a non-empty extDict. 493 */ 494 MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window) 495 { 496 return window.lowLimit < window.dictLimit; 497 } 498 499 /** 500 * ZSTD_window_needOverflowCorrection(): 501 * Returns non-zero if the indices are getting too large and need overflow 502 * protection. 503 */ 504 MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, 505 void const* srcEnd) 506 { 507 U32 const current = (U32)((BYTE const*)srcEnd - window.base); 508 return current > ZSTD_CURRENT_MAX; 509 } 510 511 /** 512 * ZSTD_window_correctOverflow(): 513 * Reduces the indices to protect from index overflow. 514 * Returns the correction made to the indices, which must be applied to every 515 * stored index. 516 * 517 * The least significant cycleLog bits of the indices must remain the same, 518 * which may be 0. Every index up to maxDist in the past must be valid. 519 * NOTE: (maxDist & cycleMask) must be zero. 520 */ 521 MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, 522 U32 maxDist, void const* src) 523 { 524 /* preemptive overflow correction: 525 * 1. correction is large enough: 526 * lowLimit > (3<<29) ==> current > 3<<29 + 1<<windowLog 527 * 1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog 528 * 529 * current - newCurrent 530 * > (3<<29 + 1<<windowLog) - (1<<windowLog + 1<<chainLog) 531 * > (3<<29) - (1<<chainLog) 532 * > (3<<29) - (1<<30) (NOTE: chainLog <= 30) 533 * > 1<<29 534 * 535 * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow: 536 * After correction, current is less than (1<<chainLog + 1<<windowLog). 537 * In 64-bit mode we are safe, because we have 64-bit ptrdiff_t. 538 * In 32-bit mode we are safe, because (chainLog <= 29), so 539 * ip+ZSTD_CHUNKSIZE_MAX - cctx->base < 1<<32. 540 * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32: 541 * windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32. 542 */ 543 U32 const cycleMask = (1U << cycleLog) - 1; 544 U32 const current = (U32)((BYTE const*)src - window->base); 545 U32 const newCurrent = (current & cycleMask) + maxDist; 546 U32 const correction = current - newCurrent; 547 assert((maxDist & cycleMask) == 0); 548 assert(current > newCurrent); 549 /* Loose bound, should be around 1<<29 (see above) */ 550 assert(correction > 1<<28); 551 552 window->base += correction; 553 window->dictBase += correction; 554 window->lowLimit -= correction; 555 window->dictLimit -= correction; 556 557 DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, 558 window->lowLimit); 559 return correction; 560 } 561 562 /** 563 * ZSTD_window_enforceMaxDist(): 564 * Updates lowLimit so that: 565 * (srcEnd - base) - lowLimit == maxDist + loadedDictEnd 566 * This allows a simple check that index >= lowLimit to see if index is valid. 567 * This must be called before a block compression call, with srcEnd as the block 568 * source end. 569 * If loadedDictEndPtr is not NULL, we set it to zero once we update lowLimit. 570 * This is because dictionaries are allowed to be referenced as long as the last 571 * byte of the dictionary is in the window, but once they are out of range, 572 * they cannot be referenced. If loadedDictEndPtr is NULL, we use 573 * loadedDictEnd == 0. 574 */ 575 MEM_STATIC void ZSTD_window_enforceMaxDist(ZSTD_window_t* window, 576 void const* srcEnd, U32 maxDist, 577 U32* loadedDictEndPtr) 578 { 579 U32 const current = (U32)((BYTE const*)srcEnd - window->base); 580 U32 loadedDictEnd = loadedDictEndPtr != NULL ? *loadedDictEndPtr : 0; 581 if (current > maxDist + loadedDictEnd) { 582 U32 const newLowLimit = current - maxDist; 583 if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit; 584 if (window->dictLimit < window->lowLimit) { 585 DEBUGLOG(5, "Update dictLimit from %u to %u", window->dictLimit, 586 window->lowLimit); 587 window->dictLimit = window->lowLimit; 588 } 589 if (loadedDictEndPtr) 590 *loadedDictEndPtr = 0; 591 } 592 } 593 594 /** 595 * ZSTD_window_update(): 596 * Updates the window by appending [src, src + srcSize) to the window. 597 * If it is not contiguous, the current prefix becomes the extDict, and we 598 * forget about the extDict. Handles overlap of the prefix and extDict. 599 * Returns non-zero if the segment is contiguous. 600 */ 601 MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window, 602 void const* src, size_t srcSize) 603 { 604 BYTE const* const ip = (BYTE const*)src; 605 U32 contiguous = 1; 606 /* Check if blocks follow each other */ 607 if (src != window->nextSrc) { 608 /* not contiguous */ 609 size_t const distanceFromBase = (size_t)(window->nextSrc - window->base); 610 DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", 611 window->dictLimit); 612 window->lowLimit = window->dictLimit; 613 assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */ 614 window->dictLimit = (U32)distanceFromBase; 615 window->dictBase = window->base; 616 window->base = ip - distanceFromBase; 617 // ms->nextToUpdate = window->dictLimit; 618 if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */ 619 contiguous = 0; 620 } 621 window->nextSrc = ip + srcSize; 622 /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ 623 if ( (ip+srcSize > window->dictBase + window->lowLimit) 624 & (ip < window->dictBase + window->dictLimit)) { 625 ptrdiff_t const highInputIdx = (ip + srcSize) - window->dictBase; 626 U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx; 627 window->lowLimit = lowLimitMax; 628 } 629 return contiguous; 630 } 631 632 #if defined (__cplusplus) 633 } 634 #endif 635 636 637 /* ============================================================== 638 * Private declarations 639 * These prototypes shall only be called from within lib/compress 640 * ============================================================== */ 641 642 /* ZSTD_getCParamsFromCCtxParams() : 643 * cParams are built depending on compressionLevel, src size hints, 644 * LDM and manually set compression parameters. 645 */ 646 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( 647 const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize); 648 649 /*! ZSTD_initCStream_internal() : 650 * Private use only. Init streaming operation. 651 * expects params to be valid. 652 * must receive dict, or cdict, or none, but not both. 653 * @return : 0, or an error code */ 654 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, 655 const void* dict, size_t dictSize, 656 const ZSTD_CDict* cdict, 657 ZSTD_CCtx_params params, unsigned long long pledgedSrcSize); 658 659 /*! ZSTD_compressStream_generic() : 660 * Private use only. To be called from zstdmt_compress.c in single-thread mode. */ 661 size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, 662 ZSTD_outBuffer* output, 663 ZSTD_inBuffer* input, 664 ZSTD_EndDirective const flushMode); 665 666 /*! ZSTD_getCParamsFromCDict() : 667 * as the name implies */ 668 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict); 669 670 /* ZSTD_compressBegin_advanced_internal() : 671 * Private use only. To be called from zstdmt_compress.c. */ 672 size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, 673 const void* dict, size_t dictSize, 674 ZSTD_dictContentType_e dictContentType, 675 const ZSTD_CDict* cdict, 676 ZSTD_CCtx_params params, 677 unsigned long long pledgedSrcSize); 678 679 /* ZSTD_compress_advanced_internal() : 680 * Private use only. To be called from zstdmt_compress.c. */ 681 size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx, 682 void* dst, size_t dstCapacity, 683 const void* src, size_t srcSize, 684 const void* dict,size_t dictSize, 685 ZSTD_CCtx_params params); 686 687 688 /* ZSTD_writeLastEmptyBlock() : 689 * output an empty Block with end-of-frame mark to complete a frame 690 * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) 691 * or an error code if `dstCapcity` is too small (<ZSTD_blockHeaderSize) 692 */ 693 size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity); 694 695 696 /* ZSTD_referenceExternalSequences() : 697 * Must be called before starting a compression operation. 698 * seqs must parse a prefix of the source. 699 * This cannot be used when long range matching is enabled. 700 * Zstd will use these sequences, and pass the literals to a secondary block 701 * compressor. 702 * @return : An error code on failure. 703 * NOTE: seqs are not verified! Invalid sequences can cause out-of-bounds memory 704 * access and data corruption. 705 */ 706 size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq); 707 708 709 #endif /* ZSTD_COMPRESS_H */ 710