libdeflate 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +1 -0
  6. data/.rubocop_todo.yml +9 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +52 -0
  11. data/Rakefile +15 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/ext/libdeflate/extconf.rb +14 -0
  15. data/ext/libdeflate/libdeflate/.gitignore +19 -0
  16. data/ext/libdeflate/libdeflate/COPYING +21 -0
  17. data/ext/libdeflate/libdeflate/Makefile +231 -0
  18. data/ext/libdeflate/libdeflate/Makefile.msc +64 -0
  19. data/ext/libdeflate/libdeflate/NEWS +57 -0
  20. data/ext/libdeflate/libdeflate/README.md +170 -0
  21. data/ext/libdeflate/libdeflate/common/common_defs.h +351 -0
  22. data/ext/libdeflate/libdeflate/common/compiler_gcc.h +134 -0
  23. data/ext/libdeflate/libdeflate/common/compiler_msc.h +95 -0
  24. data/ext/libdeflate/libdeflate/lib/adler32.c +213 -0
  25. data/ext/libdeflate/libdeflate/lib/adler32_impl.h +281 -0
  26. data/ext/libdeflate/libdeflate/lib/aligned_malloc.c +57 -0
  27. data/ext/libdeflate/libdeflate/lib/aligned_malloc.h +13 -0
  28. data/ext/libdeflate/libdeflate/lib/bt_matchfinder.h +357 -0
  29. data/ext/libdeflate/libdeflate/lib/crc32.c +368 -0
  30. data/ext/libdeflate/libdeflate/lib/crc32_impl.h +286 -0
  31. data/ext/libdeflate/libdeflate/lib/crc32_table.h +526 -0
  32. data/ext/libdeflate/libdeflate/lib/decompress_impl.h +404 -0
  33. data/ext/libdeflate/libdeflate/lib/deflate_compress.c +2817 -0
  34. data/ext/libdeflate/libdeflate/lib/deflate_compress.h +14 -0
  35. data/ext/libdeflate/libdeflate/lib/deflate_constants.h +66 -0
  36. data/ext/libdeflate/libdeflate/lib/deflate_decompress.c +889 -0
  37. data/ext/libdeflate/libdeflate/lib/gzip_compress.c +95 -0
  38. data/ext/libdeflate/libdeflate/lib/gzip_constants.h +45 -0
  39. data/ext/libdeflate/libdeflate/lib/gzip_decompress.c +130 -0
  40. data/ext/libdeflate/libdeflate/lib/hc_matchfinder.h +405 -0
  41. data/ext/libdeflate/libdeflate/lib/lib_common.h +35 -0
  42. data/ext/libdeflate/libdeflate/lib/matchfinder_avx2.h +53 -0
  43. data/ext/libdeflate/libdeflate/lib/matchfinder_common.h +205 -0
  44. data/ext/libdeflate/libdeflate/lib/matchfinder_neon.h +61 -0
  45. data/ext/libdeflate/libdeflate/lib/matchfinder_sse2.h +53 -0
  46. data/ext/libdeflate/libdeflate/lib/unaligned.h +202 -0
  47. data/ext/libdeflate/libdeflate/lib/x86_cpu_features.c +169 -0
  48. data/ext/libdeflate/libdeflate/lib/x86_cpu_features.h +48 -0
  49. data/ext/libdeflate/libdeflate/lib/zlib_compress.c +87 -0
  50. data/ext/libdeflate/libdeflate/lib/zlib_constants.h +21 -0
  51. data/ext/libdeflate/libdeflate/lib/zlib_decompress.c +91 -0
  52. data/ext/libdeflate/libdeflate/libdeflate.h +274 -0
  53. data/ext/libdeflate/libdeflate/programs/benchmark.c +558 -0
  54. data/ext/libdeflate/libdeflate/programs/checksum.c +197 -0
  55. data/ext/libdeflate/libdeflate/programs/detect.sh +62 -0
  56. data/ext/libdeflate/libdeflate/programs/gzip.c +603 -0
  57. data/ext/libdeflate/libdeflate/programs/prog_util.c +530 -0
  58. data/ext/libdeflate/libdeflate/programs/prog_util.h +162 -0
  59. data/ext/libdeflate/libdeflate/programs/test_checksums.c +135 -0
  60. data/ext/libdeflate/libdeflate/programs/tgetopt.c +118 -0
  61. data/ext/libdeflate/libdeflate/tools/afl-fuzz/Makefile +12 -0
  62. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/fuzz.c +40 -0
  63. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_compress/inputs/0 +0 -0
  64. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/fuzz.c +28 -0
  65. data/ext/libdeflate/libdeflate/tools/afl-fuzz/deflate_decompress/inputs/0 +3 -0
  66. data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/fuzz.c +28 -0
  67. data/ext/libdeflate/libdeflate/tools/afl-fuzz/gzip_decompress/inputs/0 +0 -0
  68. data/ext/libdeflate/libdeflate/tools/afl-fuzz/prepare_for_fuzz.sh +14 -0
  69. data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/fuzz.c +28 -0
  70. data/ext/libdeflate/libdeflate/tools/afl-fuzz/zlib_decompress/inputs/0 +3 -0
  71. data/ext/libdeflate/libdeflate/tools/android_build.sh +104 -0
  72. data/ext/libdeflate/libdeflate/tools/checksum_benchmarks.sh +76 -0
  73. data/ext/libdeflate/libdeflate/tools/exec_tests.sh +30 -0
  74. data/ext/libdeflate/libdeflate/tools/gen_crc32_multipliers.c +108 -0
  75. data/ext/libdeflate/libdeflate/tools/gen_crc32_table.c +100 -0
  76. data/ext/libdeflate/libdeflate/tools/gzip_tests.sh +412 -0
  77. data/ext/libdeflate/libdeflate/tools/make-windows-releases +21 -0
  78. data/ext/libdeflate/libdeflate/tools/mips_build.sh +9 -0
  79. data/ext/libdeflate/libdeflate/tools/msc_test.bat +3 -0
  80. data/ext/libdeflate/libdeflate/tools/pgo_build.sh +23 -0
  81. data/ext/libdeflate/libdeflate/tools/produce_gzip_benchmark_table.sh +37 -0
  82. data/ext/libdeflate/libdeflate/tools/run_tests.sh +305 -0
  83. data/ext/libdeflate/libdeflate/tools/windows_build.sh +10 -0
  84. data/ext/libdeflate/libdeflate_ext.c +389 -0
  85. data/ext/libdeflate/libdeflate_ext.h +8 -0
  86. data/lib/libdeflate.rb +2 -0
  87. data/lib/libdeflate/version.rb +3 -0
  88. data/libdeflate.gemspec +33 -0
  89. metadata +230 -0
