changeset 40121 | 73fef626dae3 |
parent 37495 | b1fb341d8a61 |
child 42070 | 675775c33ab6 |
40120:89742f1fa6cb | 40121:73fef626dae3 |
---|---|
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found |
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). |
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. |
8 * You may select, at your option, one of the above-listed licenses. |
9 */ |
9 */ |
10 |
10 |
11 |
|
12 /*-************************************* |
|
13 * Tuning parameters |
|
14 ***************************************/ |
|
15 #ifndef ZSTD_CLEVEL_DEFAULT |
|
16 # define ZSTD_CLEVEL_DEFAULT 3 |
|
17 #endif |
|
18 |
|
19 |
|
20 /*-************************************* |
11 /*-************************************* |
21 * Dependencies |
12 * Dependencies |
22 ***************************************/ |
13 ***************************************/ |
23 #include <string.h> /* memset */ |
14 #include <string.h> /* memset */ |
24 #include "cpu.h" |
15 #include "cpu.h" |
25 #include "mem.h" |
16 #include "mem.h" |
17 #include "hist.h" /* HIST_countFast_wksp */ |
|
26 #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */ |
18 #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */ |
27 #include "fse.h" |
19 #include "fse.h" |
28 #define HUF_STATIC_LINKING_ONLY |
20 #define HUF_STATIC_LINKING_ONLY |
29 #include "huf.h" |
21 #include "huf.h" |
30 #include "zstd_compress_internal.h" |
22 #include "zstd_compress_internal.h" |
52 size_t dictContentSize; |
44 size_t dictContentSize; |
53 void* workspace; |
45 void* workspace; |
54 size_t workspaceSize; |
46 size_t workspaceSize; |
55 ZSTD_matchState_t matchState; |
47 ZSTD_matchState_t matchState; |
56 ZSTD_compressedBlockState_t cBlockState; |
48 ZSTD_compressedBlockState_t cBlockState; |
57 ZSTD_compressionParameters cParams; |
|
58 ZSTD_customMem customMem; |
49 ZSTD_customMem customMem; |
59 U32 dictID; |
50 U32 dictID; |
60 }; /* typedef'd to ZSTD_CDict within "zstd.h" */ |
51 }; /* typedef'd to ZSTD_CDict within "zstd.h" */ |
61 |
52 |
62 ZSTD_CCtx* ZSTD_createCCtx(void) |
53 ZSTD_CCtx* ZSTD_createCCtx(void) |
63 { |
54 { |
64 return ZSTD_createCCtx_advanced(ZSTD_defaultCMem); |
55 return ZSTD_createCCtx_advanced(ZSTD_defaultCMem); |
65 } |
56 } |
66 |
57 |
58 static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) |
|
59 { |
|
60 assert(cctx != NULL); |
|
61 memset(cctx, 0, sizeof(*cctx)); |
|
62 cctx->customMem = memManager; |
|
63 cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); |
|
64 { size_t const err = ZSTD_CCtx_resetParameters(cctx); |
|
65 assert(!ZSTD_isError(err)); |
|
66 (void)err; |
|
67 } |
|
68 } |
|
69 |
|
67 ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) |
70 ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) |
68 { |
71 { |
69 ZSTD_STATIC_ASSERT(zcss_init==0); |
72 ZSTD_STATIC_ASSERT(zcss_init==0); |
70 ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); |
73 ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); |
71 if (!customMem.customAlloc ^ !customMem.customFree) return NULL; |
74 if (!customMem.customAlloc ^ !customMem.customFree) return NULL; |
72 { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_calloc(sizeof(ZSTD_CCtx), customMem); |
75 { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem); |
73 if (!cctx) return NULL; |
76 if (!cctx) return NULL; |
74 cctx->customMem = customMem; |
77 ZSTD_initCCtx(cctx, customMem); |
75 cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT; |
|
76 cctx->requestedParams.fParams.contentSizeFlag = 1; |
|
77 cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); |
|
78 return cctx; |
78 return cctx; |
79 } |
79 } |
80 } |
80 } |
81 |
81 |
82 ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize) |
82 ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize) |
100 } |
100 } |
101 cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); |
101 cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); |
102 return cctx; |
102 return cctx; |
103 } |
103 } |
104 |
104 |
105 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) |
105 static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx) |
106 { |
106 { |
107 if (cctx==NULL) return 0; /* support free on NULL */ |
107 assert(cctx != NULL); |
108 if (cctx->staticSize) return ERROR(memory_allocation); /* not compatible with static CCtx */ |
108 assert(cctx->staticSize == 0); |
109 ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL; |
109 ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL; |
110 ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL; |
110 ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL; |
111 #ifdef ZSTD_MULTITHREAD |
111 #ifdef ZSTD_MULTITHREAD |
112 ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL; |
112 ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL; |
113 #endif |
113 #endif |
114 } |
|
115 |
|
116 size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) |
|
117 { |
|
118 if (cctx==NULL) return 0; /* support free on NULL */ |
|
119 if (cctx->staticSize) return ERROR(memory_allocation); /* not compatible with static CCtx */ |
|
120 ZSTD_freeCCtxContent(cctx); |
|
114 ZSTD_free(cctx, cctx->customMem); |
121 ZSTD_free(cctx, cctx->customMem); |
115 return 0; /* reserved as a potential error code in the future */ |
122 return 0; |
116 } |
123 } |
117 |
124 |
118 |
125 |
119 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx) |
126 static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx) |
120 { |
127 { |
140 return ZSTD_sizeof_CCtx(zcs); /* same object */ |
147 return ZSTD_sizeof_CCtx(zcs); /* same object */ |
141 } |
148 } |
142 |
149 |
143 /* private API call, for dictBuilder only */ |
150 /* private API call, for dictBuilder only */ |
144 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } |
151 const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } |
145 |
|
146 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( |
|
147 const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize) |
|
148 { |
|
149 ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize); |
|
150 if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; |
|
151 if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog; |
|
152 if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog; |
|
153 if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog; |
|
154 if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog; |
|
155 if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength; |
|
156 if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength; |
|
157 if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy; |
|
158 return cParams; |
|
159 } |
|
160 |
152 |
161 static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( |
153 static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( |
162 ZSTD_compressionParameters cParams) |
154 ZSTD_compressionParameters cParams) |
163 { |
155 { |
164 ZSTD_CCtx_params cctxParams; |
156 ZSTD_CCtx_params cctxParams; |
249 case ZSTD_p_chainLog: |
241 case ZSTD_p_chainLog: |
250 case ZSTD_p_searchLog: |
242 case ZSTD_p_searchLog: |
251 case ZSTD_p_minMatch: |
243 case ZSTD_p_minMatch: |
252 case ZSTD_p_targetLength: |
244 case ZSTD_p_targetLength: |
253 case ZSTD_p_compressionStrategy: |
245 case ZSTD_p_compressionStrategy: |
254 case ZSTD_p_compressLiterals: |
|
255 return 1; |
246 return 1; |
256 |
247 |
257 case ZSTD_p_format: |
248 case ZSTD_p_format: |
258 case ZSTD_p_windowLog: |
249 case ZSTD_p_windowLog: |
259 case ZSTD_p_contentSizeFlag: |
250 case ZSTD_p_contentSizeFlag: |
266 case ZSTD_p_enableLongDistanceMatching: |
257 case ZSTD_p_enableLongDistanceMatching: |
267 case ZSTD_p_ldmHashLog: |
258 case ZSTD_p_ldmHashLog: |
268 case ZSTD_p_ldmMinMatch: |
259 case ZSTD_p_ldmMinMatch: |
269 case ZSTD_p_ldmBucketSizeLog: |
260 case ZSTD_p_ldmBucketSizeLog: |
270 case ZSTD_p_ldmHashEveryLog: |
261 case ZSTD_p_ldmHashEveryLog: |
262 case ZSTD_p_forceAttachDict: |
|
271 default: |
263 default: |
272 return 0; |
264 return 0; |
273 } |
265 } |
274 } |
266 } |
275 |
267 |
300 case ZSTD_p_targetLength: |
292 case ZSTD_p_targetLength: |
301 case ZSTD_p_compressionStrategy: |
293 case ZSTD_p_compressionStrategy: |
302 if (cctx->cdict) return ERROR(stage_wrong); |
294 if (cctx->cdict) return ERROR(stage_wrong); |
303 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
295 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
304 |
296 |
305 case ZSTD_p_compressLiterals: |
|
306 case ZSTD_p_contentSizeFlag: |
297 case ZSTD_p_contentSizeFlag: |
307 case ZSTD_p_checksumFlag: |
298 case ZSTD_p_checksumFlag: |
308 case ZSTD_p_dictIDFlag: |
299 case ZSTD_p_dictIDFlag: |
309 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
300 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
310 |
301 |
311 case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize, |
302 case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize, |
312 * even when referencing into Dictionary content. |
303 * even when referencing into Dictionary content. |
313 * default : 0 when using a CDict, 1 when using a Prefix */ |
304 * default : 0 when using a CDict, 1 when using a Prefix */ |
305 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
|
306 |
|
307 case ZSTD_p_forceAttachDict: |
|
314 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
308 return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value); |
315 |
309 |
316 case ZSTD_p_nbWorkers: |
310 case ZSTD_p_nbWorkers: |
317 if ((value>0) && cctx->staticSize) { |
311 if ((value>0) && cctx->staticSize) { |
318 return ERROR(parameter_unsupported); /* MT not compatible with static alloc */ |
312 return ERROR(parameter_unsupported); /* MT not compatible with static alloc */ |
349 |
343 |
350 case ZSTD_p_compressionLevel : { |
344 case ZSTD_p_compressionLevel : { |
351 int cLevel = (int)value; /* cast expected to restore negative sign */ |
345 int cLevel = (int)value; /* cast expected to restore negative sign */ |
352 if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel(); |
346 if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel(); |
353 if (cLevel) { /* 0 : does not change current level */ |
347 if (cLevel) { /* 0 : does not change current level */ |
354 CCtxParams->disableLiteralCompression = (cLevel<0); /* negative levels disable huffman */ |
|
355 CCtxParams->compressionLevel = cLevel; |
348 CCtxParams->compressionLevel = cLevel; |
356 } |
349 } |
357 if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel; |
350 if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel; |
358 return 0; /* return type (size_t) cannot represent negative values */ |
351 return 0; /* return type (size_t) cannot represent negative values */ |
359 } |
352 } |
397 if (value>0) /* 0 => use default */ |
390 if (value>0) /* 0 => use default */ |
398 CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra); |
391 CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra); |
399 CCtxParams->cParams.strategy = (ZSTD_strategy)value; |
392 CCtxParams->cParams.strategy = (ZSTD_strategy)value; |
400 return (size_t)CCtxParams->cParams.strategy; |
393 return (size_t)CCtxParams->cParams.strategy; |
401 |
394 |
402 case ZSTD_p_compressLiterals: |
|
403 CCtxParams->disableLiteralCompression = !value; |
|
404 return !CCtxParams->disableLiteralCompression; |
|
405 |
|
406 case ZSTD_p_contentSizeFlag : |
395 case ZSTD_p_contentSizeFlag : |
407 /* Content size written in frame header _when known_ (default:1) */ |
396 /* Content size written in frame header _when known_ (default:1) */ |
408 DEBUGLOG(4, "set content size flag = %u", (value>0)); |
397 DEBUGLOG(4, "set content size flag = %u", (value>0)); |
409 CCtxParams->fParams.contentSizeFlag = value > 0; |
398 CCtxParams->fParams.contentSizeFlag = value > 0; |
410 return CCtxParams->fParams.contentSizeFlag; |
399 return CCtxParams->fParams.contentSizeFlag; |
420 return !CCtxParams->fParams.noDictIDFlag; |
409 return !CCtxParams->fParams.noDictIDFlag; |
421 |
410 |
422 case ZSTD_p_forceMaxWindow : |
411 case ZSTD_p_forceMaxWindow : |
423 CCtxParams->forceWindow = (value > 0); |
412 CCtxParams->forceWindow = (value > 0); |
424 return CCtxParams->forceWindow; |
413 return CCtxParams->forceWindow; |
414 |
|
415 case ZSTD_p_forceAttachDict : |
|
416 CCtxParams->attachDictPref = value ? |
|
417 (value > 0 ? ZSTD_dictForceAttach : ZSTD_dictForceCopy) : |
|
418 ZSTD_dictDefaultAttach; |
|
419 return CCtxParams->attachDictPref; |
|
425 |
420 |
426 case ZSTD_p_nbWorkers : |
421 case ZSTD_p_nbWorkers : |
427 #ifndef ZSTD_MULTITHREAD |
422 #ifndef ZSTD_MULTITHREAD |
428 if (value>0) return ERROR(parameter_unsupported); |
423 if (value>0) return ERROR(parameter_unsupported); |
429 return 0; |
424 return 0; |
473 CCtxParams->ldmParams.hashEveryLog = value; |
468 CCtxParams->ldmParams.hashEveryLog = value; |
474 return CCtxParams->ldmParams.hashEveryLog; |
469 return CCtxParams->ldmParams.hashEveryLog; |
475 |
470 |
476 default: return ERROR(parameter_unsupported); |
471 default: return ERROR(parameter_unsupported); |
477 } |
472 } |
473 } |
|
474 |
|
475 size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value) |
|
476 { |
|
477 return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value); |
|
478 } |
|
479 |
|
480 size_t ZSTD_CCtxParam_getParameter( |
|
481 ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned* value) |
|
482 { |
|
483 switch(param) |
|
484 { |
|
485 case ZSTD_p_format : |
|
486 *value = CCtxParams->format; |
|
487 break; |
|
488 case ZSTD_p_compressionLevel : |
|
489 *value = CCtxParams->compressionLevel; |
|
490 break; |
|
491 case ZSTD_p_windowLog : |
|
492 *value = CCtxParams->cParams.windowLog; |
|
493 break; |
|
494 case ZSTD_p_hashLog : |
|
495 *value = CCtxParams->cParams.hashLog; |
|
496 break; |
|
497 case ZSTD_p_chainLog : |
|
498 *value = CCtxParams->cParams.chainLog; |
|
499 break; |
|
500 case ZSTD_p_searchLog : |
|
501 *value = CCtxParams->cParams.searchLog; |
|
502 break; |
|
503 case ZSTD_p_minMatch : |
|
504 *value = CCtxParams->cParams.searchLength; |
|
505 break; |
|
506 case ZSTD_p_targetLength : |
|
507 *value = CCtxParams->cParams.targetLength; |
|
508 break; |
|
509 case ZSTD_p_compressionStrategy : |
|
510 *value = (unsigned)CCtxParams->cParams.strategy; |
|
511 break; |
|
512 case ZSTD_p_contentSizeFlag : |
|
513 *value = CCtxParams->fParams.contentSizeFlag; |
|
514 break; |
|
515 case ZSTD_p_checksumFlag : |
|
516 *value = CCtxParams->fParams.checksumFlag; |
|
517 break; |
|
518 case ZSTD_p_dictIDFlag : |
|
519 *value = !CCtxParams->fParams.noDictIDFlag; |
|
520 break; |
|
521 case ZSTD_p_forceMaxWindow : |
|
522 *value = CCtxParams->forceWindow; |
|
523 break; |
|
524 case ZSTD_p_forceAttachDict : |
|
525 *value = CCtxParams->attachDictPref; |
|
526 break; |
|
527 case ZSTD_p_nbWorkers : |
|
528 #ifndef ZSTD_MULTITHREAD |
|
529 assert(CCtxParams->nbWorkers == 0); |
|
530 #endif |
|
531 *value = CCtxParams->nbWorkers; |
|
532 break; |
|
533 case ZSTD_p_jobSize : |
|
534 #ifndef ZSTD_MULTITHREAD |
|
535 return ERROR(parameter_unsupported); |
|
536 #else |
|
537 *value = CCtxParams->jobSize; |
|
538 break; |
|
539 #endif |
|
540 case ZSTD_p_overlapSizeLog : |
|
541 #ifndef ZSTD_MULTITHREAD |
|
542 return ERROR(parameter_unsupported); |
|
543 #else |
|
544 *value = CCtxParams->overlapSizeLog; |
|
545 break; |
|
546 #endif |
|
547 case ZSTD_p_enableLongDistanceMatching : |
|
548 *value = CCtxParams->ldmParams.enableLdm; |
|
549 break; |
|
550 case ZSTD_p_ldmHashLog : |
|
551 *value = CCtxParams->ldmParams.hashLog; |
|
552 break; |
|
553 case ZSTD_p_ldmMinMatch : |
|
554 *value = CCtxParams->ldmParams.minMatchLength; |
|
555 break; |
|
556 case ZSTD_p_ldmBucketSizeLog : |
|
557 *value = CCtxParams->ldmParams.bucketSizeLog; |
|
558 break; |
|
559 case ZSTD_p_ldmHashEveryLog : |
|
560 *value = CCtxParams->ldmParams.hashEveryLog; |
|
561 break; |
|
562 default: return ERROR(parameter_unsupported); |
|
563 } |
|
564 return 0; |
|
478 } |
565 } |
479 |
566 |
480 /** ZSTD_CCtx_setParametersUsingCCtxParams() : |
567 /** ZSTD_CCtx_setParametersUsingCCtxParams() : |
481 * just applies `params` into `cctx` |
568 * just applies `params` into `cctx` |
482 * no action is performed, parameters are merely stored. |
569 * no action is performed, parameters are merely stored. |
485 * In which case, new parameters will be applied on the fly, starting with next compression job. |
572 * In which case, new parameters will be applied on the fly, starting with next compression job. |
486 */ |
573 */ |
487 size_t ZSTD_CCtx_setParametersUsingCCtxParams( |
574 size_t ZSTD_CCtx_setParametersUsingCCtxParams( |
488 ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params) |
575 ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params) |
489 { |
576 { |
577 DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams"); |
|
490 if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); |
578 if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); |
491 if (cctx->cdict) return ERROR(stage_wrong); |
579 if (cctx->cdict) return ERROR(stage_wrong); |
492 |
580 |
493 cctx->requestedParams = *params; |
581 cctx->requestedParams = *params; |
494 return 0; |
582 return 0; |
563 cctx->prefixDict.dictSize = prefixSize; |
651 cctx->prefixDict.dictSize = prefixSize; |
564 cctx->prefixDict.dictContentType = dictContentType; |
652 cctx->prefixDict.dictContentType = dictContentType; |
565 return 0; |
653 return 0; |
566 } |
654 } |
567 |
655 |
568 static void ZSTD_startNewCompression(ZSTD_CCtx* cctx) |
|
569 { |
|
570 cctx->streamStage = zcss_init; |
|
571 cctx->pledgedSrcSizePlusOne = 0; |
|
572 } |
|
573 |
|
574 /*! ZSTD_CCtx_reset() : |
656 /*! ZSTD_CCtx_reset() : |
575 * Also dumps dictionary */ |
657 * Also dumps dictionary */ |
576 void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) |
658 void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) |
577 { |
659 { |
578 ZSTD_startNewCompression(cctx); |
660 cctx->streamStage = zcss_init; |
661 cctx->pledgedSrcSizePlusOne = 0; |
|
662 } |
|
663 |
|
664 size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx) |
|
665 { |
|
666 if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); |
|
579 cctx->cdict = NULL; |
667 cctx->cdict = NULL; |
668 return ZSTD_CCtxParams_reset(&cctx->requestedParams); |
|
580 } |
669 } |
581 |
670 |
582 /** ZSTD_checkCParams() : |
671 /** ZSTD_checkCParams() : |
583 control CParam values remain within authorized range. |
672 control CParam values remain within authorized range. |
584 @return : 0, or an error code if one value is beyond authorized range */ |
673 @return : 0, or an error code if one value is beyond authorized range */ |
587 CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); |
676 CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); |
588 CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); |
677 CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); |
589 CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); |
678 CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); |
590 CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); |
679 CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); |
591 CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); |
680 CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); |
592 if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN) |
681 ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0); |
593 return ERROR(parameter_unsupported); |
682 if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX) |
683 return ERROR(parameter_outOfBound); |
|
594 if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) |
684 if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) |
595 return ERROR(parameter_unsupported); |
685 return ERROR(parameter_unsupported); |
596 return 0; |
686 return 0; |
597 } |
687 } |
598 |
688 |
599 /** ZSTD_clampCParams() : |
689 /** ZSTD_clampCParams() : |
600 * make CParam values within valid range. |
690 * make CParam values within valid range. |
601 * @return : valid CParams */ |
691 * @return : valid CParams */ |
602 static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters cParams) |
692 static ZSTD_compressionParameters |
693 ZSTD_clampCParams(ZSTD_compressionParameters cParams) |
|
603 { |
694 { |
604 # define CLAMP(val,min,max) { \ |
695 # define CLAMP(val,min,max) { \ |
605 if (val<min) val=min; \ |
696 if (val<min) val=min; \ |
606 else if (val>max) val=max; \ |
697 else if (val>max) val=max; \ |
607 } |
698 } |
608 CLAMP(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); |
699 CLAMP(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); |
609 CLAMP(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); |
700 CLAMP(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); |
610 CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); |
701 CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); |
611 CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); |
702 CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); |
612 CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); |
703 CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); |
613 if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN) cParams.targetLength = ZSTD_TARGETLENGTH_MIN; |
704 ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0); |
614 if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) cParams.strategy = ZSTD_btultra; |
705 if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX) |
706 cParams.targetLength = ZSTD_TARGETLENGTH_MAX; |
|
707 CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra); |
|
615 return cParams; |
708 return cParams; |
616 } |
709 } |
617 |
710 |
618 /** ZSTD_cycleLog() : |
711 /** ZSTD_cycleLog() : |
619 * condition for correct operation : hashLog > 1 */ |
712 * condition for correct operation : hashLog > 1 */ |
625 |
718 |
626 /** ZSTD_adjustCParams_internal() : |
719 /** ZSTD_adjustCParams_internal() : |
627 optimize `cPar` for a given input (`srcSize` and `dictSize`). |
720 optimize `cPar` for a given input (`srcSize` and `dictSize`). |
628 mostly downsizing to reduce memory consumption and initialization latency. |
721 mostly downsizing to reduce memory consumption and initialization latency. |
629 Both `srcSize` and `dictSize` are optional (use 0 if unknown). |
722 Both `srcSize` and `dictSize` are optional (use 0 if unknown). |
630 Note : cPar is considered validated at this stage. Use ZSTD_checkCParams() to ensure that condition. */ |
723 Note : cPar is assumed validated. Use ZSTD_checkCParams() to ensure this condition. */ |
631 ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize) |
724 static ZSTD_compressionParameters |
725 ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, |
|
726 unsigned long long srcSize, |
|
727 size_t dictSize) |
|
632 { |
728 { |
633 static const U64 minSrcSize = 513; /* (1<<9) + 1 */ |
729 static const U64 minSrcSize = 513; /* (1<<9) + 1 */ |
634 static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); |
730 static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); |
635 assert(ZSTD_checkCParams(cPar)==0); |
731 assert(ZSTD_checkCParams(cPar)==0); |
636 |
732 |
646 static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN; |
742 static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN; |
647 U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN : |
743 U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN : |
648 ZSTD_highbit32(tSize-1) + 1; |
744 ZSTD_highbit32(tSize-1) + 1; |
649 if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; |
745 if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; |
650 } |
746 } |
651 if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog; |
747 if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1; |
652 { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); |
748 { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); |
653 if (cycleLog > cPar.windowLog) |
749 if (cycleLog > cPar.windowLog) |
654 cPar.chainLog -= (cycleLog - cPar.windowLog); |
750 cPar.chainLog -= (cycleLog - cPar.windowLog); |
655 } |
751 } |
656 |
752 |
658 cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ |
754 cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ |
659 |
755 |
660 return cPar; |
756 return cPar; |
661 } |
757 } |
662 |
758 |
663 ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize) |
759 ZSTD_compressionParameters |
760 ZSTD_adjustCParams(ZSTD_compressionParameters cPar, |
|
761 unsigned long long srcSize, |
|
762 size_t dictSize) |
|
664 { |
763 { |
665 cPar = ZSTD_clampCParams(cPar); |
764 cPar = ZSTD_clampCParams(cPar); |
666 return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize); |
765 return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize); |
667 } |
766 } |
668 |
767 |
669 static size_t ZSTD_sizeof_matchState(ZSTD_compressionParameters const* cParams, const U32 forCCtx) |
768 ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( |
769 const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize) |
|
770 { |
|
771 ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize); |
|
772 if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; |
|
773 if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog; |
|
774 if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog; |
|
775 if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog; |
|
776 if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog; |
|
777 if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength; |
|
778 if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength; |
|
779 if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy; |
|
780 assert(!ZSTD_checkCParams(cParams)); |
|
781 return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize); |
|
782 } |
|
783 |
|
784 static size_t |
|
785 ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, |
|
786 const U32 forCCtx) |
|
670 { |
787 { |
671 size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog); |
788 size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog); |
672 size_t const hSize = ((size_t)1) << cParams->hashLog; |
789 size_t const hSize = ((size_t)1) << cParams->hashLog; |
673 U32 const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; |
790 U32 const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; |
674 size_t const h3Size = ((size_t)1) << hashLog3; |
791 size_t const h3Size = ((size_t)1) << hashLog3; |
691 { ZSTD_compressionParameters const cParams = |
808 { ZSTD_compressionParameters const cParams = |
692 ZSTD_getCParamsFromCCtxParams(params, 0, 0); |
809 ZSTD_getCParamsFromCCtxParams(params, 0, 0); |
693 size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); |
810 size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); |
694 U32 const divider = (cParams.searchLength==3) ? 3 : 4; |
811 U32 const divider = (cParams.searchLength==3) ? 3 : 4; |
695 size_t const maxNbSeq = blockSize / divider; |
812 size_t const maxNbSeq = blockSize / divider; |
696 size_t const tokenSpace = blockSize + 11*maxNbSeq; |
813 size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq; |
697 size_t const entropySpace = HUF_WORKSPACE_SIZE; |
814 size_t const entropySpace = HUF_WORKSPACE_SIZE; |
698 size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t); |
815 size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t); |
699 size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1); |
816 size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1); |
700 |
817 |
701 size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams); |
818 size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams); |
750 { |
867 { |
751 ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams); |
868 ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams); |
752 return ZSTD_estimateCStreamSize_usingCCtxParams(¶ms); |
869 return ZSTD_estimateCStreamSize_usingCCtxParams(¶ms); |
753 } |
870 } |
754 |
871 |
755 static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) { |
872 static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) |
873 { |
|
756 ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0); |
874 ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0); |
757 return ZSTD_estimateCStreamSize_usingCParams(cParams); |
875 return ZSTD_estimateCStreamSize_usingCParams(cParams); |
758 } |
876 } |
759 |
877 |
760 size_t ZSTD_estimateCStreamSize(int compressionLevel) { |
878 size_t ZSTD_estimateCStreamSize(int compressionLevel) |
879 { |
|
761 int level; |
880 int level; |
762 size_t memBudget = 0; |
881 size_t memBudget = 0; |
763 for (level=1; level<=compressionLevel; level++) { |
882 for (level=1; level<=compressionLevel; level++) { |
764 size_t const newMB = ZSTD_estimateCStreamSize_internal(level); |
883 size_t const newMB = ZSTD_estimateCStreamSize_internal(level); |
765 if (newMB > memBudget) memBudget = newMB; |
884 if (newMB > memBudget) memBudget = newMB; |
784 if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress); |
903 if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress); |
785 assert(buffered <= ZSTD_BLOCKSIZE_MAX); |
904 assert(buffered <= ZSTD_BLOCKSIZE_MAX); |
786 fp.ingested = cctx->consumedSrcSize + buffered; |
905 fp.ingested = cctx->consumedSrcSize + buffered; |
787 fp.consumed = cctx->consumedSrcSize; |
906 fp.consumed = cctx->consumedSrcSize; |
788 fp.produced = cctx->producedCSize; |
907 fp.produced = cctx->producedCSize; |
908 fp.flushed = cctx->producedCSize; /* simplified; some data might still be left within streaming output buffer */ |
|
909 fp.currentJobID = 0; |
|
910 fp.nbActiveWorkers = 0; |
|
789 return fp; |
911 return fp; |
790 } } |
912 } } |
913 |
|
914 /*! ZSTD_toFlushNow() |
|
915 * Only useful for multithreading scenarios currently (nbWorkers >= 1). |
|
916 */ |
|
917 size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx) |
|
918 { |
|
919 #ifdef ZSTD_MULTITHREAD |
|
920 if (cctx->appliedParams.nbWorkers > 0) { |
|
921 return ZSTDMT_toFlushNow(cctx->mtctx); |
|
922 } |
|
923 #endif |
|
924 (void)cctx; |
|
925 return 0; /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */ |
|
926 } |
|
927 |
|
791 |
928 |
792 |
929 |
793 static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1, |
930 static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1, |
794 ZSTD_compressionParameters cParams2) |
931 ZSTD_compressionParameters cParams2) |
795 { |
932 { |
796 return (cParams1.hashLog == cParams2.hashLog) |
933 return (cParams1.hashLog == cParams2.hashLog) |
797 & (cParams1.chainLog == cParams2.chainLog) |
934 & (cParams1.chainLog == cParams2.chainLog) |
798 & (cParams1.strategy == cParams2.strategy) /* opt parser space */ |
935 & (cParams1.strategy == cParams2.strategy) /* opt parser space */ |
799 & ((cParams1.searchLength==3) == (cParams2.searchLength==3)); /* hashlog3 space */ |
936 & ((cParams1.searchLength==3) == (cParams2.searchLength==3)); /* hashlog3 space */ |
937 } |
|
938 |
|
939 static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1, |
|
940 ZSTD_compressionParameters cParams2) |
|
941 { |
|
942 (void)cParams1; |
|
943 (void)cParams2; |
|
944 assert(cParams1.windowLog == cParams2.windowLog); |
|
945 assert(cParams1.chainLog == cParams2.chainLog); |
|
946 assert(cParams1.hashLog == cParams2.hashLog); |
|
947 assert(cParams1.searchLog == cParams2.searchLog); |
|
948 assert(cParams1.searchLength == cParams2.searchLength); |
|
949 assert(cParams1.targetLength == cParams2.targetLength); |
|
950 assert(cParams1.strategy == cParams2.strategy); |
|
800 } |
951 } |
801 |
952 |
802 /** The parameters are equivalent if ldm is not enabled in both sets or |
953 /** The parameters are equivalent if ldm is not enabled in both sets or |
803 * all the parameters are equivalent. */ |
954 * all the parameters are equivalent. */ |
804 static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1, |
955 static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1, |
815 typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; |
966 typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; |
816 |
967 |
817 /* ZSTD_sufficientBuff() : |
968 /* ZSTD_sufficientBuff() : |
818 * check internal buffers exist for streaming if buffPol == ZSTDb_buffered . |
969 * check internal buffers exist for streaming if buffPol == ZSTDb_buffered . |
819 * Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */ |
970 * Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */ |
820 static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t blockSize1, |
971 static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t maxNbSeq1, |
972 size_t maxNbLit1, |
|
821 ZSTD_buffered_policy_e buffPol2, |
973 ZSTD_buffered_policy_e buffPol2, |
822 ZSTD_compressionParameters cParams2, |
974 ZSTD_compressionParameters cParams2, |
823 U64 pledgedSrcSize) |
975 U64 pledgedSrcSize) |
824 { |
976 { |
825 size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize)); |
977 size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize)); |
826 size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2); |
978 size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2); |
979 size_t const maxNbSeq2 = blockSize2 / ((cParams2.searchLength == 3) ? 3 : 4); |
|
980 size_t const maxNbLit2 = blockSize2; |
|
827 size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0; |
981 size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0; |
828 DEBUGLOG(4, "ZSTD_sufficientBuff: is windowSize2=%u <= wlog1=%u", |
982 DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u", |
829 (U32)windowSize2, cParams2.windowLog); |
983 (U32)neededBufferSize2, (U32)bufferSize1); |
830 DEBUGLOG(4, "ZSTD_sufficientBuff: is blockSize2=%u <= blockSize1=%u", |
984 DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u", |
831 (U32)blockSize2, (U32)blockSize1); |
985 (U32)maxNbSeq2, (U32)maxNbSeq1); |
832 return (blockSize2 <= blockSize1) /* seqStore space depends on blockSize */ |
986 DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbLit2=%u <= maxNbLit1=%u", |
987 (U32)maxNbLit2, (U32)maxNbLit1); |
|
988 return (maxNbLit2 <= maxNbLit1) |
|
989 & (maxNbSeq2 <= maxNbSeq1) |
|
833 & (neededBufferSize2 <= bufferSize1); |
990 & (neededBufferSize2 <= bufferSize1); |
834 } |
991 } |
835 |
992 |
836 /** Equivalence for resetCCtx purposes */ |
993 /** Equivalence for resetCCtx purposes */ |
837 static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1, |
994 static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1, |
838 ZSTD_CCtx_params params2, |
995 ZSTD_CCtx_params params2, |
839 size_t buffSize1, size_t blockSize1, |
996 size_t buffSize1, |
997 size_t maxNbSeq1, size_t maxNbLit1, |
|
840 ZSTD_buffered_policy_e buffPol2, |
998 ZSTD_buffered_policy_e buffPol2, |
841 U64 pledgedSrcSize) |
999 U64 pledgedSrcSize) |
842 { |
1000 { |
843 DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize); |
1001 DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize); |
844 return ZSTD_equivalentCParams(params1.cParams, params2.cParams) && |
1002 if (!ZSTD_equivalentCParams(params1.cParams, params2.cParams)) { |
845 ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams) && |
1003 DEBUGLOG(4, "ZSTD_equivalentCParams() == 0"); |
846 ZSTD_sufficientBuff(buffSize1, blockSize1, buffPol2, params2.cParams, pledgedSrcSize); |
1004 return 0; |
1005 } |
|
1006 if (!ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams)) { |
|
1007 DEBUGLOG(4, "ZSTD_equivalentLdmParams() == 0"); |
|
1008 return 0; |
|
1009 } |
|
1010 if (!ZSTD_sufficientBuff(buffSize1, maxNbSeq1, maxNbLit1, buffPol2, |
|
1011 params2.cParams, pledgedSrcSize)) { |
|
1012 DEBUGLOG(4, "ZSTD_sufficientBuff() == 0"); |
|
1013 return 0; |
|
1014 } |
|
1015 return 1; |
|
847 } |
1016 } |
848 |
1017 |
849 static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) |
1018 static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) |
850 { |
1019 { |
851 int i; |
1020 int i; |
852 for (i = 0; i < ZSTD_REP_NUM; ++i) |
1021 for (i = 0; i < ZSTD_REP_NUM; ++i) |
853 bs->rep[i] = repStartValue[i]; |
1022 bs->rep[i] = repStartValue[i]; |
854 bs->entropy.hufCTable_repeatMode = HUF_repeat_none; |
1023 bs->entropy.huf.repeatMode = HUF_repeat_none; |
855 bs->entropy.offcode_repeatMode = FSE_repeat_none; |
1024 bs->entropy.fse.offcode_repeatMode = FSE_repeat_none; |
856 bs->entropy.matchlength_repeatMode = FSE_repeat_none; |
1025 bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none; |
857 bs->entropy.litlength_repeatMode = FSE_repeat_none; |
1026 bs->entropy.fse.litlength_repeatMode = FSE_repeat_none; |
858 } |
1027 } |
859 |
1028 |
860 /*! ZSTD_invalidateMatchState() |
1029 /*! ZSTD_invalidateMatchState() |
861 * Invalidate all the matches in the match finder tables. |
1030 * Invalidate all the matches in the match finder tables. |
862 * Requires nextSrc and base to be set (can be NULL). |
1031 * Requires nextSrc and base to be set (can be NULL). |
864 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) |
1033 static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) |
865 { |
1034 { |
866 ZSTD_window_clear(&ms->window); |
1035 ZSTD_window_clear(&ms->window); |
867 |
1036 |
868 ms->nextToUpdate = ms->window.dictLimit + 1; |
1037 ms->nextToUpdate = ms->window.dictLimit + 1; |
1038 ms->nextToUpdate3 = ms->window.dictLimit + 1; |
|
869 ms->loadedDictEnd = 0; |
1039 ms->loadedDictEnd = 0; |
870 ms->opt.litLengthSum = 0; /* force reset of btopt stats */ |
1040 ms->opt.litLengthSum = 0; /* force reset of btopt stats */ |
1041 ms->dictMatchState = NULL; |
|
871 } |
1042 } |
872 |
1043 |
873 /*! ZSTD_continueCCtx() : |
1044 /*! ZSTD_continueCCtx() : |
874 * reuse CCtx without reset (note : requires no dictionary) */ |
1045 * reuse CCtx without reset (note : requires no dictionary) */ |
875 static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize) |
1046 static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize) |
878 size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); |
1049 size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); |
879 DEBUGLOG(4, "ZSTD_continueCCtx: re-use context in place"); |
1050 DEBUGLOG(4, "ZSTD_continueCCtx: re-use context in place"); |
880 |
1051 |
881 cctx->blockSize = blockSize; /* previous block size could be different even for same windowLog, due to pledgedSrcSize */ |
1052 cctx->blockSize = blockSize; /* previous block size could be different even for same windowLog, due to pledgedSrcSize */ |
882 cctx->appliedParams = params; |
1053 cctx->appliedParams = params; |
1054 cctx->blockState.matchState.cParams = params.cParams; |
|
883 cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; |
1055 cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; |
884 cctx->consumedSrcSize = 0; |
1056 cctx->consumedSrcSize = 0; |
885 cctx->producedCSize = 0; |
1057 cctx->producedCSize = 0; |
886 if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) |
1058 if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) |
887 cctx->appliedParams.fParams.contentSizeFlag = 0; |
1059 cctx->appliedParams.fParams.contentSizeFlag = 0; |
898 return 0; |
1070 return 0; |
899 } |
1071 } |
900 |
1072 |
901 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; |
1073 typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; |
902 |
1074 |
903 static void* ZSTD_reset_matchState(ZSTD_matchState_t* ms, void* ptr, ZSTD_compressionParameters const* cParams, ZSTD_compResetPolicy_e const crp, U32 const forCCtx) |
1075 static void* |
1076 ZSTD_reset_matchState(ZSTD_matchState_t* ms, |
|
1077 void* ptr, |
|
1078 const ZSTD_compressionParameters* cParams, |
|
1079 ZSTD_compResetPolicy_e const crp, U32 const forCCtx) |
|
904 { |
1080 { |
905 size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog); |
1081 size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog); |
906 size_t const hSize = ((size_t)1) << cParams->hashLog; |
1082 size_t const hSize = ((size_t)1) << cParams->hashLog; |
907 U32 const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; |
1083 U32 const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; |
908 size_t const h3Size = ((size_t)1) << hashLog3; |
1084 size_t const h3Size = ((size_t)1) << hashLog3; |
910 |
1086 |
911 assert(((size_t)ptr & 3) == 0); |
1087 assert(((size_t)ptr & 3) == 0); |
912 |
1088 |
913 ms->hashLog3 = hashLog3; |
1089 ms->hashLog3 = hashLog3; |
914 memset(&ms->window, 0, sizeof(ms->window)); |
1090 memset(&ms->window, 0, sizeof(ms->window)); |
1091 ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */ |
|
1092 ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */ |
|
1093 ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */ |
|
915 ZSTD_invalidateMatchState(ms); |
1094 ZSTD_invalidateMatchState(ms); |
916 |
1095 |
917 /* opt parser space */ |
1096 /* opt parser space */ |
918 if (forCCtx && ((cParams->strategy == ZSTD_btopt) | (cParams->strategy == ZSTD_btultra))) { |
1097 if (forCCtx && ((cParams->strategy == ZSTD_btopt) | (cParams->strategy == ZSTD_btultra))) { |
919 DEBUGLOG(4, "reserving optimal parser space"); |
1098 DEBUGLOG(4, "reserving optimal parser space"); |
935 ms->hashTable = (U32*)(ptr); |
1114 ms->hashTable = (U32*)(ptr); |
936 ms->chainTable = ms->hashTable + hSize; |
1115 ms->chainTable = ms->hashTable + hSize; |
937 ms->hashTable3 = ms->chainTable + chainSize; |
1116 ms->hashTable3 = ms->chainTable + chainSize; |
938 ptr = ms->hashTable3 + h3Size; |
1117 ptr = ms->hashTable3 + h3Size; |
939 |
1118 |
1119 ms->cParams = *cParams; |
|
1120 |
|
940 assert(((size_t)ptr & 3) == 0); |
1121 assert(((size_t)ptr & 3) == 0); |
941 return ptr; |
1122 return ptr; |
942 } |
1123 } |
1124 |
|
1125 #define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */ |
|
1126 #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 /* when workspace is continuously too large |
|
1127 * during at least this number of times, |
|
1128 * context's memory usage is considered wasteful, |
|
1129 * because it's sized to handle a worst case scenario which rarely happens. |
|
1130 * In which case, resize it down to free some memory */ |
|
943 |
1131 |
944 /*! ZSTD_resetCCtx_internal() : |
1132 /*! ZSTD_resetCCtx_internal() : |
945 note : `params` are assumed fully validated at this stage */ |
1133 note : `params` are assumed fully validated at this stage */ |
946 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, |
1134 static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, |
947 ZSTD_CCtx_params params, U64 pledgedSrcSize, |
1135 ZSTD_CCtx_params params, |
1136 U64 pledgedSrcSize, |
|
948 ZSTD_compResetPolicy_e const crp, |
1137 ZSTD_compResetPolicy_e const crp, |
949 ZSTD_buffered_policy_e const zbuff) |
1138 ZSTD_buffered_policy_e const zbuff) |
950 { |
1139 { |
951 DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u", |
1140 DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u", |
952 (U32)pledgedSrcSize, params.cParams.windowLog); |
1141 (U32)pledgedSrcSize, params.cParams.windowLog); |
953 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
1142 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
954 |
1143 |
955 if (crp == ZSTDcrp_continue) { |
1144 if (crp == ZSTDcrp_continue) { |
956 if (ZSTD_equivalentParams(zc->appliedParams, params, |
1145 if (ZSTD_equivalentParams(zc->appliedParams, params, |
957 zc->inBuffSize, zc->blockSize, |
1146 zc->inBuffSize, |
958 zbuff, pledgedSrcSize)) { |
1147 zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit, |
959 DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%u)", |
1148 zbuff, pledgedSrcSize)) { |
960 zc->appliedParams.cParams.windowLog, (U32)zc->blockSize); |
1149 DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)", |
961 return ZSTD_continueCCtx(zc, params, pledgedSrcSize); |
1150 zc->appliedParams.cParams.windowLog, zc->blockSize); |
1151 zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */ |
|
1152 if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION) |
|
1153 return ZSTD_continueCCtx(zc, params, pledgedSrcSize); |
|
962 } } |
1154 } } |
963 DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx"); |
1155 DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx"); |
964 |
1156 |
965 if (params.ldmParams.enableLdm) { |
1157 if (params.ldmParams.enableLdm) { |
966 /* Adjust long distance matching parameters */ |
1158 /* Adjust long distance matching parameters */ |
967 params.ldmParams.windowLog = params.cParams.windowLog; |
|
968 ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams); |
1159 ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams); |
969 assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog); |
1160 assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog); |
970 assert(params.ldmParams.hashEveryLog < 32); |
1161 assert(params.ldmParams.hashEveryLog < 32); |
971 zc->ldmState.hashPower = |
1162 zc->ldmState.hashPower = ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength); |
972 ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength); |
|
973 } |
1163 } |
974 |
1164 |
975 { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize)); |
1165 { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize)); |
976 size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); |
1166 size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); |
977 U32 const divider = (params.cParams.searchLength==3) ? 3 : 4; |
1167 U32 const divider = (params.cParams.searchLength==3) ? 3 : 4; |
978 size_t const maxNbSeq = blockSize / divider; |
1168 size_t const maxNbSeq = blockSize / divider; |
979 size_t const tokenSpace = blockSize + 11*maxNbSeq; |
1169 size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize + 11*maxNbSeq; |
980 size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0; |
1170 size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0; |
981 size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0; |
1171 size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0; |
982 size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1); |
1172 size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1); |
983 size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize); |
1173 size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize); |
984 void* ptr; |
1174 void* ptr; /* used to partition workSpace */ |
985 |
1175 |
986 /* Check if workSpace is large enough, alloc a new one if needed */ |
1176 /* Check if workSpace is large enough, alloc a new one if needed */ |
987 { size_t const entropySpace = HUF_WORKSPACE_SIZE; |
1177 { size_t const entropySpace = HUF_WORKSPACE_SIZE; |
988 size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t); |
1178 size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t); |
989 size_t const bufferSpace = buffInSize + buffOutSize; |
1179 size_t const bufferSpace = buffInSize + buffOutSize; |
991 size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq); |
1181 size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq); |
992 |
1182 |
993 size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace + |
1183 size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace + |
994 ldmSeqSpace + matchStateSize + tokenSpace + |
1184 ldmSeqSpace + matchStateSize + tokenSpace + |
995 bufferSpace; |
1185 bufferSpace; |
996 DEBUGLOG(4, "Need %uKB workspace, including %uKB for match state, and %uKB for buffers", |
1186 |
997 (U32)(neededSpace>>10), (U32)(matchStateSize>>10), (U32)(bufferSpace>>10)); |
1187 int const workSpaceTooSmall = zc->workSpaceSize < neededSpace; |
998 DEBUGLOG(4, "windowSize: %u - blockSize: %u", (U32)windowSize, (U32)blockSize); |
1188 int const workSpaceTooLarge = zc->workSpaceSize > ZSTD_WORKSPACETOOLARGE_FACTOR * neededSpace; |
999 |
1189 int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION); |
1000 if (zc->workSpaceSize < neededSpace) { /* too small : resize */ |
1190 zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0; |
1001 DEBUGLOG(4, "Need to update workSpaceSize from %uK to %uK", |
1191 |
1002 (unsigned)(zc->workSpaceSize>>10), |
1192 DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers", |
1003 (unsigned)(neededSpace>>10)); |
1193 neededSpace>>10, matchStateSize>>10, bufferSpace>>10); |
1194 DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); |
|
1195 |
|
1196 if (workSpaceTooSmall || workSpaceWasteful) { |
|
1197 DEBUGLOG(4, "Need to resize workSpaceSize from %zuKB to %zuKB", |
|
1198 zc->workSpaceSize >> 10, |
|
1199 neededSpace >> 10); |
|
1004 /* static cctx : no resize, error out */ |
1200 /* static cctx : no resize, error out */ |
1005 if (zc->staticSize) return ERROR(memory_allocation); |
1201 if (zc->staticSize) return ERROR(memory_allocation); |
1006 |
1202 |
1007 zc->workSpaceSize = 0; |
1203 zc->workSpaceSize = 0; |
1008 ZSTD_free(zc->workSpace, zc->customMem); |
1204 ZSTD_free(zc->workSpace, zc->customMem); |
1009 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem); |
1205 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem); |
1010 if (zc->workSpace == NULL) return ERROR(memory_allocation); |
1206 if (zc->workSpace == NULL) return ERROR(memory_allocation); |
1011 zc->workSpaceSize = neededSpace; |
1207 zc->workSpaceSize = neededSpace; |
1012 ptr = zc->workSpace; |
1208 zc->workSpaceOversizedDuration = 0; |
1013 |
1209 |
1014 /* Statically sized space. entropyWorkspace never moves (but prev/next block swap places) */ |
1210 /* Statically sized space. |
1211 * entropyWorkspace never moves, |
|
1212 * though prev/next block swap places */ |
|
1015 assert(((size_t)zc->workSpace & 3) == 0); /* ensure correct alignment */ |
1213 assert(((size_t)zc->workSpace & 3) == 0); /* ensure correct alignment */ |
1016 assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t)); |
1214 assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t)); |
1017 zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace; |
1215 zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace; |
1018 zc->blockState.nextCBlock = zc->blockState.prevCBlock + 1; |
1216 zc->blockState.nextCBlock = zc->blockState.prevCBlock + 1; |
1019 ptr = zc->blockState.nextCBlock + 1; |
1217 ptr = zc->blockState.nextCBlock + 1; |
1020 zc->entropyWorkspace = (U32*)ptr; |
1218 zc->entropyWorkspace = (U32*)ptr; |
1021 } } |
1219 } } |
1022 |
1220 |
1023 /* init params */ |
1221 /* init params */ |
1024 zc->appliedParams = params; |
1222 zc->appliedParams = params; |
1223 zc->blockState.matchState.cParams = params.cParams; |
|
1025 zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; |
1224 zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; |
1026 zc->consumedSrcSize = 0; |
1225 zc->consumedSrcSize = 0; |
1027 zc->producedCSize = 0; |
1226 zc->producedCSize = 0; |
1028 if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) |
1227 if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) |
1029 zc->appliedParams.fParams.contentSizeFlag = 0; |
1228 zc->appliedParams.fParams.contentSizeFlag = 0; |
1056 assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */ |
1255 assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */ |
1057 |
1256 |
1058 ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, ¶ms.cParams, crp, /* forCCtx */ 1); |
1257 ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, ¶ms.cParams, crp, /* forCCtx */ 1); |
1059 |
1258 |
1060 /* sequences storage */ |
1259 /* sequences storage */ |
1260 zc->seqStore.maxNbSeq = maxNbSeq; |
|
1061 zc->seqStore.sequencesStart = (seqDef*)ptr; |
1261 zc->seqStore.sequencesStart = (seqDef*)ptr; |
1062 ptr = zc->seqStore.sequencesStart + maxNbSeq; |
1262 ptr = zc->seqStore.sequencesStart + maxNbSeq; |
1063 zc->seqStore.llCode = (BYTE*) ptr; |
1263 zc->seqStore.llCode = (BYTE*) ptr; |
1064 zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq; |
1264 zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq; |
1065 zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq; |
1265 zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq; |
1066 zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq; |
1266 zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq; |
1067 ptr = zc->seqStore.litStart + blockSize; |
1267 /* ZSTD_wildcopy() is used to copy into the literals buffer, |
1268 * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes. |
|
1269 */ |
|
1270 zc->seqStore.maxNbLit = blockSize; |
|
1271 ptr = zc->seqStore.litStart + blockSize + WILDCOPY_OVERLENGTH; |
|
1068 |
1272 |
1069 /* ldm bucketOffsets table */ |
1273 /* ldm bucketOffsets table */ |
1070 if (params.ldmParams.enableLdm) { |
1274 if (params.ldmParams.enableLdm) { |
1071 size_t const ldmBucketSize = |
1275 size_t const ldmBucketSize = |
1072 ((size_t)1) << (params.ldmParams.hashLog - |
1276 ((size_t)1) << (params.ldmParams.hashLog - |
1096 int i; |
1300 int i; |
1097 for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0; |
1301 for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0; |
1098 assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); |
1302 assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); |
1099 } |
1303 } |
1100 |
1304 |
1101 static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, |
1305 /* These are the approximate sizes for each strategy past which copying the |
1306 * dictionary tables into the working context is faster than using them |
|
1307 * in-place. |
|
1308 */ |
|
1309 static const size_t attachDictSizeCutoffs[(unsigned)ZSTD_btultra+1] = { |
|
1310 8 KB, /* unused */ |
|
1311 8 KB, /* ZSTD_fast */ |
|
1312 16 KB, /* ZSTD_dfast */ |
|
1313 32 KB, /* ZSTD_greedy */ |
|
1314 32 KB, /* ZSTD_lazy */ |
|
1315 32 KB, /* ZSTD_lazy2 */ |
|
1316 32 KB, /* ZSTD_btlazy2 */ |
|
1317 32 KB, /* ZSTD_btopt */ |
|
1318 8 KB /* ZSTD_btultra */ |
|
1319 }; |
|
1320 |
|
1321 static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict, |
|
1322 ZSTD_CCtx_params params, |
|
1323 U64 pledgedSrcSize) |
|
1324 { |
|
1325 size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy]; |
|
1326 return ( pledgedSrcSize <= cutoff |
|
1327 || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN |
|
1328 || params.attachDictPref == ZSTD_dictForceAttach ) |
|
1329 && params.attachDictPref != ZSTD_dictForceCopy |
|
1330 && !params.forceWindow; /* dictMatchState isn't correctly |
|
1331 * handled in _enforceMaxDist */ |
|
1332 } |
|
1333 |
|
1334 static size_t ZSTD_resetCCtx_byAttachingCDict( |
|
1335 ZSTD_CCtx* cctx, |
|
1336 const ZSTD_CDict* cdict, |
|
1337 ZSTD_CCtx_params params, |
|
1338 U64 pledgedSrcSize, |
|
1339 ZSTD_buffered_policy_e zbuff) |
|
1340 { |
|
1341 { |
|
1342 const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; |
|
1343 unsigned const windowLog = params.cParams.windowLog; |
|
1344 assert(windowLog != 0); |
|
1345 /* Resize working context table params for input only, since the dict |
|
1346 * has its own tables. */ |
|
1347 params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0); |
|
1348 params.cParams.windowLog = windowLog; |
|
1349 ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, |
|
1350 ZSTDcrp_continue, zbuff); |
|
1351 assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); |
|
1352 } |
|
1353 |
|
1354 { |
|
1355 const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc |
|
1356 - cdict->matchState.window.base); |
|
1357 const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit; |
|
1358 if (cdictLen == 0) { |
|
1359 /* don't even attach dictionaries with no contents */ |
|
1360 DEBUGLOG(4, "skipping attaching empty dictionary"); |
|
1361 } else { |
|
1362 DEBUGLOG(4, "attaching dictionary into context"); |
|
1363 cctx->blockState.matchState.dictMatchState = &cdict->matchState; |
|
1364 |
|
1365 /* prep working match state so dict matches never have negative indices |
|
1366 * when they are translated to the working context's index space. */ |
|
1367 if (cctx->blockState.matchState.window.dictLimit < cdictEnd) { |
|
1368 cctx->blockState.matchState.window.nextSrc = |
|
1369 cctx->blockState.matchState.window.base + cdictEnd; |
|
1370 ZSTD_window_clear(&cctx->blockState.matchState.window); |
|
1371 } |
|
1372 cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit; |
|
1373 } |
|
1374 } |
|
1375 |
|
1376 cctx->dictID = cdict->dictID; |
|
1377 |
|
1378 /* copy block state */ |
|
1379 memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); |
|
1380 |
|
1381 return 0; |
|
1382 } |
|
1383 |
|
1384 static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, |
|
1102 const ZSTD_CDict* cdict, |
1385 const ZSTD_CDict* cdict, |
1103 unsigned windowLog, |
1386 ZSTD_CCtx_params params, |
1104 ZSTD_frameParameters fParams, |
|
1105 U64 pledgedSrcSize, |
1387 U64 pledgedSrcSize, |
1106 ZSTD_buffered_policy_e zbuff) |
1388 ZSTD_buffered_policy_e zbuff) |
1107 { |
1389 { |
1108 { ZSTD_CCtx_params params = cctx->requestedParams; |
1390 const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; |
1391 |
|
1392 DEBUGLOG(4, "copying dictionary into context"); |
|
1393 |
|
1394 { unsigned const windowLog = params.cParams.windowLog; |
|
1395 assert(windowLog != 0); |
|
1109 /* Copy only compression parameters related to tables. */ |
1396 /* Copy only compression parameters related to tables. */ |
1110 params.cParams = cdict->cParams; |
1397 params.cParams = *cdict_cParams; |
1111 if (windowLog) params.cParams.windowLog = windowLog; |
1398 params.cParams.windowLog = windowLog; |
1112 params.fParams = fParams; |
|
1113 ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, |
1399 ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, |
1114 ZSTDcrp_noMemset, zbuff); |
1400 ZSTDcrp_noMemset, zbuff); |
1115 assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy); |
1401 assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); |
1116 assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog); |
1402 assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog); |
1117 assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog); |
1403 assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog); |
1118 } |
1404 } |
1119 |
1405 |
1120 /* copy tables */ |
1406 /* copy tables */ |
1121 { size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog); |
1407 { size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog); |
1122 size_t const hSize = (size_t)1 << cdict->cParams.hashLog; |
1408 size_t const hSize = (size_t)1 << cdict_cParams->hashLog; |
1123 size_t const tableSpace = (chainSize + hSize) * sizeof(U32); |
1409 size_t const tableSpace = (chainSize + hSize) * sizeof(U32); |
1124 assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */ |
1410 assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */ |
1125 assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize); |
1411 assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize); |
1126 assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */ |
1412 assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */ |
1127 assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize); |
1413 assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize); |
1128 memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */ |
1414 memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */ |
1129 } |
1415 } |
1416 |
|
1130 /* Zero the hashTable3, since the cdict never fills it */ |
1417 /* Zero the hashTable3, since the cdict never fills it */ |
1131 { size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3; |
1418 { size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3; |
1132 assert(cdict->matchState.hashLog3 == 0); |
1419 assert(cdict->matchState.hashLog3 == 0); |
1133 memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); |
1420 memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); |
1134 } |
1421 } |
1135 |
1422 |
1136 /* copy dictionary offsets */ |
1423 /* copy dictionary offsets */ |
1137 { |
1424 { ZSTD_matchState_t const* srcMatchState = &cdict->matchState; |
1138 ZSTD_matchState_t const* srcMatchState = &cdict->matchState; |
|
1139 ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState; |
1425 ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState; |
1140 dstMatchState->window = srcMatchState->window; |
1426 dstMatchState->window = srcMatchState->window; |
1141 dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; |
1427 dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; |
1142 dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; |
1428 dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; |
1143 dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; |
1429 dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; |
1144 } |
1430 } |
1431 |
|
1145 cctx->dictID = cdict->dictID; |
1432 cctx->dictID = cdict->dictID; |
1146 |
1433 |
1147 /* copy block state */ |
1434 /* copy block state */ |
1148 memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); |
1435 memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); |
1149 |
1436 |
1150 return 0; |
1437 return 0; |
1438 } |
|
1439 |
|
1440 /* We have a choice between copying the dictionary context into the working |
|
1441 * context, or referencing the dictionary context from the working context |
|
1442 * in-place. We decide here which strategy to use. */ |
|
1443 static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, |
|
1444 const ZSTD_CDict* cdict, |
|
1445 ZSTD_CCtx_params params, |
|
1446 U64 pledgedSrcSize, |
|
1447 ZSTD_buffered_policy_e zbuff) |
|
1448 { |
|
1449 |
|
1450 DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize); |
|
1451 |
|
1452 if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) { |
|
1453 return ZSTD_resetCCtx_byAttachingCDict( |
|
1454 cctx, cdict, params, pledgedSrcSize, zbuff); |
|
1455 } else { |
|
1456 return ZSTD_resetCCtx_byCopyingCDict( |
|
1457 cctx, cdict, params, pledgedSrcSize, zbuff); |
|
1458 } |
|
1151 } |
1459 } |
1152 |
1460 |
1153 /*! ZSTD_copyCCtx_internal() : |
1461 /*! ZSTD_copyCCtx_internal() : |
1154 * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. |
1462 * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. |
1155 * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). |
1463 * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). |
1190 memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, tableSpace); /* presumes all tables follow each other */ |
1498 memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, tableSpace); /* presumes all tables follow each other */ |
1191 } |
1499 } |
1192 |
1500 |
1193 /* copy dictionary offsets */ |
1501 /* copy dictionary offsets */ |
1194 { |
1502 { |
1195 ZSTD_matchState_t const* srcMatchState = &srcCCtx->blockState.matchState; |
1503 const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState; |
1196 ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState; |
1504 ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState; |
1197 dstMatchState->window = srcMatchState->window; |
1505 dstMatchState->window = srcMatchState->window; |
1198 dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; |
1506 dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; |
1199 dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; |
1507 dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; |
1200 dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; |
1508 dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; |
1292 * Block entropic compression |
1600 * Block entropic compression |
1293 *********************************************************/ |
1601 *********************************************************/ |
1294 |
1602 |
1295 /* See doc/zstd_compression_format.md for detailed format description */ |
1603 /* See doc/zstd_compression_format.md for detailed format description */ |
1296 |
1604 |
1297 size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize) |
1605 static size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock) |
1298 { |
1606 { |
1607 U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3); |
|
1299 if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall); |
1608 if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall); |
1609 MEM_writeLE24(dst, cBlockHeader24); |
|
1300 memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); |
1610 memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); |
1301 MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw); |
1611 return ZSTD_blockHeaderSize + srcSize; |
1302 return ZSTD_blockHeaderSize+srcSize; |
1612 } |
1303 } |
|
1304 |
|
1305 |
1613 |
1306 static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize) |
1614 static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize) |
1307 { |
1615 { |
1308 BYTE* const ostart = (BYTE* const)dst; |
1616 BYTE* const ostart = (BYTE* const)dst; |
1309 U32 const flSize = 1 + (srcSize>31) + (srcSize>4095); |
1617 U32 const flSize = 1 + (srcSize>31) + (srcSize>4095); |
1354 ostart[flSize] = *(const BYTE*)src; |
1662 ostart[flSize] = *(const BYTE*)src; |
1355 return flSize+1; |
1663 return flSize+1; |
1356 } |
1664 } |
1357 |
1665 |
1358 |
1666 |
1359 static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; } |
1667 /* ZSTD_minGain() : |
1360 |
1668 * minimum compression required |
1361 static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy, |
1669 * to generate a compress block or a compressed literals section. |
1362 ZSTD_entropyCTables_t* nextEntropy, |
1670 * note : use same formula for both situations */ |
1671 static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat) |
|
1672 { |
|
1673 U32 const minlog = (strat==ZSTD_btultra) ? 7 : 6; |
|
1674 return (srcSize >> minlog) + 2; |
|
1675 } |
|
1676 |
|
1677 static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, |
|
1678 ZSTD_hufCTables_t* nextHuf, |
|
1363 ZSTD_strategy strategy, int disableLiteralCompression, |
1679 ZSTD_strategy strategy, int disableLiteralCompression, |
1364 void* dst, size_t dstCapacity, |
1680 void* dst, size_t dstCapacity, |
1365 const void* src, size_t srcSize, |
1681 const void* src, size_t srcSize, |
1366 U32* workspace, const int bmi2) |
1682 U32* workspace, const int bmi2) |
1367 { |
1683 { |
1368 size_t const minGain = ZSTD_minGain(srcSize); |
1684 size_t const minGain = ZSTD_minGain(srcSize, strategy); |
1369 size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); |
1685 size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); |
1370 BYTE* const ostart = (BYTE*)dst; |
1686 BYTE* const ostart = (BYTE*)dst; |
1371 U32 singleStream = srcSize < 256; |
1687 U32 singleStream = srcSize < 256; |
1372 symbolEncodingType_e hType = set_compressed; |
1688 symbolEncodingType_e hType = set_compressed; |
1373 size_t cLitSize; |
1689 size_t cLitSize; |
1374 |
1690 |
1375 DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)", |
1691 DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)", |
1376 disableLiteralCompression); |
1692 disableLiteralCompression); |
1377 |
1693 |
1378 /* Prepare nextEntropy assuming reusing the existing table */ |
1694 /* Prepare nextEntropy assuming reusing the existing table */ |
1379 nextEntropy->hufCTable_repeatMode = prevEntropy->hufCTable_repeatMode; |
1695 memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); |
1380 memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, |
|
1381 sizeof(prevEntropy->hufCTable)); |
|
1382 |
1696 |
1383 if (disableLiteralCompression) |
1697 if (disableLiteralCompression) |
1384 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); |
1698 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); |
1385 |
1699 |
1386 /* small ? don't even attempt compression (speed opt) */ |
1700 /* small ? don't even attempt compression (speed opt) */ |
1387 # define COMPRESS_LITERALS_SIZE_MIN 63 |
1701 # define COMPRESS_LITERALS_SIZE_MIN 63 |
1388 { size_t const minLitSize = (prevEntropy->hufCTable_repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; |
1702 { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; |
1389 if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); |
1703 if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); |
1390 } |
1704 } |
1391 |
1705 |
1392 if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */ |
1706 if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */ |
1393 { HUF_repeat repeat = prevEntropy->hufCTable_repeatMode; |
1707 { HUF_repeat repeat = prevHuf->repeatMode; |
1394 int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0; |
1708 int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0; |
1395 if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; |
1709 if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; |
1396 cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, |
1710 cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, |
1397 workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextEntropy->hufCTable, &repeat, preferRepeat, bmi2) |
1711 workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) |
1398 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, |
1712 : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, |
1399 workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextEntropy->hufCTable, &repeat, preferRepeat, bmi2); |
1713 workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2); |
1400 if (repeat != HUF_repeat_none) { |
1714 if (repeat != HUF_repeat_none) { |
1401 /* reused the existing table */ |
1715 /* reused the existing table */ |
1402 hType = set_repeat; |
1716 hType = set_repeat; |
1403 } |
1717 } |
1404 } |
1718 } |
1405 |
1719 |
1406 if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) { |
1720 if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) { |
1407 memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, sizeof(prevEntropy->hufCTable)); |
1721 memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); |
1408 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); |
1722 return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); |
1409 } |
1723 } |
1410 if (cLitSize==1) { |
1724 if (cLitSize==1) { |
1411 memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, sizeof(prevEntropy->hufCTable)); |
1725 memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); |
1412 return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); |
1726 return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); |
1413 } |
1727 } |
1414 |
1728 |
1415 if (hType == set_compressed) { |
1729 if (hType == set_compressed) { |
1416 /* using a newly constructed table */ |
1730 /* using a newly constructed table */ |
1417 nextEntropy->hufCTable_repeatMode = HUF_repeat_check; |
1731 nextHuf->repeatMode = HUF_repeat_check; |
1418 } |
1732 } |
1419 |
1733 |
1420 /* Build header */ |
1734 /* Build header */ |
1421 switch(lhSize) |
1735 switch(lhSize) |
1422 { |
1736 { |
1449 BYTE* const llCodeTable = seqStorePtr->llCode; |
1763 BYTE* const llCodeTable = seqStorePtr->llCode; |
1450 BYTE* const ofCodeTable = seqStorePtr->ofCode; |
1764 BYTE* const ofCodeTable = seqStorePtr->ofCode; |
1451 BYTE* const mlCodeTable = seqStorePtr->mlCode; |
1765 BYTE* const mlCodeTable = seqStorePtr->mlCode; |
1452 U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); |
1766 U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); |
1453 U32 u; |
1767 U32 u; |
1768 assert(nbSeq <= seqStorePtr->maxNbSeq); |
|
1454 for (u=0; u<nbSeq; u++) { |
1769 for (u=0; u<nbSeq; u++) { |
1455 U32 const llv = sequences[u].litLength; |
1770 U32 const llv = sequences[u].litLength; |
1456 U32 const mlv = sequences[u].matchLength; |
1771 U32 const mlv = sequences[u].matchLength; |
1457 llCodeTable[u] = (BYTE)ZSTD_LLcode(llv); |
1772 llCodeTable[u] = (BYTE)ZSTD_LLcode(llv); |
1458 ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset); |
1773 ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset); |
1462 llCodeTable[seqStorePtr->longLengthPos] = MaxLL; |
1777 llCodeTable[seqStorePtr->longLengthPos] = MaxLL; |
1463 if (seqStorePtr->longLengthID==2) |
1778 if (seqStorePtr->longLengthID==2) |
1464 mlCodeTable[seqStorePtr->longLengthPos] = MaxML; |
1779 mlCodeTable[seqStorePtr->longLengthPos] = MaxML; |
1465 } |
1780 } |
1466 |
1781 |
1782 |
|
1783 /** |
|
1784 * -log2(x / 256) lookup table for x in [0, 256). |
|
1785 * If x == 0: Return 0 |
|
1786 * Else: Return floor(-log2(x / 256) * 256) |
|
1787 */ |
|
1788 static unsigned const kInverseProbabiltyLog256[256] = { |
|
1789 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162, |
|
1790 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889, |
|
1791 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734, |
|
1792 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626, |
|
1793 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542, |
|
1794 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473, |
|
1795 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415, |
|
1796 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366, |
|
1797 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322, |
|
1798 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282, |
|
1799 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247, |
|
1800 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215, |
|
1801 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185, |
|
1802 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157, |
|
1803 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132, |
|
1804 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108, |
|
1805 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85, |
|
1806 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64, |
|
1807 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44, |
|
1808 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25, |
|
1809 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7, |
|
1810 5, 4, 2, 1, |
|
1811 }; |
|
1812 |
|
1813 |
|
1814 /** |
|
1815 * Returns the cost in bits of encoding the distribution described by count |
|
1816 * using the entropy bound. |
|
1817 */ |
|
1818 static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total) |
|
1819 { |
|
1820 unsigned cost = 0; |
|
1821 unsigned s; |
|
1822 for (s = 0; s <= max; ++s) { |
|
1823 unsigned norm = (unsigned)((256 * count[s]) / total); |
|
1824 if (count[s] != 0 && norm == 0) |
|
1825 norm = 1; |
|
1826 assert(count[s] < total); |
|
1827 cost += count[s] * kInverseProbabiltyLog256[norm]; |
|
1828 } |
|
1829 return cost >> 8; |
|
1830 } |
|
1831 |
|
1832 |
|
1833 /** |
|
1834 * Returns the cost in bits of encoding the distribution in count using the |
|
1835 * table described by norm. The max symbol support by norm is assumed >= max. |
|
1836 * norm must be valid for every symbol with non-zero probability in count. |
|
1837 */ |
|
1838 static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, |
|
1839 unsigned const* count, unsigned const max) |
|
1840 { |
|
1841 unsigned const shift = 8 - accuracyLog; |
|
1842 size_t cost = 0; |
|
1843 unsigned s; |
|
1844 assert(accuracyLog <= 8); |
|
1845 for (s = 0; s <= max; ++s) { |
|
1846 unsigned const normAcc = norm[s] != -1 ? norm[s] : 1; |
|
1847 unsigned const norm256 = normAcc << shift; |
|
1848 assert(norm256 > 0); |
|
1849 assert(norm256 < 256); |
|
1850 cost += count[s] * kInverseProbabiltyLog256[norm256]; |
|
1851 } |
|
1852 return cost >> 8; |
|
1853 } |
|
1854 |
|
1855 |
|
1856 static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) { |
|
1857 void const* ptr = ctable; |
|
1858 U16 const* u16ptr = (U16 const*)ptr; |
|
1859 U32 const maxSymbolValue = MEM_read16(u16ptr + 1); |
|
1860 return maxSymbolValue; |
|
1861 } |
|
1862 |
|
1863 |
|
1864 /** |
|
1865 * Returns the cost in bits of encoding the distribution in count using ctable. |
|
1866 * Returns an error if ctable cannot represent all the symbols in count. |
|
1867 */ |
|
1868 static size_t ZSTD_fseBitCost( |
|
1869 FSE_CTable const* ctable, |
|
1870 unsigned const* count, |
|
1871 unsigned const max) |
|
1872 { |
|
1873 unsigned const kAccuracyLog = 8; |
|
1874 size_t cost = 0; |
|
1875 unsigned s; |
|
1876 FSE_CState_t cstate; |
|
1877 FSE_initCState(&cstate, ctable); |
|
1878 if (ZSTD_getFSEMaxSymbolValue(ctable) < max) { |
|
1879 DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u", |
|
1880 ZSTD_getFSEMaxSymbolValue(ctable), max); |
|
1881 return ERROR(GENERIC); |
|
1882 } |
|
1883 for (s = 0; s <= max; ++s) { |
|
1884 unsigned const tableLog = cstate.stateLog; |
|
1885 unsigned const badCost = (tableLog + 1) << kAccuracyLog; |
|
1886 unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog); |
|
1887 if (count[s] == 0) |
|
1888 continue; |
|
1889 if (bitCost >= badCost) { |
|
1890 DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s); |
|
1891 return ERROR(GENERIC); |
|
1892 } |
|
1893 cost += count[s] * bitCost; |
|
1894 } |
|
1895 return cost >> kAccuracyLog; |
|
1896 } |
|
1897 |
|
1898 /** |
|
1899 * Returns the cost in bytes of encoding the normalized count header. |
|
1900 * Returns an error if any of the helper functions return an error. |
|
1901 */ |
|
1902 static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max, |
|
1903 size_t const nbSeq, unsigned const FSELog) |
|
1904 { |
|
1905 BYTE wksp[FSE_NCOUNTBOUND]; |
|
1906 S16 norm[MaxSeq + 1]; |
|
1907 const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); |
|
1908 CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq, max)); |
|
1909 return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog); |
|
1910 } |
|
1911 |
|
1912 |
|
1467 typedef enum { |
1913 typedef enum { |
1468 ZSTD_defaultDisallowed = 0, |
1914 ZSTD_defaultDisallowed = 0, |
1469 ZSTD_defaultAllowed = 1 |
1915 ZSTD_defaultAllowed = 1 |
1470 } ZSTD_defaultPolicy_e; |
1916 } ZSTD_defaultPolicy_e; |
1471 |
1917 |
1472 MEM_STATIC |
1918 MEM_STATIC symbolEncodingType_e |
1473 symbolEncodingType_e ZSTD_selectEncodingType( |
1919 ZSTD_selectEncodingType( |
1474 FSE_repeat* repeatMode, size_t const mostFrequent, size_t nbSeq, |
1920 FSE_repeat* repeatMode, unsigned const* count, unsigned const max, |
1475 U32 defaultNormLog, ZSTD_defaultPolicy_e const isDefaultAllowed) |
1921 size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, |
1476 { |
1922 FSE_CTable const* prevCTable, |
1477 #define MIN_SEQ_FOR_DYNAMIC_FSE 64 |
1923 short const* defaultNorm, U32 defaultNormLog, |
1478 #define MAX_SEQ_FOR_STATIC_FSE 1000 |
1924 ZSTD_defaultPolicy_e const isDefaultAllowed, |
1925 ZSTD_strategy const strategy) |
|
1926 { |
|
1479 ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0); |
1927 ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0); |
1480 if ((mostFrequent == nbSeq) && (!isDefaultAllowed || nbSeq > 2)) { |
1928 if (mostFrequent == nbSeq) { |
1929 *repeatMode = FSE_repeat_none; |
|
1930 if (isDefaultAllowed && nbSeq <= 2) { |
|
1931 /* Prefer set_basic over set_rle when there are 2 or less symbols, |
|
1932 * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol. |
|
1933 * If basic encoding isn't possible, always choose RLE. |
|
1934 */ |
|
1935 DEBUGLOG(5, "Selected set_basic"); |
|
1936 return set_basic; |
|
1937 } |
|
1481 DEBUGLOG(5, "Selected set_rle"); |
1938 DEBUGLOG(5, "Selected set_rle"); |
1482 /* Prefer set_basic over set_rle when there are 2 or less symbols, |
|
1483 * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol. |
|
1484 * If basic encoding isn't possible, always choose RLE. |
|
1485 */ |
|
1486 *repeatMode = FSE_repeat_check; |
|
1487 return set_rle; |
1939 return set_rle; |
1488 } |
1940 } |
1489 if ( isDefaultAllowed |
1941 if (strategy < ZSTD_lazy) { |
1490 && (*repeatMode == FSE_repeat_valid) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { |
1942 if (isDefaultAllowed) { |
1491 DEBUGLOG(5, "Selected set_repeat"); |
1943 size_t const staticFse_nbSeq_max = 1000; |
1492 return set_repeat; |
1944 size_t const mult = 10 - strategy; |
1493 } |
1945 size_t const baseLog = 3; |
1494 if ( isDefaultAllowed |
1946 size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */ |
1495 && ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (defaultNormLog-1)))) ) { |
1947 assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */ |
1496 DEBUGLOG(5, "Selected set_basic"); |
1948 assert(mult <= 9 && mult >= 7); |
1497 /* The format allows default tables to be repeated, but it isn't useful. |
1949 if ( (*repeatMode == FSE_repeat_valid) |
1498 * When using simple heuristics to select encoding type, we don't want |
1950 && (nbSeq < staticFse_nbSeq_max) ) { |
1499 * to confuse these tables with dictionaries. When running more careful |
1951 DEBUGLOG(5, "Selected set_repeat"); |
1500 * analysis, we don't need to waste time checking both repeating tables |
1952 return set_repeat; |
1501 * and default tables. |
1953 } |
1502 */ |
1954 if ( (nbSeq < dynamicFse_nbSeq_min) |
1503 *repeatMode = FSE_repeat_none; |
1955 || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) { |
1504 return set_basic; |
1956 DEBUGLOG(5, "Selected set_basic"); |
1957 /* The format allows default tables to be repeated, but it isn't useful. |
|
1958 * When using simple heuristics to select encoding type, we don't want |
|
1959 * to confuse these tables with dictionaries. When running more careful |
|
1960 * analysis, we don't need to waste time checking both repeating tables |
|
1961 * and default tables. |
|
1962 */ |
|
1963 *repeatMode = FSE_repeat_none; |
|
1964 return set_basic; |
|
1965 } |
|
1966 } |
|
1967 } else { |
|
1968 size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC); |
|
1969 size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC); |
|
1970 size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog); |
|
1971 size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq); |
|
1972 |
|
1973 if (isDefaultAllowed) { |
|
1974 assert(!ZSTD_isError(basicCost)); |
|
1975 assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost))); |
|
1976 } |
|
1977 assert(!ZSTD_isError(NCountCost)); |
|
1978 assert(compressedCost < ERROR(maxCode)); |
|
1979 DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u", |
|
1980 (U32)basicCost, (U32)repeatCost, (U32)compressedCost); |
|
1981 if (basicCost <= repeatCost && basicCost <= compressedCost) { |
|
1982 DEBUGLOG(5, "Selected set_basic"); |
|
1983 assert(isDefaultAllowed); |
|
1984 *repeatMode = FSE_repeat_none; |
|
1985 return set_basic; |
|
1986 } |
|
1987 if (repeatCost <= compressedCost) { |
|
1988 DEBUGLOG(5, "Selected set_repeat"); |
|
1989 assert(!ZSTD_isError(repeatCost)); |
|
1990 return set_repeat; |
|
1991 } |
|
1992 assert(compressedCost < basicCost && compressedCost < repeatCost); |
|
1505 } |
1993 } |
1506 DEBUGLOG(5, "Selected set_compressed"); |
1994 DEBUGLOG(5, "Selected set_compressed"); |
1507 *repeatMode = FSE_repeat_check; |
1995 *repeatMode = FSE_repeat_check; |
1508 return set_compressed; |
1996 return set_compressed; |
1509 } |
1997 } |
1510 |
1998 |
1511 MEM_STATIC |
1999 MEM_STATIC size_t |
1512 size_t ZSTD_buildCTable(void* dst, size_t dstCapacity, |
2000 ZSTD_buildCTable(void* dst, size_t dstCapacity, |
1513 FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type, |
2001 FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type, |
1514 U32* count, U32 max, |
2002 U32* count, U32 max, |
1515 BYTE const* codeTable, size_t nbSeq, |
2003 const BYTE* codeTable, size_t nbSeq, |
1516 S16 const* defaultNorm, U32 defaultNormLog, U32 defaultMax, |
2004 const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, |
1517 FSE_CTable const* prevCTable, size_t prevCTableSize, |
2005 const FSE_CTable* prevCTable, size_t prevCTableSize, |
1518 void* workspace, size_t workspaceSize) |
2006 void* workspace, size_t workspaceSize) |
1519 { |
2007 { |
1520 BYTE* op = (BYTE*)dst; |
2008 BYTE* op = (BYTE*)dst; |
1521 BYTE const* const oend = op + dstCapacity; |
2009 const BYTE* const oend = op + dstCapacity; |
1522 |
2010 |
1523 switch (type) { |
2011 switch (type) { |
1524 case set_rle: |
2012 case set_rle: |
1525 *op = codeTable[0]; |
2013 *op = codeTable[0]; |
1526 CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max)); |
2014 CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max)); |
1672 sequences, nbSeq, longOffsets); |
2160 sequences, nbSeq, longOffsets); |
1673 } |
2161 } |
1674 |
2162 |
1675 #endif |
2163 #endif |
1676 |
2164 |
1677 size_t ZSTD_encodeSequences( |
2165 static size_t ZSTD_encodeSequences( |
1678 void* dst, size_t dstCapacity, |
2166 void* dst, size_t dstCapacity, |
1679 FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, |
2167 FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, |
1680 FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, |
2168 FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, |
1681 FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, |
2169 FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, |
1682 seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2) |
2170 seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2) |
1704 ZSTD_CCtx_params const* cctxParams, |
2192 ZSTD_CCtx_params const* cctxParams, |
1705 void* dst, size_t dstCapacity, U32* workspace, |
2193 void* dst, size_t dstCapacity, U32* workspace, |
1706 const int bmi2) |
2194 const int bmi2) |
1707 { |
2195 { |
1708 const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; |
2196 const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; |
2197 ZSTD_strategy const strategy = cctxParams->cParams.strategy; |
|
1709 U32 count[MaxSeq+1]; |
2198 U32 count[MaxSeq+1]; |
1710 FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable; |
2199 FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable; |
1711 FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable; |
2200 FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; |
1712 FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable; |
2201 FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; |
1713 U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */ |
2202 U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */ |
1714 const seqDef* const sequences = seqStorePtr->sequencesStart; |
2203 const seqDef* const sequences = seqStorePtr->sequencesStart; |
1715 const BYTE* const ofCodeTable = seqStorePtr->ofCode; |
2204 const BYTE* const ofCodeTable = seqStorePtr->ofCode; |
1716 const BYTE* const llCodeTable = seqStorePtr->llCode; |
2205 const BYTE* const llCodeTable = seqStorePtr->llCode; |
1717 const BYTE* const mlCodeTable = seqStorePtr->mlCode; |
2206 const BYTE* const mlCodeTable = seqStorePtr->mlCode; |
1718 BYTE* const ostart = (BYTE*)dst; |
2207 BYTE* const ostart = (BYTE*)dst; |
1719 BYTE* const oend = ostart + dstCapacity; |
2208 BYTE* const oend = ostart + dstCapacity; |
1720 BYTE* op = ostart; |
2209 BYTE* op = ostart; |
1721 size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; |
2210 size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; |
1722 BYTE* seqHead; |
2211 BYTE* seqHead; |
2212 BYTE* lastNCount = NULL; |
|
1723 |
2213 |
1724 ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); |
2214 ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); |
1725 |
2215 |
1726 /* Compress literals */ |
2216 /* Compress literals */ |
1727 { const BYTE* const literals = seqStorePtr->litStart; |
2217 { const BYTE* const literals = seqStorePtr->litStart; |
1728 size_t const litSize = seqStorePtr->lit - literals; |
2218 size_t const litSize = seqStorePtr->lit - literals; |
2219 int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); |
|
1729 size_t const cSize = ZSTD_compressLiterals( |
2220 size_t const cSize = ZSTD_compressLiterals( |
1730 prevEntropy, nextEntropy, |
2221 &prevEntropy->huf, &nextEntropy->huf, |
1731 cctxParams->cParams.strategy, cctxParams->disableLiteralCompression, |
2222 cctxParams->cParams.strategy, disableLiteralCompression, |
1732 op, dstCapacity, |
2223 op, dstCapacity, |
1733 literals, litSize, |
2224 literals, litSize, |
1734 workspace, bmi2); |
2225 workspace, bmi2); |
1735 if (ZSTD_isError(cSize)) |
2226 if (ZSTD_isError(cSize)) |
1736 return cSize; |
2227 return cSize; |
1745 else if (nbSeq < LONGNBSEQ) |
2236 else if (nbSeq < LONGNBSEQ) |
1746 op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; |
2237 op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; |
1747 else |
2238 else |
1748 op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; |
2239 op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; |
1749 if (nbSeq==0) { |
2240 if (nbSeq==0) { |
1750 memcpy(nextEntropy->litlengthCTable, prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable)); |
2241 /* Copy the old tables over as if we repeated them */ |
1751 nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode; |
2242 memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); |
1752 memcpy(nextEntropy->offcodeCTable, prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable)); |
2243 return op - ostart; |
1753 nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode; |
|
1754 memcpy(nextEntropy->matchlengthCTable, prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable)); |
|
1755 nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode; |
|
1756 return op - ostart; |
|
1757 } |
2244 } |
1758 |
2245 |
1759 /* seqHead : flags for FSE encoding type */ |
2246 /* seqHead : flags for FSE encoding type */ |
1760 seqHead = op++; |
2247 seqHead = op++; |
1761 |
2248 |
1762 /* convert length/distances into codes */ |
2249 /* convert length/distances into codes */ |
1763 ZSTD_seqToCodes(seqStorePtr); |
2250 ZSTD_seqToCodes(seqStorePtr); |
1764 /* build CTable for Literal Lengths */ |
2251 /* build CTable for Literal Lengths */ |
1765 { U32 max = MaxLL; |
2252 { U32 max = MaxLL; |
1766 size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); |
2253 size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); /* can't fail */ |
1767 DEBUGLOG(5, "Building LL table"); |
2254 DEBUGLOG(5, "Building LL table"); |
1768 nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode; |
2255 nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode; |
1769 LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, mostFrequent, nbSeq, LL_defaultNormLog, ZSTD_defaultAllowed); |
2256 LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy); |
2257 assert(set_basic < set_compressed && set_rle < set_compressed); |
|
2258 assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ |
|
1770 { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype, |
2259 { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype, |
1771 count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL, |
2260 count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL, |
1772 prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable), |
2261 prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable), |
1773 workspace, HUF_WORKSPACE_SIZE); |
2262 workspace, HUF_WORKSPACE_SIZE); |
1774 if (ZSTD_isError(countSize)) return countSize; |
2263 if (ZSTD_isError(countSize)) return countSize; |
2264 if (LLtype == set_compressed) |
|
2265 lastNCount = op; |
|
1775 op += countSize; |
2266 op += countSize; |
1776 } } |
2267 } } |
1777 /* build CTable for Offsets */ |
2268 /* build CTable for Offsets */ |
1778 { U32 max = MaxOff; |
2269 { U32 max = MaxOff; |
1779 size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); |
2270 size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); /* can't fail */ |
1780 /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */ |
2271 /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */ |
1781 ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed; |
2272 ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed; |
1782 DEBUGLOG(5, "Building OF table"); |
2273 DEBUGLOG(5, "Building OF table"); |
1783 nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode; |
2274 nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode; |
1784 Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, mostFrequent, nbSeq, OF_defaultNormLog, defaultPolicy); |
2275 Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode, count, max, mostFrequent, nbSeq, OffFSELog, prevEntropy->fse.offcodeCTable, OF_defaultNorm, OF_defaultNormLog, defaultPolicy, strategy); |
2276 assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */ |
|
1785 { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype, |
2277 { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype, |
1786 count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, |
2278 count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, |
1787 prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable), |
2279 prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable), |
1788 workspace, HUF_WORKSPACE_SIZE); |
2280 workspace, HUF_WORKSPACE_SIZE); |
1789 if (ZSTD_isError(countSize)) return countSize; |
2281 if (ZSTD_isError(countSize)) return countSize; |
2282 if (Offtype == set_compressed) |
|
2283 lastNCount = op; |
|
1790 op += countSize; |
2284 op += countSize; |
1791 } } |
2285 } } |
1792 /* build CTable for MatchLengths */ |
2286 /* build CTable for MatchLengths */ |
1793 { U32 max = MaxML; |
2287 { U32 max = MaxML; |
1794 size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); |
2288 size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); /* can't fail */ |
1795 DEBUGLOG(5, "Building ML table"); |
2289 DEBUGLOG(5, "Building ML table"); |
1796 nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode; |
2290 nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode; |
1797 MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, mostFrequent, nbSeq, ML_defaultNormLog, ZSTD_defaultAllowed); |
2291 MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy); |
2292 assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ |
|
1798 { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype, |
2293 { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype, |
1799 count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML, |
2294 count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML, |
1800 prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable), |
2295 prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable), |
1801 workspace, HUF_WORKSPACE_SIZE); |
2296 workspace, HUF_WORKSPACE_SIZE); |
1802 if (ZSTD_isError(countSize)) return countSize; |
2297 if (ZSTD_isError(countSize)) return countSize; |
2298 if (MLtype == set_compressed) |
|
2299 lastNCount = op; |
|
1803 op += countSize; |
2300 op += countSize; |
1804 } } |
2301 } } |
1805 |
2302 |
1806 *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); |
2303 *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); |
1807 |
2304 |
1812 CTable_LitLength, llCodeTable, |
2309 CTable_LitLength, llCodeTable, |
1813 sequences, nbSeq, |
2310 sequences, nbSeq, |
1814 longOffsets, bmi2); |
2311 longOffsets, bmi2); |
1815 if (ZSTD_isError(bitstreamSize)) return bitstreamSize; |
2312 if (ZSTD_isError(bitstreamSize)) return bitstreamSize; |
1816 op += bitstreamSize; |
2313 op += bitstreamSize; |
2314 /* zstd versions <= 1.3.4 mistakenly report corruption when |
|
2315 * FSE_readNCount() recieves a buffer < 4 bytes. |
|
2316 * Fixed by https://github.com/facebook/zstd/pull/1146. |
|
2317 * This can happen when the last set_compressed table present is 2 |
|
2318 * bytes and the bitstream is only one byte. |
|
2319 * In this exceedingly rare case, we will simply emit an uncompressed |
|
2320 * block, since it isn't worth optimizing. |
|
2321 */ |
|
2322 if (lastNCount && (op - lastNCount) < 4) { |
|
2323 /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ |
|
2324 assert(op - lastNCount == 3); |
|
2325 DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " |
|
2326 "emitting an uncompressed block."); |
|
2327 return 0; |
|
2328 } |
|
1817 } |
2329 } |
1818 |
2330 |
1819 return op - ostart; |
2331 return op - ostart; |
1820 } |
2332 } |
1821 |
2333 |
1822 MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr, |
2334 MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr, |
1823 ZSTD_entropyCTables_t const* prevEntropy, |
2335 const ZSTD_entropyCTables_t* prevEntropy, |
1824 ZSTD_entropyCTables_t* nextEntropy, |
2336 ZSTD_entropyCTables_t* nextEntropy, |
1825 ZSTD_CCtx_params const* cctxParams, |
2337 const ZSTD_CCtx_params* cctxParams, |
1826 void* dst, size_t dstCapacity, |
2338 void* dst, size_t dstCapacity, |
1827 size_t srcSize, U32* workspace, int bmi2) |
2339 size_t srcSize, U32* workspace, int bmi2) |
1828 { |
2340 { |
1829 size_t const cSize = ZSTD_compressSequences_internal( |
2341 size_t const cSize = ZSTD_compressSequences_internal( |
1830 seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity, |
2342 seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity, |
1831 workspace, bmi2); |
2343 workspace, bmi2); |
2344 if (cSize == 0) return 0; |
|
1832 /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block. |
2345 /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block. |
1833 * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block. |
2346 * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block. |
1834 */ |
2347 */ |
1835 if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity)) |
2348 if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity)) |
1836 return 0; /* block not compressed */ |
2349 return 0; /* block not compressed */ |
1837 if (ZSTD_isError(cSize)) return cSize; |
2350 if (ZSTD_isError(cSize)) return cSize; |
1838 |
2351 |
1839 /* Check compressibility */ |
2352 /* Check compressibility */ |
1840 { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize); /* note : fixed formula, maybe should depend on compression level, or strategy */ |
2353 { size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy); |
1841 if (cSize >= maxCSize) return 0; /* block not compressed */ |
2354 if (cSize >= maxCSize) return 0; /* block not compressed */ |
1842 } |
2355 } |
1843 |
|
1844 /* We check that dictionaries have offset codes available for the first |
|
1845 * block. After the first block, the offcode table might not have large |
|
1846 * enough codes to represent the offsets in the data. |
|
1847 */ |
|
1848 if (nextEntropy->offcode_repeatMode == FSE_repeat_valid) |
|
1849 nextEntropy->offcode_repeatMode = FSE_repeat_check; |
|
1850 |
2356 |
1851 return cSize; |
2357 return cSize; |
1852 } |
2358 } |
1853 |
2359 |
1854 /* ZSTD_selectBlockCompressor() : |
2360 /* ZSTD_selectBlockCompressor() : |
1855 * Not static, but internal use only (used by long distance matcher) |
2361 * Not static, but internal use only (used by long distance matcher) |
1856 * assumption : strat is a valid strategy */ |
2362 * assumption : strat is a valid strategy */ |
1857 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) |
2363 ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode) |
1858 { |
2364 { |
1859 static const ZSTD_blockCompressor blockCompressor[2][(unsigned)ZSTD_btultra+1] = { |
2365 static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = { |
1860 { ZSTD_compressBlock_fast /* default for 0 */, |
2366 { ZSTD_compressBlock_fast /* default for 0 */, |
1861 ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, |
2367 ZSTD_compressBlock_fast, |
1862 ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, |
2368 ZSTD_compressBlock_doubleFast, |
1863 ZSTD_compressBlock_btopt, ZSTD_compressBlock_btultra }, |
2369 ZSTD_compressBlock_greedy, |
2370 ZSTD_compressBlock_lazy, |
|
2371 ZSTD_compressBlock_lazy2, |
|
2372 ZSTD_compressBlock_btlazy2, |
|
2373 ZSTD_compressBlock_btopt, |
|
2374 ZSTD_compressBlock_btultra }, |
|
1864 { ZSTD_compressBlock_fast_extDict /* default for 0 */, |
2375 { ZSTD_compressBlock_fast_extDict /* default for 0 */, |
1865 ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, |
2376 ZSTD_compressBlock_fast_extDict, |
1866 ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, |
2377 ZSTD_compressBlock_doubleFast_extDict, |
1867 ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict } |
2378 ZSTD_compressBlock_greedy_extDict, |
2379 ZSTD_compressBlock_lazy_extDict, |
|
2380 ZSTD_compressBlock_lazy2_extDict, |
|
2381 ZSTD_compressBlock_btlazy2_extDict, |
|
2382 ZSTD_compressBlock_btopt_extDict, |
|
2383 ZSTD_compressBlock_btultra_extDict }, |
|
2384 { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */, |
|
2385 ZSTD_compressBlock_fast_dictMatchState, |
|
2386 ZSTD_compressBlock_doubleFast_dictMatchState, |
|
2387 ZSTD_compressBlock_greedy_dictMatchState, |
|
2388 ZSTD_compressBlock_lazy_dictMatchState, |
|
2389 ZSTD_compressBlock_lazy2_dictMatchState, |
|
2390 ZSTD_compressBlock_btlazy2_dictMatchState, |
|
2391 ZSTD_compressBlock_btopt_dictMatchState, |
|
2392 ZSTD_compressBlock_btultra_dictMatchState } |
|
1868 }; |
2393 }; |
2394 ZSTD_blockCompressor selectedCompressor; |
|
1869 ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); |
2395 ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); |
1870 |
2396 |
1871 assert((U32)strat >= (U32)ZSTD_fast); |
2397 assert((U32)strat >= (U32)ZSTD_fast); |
1872 assert((U32)strat <= (U32)ZSTD_btultra); |
2398 assert((U32)strat <= (U32)ZSTD_btultra); |
1873 return blockCompressor[extDict!=0][(U32)strat]; |
2399 selectedCompressor = blockCompressor[(int)dictMode][(U32)strat]; |
2400 assert(selectedCompressor != NULL); |
|
2401 return selectedCompressor; |
|
1874 } |
2402 } |
1875 |
2403 |
1876 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr, |
2404 static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr, |
1877 const BYTE* anchor, size_t lastLLSize) |
2405 const BYTE* anchor, size_t lastLLSize) |
1878 { |
2406 { |
1879 memcpy(seqStorePtr->lit, anchor, lastLLSize); |
2407 memcpy(seqStorePtr->lit, anchor, lastLLSize); |
1880 seqStorePtr->lit += lastLLSize; |
2408 seqStorePtr->lit += lastLLSize; |
1881 } |
2409 } |
1882 |
2410 |
1883 static void ZSTD_resetSeqStore(seqStore_t* ssPtr) |
2411 void ZSTD_resetSeqStore(seqStore_t* ssPtr) |
1884 { |
2412 { |
1885 ssPtr->lit = ssPtr->litStart; |
2413 ssPtr->lit = ssPtr->litStart; |
1886 ssPtr->sequences = ssPtr->sequencesStart; |
2414 ssPtr->sequences = ssPtr->sequencesStart; |
1887 ssPtr->longLengthID = 0; |
2415 ssPtr->longLengthID = 0; |
1888 } |
2416 } |
1890 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, |
2418 static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, |
1891 void* dst, size_t dstCapacity, |
2419 void* dst, size_t dstCapacity, |
1892 const void* src, size_t srcSize) |
2420 const void* src, size_t srcSize) |
1893 { |
2421 { |
1894 ZSTD_matchState_t* const ms = &zc->blockState.matchState; |
2422 ZSTD_matchState_t* const ms = &zc->blockState.matchState; |
1895 DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", |
2423 size_t cSize; |
1896 (U32)dstCapacity, ms->window.dictLimit, ms->nextToUpdate); |
2424 DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)", |
2425 dstCapacity, ms->window.dictLimit, ms->nextToUpdate); |
|
2426 assert(srcSize <= ZSTD_BLOCKSIZE_MAX); |
|
2427 |
|
2428 /* Assert that we have correctly flushed the ctx params into the ms's copy */ |
|
2429 ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams); |
|
2430 |
|
1897 if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) { |
2431 if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) { |
1898 ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength); |
2432 ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength); |
1899 return 0; /* don't even attempt compression below a certain srcSize */ |
2433 cSize = 0; |
2434 goto out; /* don't even attempt compression below a certain srcSize */ |
|
1900 } |
2435 } |
1901 ZSTD_resetSeqStore(&(zc->seqStore)); |
2436 ZSTD_resetSeqStore(&(zc->seqStore)); |
2437 ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; /* required for optimal parser to read stats from dictionary */ |
|
2438 |
|
2439 /* a gap between an attached dict and the current window is not safe, |
|
2440 * they must remain adjacent, and when that stops being the case, the dict |
|
2441 * must be unset */ |
|
2442 assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit); |
|
1902 |
2443 |
1903 /* limited update after a very long match */ |
2444 /* limited update after a very long match */ |
1904 { const BYTE* const base = ms->window.base; |
2445 { const BYTE* const base = ms->window.base; |
1905 const BYTE* const istart = (const BYTE*)src; |
2446 const BYTE* const istart = (const BYTE*)src; |
1906 const U32 current = (U32)(istart-base); |
2447 const U32 current = (U32)(istart-base); |
2448 if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */ |
|
1907 if (current > ms->nextToUpdate + 384) |
2449 if (current > ms->nextToUpdate + 384) |
1908 ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384)); |
2450 ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384)); |
1909 } |
2451 } |
1910 |
2452 |
1911 /* select and store sequences */ |
2453 /* select and store sequences */ |
1912 { U32 const extDict = ZSTD_window_hasExtDict(ms->window); |
2454 { ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms); |
1913 size_t lastLLSize; |
2455 size_t lastLLSize; |
1914 { int i; |
2456 { int i; |
1915 for (i = 0; i < ZSTD_REP_NUM; ++i) |
2457 for (i = 0; i < ZSTD_REP_NUM; ++i) |
1916 zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; |
2458 zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; |
1917 } |
2459 } |
1920 /* Updates ldmSeqStore.pos */ |
2462 /* Updates ldmSeqStore.pos */ |
1921 lastLLSize = |
2463 lastLLSize = |
1922 ZSTD_ldm_blockCompress(&zc->externSeqStore, |
2464 ZSTD_ldm_blockCompress(&zc->externSeqStore, |
1923 ms, &zc->seqStore, |
2465 ms, &zc->seqStore, |
1924 zc->blockState.nextCBlock->rep, |
2466 zc->blockState.nextCBlock->rep, |
1925 &zc->appliedParams.cParams, |
2467 src, srcSize); |
1926 src, srcSize, extDict); |
|
1927 assert(zc->externSeqStore.pos <= zc->externSeqStore.size); |
2468 assert(zc->externSeqStore.pos <= zc->externSeqStore.size); |
1928 } else if (zc->appliedParams.ldmParams.enableLdm) { |
2469 } else if (zc->appliedParams.ldmParams.enableLdm) { |
1929 rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0}; |
2470 rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0}; |
1930 |
2471 |
1931 ldmSeqStore.seq = zc->ldmSequences; |
2472 ldmSeqStore.seq = zc->ldmSequences; |
1937 /* Updates ldmSeqStore.pos */ |
2478 /* Updates ldmSeqStore.pos */ |
1938 lastLLSize = |
2479 lastLLSize = |
1939 ZSTD_ldm_blockCompress(&ldmSeqStore, |
2480 ZSTD_ldm_blockCompress(&ldmSeqStore, |
1940 ms, &zc->seqStore, |
2481 ms, &zc->seqStore, |
1941 zc->blockState.nextCBlock->rep, |
2482 zc->blockState.nextCBlock->rep, |
1942 &zc->appliedParams.cParams, |
2483 src, srcSize); |
1943 src, srcSize, extDict); |
|
1944 assert(ldmSeqStore.pos == ldmSeqStore.size); |
2484 assert(ldmSeqStore.pos == ldmSeqStore.size); |
1945 } else { /* not long range mode */ |
2485 } else { /* not long range mode */ |
1946 ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, extDict); |
2486 ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode); |
1947 lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, &zc->appliedParams.cParams, src, srcSize); |
2487 lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); |
1948 } |
2488 } |
1949 { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize; |
2489 { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize; |
1950 ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize); |
2490 ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize); |
1951 } } |
2491 } } |
1952 |
2492 |
1953 /* encode sequences and literals */ |
2493 /* encode sequences and literals */ |
1954 { size_t const cSize = ZSTD_compressSequences(&zc->seqStore, |
2494 cSize = ZSTD_compressSequences(&zc->seqStore, |
1955 &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, |
2495 &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, |
1956 &zc->appliedParams, |
2496 &zc->appliedParams, |
1957 dst, dstCapacity, |
2497 dst, dstCapacity, |
1958 srcSize, zc->entropyWorkspace, zc->bmi2); |
2498 srcSize, zc->entropyWorkspace, zc->bmi2); |
1959 if (ZSTD_isError(cSize) || cSize == 0) return cSize; |
2499 |
1960 /* confirm repcodes and entropy tables */ |
2500 out: |
1961 { ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock; |
2501 if (!ZSTD_isError(cSize) && cSize != 0) { |
1962 zc->blockState.prevCBlock = zc->blockState.nextCBlock; |
2502 /* confirm repcodes and entropy tables when emitting a compressed block */ |
1963 zc->blockState.nextCBlock = tmp; |
2503 ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock; |
1964 } |
2504 zc->blockState.prevCBlock = zc->blockState.nextCBlock; |
1965 return cSize; |
2505 zc->blockState.nextCBlock = tmp; |
1966 } |
2506 } |
2507 /* We check that dictionaries have offset codes available for the first |
|
2508 * block. After the first block, the offcode table might not have large |
|
2509 * enough codes to represent the offsets in the data. |
|
2510 */ |
|
2511 if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) |
|
2512 zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; |
|
2513 |
|
2514 return cSize; |
|
1967 } |
2515 } |
1968 |
2516 |
1969 |
2517 |
1970 /*! ZSTD_compress_frameChunk() : |
2518 /*! ZSTD_compress_frameChunk() : |
1971 * Compress a chunk of data into one or multiple blocks. |
2519 * Compress a chunk of data into one or multiple blocks. |
2003 U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy); |
2551 U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy); |
2004 U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); |
2552 U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); |
2005 ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); |
2553 ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); |
2006 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); |
2554 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); |
2007 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); |
2555 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); |
2008 |
|
2009 ZSTD_reduceIndex(cctx, correction); |
2556 ZSTD_reduceIndex(cctx, correction); |
2010 if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; |
2557 if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; |
2011 else ms->nextToUpdate -= correction; |
2558 else ms->nextToUpdate -= correction; |
2012 ms->loadedDictEnd = 0; |
2559 ms->loadedDictEnd = 0; |
2560 ms->dictMatchState = NULL; |
|
2013 } |
2561 } |
2014 ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd); |
2562 ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); |
2015 if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; |
2563 if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; |
2016 |
2564 |
2017 { size_t cSize = ZSTD_compressBlock_internal(cctx, |
2565 { size_t cSize = ZSTD_compressBlock_internal(cctx, |
2018 op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, |
2566 op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, |
2019 ip, blockSize); |
2567 ip, blockSize); |
2020 if (ZSTD_isError(cSize)) return cSize; |
2568 if (ZSTD_isError(cSize)) return cSize; |
2021 |
2569 |
2022 if (cSize == 0) { /* block is not compressible */ |
2570 if (cSize == 0) { /* block is not compressible */ |
2023 U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3); |
2571 cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); |
2024 if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall); |
2572 if (ZSTD_isError(cSize)) return cSize; |
2025 MEM_writeLE32(op, cBlockHeader24); /* 4th byte will be overwritten */ |
|
2026 memcpy(op + ZSTD_blockHeaderSize, ip, blockSize); |
|
2027 cSize = ZSTD_blockHeaderSize + blockSize; |
|
2028 } else { |
2573 } else { |
2029 U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); |
2574 U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); |
2030 MEM_writeLE24(op, cBlockHeader24); |
2575 MEM_writeLE24(op, cBlockHeader24); |
2031 cSize += ZSTD_blockHeaderSize; |
2576 cSize += ZSTD_blockHeaderSize; |
2032 } |
2577 } |
2058 U32 const fcsCode = params.fParams.contentSizeFlag ? |
2603 U32 const fcsCode = params.fParams.contentSizeFlag ? |
2059 (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */ |
2604 (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */ |
2060 BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) ); |
2605 BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) ); |
2061 size_t pos=0; |
2606 size_t pos=0; |
2062 |
2607 |
2608 assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)); |
|
2063 if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall); |
2609 if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall); |
2064 DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", |
2610 DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", |
2065 !params.fParams.noDictIDFlag, dictID, dictIDSizeCode); |
2611 !params.fParams.noDictIDFlag, dictID, dictIDSizeCode); |
2066 |
2612 |
2067 if (params.format == ZSTD_f_zstd1) { |
2613 if (params.format == ZSTD_f_zstd1) { |
2120 static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, |
2666 static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, |
2121 void* dst, size_t dstCapacity, |
2667 void* dst, size_t dstCapacity, |
2122 const void* src, size_t srcSize, |
2668 const void* src, size_t srcSize, |
2123 U32 frame, U32 lastFrameChunk) |
2669 U32 frame, U32 lastFrameChunk) |
2124 { |
2670 { |
2125 ZSTD_matchState_t* ms = &cctx->blockState.matchState; |
2671 ZSTD_matchState_t* const ms = &cctx->blockState.matchState; |
2126 size_t fhSize = 0; |
2672 size_t fhSize = 0; |
2127 |
2673 |
2128 DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u", |
2674 DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u", |
2129 cctx->stage, (U32)srcSize); |
2675 cctx->stage, (U32)srcSize); |
2130 if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */ |
2676 if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */ |
2141 if (!srcSize) return fhSize; /* do not generate an empty block if no input */ |
2687 if (!srcSize) return fhSize; /* do not generate an empty block if no input */ |
2142 |
2688 |
2143 if (!ZSTD_window_update(&ms->window, src, srcSize)) { |
2689 if (!ZSTD_window_update(&ms->window, src, srcSize)) { |
2144 ms->nextToUpdate = ms->window.dictLimit; |
2690 ms->nextToUpdate = ms->window.dictLimit; |
2145 } |
2691 } |
2146 if (cctx->appliedParams.ldmParams.enableLdm) |
2692 if (cctx->appliedParams.ldmParams.enableLdm) { |
2147 ZSTD_window_update(&cctx->ldmState.window, src, srcSize); |
2693 ZSTD_window_update(&cctx->ldmState.window, src, srcSize); |
2694 } |
|
2695 |
|
2696 if (!frame) { |
|
2697 /* overflow check and correction for block mode */ |
|
2698 if (ZSTD_window_needOverflowCorrection(ms->window, (const char*)src + srcSize)) { |
|
2699 U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy); |
|
2700 U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, 1 << cctx->appliedParams.cParams.windowLog, src); |
|
2701 ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); |
|
2702 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); |
|
2703 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); |
|
2704 ZSTD_reduceIndex(cctx, correction); |
|
2705 if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; |
|
2706 else ms->nextToUpdate -= correction; |
|
2707 ms->loadedDictEnd = 0; |
|
2708 ms->dictMatchState = NULL; |
|
2709 } |
|
2710 } |
|
2148 |
2711 |
2149 DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize); |
2712 DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize); |
2150 { size_t const cSize = frame ? |
2713 { size_t const cSize = frame ? |
2151 ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : |
2714 ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : |
2152 ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize); |
2715 ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize); |
2153 if (ZSTD_isError(cSize)) return cSize; |
2716 if (ZSTD_isError(cSize)) return cSize; |
2154 cctx->consumedSrcSize += srcSize; |
2717 cctx->consumedSrcSize += srcSize; |
2155 cctx->producedCSize += (cSize + fhSize); |
2718 cctx->producedCSize += (cSize + fhSize); |
2156 if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ |
2719 assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); |
2720 if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ |
|
2721 ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); |
|
2157 if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) { |
2722 if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) { |
2158 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u", |
2723 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u", |
2159 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize); |
2724 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize); |
2160 return ERROR(srcSize_wrong); |
2725 return ERROR(srcSize_wrong); |
2161 } |
2726 } |
2182 |
2747 |
2183 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) |
2748 size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) |
2184 { |
2749 { |
2185 size_t const blockSizeMax = ZSTD_getBlockSize(cctx); |
2750 size_t const blockSizeMax = ZSTD_getBlockSize(cctx); |
2186 if (srcSize > blockSizeMax) return ERROR(srcSize_wrong); |
2751 if (srcSize > blockSizeMax) return ERROR(srcSize_wrong); |
2752 |
|
2187 return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */); |
2753 return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */); |
2188 } |
2754 } |
2189 |
2755 |
2190 /*! ZSTD_loadDictionaryContent() : |
2756 /*! ZSTD_loadDictionaryContent() : |
2191 * @return : 0, or an error code |
2757 * @return : 0, or an error code |
2192 */ |
2758 */ |
2193 static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const void* src, size_t srcSize) |
2759 static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, |
2760 ZSTD_CCtx_params const* params, |
|
2761 const void* src, size_t srcSize, |
|
2762 ZSTD_dictTableLoadMethod_e dtlm) |
|
2194 { |
2763 { |
2195 const BYTE* const ip = (const BYTE*) src; |
2764 const BYTE* const ip = (const BYTE*) src; |
2196 const BYTE* const iend = ip + srcSize; |
2765 const BYTE* const iend = ip + srcSize; |
2197 ZSTD_compressionParameters const* cParams = ¶ms->cParams; |
|
2198 |
2766 |
2199 ZSTD_window_update(&ms->window, src, srcSize); |
2767 ZSTD_window_update(&ms->window, src, srcSize); |
2200 ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); |
2768 ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); |
2769 |
|
2770 /* Assert that we the ms params match the params we're being given */ |
|
2771 ZSTD_assertEqualCParams(params->cParams, ms->cParams); |
|
2201 |
2772 |
2202 if (srcSize <= HASH_READ_SIZE) return 0; |
2773 if (srcSize <= HASH_READ_SIZE) return 0; |
2203 |
2774 |
2204 switch(params->cParams.strategy) |
2775 switch(params->cParams.strategy) |
2205 { |
2776 { |
2206 case ZSTD_fast: |
2777 case ZSTD_fast: |
2207 ZSTD_fillHashTable(ms, cParams, iend); |
2778 ZSTD_fillHashTable(ms, iend, dtlm); |
2208 break; |
2779 break; |
2209 case ZSTD_dfast: |
2780 case ZSTD_dfast: |
2210 ZSTD_fillDoubleHashTable(ms, cParams, iend); |
2781 ZSTD_fillDoubleHashTable(ms, iend, dtlm); |
2211 break; |
2782 break; |
2212 |
2783 |
2213 case ZSTD_greedy: |
2784 case ZSTD_greedy: |
2214 case ZSTD_lazy: |
2785 case ZSTD_lazy: |
2215 case ZSTD_lazy2: |
2786 case ZSTD_lazy2: |
2216 if (srcSize >= HASH_READ_SIZE) |
2787 if (srcSize >= HASH_READ_SIZE) |
2217 ZSTD_insertAndFindFirstIndex(ms, cParams, iend-HASH_READ_SIZE); |
2788 ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE); |
2218 break; |
2789 break; |
2219 |
2790 |
2220 case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ |
2791 case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ |
2221 case ZSTD_btopt: |
2792 case ZSTD_btopt: |
2222 case ZSTD_btultra: |
2793 case ZSTD_btultra: |
2223 if (srcSize >= HASH_READ_SIZE) |
2794 if (srcSize >= HASH_READ_SIZE) |
2224 ZSTD_updateTree(ms, cParams, iend-HASH_READ_SIZE, iend); |
2795 ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend); |
2225 break; |
2796 break; |
2226 |
2797 |
2227 default: |
2798 default: |
2228 assert(0); /* not possible : not a valid strategy id */ |
2799 assert(0); /* not possible : not a valid strategy id */ |
2229 } |
2800 } |
2254 /*! ZSTD_loadZstdDictionary() : |
2825 /*! ZSTD_loadZstdDictionary() : |
2255 * @return : dictID, or an error code |
2826 * @return : dictID, or an error code |
2256 * assumptions : magic number supposed already checked |
2827 * assumptions : magic number supposed already checked |
2257 * dictSize supposed > 8 |
2828 * dictSize supposed > 8 |
2258 */ |
2829 */ |
2259 static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const void* dict, size_t dictSize, void* workspace) |
2830 static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, |
2831 ZSTD_matchState_t* ms, |
|
2832 ZSTD_CCtx_params const* params, |
|
2833 const void* dict, size_t dictSize, |
|
2834 ZSTD_dictTableLoadMethod_e dtlm, |
|
2835 void* workspace) |
|
2260 { |
2836 { |
2261 const BYTE* dictPtr = (const BYTE*)dict; |
2837 const BYTE* dictPtr = (const BYTE*)dict; |
2262 const BYTE* const dictEnd = dictPtr + dictSize; |
2838 const BYTE* const dictEnd = dictPtr + dictSize; |
2263 short offcodeNCount[MaxOff+1]; |
2839 short offcodeNCount[MaxOff+1]; |
2264 unsigned offcodeMaxValue = MaxOff; |
2840 unsigned offcodeMaxValue = MaxOff; |
2265 size_t dictID; |
2841 size_t dictID; |
2266 |
2842 |
2267 ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); |
2843 ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog))); |
2844 assert(dictSize > 8); |
|
2845 assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY); |
|
2268 |
2846 |
2269 dictPtr += 4; /* skip magic number */ |
2847 dictPtr += 4; /* skip magic number */ |
2270 dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr); |
2848 dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr); |
2271 dictPtr += 4; |
2849 dictPtr += 4; |
2272 |
2850 |
2273 { unsigned maxSymbolValue = 255; |
2851 { unsigned maxSymbolValue = 255; |
2274 size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.hufCTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr); |
2852 size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr); |
2275 if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted); |
2853 if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted); |
2276 if (maxSymbolValue < 255) return ERROR(dictionary_corrupted); |
2854 if (maxSymbolValue < 255) return ERROR(dictionary_corrupted); |
2277 dictPtr += hufHeaderSize; |
2855 dictPtr += hufHeaderSize; |
2278 } |
2856 } |
2279 |
2857 |
2280 { unsigned offcodeLog; |
2858 { unsigned offcodeLog; |
2281 size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); |
2859 size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); |
2282 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); |
2860 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); |
2283 if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); |
2861 if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); |
2284 /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ |
2862 /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ |
2285 CHECK_E( FSE_buildCTable_wksp(bs->entropy.offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, workspace, HUF_WORKSPACE_SIZE), |
2863 /* fill all offset symbols to avoid garbage at end of table */ |
2864 CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable, offcodeNCount, MaxOff, offcodeLog, workspace, HUF_WORKSPACE_SIZE), |
|
2286 dictionary_corrupted); |
2865 dictionary_corrupted); |
2287 dictPtr += offcodeHeaderSize; |
2866 dictPtr += offcodeHeaderSize; |
2288 } |
2867 } |
2289 |
2868 |
2290 { short matchlengthNCount[MaxML+1]; |
2869 { short matchlengthNCount[MaxML+1]; |
2292 size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); |
2871 size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); |
2293 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); |
2872 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); |
2294 if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); |
2873 if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); |
2295 /* Every match length code must have non-zero probability */ |
2874 /* Every match length code must have non-zero probability */ |
2296 CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML)); |
2875 CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML)); |
2297 CHECK_E( FSE_buildCTable_wksp(bs->entropy.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE), |
2876 CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE), |
2298 dictionary_corrupted); |
2877 dictionary_corrupted); |
2299 dictPtr += matchlengthHeaderSize; |
2878 dictPtr += matchlengthHeaderSize; |
2300 } |
2879 } |
2301 |
2880 |
2302 { short litlengthNCount[MaxLL+1]; |
2881 { short litlengthNCount[MaxLL+1]; |
2304 size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); |
2883 size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); |
2305 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); |
2884 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); |
2306 if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); |
2885 if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); |
2307 /* Every literal length code must have non-zero probability */ |
2886 /* Every literal length code must have non-zero probability */ |
2308 CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL)); |
2887 CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL)); |
2309 CHECK_E( FSE_buildCTable_wksp(bs->entropy.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE), |
2888 CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE), |
2310 dictionary_corrupted); |
2889 dictionary_corrupted); |
2311 dictPtr += litlengthHeaderSize; |
2890 dictPtr += litlengthHeaderSize; |
2312 } |
2891 } |
2313 |
2892 |
2314 if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted); |
2893 if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted); |
2330 for (u=0; u<3; u++) { |
2909 for (u=0; u<3; u++) { |
2331 if (bs->rep[u] == 0) return ERROR(dictionary_corrupted); |
2910 if (bs->rep[u] == 0) return ERROR(dictionary_corrupted); |
2332 if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted); |
2911 if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted); |
2333 } } |
2912 } } |
2334 |
2913 |
2335 bs->entropy.hufCTable_repeatMode = HUF_repeat_valid; |
2914 bs->entropy.huf.repeatMode = HUF_repeat_valid; |
2336 bs->entropy.offcode_repeatMode = FSE_repeat_valid; |
2915 bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid; |
2337 bs->entropy.matchlength_repeatMode = FSE_repeat_valid; |
2916 bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid; |
2338 bs->entropy.litlength_repeatMode = FSE_repeat_valid; |
2917 bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid; |
2339 CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize)); |
2918 CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm)); |
2340 return dictID; |
2919 return dictID; |
2341 } |
2920 } |
2342 } |
2921 } |
2343 |
2922 |
2344 /** ZSTD_compress_insertDictionary() : |
2923 /** ZSTD_compress_insertDictionary() : |
2345 * @return : dictID, or an error code */ |
2924 * @return : dictID, or an error code */ |
2346 static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matchState_t* ms, |
2925 static size_t |
2347 ZSTD_CCtx_params const* params, |
2926 ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, |
2348 const void* dict, size_t dictSize, |
2927 ZSTD_matchState_t* ms, |
2349 ZSTD_dictContentType_e dictContentType, |
2928 const ZSTD_CCtx_params* params, |
2350 void* workspace) |
2929 const void* dict, size_t dictSize, |
2930 ZSTD_dictContentType_e dictContentType, |
|
2931 ZSTD_dictTableLoadMethod_e dtlm, |
|
2932 void* workspace) |
|
2351 { |
2933 { |
2352 DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize); |
2934 DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize); |
2353 if ((dict==NULL) || (dictSize<=8)) return 0; |
2935 if ((dict==NULL) || (dictSize<=8)) return 0; |
2354 |
2936 |
2355 ZSTD_reset_compressedBlockState(bs); |
2937 ZSTD_reset_compressedBlockState(bs); |
2356 |
2938 |
2357 /* dict restricted modes */ |
2939 /* dict restricted modes */ |
2358 if (dictContentType == ZSTD_dct_rawContent) |
2940 if (dictContentType == ZSTD_dct_rawContent) |
2359 return ZSTD_loadDictionaryContent(ms, params, dict, dictSize); |
2941 return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm); |
2360 |
2942 |
2361 if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) { |
2943 if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) { |
2362 if (dictContentType == ZSTD_dct_auto) { |
2944 if (dictContentType == ZSTD_dct_auto) { |
2363 DEBUGLOG(4, "raw content dictionary detected"); |
2945 DEBUGLOG(4, "raw content dictionary detected"); |
2364 return ZSTD_loadDictionaryContent(ms, params, dict, dictSize); |
2946 return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm); |
2365 } |
2947 } |
2366 if (dictContentType == ZSTD_dct_fullDict) |
2948 if (dictContentType == ZSTD_dct_fullDict) |
2367 return ERROR(dictionary_wrong); |
2949 return ERROR(dictionary_wrong); |
2368 assert(0); /* impossible */ |
2950 assert(0); /* impossible */ |
2369 } |
2951 } |
2370 |
2952 |
2371 /* dict as full zstd dictionary */ |
2953 /* dict as full zstd dictionary */ |
2372 return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, workspace); |
2954 return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace); |
2373 } |
2955 } |
2374 |
2956 |
2375 /*! ZSTD_compressBegin_internal() : |
2957 /*! ZSTD_compressBegin_internal() : |
2376 * @return : 0, or an error code */ |
2958 * @return : 0, or an error code */ |
2377 size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, |
2959 static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, |
2378 const void* dict, size_t dictSize, |
2960 const void* dict, size_t dictSize, |
2379 ZSTD_dictContentType_e dictContentType, |
2961 ZSTD_dictContentType_e dictContentType, |
2380 const ZSTD_CDict* cdict, |
2962 ZSTD_dictTableLoadMethod_e dtlm, |
2381 ZSTD_CCtx_params params, U64 pledgedSrcSize, |
2963 const ZSTD_CDict* cdict, |
2382 ZSTD_buffered_policy_e zbuff) |
2964 ZSTD_CCtx_params params, U64 pledgedSrcSize, |
2965 ZSTD_buffered_policy_e zbuff) |
|
2383 { |
2966 { |
2384 DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog); |
2967 DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params.cParams.windowLog); |
2385 /* params are supposed to be fully validated at this point */ |
2968 /* params are supposed to be fully validated at this point */ |
2386 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
2969 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
2387 assert(!((dict) && (cdict))); /* either dict or cdict, not both */ |
2970 assert(!((dict) && (cdict))); /* either dict or cdict, not both */ |
2388 |
2971 |
2389 if (cdict && cdict->dictContentSize>0) { |
2972 if (cdict && cdict->dictContentSize>0) { |
2390 cctx->requestedParams = params; |
2973 return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff); |
2391 return ZSTD_resetCCtx_usingCDict(cctx, cdict, params.cParams.windowLog, |
|
2392 params.fParams, pledgedSrcSize, zbuff); |
|
2393 } |
2974 } |
2394 |
2975 |
2395 CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, |
2976 CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, |
2396 ZSTDcrp_continue, zbuff) ); |
2977 ZSTDcrp_continue, zbuff) ); |
2397 { |
2978 { |
2398 size_t const dictID = ZSTD_compress_insertDictionary( |
2979 size_t const dictID = ZSTD_compress_insertDictionary( |
2399 cctx->blockState.prevCBlock, &cctx->blockState.matchState, |
2980 cctx->blockState.prevCBlock, &cctx->blockState.matchState, |
2400 ¶ms, dict, dictSize, dictContentType, cctx->entropyWorkspace); |
2981 ¶ms, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace); |
2401 if (ZSTD_isError(dictID)) return dictID; |
2982 if (ZSTD_isError(dictID)) return dictID; |
2402 assert(dictID <= (size_t)(U32)-1); |
2983 assert(dictID <= (size_t)(U32)-1); |
2403 cctx->dictID = (U32)dictID; |
2984 cctx->dictID = (U32)dictID; |
2404 } |
2985 } |
2405 return 0; |
2986 return 0; |
2406 } |
2987 } |
2407 |
2988 |
2408 size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, |
2989 size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, |
2409 const void* dict, size_t dictSize, |
2990 const void* dict, size_t dictSize, |
2410 ZSTD_dictContentType_e dictContentType, |
2991 ZSTD_dictContentType_e dictContentType, |
2992 ZSTD_dictTableLoadMethod_e dtlm, |
|
2411 const ZSTD_CDict* cdict, |
2993 const ZSTD_CDict* cdict, |
2412 ZSTD_CCtx_params params, |
2994 ZSTD_CCtx_params params, |
2413 unsigned long long pledgedSrcSize) |
2995 unsigned long long pledgedSrcSize) |
2414 { |
2996 { |
2415 DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog); |
2997 DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params.cParams.windowLog); |
2416 /* compression parameters verification and optimization */ |
2998 /* compression parameters verification and optimization */ |
2417 CHECK_F( ZSTD_checkCParams(params.cParams) ); |
2999 CHECK_F( ZSTD_checkCParams(params.cParams) ); |
2418 return ZSTD_compressBegin_internal(cctx, |
3000 return ZSTD_compressBegin_internal(cctx, |
2419 dict, dictSize, dictContentType, |
3001 dict, dictSize, dictContentType, dtlm, |
2420 cdict, |
3002 cdict, |
2421 params, pledgedSrcSize, |
3003 params, pledgedSrcSize, |
2422 ZSTDb_not_buffered); |
3004 ZSTDb_not_buffered); |
2423 } |
3005 } |
2424 |
3006 |
2429 ZSTD_parameters params, unsigned long long pledgedSrcSize) |
3011 ZSTD_parameters params, unsigned long long pledgedSrcSize) |
2430 { |
3012 { |
2431 ZSTD_CCtx_params const cctxParams = |
3013 ZSTD_CCtx_params const cctxParams = |
2432 ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
3014 ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
2433 return ZSTD_compressBegin_advanced_internal(cctx, |
3015 return ZSTD_compressBegin_advanced_internal(cctx, |
2434 dict, dictSize, ZSTD_dct_auto, |
3016 dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, |
2435 NULL /*cdict*/, |
3017 NULL /*cdict*/, |
2436 cctxParams, pledgedSrcSize); |
3018 cctxParams, pledgedSrcSize); |
2437 } |
3019 } |
2438 |
3020 |
2439 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) |
3021 size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) |
2440 { |
3022 { |
2441 ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); |
3023 ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize); |
2442 ZSTD_CCtx_params const cctxParams = |
3024 ZSTD_CCtx_params const cctxParams = |
2443 ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
3025 ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
2444 DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize); |
3026 DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize); |
2445 return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL, |
3027 return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, |
2446 cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered); |
3028 cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered); |
2447 } |
3029 } |
2448 |
3030 |
2449 size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel) |
3031 size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel) |
2450 { |
3032 { |
2503 dst, dstCapacity, src, srcSize, |
3085 dst, dstCapacity, src, srcSize, |
2504 1 /* frame mode */, 1 /* last chunk */); |
3086 1 /* frame mode */, 1 /* last chunk */); |
2505 if (ZSTD_isError(cSize)) return cSize; |
3087 if (ZSTD_isError(cSize)) return cSize; |
2506 endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); |
3088 endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); |
2507 if (ZSTD_isError(endResult)) return endResult; |
3089 if (ZSTD_isError(endResult)) return endResult; |
2508 if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ |
3090 assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); |
3091 if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ |
|
3092 ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); |
|
2509 DEBUGLOG(4, "end of frame : controlling src size"); |
3093 DEBUGLOG(4, "end of frame : controlling src size"); |
2510 if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) { |
3094 if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) { |
2511 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u", |
3095 DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u", |
2512 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize); |
3096 (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize); |
2513 return ERROR(srcSize_wrong); |
3097 return ERROR(srcSize_wrong); |
2515 return cSize + endResult; |
3099 return cSize + endResult; |
2516 } |
3100 } |
2517 |
3101 |
2518 |
3102 |
2519 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx, |
3103 static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx, |
3104 void* dst, size_t dstCapacity, |
|
3105 const void* src, size_t srcSize, |
|
3106 const void* dict,size_t dictSize, |
|
3107 ZSTD_parameters params) |
|
3108 { |
|
3109 ZSTD_CCtx_params const cctxParams = |
|
3110 ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
|
3111 DEBUGLOG(4, "ZSTD_compress_internal"); |
|
3112 return ZSTD_compress_advanced_internal(cctx, |
|
3113 dst, dstCapacity, |
|
3114 src, srcSize, |
|
3115 dict, dictSize, |
|
3116 cctxParams); |
|
3117 } |
|
3118 |
|
3119 size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, |
|
2520 void* dst, size_t dstCapacity, |
3120 void* dst, size_t dstCapacity, |
2521 const void* src, size_t srcSize, |
3121 const void* src, size_t srcSize, |
2522 const void* dict,size_t dictSize, |
3122 const void* dict,size_t dictSize, |
2523 ZSTD_parameters params) |
3123 ZSTD_parameters params) |
2524 { |
3124 { |
2525 ZSTD_CCtx_params const cctxParams = |
|
2526 ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
|
2527 DEBUGLOG(4, "ZSTD_compress_internal"); |
|
2528 return ZSTD_compress_advanced_internal(cctx, |
|
2529 dst, dstCapacity, |
|
2530 src, srcSize, |
|
2531 dict, dictSize, |
|
2532 cctxParams); |
|
2533 } |
|
2534 |
|
2535 size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx, |
|
2536 void* dst, size_t dstCapacity, |
|
2537 const void* src, size_t srcSize, |
|
2538 const void* dict,size_t dictSize, |
|
2539 ZSTD_parameters params) |
|
2540 { |
|
2541 DEBUGLOG(4, "ZSTD_compress_advanced"); |
3125 DEBUGLOG(4, "ZSTD_compress_advanced"); |
2542 CHECK_F(ZSTD_checkCParams(params.cParams)); |
3126 CHECK_F(ZSTD_checkCParams(params.cParams)); |
2543 return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params); |
3127 return ZSTD_compress_internal(cctx, |
3128 dst, dstCapacity, |
|
3129 src, srcSize, |
|
3130 dict, dictSize, |
|
3131 params); |
|
2544 } |
3132 } |
2545 |
3133 |
2546 /* Internal */ |
3134 /* Internal */ |
2547 size_t ZSTD_compress_advanced_internal( |
3135 size_t ZSTD_compress_advanced_internal( |
2548 ZSTD_CCtx* cctx, |
3136 ZSTD_CCtx* cctx, |
2549 void* dst, size_t dstCapacity, |
3137 void* dst, size_t dstCapacity, |
2550 const void* src, size_t srcSize, |
3138 const void* src, size_t srcSize, |
2551 const void* dict,size_t dictSize, |
3139 const void* dict,size_t dictSize, |
2552 ZSTD_CCtx_params params) |
3140 ZSTD_CCtx_params params) |
2553 { |
3141 { |
2554 DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", |
3142 DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (U32)srcSize); |
2555 (U32)srcSize); |
3143 CHECK_F( ZSTD_compressBegin_internal(cctx, |
2556 CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL, |
3144 dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, |
2557 params, srcSize, ZSTDb_not_buffered) ); |
3145 params, srcSize, ZSTDb_not_buffered) ); |
2558 return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); |
3146 return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); |
2559 } |
3147 } |
2560 |
3148 |
2561 size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, |
3149 size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, |
2562 const void* dict, size_t dictSize, int compressionLevel) |
3150 void* dst, size_t dstCapacity, |
2563 { |
3151 const void* src, size_t srcSize, |
2564 ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize ? srcSize : 1, dict ? dictSize : 0); |
3152 const void* dict, size_t dictSize, |
3153 int compressionLevel) |
|
3154 { |
|
3155 ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0); |
|
2565 ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
3156 ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params); |
2566 assert(params.fParams.contentSizeFlag == 1); |
3157 assert(params.fParams.contentSizeFlag == 1); |
2567 ZSTD_CCtxParam_setParameter(&cctxParams, ZSTD_p_compressLiterals, compressionLevel>=0); |
|
2568 return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams); |
3158 return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams); |
2569 } |
3159 } |
2570 |
3160 |
2571 size_t ZSTD_compressCCtx (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel) |
3161 size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, |
3162 void* dst, size_t dstCapacity, |
|
3163 const void* src, size_t srcSize, |
|
3164 int compressionLevel) |
|
2572 { |
3165 { |
2573 DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize); |
3166 DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize); |
3167 assert(cctx != NULL); |
|
2574 return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel); |
3168 return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel); |
2575 } |
3169 } |
2576 |
3170 |
2577 size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel) |
3171 size_t ZSTD_compress(void* dst, size_t dstCapacity, |
3172 const void* src, size_t srcSize, |
|
3173 int compressionLevel) |
|
2578 { |
3174 { |
2579 size_t result; |
3175 size_t result; |
2580 ZSTD_CCtx ctxBody; |
3176 ZSTD_CCtx ctxBody; |
2581 memset(&ctxBody, 0, sizeof(ctxBody)); |
3177 ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem); |
2582 ctxBody.customMem = ZSTD_defaultCMem; |
|
2583 result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); |
3178 result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); |
2584 ZSTD_free(ctxBody.workSpace, ZSTD_defaultCMem); /* can't free ctxBody itself, as it's on stack; free only heap content */ |
3179 ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */ |
2585 return result; |
3180 return result; |
2586 } |
3181 } |
2587 |
3182 |
2588 |
3183 |
2589 /* ===== Dictionary API ===== */ |
3184 /* ===== Dictionary API ===== */ |
2617 const void* dictBuffer, size_t dictSize, |
3212 const void* dictBuffer, size_t dictSize, |
2618 ZSTD_dictLoadMethod_e dictLoadMethod, |
3213 ZSTD_dictLoadMethod_e dictLoadMethod, |
2619 ZSTD_dictContentType_e dictContentType, |
3214 ZSTD_dictContentType_e dictContentType, |
2620 ZSTD_compressionParameters cParams) |
3215 ZSTD_compressionParameters cParams) |
2621 { |
3216 { |
2622 DEBUGLOG(3, "ZSTD_initCDict_internal, dictContentType %u", (U32)dictContentType); |
3217 DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (U32)dictContentType); |
2623 assert(!ZSTD_checkCParams(cParams)); |
3218 assert(!ZSTD_checkCParams(cParams)); |
2624 cdict->cParams = cParams; |
3219 cdict->matchState.cParams = cParams; |
2625 if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { |
3220 if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { |
2626 cdict->dictBuffer = NULL; |
3221 cdict->dictBuffer = NULL; |
2627 cdict->dictContent = dictBuffer; |
3222 cdict->dictContent = dictBuffer; |
2628 } else { |
3223 } else { |
2629 void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem); |
3224 void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem); |
2652 params.fParams.contentSizeFlag = 1; |
3247 params.fParams.contentSizeFlag = 1; |
2653 params.cParams = cParams; |
3248 params.cParams = cParams; |
2654 { size_t const dictID = ZSTD_compress_insertDictionary( |
3249 { size_t const dictID = ZSTD_compress_insertDictionary( |
2655 &cdict->cBlockState, &cdict->matchState, ¶ms, |
3250 &cdict->cBlockState, &cdict->matchState, ¶ms, |
2656 cdict->dictContent, cdict->dictContentSize, |
3251 cdict->dictContent, cdict->dictContentSize, |
2657 dictContentType, cdict->workspace); |
3252 dictContentType, ZSTD_dtlm_full, cdict->workspace); |
2658 if (ZSTD_isError(dictID)) return dictID; |
3253 if (ZSTD_isError(dictID)) return dictID; |
2659 assert(dictID <= (size_t)(U32)-1); |
3254 assert(dictID <= (size_t)(U32)-1); |
2660 cdict->dictID = (U32)dictID; |
3255 cdict->dictID = (U32)dictID; |
2661 } |
3256 } |
2662 } |
3257 } |
2773 } |
3368 } |
2774 |
3369 |
2775 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) |
3370 ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) |
2776 { |
3371 { |
2777 assert(cdict != NULL); |
3372 assert(cdict != NULL); |
2778 return cdict->cParams; |
3373 return cdict->matchState.cParams; |
2779 } |
3374 } |
2780 |
3375 |
2781 /* ZSTD_compressBegin_usingCDict_advanced() : |
3376 /* ZSTD_compressBegin_usingCDict_advanced() : |
2782 * cdict must be != NULL */ |
3377 * cdict must be != NULL */ |
2783 size_t ZSTD_compressBegin_usingCDict_advanced( |
3378 size_t ZSTD_compressBegin_usingCDict_advanced( |
2797 U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1; |
3392 U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1; |
2798 params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog); |
3393 params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog); |
2799 } |
3394 } |
2800 params.fParams = fParams; |
3395 params.fParams = fParams; |
2801 return ZSTD_compressBegin_internal(cctx, |
3396 return ZSTD_compressBegin_internal(cctx, |
2802 NULL, 0, ZSTD_dct_auto, |
3397 NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, |
2803 cdict, |
3398 cdict, |
2804 params, pledgedSrcSize, |
3399 params, pledgedSrcSize, |
2805 ZSTDb_not_buffered); |
3400 ZSTDb_not_buffered); |
2806 } |
3401 } |
2807 } |
3402 } |
2811 * if pledgedSrcSize>0, it will enable contentSizeFlag */ |
3406 * if pledgedSrcSize>0, it will enable contentSizeFlag */ |
2812 size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) |
3407 size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) |
2813 { |
3408 { |
2814 ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; |
3409 ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; |
2815 DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag); |
3410 DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag); |
2816 return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0); |
3411 return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); |
2817 } |
3412 } |
2818 |
3413 |
2819 size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, |
3414 size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, |
2820 void* dst, size_t dstCapacity, |
3415 void* dst, size_t dstCapacity, |
2821 const void* src, size_t srcSize, |
3416 const void* src, size_t srcSize, |
2878 } |
3473 } |
2879 |
3474 |
2880 static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx, |
3475 static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx, |
2881 const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType, |
3476 const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType, |
2882 const ZSTD_CDict* const cdict, |
3477 const ZSTD_CDict* const cdict, |
2883 ZSTD_CCtx_params const params, unsigned long long const pledgedSrcSize) |
3478 ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize) |
2884 { |
3479 { |
2885 DEBUGLOG(4, "ZSTD_resetCStream_internal (disableLiteralCompression=%i)", |
3480 DEBUGLOG(4, "ZSTD_resetCStream_internal"); |
2886 params.disableLiteralCompression); |
3481 /* Finalize the compression parameters */ |
3482 params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, dictSize); |
|
2887 /* params are supposed to be fully validated at this point */ |
3483 /* params are supposed to be fully validated at this point */ |
2888 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
3484 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
2889 assert(!((dict) && (cdict))); /* either dict or cdict, not both */ |
3485 assert(!((dict) && (cdict))); /* either dict or cdict, not both */ |
2890 |
3486 |
2891 CHECK_F( ZSTD_compressBegin_internal(cctx, |
3487 CHECK_F( ZSTD_compressBegin_internal(cctx, |
2892 dict, dictSize, dictContentType, |
3488 dict, dictSize, dictContentType, ZSTD_dtlm_fast, |
2893 cdict, |
3489 cdict, |
2894 params, pledgedSrcSize, |
3490 params, pledgedSrcSize, |
2895 ZSTDb_buffered) ); |
3491 ZSTDb_buffered) ); |
2896 |
3492 |
2897 cctx->inToCompress = 0; |
3493 cctx->inToCompress = 0; |
2910 { |
3506 { |
2911 ZSTD_CCtx_params params = zcs->requestedParams; |
3507 ZSTD_CCtx_params params = zcs->requestedParams; |
2912 DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize); |
3508 DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize); |
2913 if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; |
3509 if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; |
2914 params.fParams.contentSizeFlag = 1; |
3510 params.fParams.contentSizeFlag = 1; |
2915 params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, 0); |
|
2916 return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize); |
3511 return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize); |
2917 } |
3512 } |
2918 |
3513 |
2919 /*! ZSTD_initCStream_internal() : |
3514 /*! ZSTD_initCStream_internal() : |
2920 * Note : for lib/compress only. Used by zstdmt_compress.c. |
3515 * Note : for lib/compress only. Used by zstdmt_compress.c. |
2923 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, |
3518 size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, |
2924 const void* dict, size_t dictSize, const ZSTD_CDict* cdict, |
3519 const void* dict, size_t dictSize, const ZSTD_CDict* cdict, |
2925 ZSTD_CCtx_params params, unsigned long long pledgedSrcSize) |
3520 ZSTD_CCtx_params params, unsigned long long pledgedSrcSize) |
2926 { |
3521 { |
2927 DEBUGLOG(4, "ZSTD_initCStream_internal"); |
3522 DEBUGLOG(4, "ZSTD_initCStream_internal"); |
3523 params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, dictSize); |
|
2928 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
3524 assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); |
2929 assert(!((dict) && (cdict))); /* either dict or cdict, not both */ |
3525 assert(!((dict) && (cdict))); /* either dict or cdict, not both */ |
2930 |
3526 |
2931 if (dict && dictSize >= 8) { |
3527 if (dict && dictSize >= 8) { |
2932 DEBUGLOG(4, "loading dictionary of size %u", (U32)dictSize); |
3528 DEBUGLOG(4, "loading dictionary of size %u", (U32)dictSize); |
2989 { |
3585 { |
2990 DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u", |
3586 DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u", |
2991 (U32)pledgedSrcSize, params.fParams.contentSizeFlag); |
3587 (U32)pledgedSrcSize, params.fParams.contentSizeFlag); |
2992 CHECK_F( ZSTD_checkCParams(params.cParams) ); |
3588 CHECK_F( ZSTD_checkCParams(params.cParams) ); |
2993 if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */ |
3589 if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */ |
2994 { ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params); |
3590 zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params); |
2995 return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, cctxParams, pledgedSrcSize); |
3591 return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, zcs->requestedParams, pledgedSrcSize); |
2996 } |
|
2997 } |
3592 } |
2998 |
3593 |
2999 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel) |
3594 size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel) |
3000 { |
3595 { |
3001 ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize); |
3596 ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel); |
3002 ZSTD_CCtx_params const cctxParams = |
3597 return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, zcs->requestedParams, ZSTD_CONTENTSIZE_UNKNOWN); |
3003 ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params); |
|
3004 return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN); |
|
3005 } |
3598 } |
3006 |
3599 |
3007 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss) |
3600 size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss) |
3008 { |
3601 { |
3009 U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; /* temporary : 0 interpreted as "unknown" during transition period. Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. `0` will be interpreted as "empty" in the future */ |
3602 U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss; /* temporary : 0 interpreted as "unknown" during transition period. Users willing to specify "unknown" **must** use ZSTD_CONTENTSIZE_UNKNOWN. `0` will be interpreted as "empty" in the future */ |
3010 ZSTD_parameters const params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0); |
3603 ZSTD_CCtxParams_init(&zcs->requestedParams, compressionLevel); |
3011 ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params); |
3604 return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, zcs->requestedParams, pledgedSrcSize); |
3012 return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, pledgedSrcSize); |
|
3013 } |
3605 } |
3014 |
3606 |
3015 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) |
3607 size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) |
3016 { |
3608 { |
3017 DEBUGLOG(4, "ZSTD_initCStream"); |
3609 DEBUGLOG(4, "ZSTD_initCStream"); |
3071 DEBUGLOG(4, "ZSTD_compressEnd : %u", (U32)cSize); |
3663 DEBUGLOG(4, "ZSTD_compressEnd : %u", (U32)cSize); |
3072 if (ZSTD_isError(cSize)) return cSize; |
3664 if (ZSTD_isError(cSize)) return cSize; |
3073 ip = iend; |
3665 ip = iend; |
3074 op += cSize; |
3666 op += cSize; |
3075 zcs->frameEnded = 1; |
3667 zcs->frameEnded = 1; |
3076 ZSTD_startNewCompression(zcs); |
3668 ZSTD_CCtx_reset(zcs); |
3077 someMoreWork = 0; break; |
3669 someMoreWork = 0; break; |
3078 } |
3670 } |
3079 /* complete loading into inBuffer */ |
3671 /* complete loading into inBuffer */ |
3080 { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; |
3672 { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; |
3081 size_t const loaded = ZSTD_limitCopy( |
3673 size_t const loaded = ZSTD_limitCopy( |
3124 if (cDst == op) { /* no need to flush */ |
3716 if (cDst == op) { /* no need to flush */ |
3125 op += cSize; |
3717 op += cSize; |
3126 if (zcs->frameEnded) { |
3718 if (zcs->frameEnded) { |
3127 DEBUGLOG(5, "Frame completed directly in outBuffer"); |
3719 DEBUGLOG(5, "Frame completed directly in outBuffer"); |
3128 someMoreWork = 0; |
3720 someMoreWork = 0; |
3129 ZSTD_startNewCompression(zcs); |
3721 ZSTD_CCtx_reset(zcs); |
3130 } |
3722 } |
3131 break; |
3723 break; |
3132 } |
3724 } |
3133 zcs->outBuffContentSize = cSize; |
3725 zcs->outBuffContentSize = cSize; |
3134 zcs->outBuffFlushedSize = 0; |
3726 zcs->outBuffFlushedSize = 0; |
3152 } |
3744 } |
3153 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; |
3745 zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; |
3154 if (zcs->frameEnded) { |
3746 if (zcs->frameEnded) { |
3155 DEBUGLOG(5, "Frame completed on flush"); |
3747 DEBUGLOG(5, "Frame completed on flush"); |
3156 someMoreWork = 0; |
3748 someMoreWork = 0; |
3157 ZSTD_startNewCompression(zcs); |
3749 ZSTD_CCtx_reset(zcs); |
3158 break; |
3750 break; |
3159 } |
3751 } |
3160 zcs->streamStage = zcss_load; |
3752 zcs->streamStage = zcss_load; |
3161 break; |
3753 break; |
3162 } |
3754 } |
3205 DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage"); |
3797 DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage"); |
3206 if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1; /* auto-fix pledgedSrcSize */ |
3798 if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1; /* auto-fix pledgedSrcSize */ |
3207 params.cParams = ZSTD_getCParamsFromCCtxParams( |
3799 params.cParams = ZSTD_getCParamsFromCCtxParams( |
3208 &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/); |
3800 &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/); |
3209 |
3801 |
3802 |
|
3210 #ifdef ZSTD_MULTITHREAD |
3803 #ifdef ZSTD_MULTITHREAD |
3211 if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { |
3804 if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) { |
3212 params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */ |
3805 params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */ |
3213 } |
3806 } |
3214 if (params.nbWorkers > 0) { |
3807 if (params.nbWorkers > 0) { |
3215 /* mt context creation */ |
3808 /* mt context creation */ |
3216 if (cctx->mtctx == NULL || (params.nbWorkers != ZSTDMT_getNbWorkers(cctx->mtctx))) { |
3809 if (cctx->mtctx == NULL) { |
3217 DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u", |
3810 DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u", |
3218 params.nbWorkers); |
3811 params.nbWorkers); |
3219 if (cctx->mtctx != NULL) |
|
3220 DEBUGLOG(4, "ZSTD_compress_generic: previous nbWorkers was %u", |
|
3221 ZSTDMT_getNbWorkers(cctx->mtctx)); |
|
3222 ZSTDMT_freeCCtx(cctx->mtctx); |
|
3223 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem); |
3812 cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem); |
3224 if (cctx->mtctx == NULL) return ERROR(memory_allocation); |
3813 if (cctx->mtctx == NULL) return ERROR(memory_allocation); |
3225 } |
3814 } |
3226 /* mt compression */ |
3815 /* mt compression */ |
3227 DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers); |
3816 DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers); |
3249 cctx->cParamsChanged = 0; |
3838 cctx->cParamsChanged = 0; |
3250 } |
3839 } |
3251 { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); |
3840 { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); |
3252 if ( ZSTD_isError(flushMin) |
3841 if ( ZSTD_isError(flushMin) |
3253 || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ |
3842 || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ |
3254 ZSTD_startNewCompression(cctx); |
3843 ZSTD_CCtx_reset(cctx); |
3255 } |
3844 } |
3845 DEBUGLOG(5, "completed ZSTD_compress_generic delegating to ZSTDMT_compressStream_generic"); |
|
3256 return flushMin; |
3846 return flushMin; |
3257 } } |
3847 } } |
3258 #endif |
3848 #endif |
3259 CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) ); |
3849 CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) ); |
3260 DEBUGLOG(5, "completed ZSTD_compress_generic"); |
3850 DEBUGLOG(5, "completed ZSTD_compress_generic"); |
3306 |
3896 |
3307 /*-===== Pre-defined compression levels =====-*/ |
3897 /*-===== Pre-defined compression levels =====-*/ |
3308 |
3898 |
3309 #define ZSTD_MAX_CLEVEL 22 |
3899 #define ZSTD_MAX_CLEVEL 22 |
3310 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } |
3900 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } |
3901 int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } |
|
3311 |
3902 |
3312 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { |
3903 static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { |
3313 { /* "default" - guarantees a monotonically increasing memory budget */ |
3904 { /* "default" - guarantees a monotonically increasing memory budget */ |
3314 /* W, C, H, S, L, TL, strat */ |
3905 /* W, C, H, S, L, TL, strat */ |
3315 { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ |
3906 { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ |
3316 { 19, 13, 14, 1, 7, 1, ZSTD_fast }, /* level 1 */ |
3907 { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */ |
3317 { 19, 15, 16, 1, 6, 1, ZSTD_fast }, /* level 2 */ |
3908 { 19, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ |
3318 { 20, 16, 17, 1, 5, 8, ZSTD_dfast }, /* level 3 */ |
3909 { 20, 16, 17, 1, 5, 1, ZSTD_dfast }, /* level 3 */ |
3319 { 20, 17, 18, 1, 5, 8, ZSTD_dfast }, /* level 4 */ |
3910 { 20, 18, 18, 1, 5, 1, ZSTD_dfast }, /* level 4 */ |
3320 { 20, 17, 18, 2, 5, 16, ZSTD_greedy }, /* level 5 */ |
3911 { 20, 18, 18, 2, 5, 2, ZSTD_greedy }, /* level 5 */ |
3321 { 21, 17, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */ |
3912 { 21, 18, 19, 2, 5, 4, ZSTD_lazy }, /* level 6 */ |
3322 { 21, 18, 19, 3, 5, 16, ZSTD_lazy }, /* level 7 */ |
3913 { 21, 18, 19, 3, 5, 8, ZSTD_lazy2 }, /* level 7 */ |
3323 { 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */ |
3914 { 21, 19, 19, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */ |
3324 { 21, 19, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 9 */ |
3915 { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ |
3325 { 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ |
3916 { 21, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ |
3326 { 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */ |
3917 { 21, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */ |
3327 { 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */ |
3918 { 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */ |
3328 { 22, 21, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ |
3919 { 22, 21, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ |
3329 { 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ |
3920 { 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ |
3330 { 22, 22, 22, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ |
3921 { 22, 22, 22, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ |
3331 { 22, 21, 22, 4, 5, 48, ZSTD_btopt }, /* level 16 */ |
3922 { 22, 21, 22, 4, 5, 48, ZSTD_btopt }, /* level 16 */ |
3332 { 23, 22, 22, 4, 4, 48, ZSTD_btopt }, /* level 17 */ |
3923 { 23, 22, 22, 4, 4, 64, ZSTD_btopt }, /* level 17 */ |
3333 { 23, 22, 22, 5, 3, 64, ZSTD_btopt }, /* level 18 */ |
3924 { 23, 23, 22, 6, 3,256, ZSTD_btopt }, /* level 18 */ |
3334 { 23, 23, 22, 7, 3,128, ZSTD_btopt }, /* level 19 */ |
3925 { 23, 24, 22, 7, 3,256, ZSTD_btultra }, /* level 19 */ |
3335 { 25, 25, 23, 7, 3,128, ZSTD_btultra }, /* level 20 */ |
3926 { 25, 25, 23, 7, 3,256, ZSTD_btultra }, /* level 20 */ |
3336 { 26, 26, 24, 7, 3,256, ZSTD_btultra }, /* level 21 */ |
3927 { 26, 26, 24, 7, 3,512, ZSTD_btultra }, /* level 21 */ |
3337 { 27, 27, 25, 9, 3,512, ZSTD_btultra }, /* level 22 */ |
3928 { 27, 27, 25, 9, 3,999, ZSTD_btultra }, /* level 22 */ |
3338 }, |
3929 }, |
3339 { /* for srcSize <= 256 KB */ |
3930 { /* for srcSize <= 256 KB */ |
3340 /* W, C, H, S, L, T, strat */ |
3931 /* W, C, H, S, L, T, strat */ |
3341 { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ |
3932 { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ |
3342 { 18, 13, 14, 1, 6, 1, ZSTD_fast }, /* level 1 */ |
3933 { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ |
3343 { 18, 14, 13, 1, 5, 8, ZSTD_dfast }, /* level 2 */ |
3934 { 18, 14, 14, 1, 5, 1, ZSTD_dfast }, /* level 2 */ |
3344 { 18, 16, 15, 1, 5, 8, ZSTD_dfast }, /* level 3 */ |
3935 { 18, 16, 16, 1, 4, 1, ZSTD_dfast }, /* level 3 */ |
3345 { 18, 15, 17, 1, 5, 8, ZSTD_greedy }, /* level 4.*/ |
3936 { 18, 16, 17, 2, 5, 2, ZSTD_greedy }, /* level 4.*/ |
3346 { 18, 16, 17, 4, 5, 8, ZSTD_greedy }, /* level 5.*/ |
3937 { 18, 18, 18, 3, 5, 2, ZSTD_greedy }, /* level 5.*/ |
3347 { 18, 16, 17, 3, 5, 8, ZSTD_lazy }, /* level 6.*/ |
3938 { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ |
3348 { 18, 17, 17, 4, 4, 8, ZSTD_lazy }, /* level 7 */ |
3939 { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ |
3349 { 18, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ |
3940 { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ |
3350 { 18, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ |
3941 { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ |
3351 { 18, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ |
3942 { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ |
3352 { 18, 18, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 11.*/ |
3943 { 18, 18, 19, 5, 4, 16, ZSTD_btlazy2 }, /* level 11.*/ |
3353 { 18, 18, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 12.*/ |
3944 { 18, 19, 19, 6, 4, 16, ZSTD_btlazy2 }, /* level 12.*/ |
3354 { 18, 19, 17, 7, 4, 8, ZSTD_btlazy2 }, /* level 13 */ |
3945 { 18, 19, 19, 8, 4, 16, ZSTD_btlazy2 }, /* level 13 */ |
3355 { 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/ |
3946 { 18, 18, 19, 4, 4, 24, ZSTD_btopt }, /* level 14.*/ |
3356 { 18, 18, 18, 4, 3, 16, ZSTD_btopt }, /* level 15.*/ |
3947 { 18, 18, 19, 4, 3, 24, ZSTD_btopt }, /* level 15.*/ |
3357 { 18, 19, 18, 6, 3, 32, ZSTD_btopt }, /* level 16.*/ |
3948 { 18, 19, 19, 6, 3, 64, ZSTD_btopt }, /* level 16.*/ |
3358 { 18, 19, 18, 8, 3, 64, ZSTD_btopt }, /* level 17.*/ |
3949 { 18, 19, 19, 8, 3,128, ZSTD_btopt }, /* level 17.*/ |
3359 { 18, 19, 18, 9, 3,128, ZSTD_btopt }, /* level 18.*/ |
3950 { 18, 19, 19, 10, 3,256, ZSTD_btopt }, /* level 18.*/ |
3360 { 18, 19, 18, 10, 3,256, ZSTD_btopt }, /* level 19.*/ |
3951 { 18, 19, 19, 10, 3,256, ZSTD_btultra }, /* level 19.*/ |
3361 { 18, 19, 18, 11, 3,512, ZSTD_btultra }, /* level 20.*/ |
3952 { 18, 19, 19, 11, 3,512, ZSTD_btultra }, /* level 20.*/ |
3362 { 18, 19, 18, 12, 3,512, ZSTD_btultra }, /* level 21.*/ |
3953 { 18, 19, 19, 12, 3,512, ZSTD_btultra }, /* level 21.*/ |
3363 { 18, 19, 18, 13, 3,512, ZSTD_btultra }, /* level 22.*/ |
3954 { 18, 19, 19, 13, 3,999, ZSTD_btultra }, /* level 22.*/ |
3364 }, |
3955 }, |
3365 { /* for srcSize <= 128 KB */ |
3956 { /* for srcSize <= 128 KB */ |
3366 /* W, C, H, S, L, T, strat */ |
3957 /* W, C, H, S, L, T, strat */ |
3367 { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* level 0 - not used */ |
3958 { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ |
3368 { 17, 12, 13, 1, 6, 1, ZSTD_fast }, /* level 1 */ |
3959 { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */ |
3369 { 17, 13, 16, 1, 5, 1, ZSTD_fast }, /* level 2 */ |
3960 { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ |
3370 { 17, 16, 16, 2, 5, 8, ZSTD_dfast }, /* level 3 */ |
3961 { 17, 15, 16, 2, 5, 1, ZSTD_dfast }, /* level 3 */ |
3371 { 17, 13, 15, 3, 4, 8, ZSTD_greedy }, /* level 4 */ |
3962 { 17, 17, 17, 2, 4, 1, ZSTD_dfast }, /* level 4 */ |
3372 { 17, 15, 17, 4, 4, 8, ZSTD_greedy }, /* level 5 */ |
3963 { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ |
3373 { 17, 16, 17, 3, 4, 8, ZSTD_lazy }, /* level 6 */ |
3964 { 17, 17, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ |
3374 { 17, 15, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 7 */ |
3965 { 17, 17, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ |
3375 { 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ |
3966 { 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ |
3376 { 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ |
3967 { 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ |
3377 { 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ |
3968 { 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ |
3378 { 17, 17, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 11 */ |
3969 { 17, 17, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 11 */ |
3379 { 17, 17, 17, 8, 4, 8, ZSTD_lazy2 }, /* level 12 */ |
3970 { 17, 18, 17, 6, 4, 16, ZSTD_btlazy2 }, /* level 12 */ |
3380 { 17, 18, 17, 6, 4, 8, ZSTD_btlazy2 }, /* level 13.*/ |
3971 { 17, 18, 17, 8, 4, 16, ZSTD_btlazy2 }, /* level 13.*/ |
3381 { 17, 17, 17, 7, 3, 8, ZSTD_btopt }, /* level 14.*/ |
3972 { 17, 18, 17, 4, 4, 32, ZSTD_btopt }, /* level 14.*/ |
3382 { 17, 17, 17, 7, 3, 16, ZSTD_btopt }, /* level 15.*/ |
3973 { 17, 18, 17, 6, 3, 64, ZSTD_btopt }, /* level 15.*/ |
3383 { 17, 18, 17, 7, 3, 32, ZSTD_btopt }, /* level 16.*/ |
3974 { 17, 18, 17, 7, 3,128, ZSTD_btopt }, /* level 16.*/ |
3384 { 17, 18, 17, 7, 3, 64, ZSTD_btopt }, /* level 17.*/ |
3975 { 17, 18, 17, 7, 3,256, ZSTD_btopt }, /* level 17.*/ |
3385 { 17, 18, 17, 7, 3,256, ZSTD_btopt }, /* level 18.*/ |
3976 { 17, 18, 17, 8, 3,256, ZSTD_btopt }, /* level 18.*/ |
3386 { 17, 18, 17, 8, 3,256, ZSTD_btopt }, /* level 19.*/ |
3977 { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 19.*/ |
3387 { 17, 18, 17, 9, 3,256, ZSTD_btultra }, /* level 20.*/ |
3978 { 17, 18, 17, 9, 3,256, ZSTD_btultra }, /* level 20.*/ |
3388 { 17, 18, 17, 10, 3,256, ZSTD_btultra }, /* level 21.*/ |
3979 { 17, 18, 17, 10, 3,256, ZSTD_btultra }, /* level 21.*/ |
3389 { 17, 18, 17, 11, 3,512, ZSTD_btultra }, /* level 22.*/ |
3980 { 17, 18, 17, 11, 3,512, ZSTD_btultra }, /* level 22.*/ |
3390 }, |
3981 }, |
3391 { /* for srcSize <= 16 KB */ |
3982 { /* for srcSize <= 16 KB */ |
3392 /* W, C, H, S, L, T, strat */ |
3983 /* W, C, H, S, L, T, strat */ |
3393 { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ |
3984 { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ |
3394 { 14, 14, 14, 1, 6, 1, ZSTD_fast }, /* level 1 */ |
3985 { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */ |
3395 { 14, 14, 14, 1, 4, 1, ZSTD_fast }, /* level 2 */ |
3986 { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */ |
3396 { 14, 14, 14, 1, 4, 6, ZSTD_dfast }, /* level 3.*/ |
3987 { 14, 14, 14, 2, 4, 1, ZSTD_dfast }, /* level 3.*/ |
3397 { 14, 14, 14, 4, 4, 6, ZSTD_greedy }, /* level 4.*/ |
3988 { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4.*/ |
3398 { 14, 14, 14, 3, 4, 6, ZSTD_lazy }, /* level 5.*/ |
3989 { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/ |
3399 { 14, 14, 14, 4, 4, 6, ZSTD_lazy2 }, /* level 6 */ |
3990 { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */ |
3400 { 14, 14, 14, 5, 4, 6, ZSTD_lazy2 }, /* level 7 */ |
3991 { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */ |
3401 { 14, 14, 14, 6, 4, 6, ZSTD_lazy2 }, /* level 8.*/ |
3992 { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/ |
3402 { 14, 15, 14, 6, 4, 6, ZSTD_btlazy2 }, /* level 9.*/ |
3993 { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/ |
3403 { 14, 15, 14, 3, 3, 6, ZSTD_btopt }, /* level 10.*/ |
3994 { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/ |
3404 { 14, 15, 14, 6, 3, 8, ZSTD_btopt }, /* level 11.*/ |
3995 { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/ |
3405 { 14, 15, 14, 6, 3, 16, ZSTD_btopt }, /* level 12.*/ |
3996 { 14, 15, 14, 6, 3, 16, ZSTD_btopt }, /* level 12.*/ |
3406 { 14, 15, 14, 6, 3, 24, ZSTD_btopt }, /* level 13.*/ |
3997 { 14, 15, 14, 6, 3, 24, ZSTD_btopt }, /* level 13.*/ |
3407 { 14, 15, 15, 6, 3, 48, ZSTD_btopt }, /* level 14.*/ |
3998 { 14, 15, 15, 6, 3, 48, ZSTD_btopt }, /* level 14.*/ |
3408 { 14, 15, 15, 6, 3, 64, ZSTD_btopt }, /* level 15.*/ |
3999 { 14, 15, 15, 6, 3, 64, ZSTD_btopt }, /* level 15.*/ |
3409 { 14, 15, 15, 6, 3, 96, ZSTD_btopt }, /* level 16.*/ |
4000 { 14, 15, 15, 6, 3, 96, ZSTD_btopt }, /* level 16.*/ |
3410 { 14, 15, 15, 6, 3,128, ZSTD_btopt }, /* level 17.*/ |
4001 { 14, 15, 15, 6, 3,128, ZSTD_btopt }, /* level 17.*/ |
3411 { 14, 15, 15, 6, 3,256, ZSTD_btopt }, /* level 18.*/ |
4002 { 14, 15, 15, 8, 3,256, ZSTD_btopt }, /* level 18.*/ |
3412 { 14, 15, 15, 7, 3,256, ZSTD_btopt }, /* level 19.*/ |
4003 { 14, 15, 15, 6, 3,256, ZSTD_btultra }, /* level 19.*/ |
3413 { 14, 15, 15, 8, 3,256, ZSTD_btultra }, /* level 20.*/ |
4004 { 14, 15, 15, 8, 3,256, ZSTD_btultra }, /* level 20.*/ |
3414 { 14, 15, 15, 9, 3,256, ZSTD_btultra }, /* level 21.*/ |
4005 { 14, 15, 15, 9, 3,256, ZSTD_btultra }, /* level 21.*/ |
3415 { 14, 15, 15, 10, 3,256, ZSTD_btultra }, /* level 22.*/ |
4006 { 14, 15, 15, 10, 3,512, ZSTD_btultra }, /* level 22.*/ |
3416 }, |
4007 }, |
3417 }; |
4008 }; |
3418 |
4009 |
3419 /*! ZSTD_getCParams() : |
4010 /*! ZSTD_getCParams() : |
3420 * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. |
4011 * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. |