GPAK  1.0.0
A general-purpose archive library

◆ _gpak_decompressor_zstd()

GPAK_API uint32_t _gpak_decompressor_zstd ( gpak_t _pak,
FILE *  _infile,
FILE *  _outfile,
size_t  _read_size 
)
Brief Description:\n Decompresses the input file using the Zstandard (zstd) algorithm.
This function decompresses the input file using the Zstandard (zstd) algorithm and writes the decompressed data to the output file.
Parameters
_pakA pointer to the gpak_t.
_infileA pointer to the input FILE.
_outfileA pointer to the output FILE.
_read_sizeThe number of bytes to read from the input file.
Returns
The number of bytes written to the output file.

Definition at line 291 of file gpak_compressors.c.

292 {
293  size_t const buffInSize = ZSTD_DStreamInSize();
294  void* const buffIn = malloc(buffInSize);
295  size_t const buffOutSize = ZSTD_DStreamOutSize();
296  void* const buffOut = malloc(buffOutSize);
297 
298  uint32_t _crc32 = crc32(0L, Z_NULL, 0);
299 
300  ZSTD_DCtx* const dctx = ZSTD_createDCtx();
301  assert(dctx != NULL && "ZSTD_createDCtx() failed!");
302 
303  if (_pak->dictionary_ && _pak->header_.dictionary_size_ > 0)
304  ZSTD_DCtx_loadDictionary(dctx, _pak->dictionary_, _pak->header_.dictionary_size_);
305 
306  size_t bytesRead = 0;
307  size_t lastRet = 0;
308  int isEmpty = 1;
309 
310  while (bytesRead < _read_size)
311  {
312  size_t const toRead = (bytesRead + buffInSize <= _read_size) ? buffInSize : (_read_size - bytesRead);
313  size_t read = _freadb(buffIn, 1, toRead, _infile);
314 
315  if (!read)
316  {
317  break;
318  }
319 
320  bytesRead += read;
321 
322  _gpak_pass_progress(_pak, bytesRead, _read_size, GPAK_STAGE_DECOMPRESSION);
323 
324  isEmpty = 0;
325  ZSTD_inBuffer input = { buffIn, read, 0 };
326  while (input.pos < input.size)
327  {
328  ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
329  size_t const ret = ZSTD_decompressStream(dctx, &output, &input);
330 
331  _crc32 = crc32(_crc32, buffOut, output.pos);
332 
333  _fwriteb(buffOut, 1, output.pos, _outfile);
334  lastRet = ret;
335  }
336  }
337 
338  if (isEmpty)
339  {
340  _gpak_make_error(_pak, GPAK_ERROR_EMPTY_INPUT);
341  goto clear;
342  }
343 
344  if (lastRet != 0)
345  {
346  _gpak_make_error(_pak, GPAK_ERROR_EOF_BEFORE_EOS);
347  goto clear;
348  }
349 
350 clear:
351  ZSTD_freeDCtx(dctx);
352  free(buffIn);
353  free(buffOut);
354 
355  return _crc32;
356 }
@ GPAK_ERROR_EMPTY_INPUT
Definition: gpak_data.h:181
@ GPAK_ERROR_EOF_BEFORE_EOS
Definition: gpak_data.h:182
@ GPAK_STAGE_DECOMPRESSION
Definition: gpak_data.h:227
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::dictionary_, gpak_header::dictionary_size_, GPAK_ERROR_EMPTY_INPUT, GPAK_ERROR_EOF_BEFORE_EOS, GPAK_STAGE_DECOMPRESSION, and gpak::header_.

Referenced by gpak_fopen().