@@ -0,0 +1,558 @@
1
+ /*
2
+ * benchmark.c - a compression testing and benchmark program
3
+ *
4
+ * Copyright 2016 Eric Biggers
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <zlib.h> /* for comparison purposes */
29
+
30
+ #include "prog_util.h"
31
+
32
+ static const tchar *const optstring = T("1::2::3::4::5::6::7::8::9::ghs:VYZz");
33
+
34
+ static void
35
+ show_usage(FILE *fp)
36
+ {
37
+ fprintf(fp,
38
+ "Usage: %"TS" [-LVL] [-ghVYZz] [-s SIZE] [FILE]...\n"
39
+ "Benchmark DEFLATE compression and decompression on the specified FILEs.\n"
40
+ "\n"
41
+ "Options:\n"
42
+ " -1 fastest (worst) compression\n"
43
+ " -6 medium compression (default)\n"
44
+ " -12 slowest (best) compression\n"
45
+ " -g use gzip wrapper\n"
46
+ " -h print this help\n"
47
+ " -s SIZE chunk size\n"
48
+ " -V show version and legal information\n"
49
+ " -Y compress with libz, not libdeflate\n"
50
+ " -Z decompress with libz, not libdeflate\n"
51
+ " -z use zlib wrapper\n",
52
+ program_invocation_name);
53
+ }
54
+
55
+ static void
56
+ show_version(void)
57
+ {
58
+ printf(
59
+ "libdeflate compression benchmark program v" LIBDEFLATE_VERSION_STRING "\n"
60
+ "Copyright 2016 Eric Biggers\n"
61
+ "\n"
62
+ "This program is free software which may be modified and/or redistributed\n"
63
+ "under the terms of the MIT license. There is NO WARRANTY, to the extent\n"
64
+ "permitted by law. See the COPYING file for details.\n"
65
+ );
66
+ }
67
+
68
+ enum wrapper {
69
+ NO_WRAPPER,
70
+ ZLIB_WRAPPER,
71
+ GZIP_WRAPPER,
72
+ };
73
+
74
+ struct compressor {
75
+ void *private;
76
+ size_t (*compress)(void *, const void *, size_t, void *, size_t);
77
+ void (*free_private)(void *);
78
+ };
79
+
80
+ struct decompressor {
81
+ void *private;
82
+ bool (*decompress)(void *, const void *, size_t, void *, size_t);
83
+ void (*free_private)(void *);
84
+ };
85
+
86
+ static int
87
+ get_libz_window_bits(enum wrapper wrapper)
88
+ {
89
+ const int windowBits = 15;
90
+ switch (wrapper) {
91
+ case ZLIB_WRAPPER:
92
+ return windowBits;
93
+ case GZIP_WRAPPER:
94
+ return windowBits + 16;
95
+ default:
96
+ return -windowBits;
97
+ }
98
+ }
99
+
100
+ static size_t
101
+ libz_compress(void *private, const void *in, size_t in_nbytes,
102
+ void *out, size_t out_nbytes_avail)
103
+ {
104
+ z_stream *z = private;
105
+
106
+ deflateReset(z);
107
+
108
+ z->next_in = (void *)in;
109
+ z->avail_in = in_nbytes;
110
+ z->next_out = out;
111
+ z->avail_out = out_nbytes_avail;
112
+
113
+ if (deflate(z, Z_FINISH) != Z_STREAM_END)
114
+ return 0;
115
+
116
+ return out_nbytes_avail - z->avail_out;
117
+ }
118
+
119
+ static bool
120
+ libz_decompress(void *private, const void *in, size_t in_nbytes,
121
+ void *out, size_t out_nbytes_avail)
122
+ {
123
+ z_stream *z = private;
124
+
125
+ inflateReset(z);
126
+
127
+ z->next_in = (void *)in;
128
+ z->avail_in = in_nbytes;
129
+ z->next_out = out;
130
+ z->avail_out = out_nbytes_avail;
131
+
132
+ return (inflate(z, Z_FINISH) == Z_STREAM_END && z->avail_out == 0);
133
+ }
134
+
135
+ static void
136
+ libz_free_compressor(void *private)
137
+ {
138
+ deflateEnd((z_stream *)private);
139
+ free(private);
140
+ }
141
+
142
+ static void
143
+ libz_free_decompressor(void *private)
144
+ {
145
+ inflateEnd((z_stream *)private);
146
+ free(private);
147
+ }
148
+
149
+ static size_t
150
+ deflate_compress(void *private, const void *in, size_t in_nbytes,
151
+ void *out, size_t out_nbytes_avail)
152
+ {
153
+ return libdeflate_deflate_compress(private, in, in_nbytes,
154
+ out, out_nbytes_avail);
155
+ }
156
+
157
+ static bool
158
+ deflate_decompress(void *private, const void *in, size_t in_nbytes,
159
+ void *out, size_t out_nbytes_avail)
160
+ {
161
+ return 0 == libdeflate_deflate_decompress(private, in, in_nbytes,
162
+ out, out_nbytes_avail, NULL);
163
+ }
164
+
165
+ static size_t
166
+ zlib_compress(void *private, const void *in, size_t in_nbytes,
167
+ void *out, size_t out_nbytes_avail)
168
+ {
169
+ return libdeflate_zlib_compress(private, in, in_nbytes,
170
+ out, out_nbytes_avail);
171
+ }
172
+
173
+ static bool
174
+ zlib_decompress(void *private, const void *in, size_t in_nbytes,
175
+ void *out, size_t out_nbytes_avail)
176
+ {
177
+ return 0 == libdeflate_zlib_decompress(private, in, in_nbytes,
178
+ out, out_nbytes_avail, NULL);
179
+ }
180
+
181
+ static size_t
182
+ gzip_compress(void *private, const void *in, size_t in_nbytes,
183
+ void *out, size_t out_nbytes_avail)
184
+ {
185
+ return libdeflate_gzip_compress(private, in, in_nbytes,
186
+ out, out_nbytes_avail);
187
+ }
188
+
189
+ static bool
190
+ gzip_decompress(void *private, const void *in, size_t in_nbytes,
191
+ void *out, size_t out_nbytes_avail)
192
+ {
193
+ return 0 == libdeflate_gzip_decompress(private, in, in_nbytes,
194
+ out, out_nbytes_avail, NULL);
195
+ }
196
+
197
+ static void
198
+ free_compressor(void *private)
199
+ {
200
+ libdeflate_free_compressor(private);
201
+ }
202
+
203
+ static void
204
+ free_decompressor(void *private)
205
+ {
206
+ libdeflate_free_decompressor(private);
207
+ }
208
+
209
+ static int
210
+ compressor_init(struct compressor *c, int level,
211
+ enum wrapper wrapper, bool use_libz)
212
+ {
213
+ if (use_libz) {
214
+ z_stream *z;
215
+
216
+ if (level > 9) {
217
+ msg("libz only supports up to compression level 9");
218
+ return -1;
219
+ }
220
+
221
+ z = xmalloc(sizeof(z_stream));
222
+ if (z == NULL)
223
+ return -1;
224
+
225
+ c->private = z;
226
+
227
+ z->next_in = NULL;
228
+ z->avail_in = 0;
229
+ z->zalloc = NULL;
230
+ z->zfree = NULL;
231
+ z->opaque = NULL;
232
+ if (deflateInit2(z, level, Z_DEFLATED,
233
+ get_libz_window_bits(wrapper),
234
+ 8, Z_DEFAULT_STRATEGY) != Z_OK)
235
+ {
236
+ msg("unable to initialize deflater");
237
+ free(z);
238
+ return -1;
239
+ }
240
+ c->compress = libz_compress;
241
+ c->free_private = libz_free_compressor;
242
+ } else {
243
+ c->private = alloc_compressor(level);
244
+ if (c->private == NULL)
245
+ return -1;
246
+ switch (wrapper) {
247
+ case ZLIB_WRAPPER:
248
+ c->compress = zlib_compress;
249
+ break;
250
+ case GZIP_WRAPPER:
251
+ c->compress = gzip_compress;
252
+ break;
253
+ default:
254
+ c->compress = deflate_compress;
255
+ break;
256
+ }
257
+ c->free_private = free_compressor;
258
+ }
259
+ return 0;
260
+ }
261
+
262
+ static size_t
263
+ do_compress(struct compressor *c, const void *in, size_t in_nbytes,
264
+ void *out, size_t out_nbytes_avail)
265
+ {
266
+ return (*c->compress)(c->private, in, in_nbytes, out, out_nbytes_avail);
267
+ }
268
+
269
+ static void
270
+ compressor_destroy(struct compressor *c)
271
+ {
272
+ (*c->free_private)(c->private);
273
+ }
274
+
275
+ static int
276
+ decompressor_init(struct decompressor *d, enum wrapper wrapper, bool use_libz)
277
+ {
278
+ if (use_libz) {
279
+ z_stream *z;
280
+
281
+ z = xmalloc(sizeof(z_stream));
282
+ if (z == NULL)
283
+ return -1;
284
+
285
+ d->private = z;
286
+
287
+ z->next_in = NULL;
288
+ z->avail_in = 0;
289
+ z->zalloc = NULL;
290
+ z->zfree = NULL;
291
+ z->opaque = NULL;
292
+ if (inflateInit2(z, get_libz_window_bits(wrapper)) != Z_OK) {
293
+ msg("unable to initialize inflater");
294
+ free(z);
295
+ return -1;
296
+ }
297
+
298
+ d->decompress = libz_decompress;
299
+ d->free_private = libz_free_decompressor;
300
+ } else {
301
+ d->private = alloc_decompressor();
302
+ if (d->private == NULL)
303
+ return -1;
304
+ switch (wrapper) {
305
+ case ZLIB_WRAPPER:
306
+ d->decompress = zlib_decompress;
307
+ break;
308
+ case GZIP_WRAPPER:
309
+ d->decompress = gzip_decompress;
310
+ break;
311
+ default:
312
+ d->decompress = deflate_decompress;
313
+ break;
314
+ }
315
+ d->free_private = free_decompressor;
316
+ }
317
+ return 0;
318
+ }
319
+
320
+ static bool
321
+ do_decompress(struct decompressor *d, const void *in, size_t in_nbytes,
322
+ void *out, size_t out_nbytes_avail)
323
+ {
324
+ return (*d->decompress)(d->private, in, in_nbytes,
325
+ out, out_nbytes_avail);
326
+ }
327
+
328
+ static void
329
+ decompressor_destroy(struct decompressor *d)
330
+ {
331
+ (*d->free_private)(d->private);
332
+ }
333
+
334
+ static int
335
+ do_benchmark(struct file_stream *in, void *original_buf, void *compressed_buf,
336
+ void *decompressed_buf, u32 chunk_size,
337
+ struct compressor *compressor,
338
+ struct decompressor *decompressor)
339
+ {
340
+ u64 total_uncompressed_size = 0;
341
+ u64 total_compressed_size = 0;
342
+ u64 total_compress_time = 0;
343
+ u64 total_decompress_time = 0;
344
+ ssize_t ret;
345
+
346
+ while ((ret = xread(in, original_buf, chunk_size)) > 0) {
347
+ u32 original_size = ret;
348
+ u32 compressed_size;
349
+ u64 start_time;
350
+ bool result;
351
+
352
+ total_uncompressed_size += original_size;
353
+
354
+ /* Compress the chunk of data. */
355
+ start_time = timer_ticks();
356
+ compressed_size = do_compress(compressor,
357
+ original_buf,
358
+ original_size,
359
+ compressed_buf,
360
+ original_size - 1);
361
+ total_compress_time += timer_ticks() - start_time;
362
+
363
+ if (compressed_size) {
364
+ /* Successfully compressed the chunk of data. */
365
+
366
+ /* Decompress the data we just compressed and compare
367
+ * the result with the original. */
368
+ start_time = timer_ticks();
369
+ result = do_decompress(decompressor,
370
+ compressed_buf,
371
+ compressed_size,
372
+ decompressed_buf,
373
+ original_size);
374
+ total_decompress_time += timer_ticks() - start_time;
375
+
376
+ if (!result) {
377
+ msg("%"TS": failed to decompress data",
378
+ in->name);
379
+ return -1;
380
+ }
381
+
382
+ if (memcmp(original_buf, decompressed_buf,
383
+ original_size) != 0)
384
+ {
385
+ msg("%"TS": data did not decompress to "
386
+ "original", in->name);
387
+ return -1;
388
+ }
389
+
390
+ total_compressed_size += compressed_size;
391
+ } else {
392
+ /* Compression did not make the chunk smaller. */
393
+ total_compressed_size += original_size;
394
+ }
395
+ }
396
+
397
+ if (ret < 0)
398
+ return ret;
399
+
400
+ if (total_uncompressed_size == 0) {
401
+ printf("\tFile was empty.\n");
402
+ return 0;
403
+ }
404
+
405
+ if (total_compress_time == 0)
406
+ total_compress_time = 1;
407
+ if (total_decompress_time == 0)
408
+ total_decompress_time = 1;
409
+
410
+ printf("\tCompressed %"PRIu64 " => %"PRIu64" bytes (%u.%03u%%)\n",
411
+ total_uncompressed_size, total_compressed_size,
412
+ (unsigned int)(total_compressed_size * 100 /
413
+ total_uncompressed_size),
414
+ (unsigned int)(total_compressed_size * 100000 /
415
+ total_uncompressed_size % 1000));
416
+ printf("\tCompression time: %"PRIu64" ms (%"PRIu64" MB/s)\n",
417
+ timer_ticks_to_ms(total_compress_time),
418
+ timer_MB_per_s(total_uncompressed_size, total_compress_time));
419
+ printf("\tDecompression time: %"PRIu64" ms (%"PRIu64" MB/s)\n",
420
+ timer_ticks_to_ms(total_decompress_time),
421
+ timer_MB_per_s(total_uncompressed_size, total_decompress_time));
422
+
423
+ return 0;
424
+ }
425
+
426
+ int
427
+ tmain(int argc, tchar *argv[])
428
+ {
429
+ u32 chunk_size = 1048576;
430
+ int level = 6;
431
+ enum wrapper wrapper = NO_WRAPPER;
432
+ bool compress_with_libz = false;
433
+ bool decompress_with_libz = false;
434
+ void *original_buf = NULL;
435
+ void *compressed_buf = NULL;
436
+ void *decompressed_buf = NULL;
437
+ struct compressor compressor;
438
+ struct decompressor decompressor;
439
+ tchar *default_file_list[] = { NULL };
440
+ int opt_char;
441
+ int i;
442
+ int ret;
443
+
444
+ program_invocation_name = get_filename(argv[0]);
445
+
446
+ while ((opt_char = tgetopt(argc, argv, optstring)) != -1) {
447
+ switch (opt_char) {
448
+ case '1':
449
+ case '2':
450
+ case '3':
451
+ case '4':
452
+ case '5':
453
+ case '6':
454
+ case '7':
455
+ case '8':
456
+ case '9':
457
+ level = parse_compression_level(opt_char, toptarg);
458
+ if (level == 0)
459
+ return 1;
460
+ break;
461
+ case 'g':
462
+ wrapper = GZIP_WRAPPER;
463
+ break;
464
+ case 'h':
465
+ show_usage(stdout);
466
+ return 0;
467
+ case 's':
468
+ chunk_size = tstrtoul(toptarg, NULL, 10);
469
+ if (chunk_size == 0) {
470
+ msg("invalid chunk size: \"%"TS"\"", toptarg);
471
+ return 1;
472
+ }
473
+ break;
474
+ case 'V':
475
+ show_version();
476
+ return 0;
477
+ case 'Y':
478
+ compress_with_libz = true;
479
+ break;
480
+ case 'Z':
481
+ decompress_with_libz = true;
482
+ break;
483
+ case 'z':
484
+ wrapper = ZLIB_WRAPPER;
485
+ break;
486
+ default:
487
+ show_usage(stderr);
488
+ return 1;
489
+ }
490
+ }
491
+
492
+ argc -= toptind;
493
+ argv += toptind;
494
+
495
+ original_buf = xmalloc(chunk_size);
496
+ compressed_buf = xmalloc(chunk_size - 1);
497
+ decompressed_buf = xmalloc(chunk_size);
498
+
499
+ ret = -1;
500
+ if (original_buf == NULL || compressed_buf == NULL ||
501
+ decompressed_buf == NULL)
502
+ goto out0;
503
+
504
+ ret = compressor_init(&compressor, level, wrapper, compress_with_libz);
505
+ if (ret)
506
+ goto out0;
507
+
508
+ ret = decompressor_init(&decompressor, wrapper, decompress_with_libz);
509
+ if (ret)
510
+ goto out1;
511
+
512
+ if (argc == 0) {
513
+ argv = default_file_list;
514
+ argc = ARRAY_LEN(default_file_list);
515
+ } else {
516
+ for (i = 0; i < argc; i++)
517
+ if (argv[i][0] == '-' && argv[i][1] == '\0')
518
+ argv[i] = NULL;
519
+ }
520
+
521
+ printf("Benchmarking DEFLATE compression:\n");
522
+ printf("\tCompression level: %d\n", level);
523
+ printf("\tChunk size: %"PRIu32"\n", chunk_size);
524
+ printf("\tWrapper: %s\n",
525
+ wrapper == NO_WRAPPER ? "None" :
526
+ wrapper == ZLIB_WRAPPER ? "zlib" : "gzip");
527
+ printf("\tCompression engine: %s\n",
528
+ compress_with_libz ? "libz" : "libdeflate");
529
+ printf("\tDecompression engine: %s\n",
530
+ decompress_with_libz ? "libz" : "libdeflate");
531
+
532
+ for (i = 0; i < argc; i++) {
533
+ struct file_stream in;
534
+
535
+ ret = xopen_for_read(argv[i], true, &in);
536
+ if (ret != 0)
537
+ goto out2;
538
+
539
+ printf("Processing %"TS"...\n", in.name);
540
+
541
+ ret = do_benchmark(&in, original_buf, compressed_buf,
542
+ decompressed_buf, chunk_size, &compressor,
543
+ &decompressor);
544
+ xclose(&in);
545
+ if (ret != 0)
546
+ goto out2;
547
+ }
548
+ ret = 0;
549
+ out2:
550
+ decompressor_destroy(&decompressor);
551
+ out1:
552
+ compressor_destroy(&compressor);
553
+ out0:
554
+ free(decompressed_buf);
555
+ free(compressed_buf);
556
+ free(original_buf);
557
+ return -ret;
558
+ }