3 #include "gpak_helper.h"
13 #include <sys/sysinfo.h>
23 #define _DICTIONARY_SAMPLE_COUNT 200
32 GetSystemInfo(&sysinfo);
33 numThreads = sysinfo.dwNumberOfProcessors;
35 numThreads = sysconf(_SC_THREAD_THREADS_MAX);
44 char* _bufferIn = (
char*)malloc(_DEFAULT_BLOCK_SIZE);
45 size_t _readed = 0ull;
46 uint32_t _crc32 = crc32(0L, Z_NULL, 0);
48 fseek(_infile, 0, SEEK_END);
49 size_t _total_size = ftell(_infile);
50 fseek(_infile, 0, SEEK_SET);
52 size_t bytes_readed = 0ull;
55 _readed = _freadb(_bufferIn, 1ull, _DEFAULT_BLOCK_SIZE, _infile);
56 _crc32 = crc32(_crc32, _bufferIn, _readed);
57 bytes_readed += _readed;
59 _fwriteb(_bufferIn, 1ull, _readed, _outfile);
69 char* _bufferIn = (
char*)malloc(_DEFAULT_BLOCK_SIZE);
70 size_t bytesReaded = 0ull;
71 size_t nextBlockSize = _DEFAULT_BLOCK_SIZE;
73 uint32_t _crc32 = crc32(0L, Z_NULL, 0);
77 size_t _readed = _freadb(_bufferIn, 1ull, nextBlockSize, _infile);
78 _crc32 = crc32(_crc32, _bufferIn, _readed);
80 _fwriteb(_bufferIn, 1ull, _readed, _outfile);
81 bytesReaded += _readed;
84 if (_read_size - bytesReaded < nextBlockSize)
85 nextBlockSize = _read_size - bytesReaded;
86 }
while (bytesReaded != _read_size);
88 if (bytesReaded != _read_size)
100 strm.zalloc = Z_NULL;
102 strm.opaque = Z_NULL;
104 char* _bufferIn = (
char*)malloc(_DEFAULT_BLOCK_SIZE);
105 char* _bufferOut = (
char*)malloc(_DEFAULT_BLOCK_SIZE);
107 fseek(_infile, 0, SEEK_END);
108 size_t _total_size = ftell(_infile);
109 fseek(_infile, 0, SEEK_SET);
115 uint32_t _crc32 = crc32(0L, Z_NULL, 0);
119 size_t _total_readed = 0ull;
122 strm.avail_in = _freadb(_bufferIn, 1ull, _DEFAULT_BLOCK_SIZE, _infile);
123 _total_readed += strm.avail_in;
124 _crc32 = crc32(_crc32, _bufferIn, strm.avail_in);
133 flush = feof(_infile) ? Z_FINISH : Z_NO_FLUSH;
134 strm.next_in = _bufferIn;
138 strm.avail_out = _DEFAULT_BLOCK_SIZE;
139 strm.next_out = _bufferOut;
140 ret = deflate(&strm, flush);
141 assert(ret != Z_STREAM_ERROR);
143 have = _DEFAULT_BLOCK_SIZE - strm.avail_out;
144 if (_fwriteb(_bufferOut, 1ull, have, _outfile) != have || ferror(_outfile))
149 }
while (strm.avail_out == 0);
150 assert(strm.avail_in == 0);
152 }
while (flush != Z_FINISH);
165 strm.zalloc = Z_NULL;
167 strm.opaque = Z_NULL;
169 char* _bufferIn = (
char*)malloc(_DEFAULT_BLOCK_SIZE);
170 char* _bufferOut = (
char*)malloc(_DEFAULT_BLOCK_SIZE);
172 int ret = inflateInit(&strm);
176 uint32_t _crc32 = crc32(0L, Z_NULL, 0);
179 size_t total_read = 0ull;
183 size_t bytes_to_read = _read_size - total_read < _DEFAULT_BLOCK_SIZE ? _read_size - total_read : _DEFAULT_BLOCK_SIZE;
184 strm.avail_in = _freadb(_bufferIn, 1, bytes_to_read, _infile);
185 total_read += strm.avail_in;
188 strm.next_in = _bufferIn;
192 strm.avail_out = _DEFAULT_BLOCK_SIZE;
193 strm.next_out = _bufferOut;
194 ret = inflate(&strm, Z_NO_FLUSH);
195 assert(ret != Z_STREAM_ERROR);
204 have = _DEFAULT_BLOCK_SIZE - strm.avail_out;
206 _crc32 = crc32(_crc32, _bufferOut, have);
208 if (_fwriteb(_bufferOut, 1, have, _outfile) != have || ferror(_outfile))
214 }
while (strm.avail_out == 0);
216 }
while (ret != Z_STREAM_END);
221 (void)inflateEnd(&strm);
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);
234 fseek(_infile, 0, SEEK_END);
235 size_t _total_size = ftell(_infile);
236 fseek(_infile, 0, SEEK_SET);
238 uint32_t _crc32 = crc32(0L, Z_NULL, 0);
241 ZSTD_CCtx*
const cctx = ZSTD_createCCtx();
243 uint32_t thread_count = get_num_threads();
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);
256 size_t _total_readed = 0ull;
257 size_t const toRead = buffInSize;
260 size_t read = _freadb(buffIn, 1, toRead, _infile);
261 _total_readed += read;
262 _crc32 = crc32(_crc32, buffIn, read);
265 int const lastChunk = (read < toRead);
266 ZSTD_EndDirective
const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
268 ZSTD_inBuffer input = { buffIn, read, 0 };
272 ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
273 size_t const remaining = ZSTD_compressStream2(cctx, &output, &input, mode);
275 _fwriteb(buffOut, 1, output.pos, _outfile);
276 finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
278 assert(input.pos == input.size &&
"Impossible: zstd only returns 0 when the input is completely consumed!");
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);
298 uint32_t _crc32 = crc32(0L, Z_NULL, 0);
300 ZSTD_DCtx*
const dctx = ZSTD_createDCtx();
301 assert(dctx != NULL &&
"ZSTD_createDCtx() failed!");
306 size_t bytesRead = 0;
310 while (bytesRead < _read_size)
312 size_t const toRead = (bytesRead + buffInSize <= _read_size) ? buffInSize : (_read_size - bytesRead);
313 size_t read = _freadb(buffIn, 1, toRead, _infile);
325 ZSTD_inBuffer input = { buffIn, read, 0 };
326 while (input.pos < input.size)
328 ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
329 size_t const ret = ZSTD_decompressStream(dctx, &output, &input);
331 _crc32 = crc32(_crc32, buffOut, output.pos);
333 _fwriteb(buffOut, 1, output.pos, _outfile);
360 char* samples = NULL;
361 size_t sample_sizes[_DICTIONARY_SAMPLE_COUNT];
362 size_t samples_count = 0ull;
363 size_t samples_capacity = 0ull;
364 size_t current_offset = 0ull;
370 if (samples_count >= _DICTIONARY_SAMPLE_COUNT - 1)
376 FILE* _infile = fopen(next_file->
path_,
"rb");
378 fseek(_infile, 0, SEEK_END);
379 sample_sizes[samples_count] = ftell(_infile);
380 fseek(_infile, 0, SEEK_SET);
382 samples_capacity += sample_sizes[samples_count];
383 samples = (
char*)realloc(samples, samples_capacity);
385 _freadb(samples + current_offset, 1ull, sample_sizes[samples_count], _infile);
387 current_offset += sample_sizes[samples_count];
391 if (samples_count >= _DICTIONARY_SAMPLE_COUNT - 1)
400 size_t average_file_size = 0ull;
402 for (
size_t idx = 0ull; idx < samples_count; ++idx)
403 average_file_size += sample_sizes[idx] / samples_count;
405 size_t nearest_pow_of_2 = 1;
406 while (nearest_pow_of_2 < average_file_size)
407 nearest_pow_of_2 *= 2;
GPAK_API filesystem_tree_node_t * filesystem_iterator_next_directory(filesystem_tree_iterator_t *_iterator)
GPAK_API void filesystem_iterator_free(filesystem_tree_iterator_t *_iterator)
GPAK_API filesystem_tree_iterator_t * filesystem_iterator_create(filesystem_tree_node_t *_root)
GPAK_API filesystem_tree_file_t * filesystem_iterator_next_file(filesystem_tree_iterator_t *_iterator)
GPAK_API uint32_t _gpak_compressor_deflate(gpak_t *_pak, FILE *_infile, FILE *_outfile)
GPAK_API uint32_t _gpak_compressor_none(gpak_t *_pak, FILE *_infile, FILE *_outfile)
GPAK_API uint32_t _gpak_decompressor_none(gpak_t *_pak, FILE *_infile, FILE *_outfile, size_t _read_size)
GPAK_API uint32_t _gpak_decompressor_inflate(gpak_t *_pak, FILE *_infile, FILE *_outfile, size_t _read_size)
GPAK_API uint32_t _gpak_decompressor_zstd(gpak_t *_pak, FILE *_infile, FILE *_outfile, size_t _read_size)
GPAK_API int32_t _gpak_compressor_generate_dictionary(gpak_t *_pak)
GPAK_API uint32_t _gpak_compressor_zstd(gpak_t *_pak, FILE *_infile, FILE *_outfile)
@ GPAK_ERROR_INFLATE_FAILED
@ GPAK_ERROR_INFLATE_INIT
@ GPAK_ERROR_DEFLATE_INIT
@ GPAK_ERROR_EOF_BEFORE_EOS
@ GPAK_STAGE_DECOMPRESSION
struct filesystem_tree_node * root_