zstd_compress_superblock.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. /*
  2. * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. * You may select, at your option, one of the above-listed licenses.
  9. */
  10. /*-*************************************
  11. * Dependencies
  12. ***************************************/
  13. #include "zstd_compress_superblock.h"
  14. #include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */
  15. #include "hist.h" /* HIST_countFast_wksp */
  16. #include "zstd_compress_internal.h"
  17. #include "zstd_compress_sequences.h"
  18. #include "zstd_compress_literals.h"
  19. /*-*************************************
  20. * Superblock entropy buffer structs
  21. ***************************************/
  22. /** ZSTD_hufCTablesMetadata_t :
  23. * Stores Literals Block Type for a super-block in hType, and
  24. * huffman tree description in hufDesBuffer.
  25. * hufDesSize refers to the size of huffman tree description in bytes.
  26. * This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
  27. typedef struct {
  28. symbolEncodingType_e hType;
  29. BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
  30. size_t hufDesSize;
  31. } ZSTD_hufCTablesMetadata_t;
  32. /** ZSTD_fseCTablesMetadata_t :
  33. * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
  34. * fse tables in fseTablesBuffer.
  35. * fseTablesSize refers to the size of fse tables in bytes.
  36. * This metadata is populated in ZSTD_buildSuperBlockEntropy_sequences() */
  37. typedef struct {
  38. symbolEncodingType_e llType;
  39. symbolEncodingType_e ofType;
  40. symbolEncodingType_e mlType;
  41. BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
  42. size_t fseTablesSize;
  43. size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
  44. } ZSTD_fseCTablesMetadata_t;
  45. typedef struct {
  46. ZSTD_hufCTablesMetadata_t hufMetadata;
  47. ZSTD_fseCTablesMetadata_t fseMetadata;
  48. } ZSTD_entropyCTablesMetadata_t;
  49. /** ZSTD_buildSuperBlockEntropy_literal() :
  50. * Builds entropy for the super-block literals.
  51. * Stores literals block type (raw, rle, compressed, repeat) and
  52. * huffman description table to hufMetadata.
  53. * @return : size of huffman description table or error code */
  54. static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSize,
  55. const ZSTD_hufCTables_t* prevHuf,
  56. ZSTD_hufCTables_t* nextHuf,
  57. ZSTD_hufCTablesMetadata_t* hufMetadata,
  58. const int disableLiteralsCompression,
  59. void* workspace, size_t wkspSize)
  60. {
  61. BYTE* const wkspStart = (BYTE*)workspace;
  62. BYTE* const wkspEnd = wkspStart + wkspSize;
  63. BYTE* const countWkspStart = wkspStart;
  64. unsigned* const countWksp = (unsigned*)workspace;
  65. const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
  66. BYTE* const nodeWksp = countWkspStart + countWkspSize;
  67. const size_t nodeWkspSize = wkspEnd-nodeWksp;
  68. unsigned maxSymbolValue = 255;
  69. unsigned huffLog = HUF_TABLELOG_DEFAULT;
  70. HUF_repeat repeat = prevHuf->repeatMode;
  71. DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
  72. /* Prepare nextEntropy assuming reusing the existing table */
  73. ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
  74. if (disableLiteralsCompression) {
  75. DEBUGLOG(5, "set_basic - disabled");
  76. hufMetadata->hType = set_basic;
  77. return 0;
  78. }
  79. /* small ? don't even attempt compression (speed opt) */
  80. # define COMPRESS_LITERALS_SIZE_MIN 63
  81. { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
  82. if (srcSize <= minLitSize) {
  83. DEBUGLOG(5, "set_basic - too small");
  84. hufMetadata->hType = set_basic;
  85. return 0;
  86. }
  87. }
  88. /* Scan input and build symbol stats */
  89. { size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize);
  90. FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
  91. if (largest == srcSize) {
  92. DEBUGLOG(5, "set_rle");
  93. hufMetadata->hType = set_rle;
  94. return 0;
  95. }
  96. if (largest <= (srcSize >> 7)+4) {
  97. DEBUGLOG(5, "set_basic - no gain");
  98. hufMetadata->hType = set_basic;
  99. return 0;
  100. }
  101. }
  102. /* Validate the previous Huffman table */
  103. if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
  104. repeat = HUF_repeat_none;
  105. }
  106. /* Build Huffman Tree */
  107. ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
  108. huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
  109. { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
  110. maxSymbolValue, huffLog,
  111. nodeWksp, nodeWkspSize);
  112. FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
  113. huffLog = (U32)maxBits;
  114. { /* Build and write the CTable */
  115. size_t const newCSize = HUF_estimateCompressedSize(
  116. (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
  117. size_t const hSize = HUF_writeCTable(
  118. hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
  119. (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog);
  120. /* Check against repeating the previous CTable */
  121. if (repeat != HUF_repeat_none) {
  122. size_t const oldCSize = HUF_estimateCompressedSize(
  123. (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
  124. if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
  125. DEBUGLOG(5, "set_repeat - smaller");
  126. ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
  127. hufMetadata->hType = set_repeat;
  128. return 0;
  129. }
  130. }
  131. if (newCSize + hSize >= srcSize) {
  132. DEBUGLOG(5, "set_basic - no gains");
  133. ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
  134. hufMetadata->hType = set_basic;
  135. return 0;
  136. }
  137. DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
  138. hufMetadata->hType = set_compressed;
  139. nextHuf->repeatMode = HUF_repeat_check;
  140. return hSize;
  141. }
  142. }
  143. }
  144. /** ZSTD_buildSuperBlockEntropy_sequences() :
  145. * Builds entropy for the super-block sequences.
  146. * Stores symbol compression modes and fse table to fseMetadata.
  147. * @return : size of fse tables or error code */
  148. static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
  149. const ZSTD_fseCTables_t* prevEntropy,
  150. ZSTD_fseCTables_t* nextEntropy,
  151. const ZSTD_CCtx_params* cctxParams,
  152. ZSTD_fseCTablesMetadata_t* fseMetadata,
  153. void* workspace, size_t wkspSize)
  154. {
  155. BYTE* const wkspStart = (BYTE*)workspace;
  156. BYTE* const wkspEnd = wkspStart + wkspSize;
  157. BYTE* const countWkspStart = wkspStart;
  158. unsigned* const countWksp = (unsigned*)workspace;
  159. const size_t countWkspSize = (MaxSeq + 1) * sizeof(unsigned);
  160. BYTE* const cTableWksp = countWkspStart + countWkspSize;
  161. const size_t cTableWkspSize = wkspEnd-cTableWksp;
  162. ZSTD_strategy const strategy = cctxParams->cParams.strategy;
  163. FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
  164. FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
  165. FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
  166. const BYTE* const ofCodeTable = seqStorePtr->ofCode;
  167. const BYTE* const llCodeTable = seqStorePtr->llCode;
  168. const BYTE* const mlCodeTable = seqStorePtr->mlCode;
  169. size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
  170. BYTE* const ostart = fseMetadata->fseTablesBuffer;
  171. BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
  172. BYTE* op = ostart;
  173. assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
  174. DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
  175. ZSTD_memset(workspace, 0, wkspSize);
  176. fseMetadata->lastCountSize = 0;
  177. /* convert length/distances into codes */
  178. ZSTD_seqToCodes(seqStorePtr);
  179. /* build CTable for Literal Lengths */
  180. { U32 LLtype;
  181. unsigned max = MaxLL;
  182. size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
  183. DEBUGLOG(5, "Building LL table");
  184. nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
  185. LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
  186. countWksp, max, mostFrequent, nbSeq,
  187. LLFSELog, prevEntropy->litlengthCTable,
  188. LL_defaultNorm, LL_defaultNormLog,
  189. ZSTD_defaultAllowed, strategy);
  190. assert(set_basic < set_compressed && set_rle < set_compressed);
  191. assert(!(LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  192. { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
  193. countWksp, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
  194. prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
  195. cTableWksp, cTableWkspSize);
  196. FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
  197. if (LLtype == set_compressed)
  198. fseMetadata->lastCountSize = countSize;
  199. op += countSize;
  200. fseMetadata->llType = (symbolEncodingType_e) LLtype;
  201. } }
  202. /* build CTable for Offsets */
  203. { U32 Offtype;
  204. unsigned max = MaxOff;
  205. size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
  206. /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
  207. ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
  208. DEBUGLOG(5, "Building OF table");
  209. nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
  210. Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
  211. countWksp, max, mostFrequent, nbSeq,
  212. OffFSELog, prevEntropy->offcodeCTable,
  213. OF_defaultNorm, OF_defaultNormLog,
  214. defaultPolicy, strategy);
  215. assert(!(Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  216. { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
  217. countWksp, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  218. prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
  219. cTableWksp, cTableWkspSize);
  220. FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
  221. if (Offtype == set_compressed)
  222. fseMetadata->lastCountSize = countSize;
  223. op += countSize;
  224. fseMetadata->ofType = (symbolEncodingType_e) Offtype;
  225. } }
  226. /* build CTable for MatchLengths */
  227. { U32 MLtype;
  228. unsigned max = MaxML;
  229. size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
  230. DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
  231. nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
  232. MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode,
  233. countWksp, max, mostFrequent, nbSeq,
  234. MLFSELog, prevEntropy->matchlengthCTable,
  235. ML_defaultNorm, ML_defaultNormLog,
  236. ZSTD_defaultAllowed, strategy);
  237. assert(!(MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
  238. { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
  239. countWksp, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
  240. prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
  241. cTableWksp, cTableWkspSize);
  242. FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
  243. if (MLtype == set_compressed)
  244. fseMetadata->lastCountSize = countSize;
  245. op += countSize;
  246. fseMetadata->mlType = (symbolEncodingType_e) MLtype;
  247. } }
  248. assert((size_t) (op-ostart) <= sizeof(fseMetadata->fseTablesBuffer));
  249. return op-ostart;
  250. }
  251. /** ZSTD_buildSuperBlockEntropy() :
  252. * Builds entropy for the super-block.
  253. * @return : 0 on success or error code */
  254. static size_t
  255. ZSTD_buildSuperBlockEntropy(seqStore_t* seqStorePtr,
  256. const ZSTD_entropyCTables_t* prevEntropy,
  257. ZSTD_entropyCTables_t* nextEntropy,
  258. const ZSTD_CCtx_params* cctxParams,
  259. ZSTD_entropyCTablesMetadata_t* entropyMetadata,
  260. void* workspace, size_t wkspSize)
  261. {
  262. size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart;
  263. DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy");
  264. entropyMetadata->hufMetadata.hufDesSize =
  265. ZSTD_buildSuperBlockEntropy_literal(seqStorePtr->litStart, litSize,
  266. &prevEntropy->huf, &nextEntropy->huf,
  267. &entropyMetadata->hufMetadata,
  268. ZSTD_disableLiteralsCompression(cctxParams),
  269. workspace, wkspSize);
  270. FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildSuperBlockEntropy_literal failed");
  271. entropyMetadata->fseMetadata.fseTablesSize =
  272. ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr,
  273. &prevEntropy->fse, &nextEntropy->fse,
  274. cctxParams,
  275. &entropyMetadata->fseMetadata,
  276. workspace, wkspSize);
  277. FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildSuperBlockEntropy_sequences failed");
  278. return 0;
  279. }
  280. /** ZSTD_compressSubBlock_literal() :
  281. * Compresses literals section for a sub-block.
  282. * When we have to write the Huffman table we will sometimes choose a header
  283. * size larger than necessary. This is because we have to pick the header size
  284. * before we know the table size + compressed size, so we have a bound on the
  285. * table size. If we guessed incorrectly, we fall back to uncompressed literals.
  286. *
  287. * We write the header when writeEntropy=1 and set entropyWrriten=1 when we succeeded
  288. * in writing the header, otherwise it is set to 0.
  289. *
  290. * hufMetadata->hType has literals block type info.
  291. * If it is set_basic, all sub-blocks literals section will be Raw_Literals_Block.
  292. * If it is set_rle, all sub-blocks literals section will be RLE_Literals_Block.
  293. * If it is set_compressed, first sub-block's literals section will be Compressed_Literals_Block
  294. * If it is set_compressed, first sub-block's literals section will be Treeless_Literals_Block
  295. * and the following sub-blocks' literals sections will be Treeless_Literals_Block.
  296. * @return : compressed size of literals section of a sub-block
  297. * Or 0 if it unable to compress.
  298. * Or error code */
  299. static size_t ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable,
  300. const ZSTD_hufCTablesMetadata_t* hufMetadata,
  301. const BYTE* literals, size_t litSize,
  302. void* dst, size_t dstSize,
  303. const int bmi2, int writeEntropy, int* entropyWritten)
  304. {
  305. size_t const header = writeEntropy ? 200 : 0;
  306. size_t const lhSize = 3 + (litSize >= (1 KB - header)) + (litSize >= (16 KB - header));
  307. BYTE* const ostart = (BYTE*)dst;
  308. BYTE* const oend = ostart + dstSize;
  309. BYTE* op = ostart + lhSize;
  310. U32 const singleStream = lhSize == 3;
  311. symbolEncodingType_e hType = writeEntropy ? hufMetadata->hType : set_repeat;
  312. size_t cLitSize = 0;
  313. (void)bmi2; /* TODO bmi2... */
  314. DEBUGLOG(5, "ZSTD_compressSubBlock_literal (litSize=%zu, lhSize=%zu, writeEntropy=%d)", litSize, lhSize, writeEntropy);
  315. *entropyWritten = 0;
  316. if (litSize == 0 || hufMetadata->hType == set_basic) {
  317. DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal");
  318. return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
  319. } else if (hufMetadata->hType == set_rle) {
  320. DEBUGLOG(5, "ZSTD_compressSubBlock_literal using rle literal");
  321. return ZSTD_compressRleLiteralsBlock(dst, dstSize, literals, litSize);
  322. }
  323. assert(litSize > 0);
  324. assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat);
  325. if (writeEntropy && hufMetadata->hType == set_compressed) {
  326. ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
  327. op += hufMetadata->hufDesSize;
  328. cLitSize += hufMetadata->hufDesSize;
  329. DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize);
  330. }
  331. /* TODO bmi2 */
  332. { const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, oend-op, literals, litSize, hufTable)
  333. : HUF_compress4X_usingCTable(op, oend-op, literals, litSize, hufTable);
  334. op += cSize;
  335. cLitSize += cSize;
  336. if (cSize == 0 || ERR_isError(cSize)) {
  337. DEBUGLOG(5, "Failed to write entropy tables %s", ZSTD_getErrorName(cSize));
  338. return 0;
  339. }
  340. /* If we expand and we aren't writing a header then emit uncompressed */
  341. if (!writeEntropy && cLitSize >= litSize) {
  342. DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal because uncompressible");
  343. return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
  344. }
  345. /* If we are writing headers then allow expansion that doesn't change our header size. */
  346. if (lhSize < (size_t)(3 + (cLitSize >= 1 KB) + (cLitSize >= 16 KB))) {
  347. assert(cLitSize > litSize);
  348. DEBUGLOG(5, "Literals expanded beyond allowed header size");
  349. return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize);
  350. }
  351. DEBUGLOG(5, "ZSTD_compressSubBlock_literal (cSize=%zu)", cSize);
  352. }
  353. /* Build header */
  354. switch(lhSize)
  355. {
  356. case 3: /* 2 - 2 - 10 - 10 */
  357. { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14);
  358. MEM_writeLE24(ostart, lhc);
  359. break;
  360. }
  361. case 4: /* 2 - 2 - 14 - 14 */
  362. { U32 const lhc = hType + (2 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<18);
  363. MEM_writeLE32(ostart, lhc);
  364. break;
  365. }
  366. case 5: /* 2 - 2 - 18 - 18 */
  367. { U32 const lhc = hType + (3 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<22);
  368. MEM_writeLE32(ostart, lhc);
  369. ostart[4] = (BYTE)(cLitSize >> 10);
  370. break;
  371. }
  372. default: /* not possible : lhSize is {3,4,5} */
  373. assert(0);
  374. }
  375. *entropyWritten = 1;
  376. DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart));
  377. return op-ostart;
  378. }
  379. static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef* sequences, size_t nbSeq, size_t litSize, int lastSequence) {
  380. const seqDef* const sstart = sequences;
  381. const seqDef* const send = sequences + nbSeq;
  382. const seqDef* sp = sstart;
  383. size_t matchLengthSum = 0;
  384. size_t litLengthSum = 0;
  385. while (send-sp > 0) {
  386. ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp);
  387. litLengthSum += seqLen.litLength;
  388. matchLengthSum += seqLen.matchLength;
  389. sp++;
  390. }
  391. assert(litLengthSum <= litSize);
  392. if (!lastSequence) {
  393. assert(litLengthSum == litSize);
  394. }
  395. return matchLengthSum + litSize;
  396. }
  397. /** ZSTD_compressSubBlock_sequences() :
  398. * Compresses sequences section for a sub-block.
  399. * fseMetadata->llType, fseMetadata->ofType, and fseMetadata->mlType have
  400. * symbol compression modes for the super-block.
  401. * The first successfully compressed block will have these in its header.
  402. * We set entropyWritten=1 when we succeed in compressing the sequences.
  403. * The following sub-blocks will always have repeat mode.
  404. * @return : compressed size of sequences section of a sub-block
  405. * Or 0 if it is unable to compress
  406. * Or error code. */
  407. static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables,
  408. const ZSTD_fseCTablesMetadata_t* fseMetadata,
  409. const seqDef* sequences, size_t nbSeq,
  410. const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode,
  411. const ZSTD_CCtx_params* cctxParams,
  412. void* dst, size_t dstCapacity,
  413. const int bmi2, int writeEntropy, int* entropyWritten)
  414. {
  415. const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
  416. BYTE* const ostart = (BYTE*)dst;
  417. BYTE* const oend = ostart + dstCapacity;
  418. BYTE* op = ostart;
  419. BYTE* seqHead;
  420. DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (nbSeq=%zu, writeEntropy=%d, longOffsets=%d)", nbSeq, writeEntropy, longOffsets);
  421. *entropyWritten = 0;
  422. /* Sequences Header */
  423. RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
  424. dstSize_tooSmall, "");
  425. if (nbSeq < 0x7F)
  426. *op++ = (BYTE)nbSeq;
  427. else if (nbSeq < LONGNBSEQ)
  428. op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
  429. else
  430. op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
  431. if (nbSeq==0) {
  432. return op - ostart;
  433. }
  434. /* seqHead : flags for FSE encoding type */
  435. seqHead = op++;
  436. DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (seqHeadSize=%u)", (unsigned)(op-ostart));
  437. if (writeEntropy) {
  438. const U32 LLtype = fseMetadata->llType;
  439. const U32 Offtype = fseMetadata->ofType;
  440. const U32 MLtype = fseMetadata->mlType;
  441. DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize);
  442. *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
  443. ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
  444. op += fseMetadata->fseTablesSize;
  445. } else {
  446. const U32 repeat = set_repeat;
  447. *seqHead = (BYTE)((repeat<<6) + (repeat<<4) + (repeat<<2));
  448. }
  449. { size_t const bitstreamSize = ZSTD_encodeSequences(
  450. op, oend - op,
  451. fseTables->matchlengthCTable, mlCode,
  452. fseTables->offcodeCTable, ofCode,
  453. fseTables->litlengthCTable, llCode,
  454. sequences, nbSeq,
  455. longOffsets, bmi2);
  456. FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed");
  457. op += bitstreamSize;
  458. /* zstd versions <= 1.3.4 mistakenly report corruption when
  459. * FSE_readNCount() receives a buffer < 4 bytes.
  460. * Fixed by https://github.com/facebook/zstd/pull/1146.
  461. * This can happen when the last set_compressed table present is 2
  462. * bytes and the bitstream is only one byte.
  463. * In this exceedingly rare case, we will simply emit an uncompressed
  464. * block, since it isn't worth optimizing.
  465. */
  466. #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  467. if (writeEntropy && fseMetadata->lastCountSize && fseMetadata->lastCountSize + bitstreamSize < 4) {
  468. /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
  469. assert(fseMetadata->lastCountSize + bitstreamSize == 3);
  470. DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
  471. "emitting an uncompressed block.");
  472. return 0;
  473. }
  474. #endif
  475. DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (bitstreamSize=%zu)", bitstreamSize);
  476. }
  477. /* zstd versions <= 1.4.0 mistakenly report error when
  478. * sequences section body size is less than 3 bytes.
  479. * Fixed by https://github.com/facebook/zstd/pull/1664.
  480. * This can happen when the previous sequences section block is compressed
  481. * with rle mode and the current block's sequences section is compressed
  482. * with repeat mode where sequences section body size can be 1 byte.
  483. */
  484. #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
  485. if (op-seqHead < 4) {
  486. DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.4.0 by emitting "
  487. "an uncompressed block when sequences are < 4 bytes");
  488. return 0;
  489. }
  490. #endif
  491. *entropyWritten = 1;
  492. return op - ostart;
  493. }
  494. /** ZSTD_compressSubBlock() :
  495. * Compresses a single sub-block.
  496. * @return : compressed size of the sub-block
  497. * Or 0 if it failed to compress. */
  498. static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy,
  499. const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
  500. const seqDef* sequences, size_t nbSeq,
  501. const BYTE* literals, size_t litSize,
  502. const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode,
  503. const ZSTD_CCtx_params* cctxParams,
  504. void* dst, size_t dstCapacity,
  505. const int bmi2,
  506. int writeLitEntropy, int writeSeqEntropy,
  507. int* litEntropyWritten, int* seqEntropyWritten,
  508. U32 lastBlock)
  509. {
  510. BYTE* const ostart = (BYTE*)dst;
  511. BYTE* const oend = ostart + dstCapacity;
  512. BYTE* op = ostart + ZSTD_blockHeaderSize;
  513. DEBUGLOG(5, "ZSTD_compressSubBlock (litSize=%zu, nbSeq=%zu, writeLitEntropy=%d, writeSeqEntropy=%d, lastBlock=%d)",
  514. litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock);
  515. { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable,
  516. &entropyMetadata->hufMetadata, literals, litSize,
  517. op, oend-op, bmi2, writeLitEntropy, litEntropyWritten);
  518. FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed");
  519. if (cLitSize == 0) return 0;
  520. op += cLitSize;
  521. }
  522. { size_t cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse,
  523. &entropyMetadata->fseMetadata,
  524. sequences, nbSeq,
  525. llCode, mlCode, ofCode,
  526. cctxParams,
  527. op, oend-op,
  528. bmi2, writeSeqEntropy, seqEntropyWritten);
  529. FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed");
  530. if (cSeqSize == 0) return 0;
  531. op += cSeqSize;
  532. }
  533. /* Write block header */
  534. { size_t cSize = (op-ostart)-ZSTD_blockHeaderSize;
  535. U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
  536. MEM_writeLE24(ostart, cBlockHeader24);
  537. }
  538. return op-ostart;
  539. }
  540. static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize,
  541. const ZSTD_hufCTables_t* huf,
  542. const ZSTD_hufCTablesMetadata_t* hufMetadata,
  543. void* workspace, size_t wkspSize,
  544. int writeEntropy)
  545. {
  546. unsigned* const countWksp = (unsigned*)workspace;
  547. unsigned maxSymbolValue = 255;
  548. size_t literalSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
  549. if (hufMetadata->hType == set_basic) return litSize;
  550. else if (hufMetadata->hType == set_rle) return 1;
  551. else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) {
  552. size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize);
  553. if (ZSTD_isError(largest)) return litSize;
  554. { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue);
  555. if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize;
  556. return cLitSizeEstimate + literalSectionHeaderSize;
  557. } }
  558. assert(0); /* impossible */
  559. return 0;
  560. }
  561. static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
  562. const BYTE* codeTable, unsigned maxCode,
  563. size_t nbSeq, const FSE_CTable* fseCTable,
  564. const U32* additionalBits,
  565. short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
  566. void* workspace, size_t wkspSize)
  567. {
  568. unsigned* const countWksp = (unsigned*)workspace;
  569. const BYTE* ctp = codeTable;
  570. const BYTE* const ctStart = ctp;
  571. const BYTE* const ctEnd = ctStart + nbSeq;
  572. size_t cSymbolTypeSizeEstimateInBits = 0;
  573. unsigned max = maxCode;
  574. HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
  575. if (type == set_basic) {
  576. /* We selected this encoding type, so it must be valid. */
  577. assert(max <= defaultMax);
  578. cSymbolTypeSizeEstimateInBits = max <= defaultMax
  579. ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max)
  580. : ERROR(GENERIC);
  581. } else if (type == set_rle) {
  582. cSymbolTypeSizeEstimateInBits = 0;
  583. } else if (type == set_compressed || type == set_repeat) {
  584. cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max);
  585. }
  586. if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) return nbSeq * 10;
  587. while (ctp < ctEnd) {
  588. if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp];
  589. else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */
  590. ctp++;
  591. }
  592. return cSymbolTypeSizeEstimateInBits / 8;
  593. }
  594. static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
  595. const BYTE* llCodeTable,
  596. const BYTE* mlCodeTable,
  597. size_t nbSeq,
  598. const ZSTD_fseCTables_t* fseTables,
  599. const ZSTD_fseCTablesMetadata_t* fseMetadata,
  600. void* workspace, size_t wkspSize,
  601. int writeEntropy)
  602. {
  603. size_t sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
  604. size_t cSeqSizeEstimate = 0;
  605. cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
  606. nbSeq, fseTables->offcodeCTable, NULL,
  607. OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
  608. workspace, wkspSize);
  609. cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL,
  610. nbSeq, fseTables->litlengthCTable, LL_bits,
  611. LL_defaultNorm, LL_defaultNormLog, MaxLL,
  612. workspace, wkspSize);
  613. cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML,
  614. nbSeq, fseTables->matchlengthCTable, ML_bits,
  615. ML_defaultNorm, ML_defaultNormLog, MaxML,
  616. workspace, wkspSize);
  617. if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
  618. return cSeqSizeEstimate + sequencesSectionHeaderSize;
  619. }
  620. static size_t ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize,
  621. const BYTE* ofCodeTable,
  622. const BYTE* llCodeTable,
  623. const BYTE* mlCodeTable,
  624. size_t nbSeq,
  625. const ZSTD_entropyCTables_t* entropy,
  626. const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
  627. void* workspace, size_t wkspSize,
  628. int writeLitEntropy, int writeSeqEntropy) {
  629. size_t cSizeEstimate = 0;
  630. cSizeEstimate += ZSTD_estimateSubBlockSize_literal(literals, litSize,
  631. &entropy->huf, &entropyMetadata->hufMetadata,
  632. workspace, wkspSize, writeLitEntropy);
  633. cSizeEstimate += ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable,
  634. nbSeq, &entropy->fse, &entropyMetadata->fseMetadata,
  635. workspace, wkspSize, writeSeqEntropy);
  636. return cSizeEstimate + ZSTD_blockHeaderSize;
  637. }
  638. static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata)
  639. {
  640. if (fseMetadata->llType == set_compressed || fseMetadata->llType == set_rle)
  641. return 1;
  642. if (fseMetadata->mlType == set_compressed || fseMetadata->mlType == set_rle)
  643. return 1;
  644. if (fseMetadata->ofType == set_compressed || fseMetadata->ofType == set_rle)
  645. return 1;
  646. return 0;
  647. }
  648. /** ZSTD_compressSubBlock_multi() :
  649. * Breaks super-block into multiple sub-blocks and compresses them.
  650. * Entropy will be written to the first block.
  651. * The following blocks will use repeat mode to compress.
  652. * All sub-blocks are compressed blocks (no raw or rle blocks).
  653. * @return : compressed size of the super block (which is multiple ZSTD blocks)
  654. * Or 0 if it failed to compress. */
  655. static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
  656. const ZSTD_compressedBlockState_t* prevCBlock,
  657. ZSTD_compressedBlockState_t* nextCBlock,
  658. const ZSTD_entropyCTablesMetadata_t* entropyMetadata,
  659. const ZSTD_CCtx_params* cctxParams,
  660. void* dst, size_t dstCapacity,
  661. const void* src, size_t srcSize,
  662. const int bmi2, U32 lastBlock,
  663. void* workspace, size_t wkspSize)
  664. {
  665. const seqDef* const sstart = seqStorePtr->sequencesStart;
  666. const seqDef* const send = seqStorePtr->sequences;
  667. const seqDef* sp = sstart;
  668. const BYTE* const lstart = seqStorePtr->litStart;
  669. const BYTE* const lend = seqStorePtr->lit;
  670. const BYTE* lp = lstart;
  671. BYTE const* ip = (BYTE const*)src;
  672. BYTE const* const iend = ip + srcSize;
  673. BYTE* const ostart = (BYTE*)dst;
  674. BYTE* const oend = ostart + dstCapacity;
  675. BYTE* op = ostart;
  676. const BYTE* llCodePtr = seqStorePtr->llCode;
  677. const BYTE* mlCodePtr = seqStorePtr->mlCode;
  678. const BYTE* ofCodePtr = seqStorePtr->ofCode;
  679. size_t targetCBlockSize = cctxParams->targetCBlockSize;
  680. size_t litSize, seqCount;
  681. int writeLitEntropy = entropyMetadata->hufMetadata.hType == set_compressed;
  682. int writeSeqEntropy = 1;
  683. int lastSequence = 0;
  684. DEBUGLOG(5, "ZSTD_compressSubBlock_multi (litSize=%u, nbSeq=%u)",
  685. (unsigned)(lend-lp), (unsigned)(send-sstart));
  686. litSize = 0;
  687. seqCount = 0;
  688. do {
  689. size_t cBlockSizeEstimate = 0;
  690. if (sstart == send) {
  691. lastSequence = 1;
  692. } else {
  693. const seqDef* const sequence = sp + seqCount;
  694. lastSequence = sequence == send - 1;
  695. litSize += ZSTD_getSequenceLength(seqStorePtr, sequence).litLength;
  696. seqCount++;
  697. }
  698. if (lastSequence) {
  699. assert(lp <= lend);
  700. assert(litSize <= (size_t)(lend - lp));
  701. litSize = (size_t)(lend - lp);
  702. }
  703. /* I think there is an optimization opportunity here.
  704. * Calling ZSTD_estimateSubBlockSize for every sequence can be wasteful
  705. * since it recalculates estimate from scratch.
  706. * For example, it would recount literal distribution and symbol codes everytime.
  707. */
  708. cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount,
  709. &nextCBlock->entropy, entropyMetadata,
  710. workspace, wkspSize, writeLitEntropy, writeSeqEntropy);
  711. if (cBlockSizeEstimate > targetCBlockSize || lastSequence) {
  712. int litEntropyWritten = 0;
  713. int seqEntropyWritten = 0;
  714. const size_t decompressedSize = ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, lastSequence);
  715. const size_t cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata,
  716. sp, seqCount,
  717. lp, litSize,
  718. llCodePtr, mlCodePtr, ofCodePtr,
  719. cctxParams,
  720. op, oend-op,
  721. bmi2, writeLitEntropy, writeSeqEntropy,
  722. &litEntropyWritten, &seqEntropyWritten,
  723. lastBlock && lastSequence);
  724. FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed");
  725. if (cSize > 0 && cSize < decompressedSize) {
  726. DEBUGLOG(5, "Committed the sub-block");
  727. assert(ip + decompressedSize <= iend);
  728. ip += decompressedSize;
  729. sp += seqCount;
  730. lp += litSize;
  731. op += cSize;
  732. llCodePtr += seqCount;
  733. mlCodePtr += seqCount;
  734. ofCodePtr += seqCount;
  735. litSize = 0;
  736. seqCount = 0;
  737. /* Entropy only needs to be written once */
  738. if (litEntropyWritten) {
  739. writeLitEntropy = 0;
  740. }
  741. if (seqEntropyWritten) {
  742. writeSeqEntropy = 0;
  743. }
  744. }
  745. }
  746. } while (!lastSequence);
  747. if (writeLitEntropy) {
  748. DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten");
  749. ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
  750. }
  751. if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) {
  752. /* If we haven't written our entropy tables, then we've violated our contract and
  753. * must emit an uncompressed block.
  754. */
  755. DEBUGLOG(5, "ZSTD_compressSubBlock_multi has sequence entropy tables unwritten");
  756. return 0;
  757. }
  758. if (ip < iend) {
  759. size_t const cSize = ZSTD_noCompressBlock(op, oend - op, ip, iend - ip, lastBlock);
  760. DEBUGLOG(5, "ZSTD_compressSubBlock_multi last sub-block uncompressed, %zu bytes", (size_t)(iend - ip));
  761. FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
  762. assert(cSize != 0);
  763. op += cSize;
  764. /* We have to regenerate the repcodes because we've skipped some sequences */
  765. if (sp < send) {
  766. seqDef const* seq;
  767. repcodes_t rep;
  768. ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep));
  769. for (seq = sstart; seq < sp; ++seq) {
  770. rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
  771. }
  772. ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep));
  773. }
  774. }
  775. DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed");
  776. return op-ostart;
  777. }
  778. size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
  779. void* dst, size_t dstCapacity,
  780. void const* src, size_t srcSize,
  781. unsigned lastBlock) {
  782. ZSTD_entropyCTablesMetadata_t entropyMetadata;
  783. FORWARD_IF_ERROR(ZSTD_buildSuperBlockEntropy(&zc->seqStore,
  784. &zc->blockState.prevCBlock->entropy,
  785. &zc->blockState.nextCBlock->entropy,
  786. &zc->appliedParams,
  787. &entropyMetadata,
  788. zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
  789. return ZSTD_compressSubBlock_multi(&zc->seqStore,
  790. zc->blockState.prevCBlock,
  791. zc->blockState.nextCBlock,
  792. &entropyMetadata,
  793. &zc->appliedParams,
  794. dst, dstCapacity,
  795. src, srcSize,
  796. zc->bmi2, lastBlock,
  797. zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
  798. }