GPAK  1.0.0
A general-purpose archive library

◆ _gpak_compressor_zstd()

GPAK_API uint32_t _gpak_compressor_zstd ( gpak_t _pak,
FILE *  _infile,
FILE *  _outfile 
)
Brief Description:\n Compresses the input file using the Zstandard (zstd) algorithm.

This function compresses the input file using the Zstandard (zstd) algorithm and writes the compressed data to the output file.

Parameters
_pakA pointer to the gpak_t.
_infileA pointer to the input FILE.
_outfileA pointer to the output FILE.
Returns
The number of bytes written to the output file.

Definition at line 227 of file gpak_compressors.c.

228 {
229  size_t const buffInSize = ZSTD_CStreamInSize();
230  void* const buffIn = malloc(buffInSize);
231  size_t const buffOutSize = ZSTD_CStreamOutSize();
232  void* const buffOut = malloc(buffOutSize);
233 
234  fseek(_infile, 0, SEEK_END);
235  size_t _total_size = ftell(_infile);
236  fseek(_infile, 0, SEEK_SET);
237 
238  uint32_t _crc32 = crc32(0L, Z_NULL, 0);
239 
240  /* Create the context. */
241  ZSTD_CCtx* const cctx = ZSTD_createCCtx();
242 
243  uint32_t thread_count = get_num_threads();
244 
245  /* Set parameters. */
246  ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, _pak->header_.compression_level_);
247  ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1);
248  ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, 1);
249  ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 27);
250  ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, thread_count);
251  ZSTD_CCtx_setParameter(cctx, ZSTD_c_jobSize, buffInSize * thread_count);
252 
253  if (_pak->dictionary_ && _pak->header_.dictionary_size_ > 0)
254  ZSTD_CCtx_loadDictionary(cctx, _pak->dictionary_, _pak->header_.dictionary_size_);
255 
256  size_t _total_readed = 0ull;
257  size_t const toRead = buffInSize;
258  for (;;)
259  {
260  size_t read = _freadb(buffIn, 1, toRead, _infile);
261  _total_readed += read;
262  _crc32 = crc32(_crc32, buffIn, read);
263  _gpak_pass_progress(_pak, _total_readed, _total_size, GPAK_STAGE_COMPRESSION);
264 
265  int const lastChunk = (read < toRead);
266  ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
267 
268  ZSTD_inBuffer input = { buffIn, read, 0 };
269  int finished;
270  do
271  {
272  ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
273  size_t const remaining = ZSTD_compressStream2(cctx, &output, &input, mode);
274  //CHECK_ZSTD(remaining);
275  _fwriteb(buffOut, 1, output.pos, _outfile);
276  finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
277  } while (!finished);
278  assert(input.pos == input.size && "Impossible: zstd only returns 0 when the input is completely consumed!");
279 
280  if (lastChunk)
281  break;
282  }
283 
284  ZSTD_freeCCtx(cctx);
285  free(buffIn);
286  free(buffOut);
287 
288  return _crc32;
289 }
@ GPAK_STAGE_COMPRESSION
Definition: gpak_data.h:226
char compression_level_
Definition: gpak_data.h:114
uint32_t dictionary_size_
Definition: gpak_data.h:116
char * dictionary_
Definition: gpak_data.h:262
pak_header_t header_
Definition: gpak_data.h:258

References gpak_header::compression_level_, gpak::dictionary_, gpak_header::dictionary_size_, GPAK_STAGE_COMPRESSION, and gpak::header_.