static void benchmark_codec (SquashCodec* codec, void* data) { struct BenchmarkContext* context = (struct BenchmarkContext*) data; SquashOptions* opts; int level = 0; char level_s[4]; bool have_results = false; umask (0100); fprintf (stdout, " %s:%s\n", squash_plugin_get_name (squash_codec_get_plugin (codec)), squash_codec_get_name (codec)); opts = squash_options_new (codec, NULL); if (opts != NULL) { squash_object_ref_sink (opts); for ( level = 0 ; level <= 999 ; level++ ) { snprintf (level_s, 4, "%d", level); if (squash_options_parse_option (opts, "level", level_s) == SQUASH_OK) { if (benchmark_codec_with_options (context, codec, opts)) { have_results = true; } } } squash_object_unref (opts); } if (!have_results) { benchmark_codec_with_options (context, codec, NULL); } }
//---------- Codec::Codec(SquashCodec * squashCodec) { ofxSquash::initialize(); this->name = squash_codec_get_name(squashCodec); this->valid = squash_codec_init(squashCodec) == SQUASH_OK; this->squashCodec = squashCodec; }
static void list_codecs_foreach_cb (SquashCodec* codec, void* data) { if (data != NULL) fputs ((char*) data, stdout); fputs (squash_codec_get_name (codec), stdout); fputc ('\n', stdout); }
static MSCompFormat squash_ms_format_from_codec (SquashCodec* codec) { const char* name = squash_codec_get_name (codec); if (name[5] == 0) return MSCOMP_LZNT1; else if (name[6] == 0) return MSCOMP_XPRESS; else if (name[14] == 0) return MSCOMP_XPRESS_HUFF; else squash_assert_unreachable(); }
static SquashStatus squash_wflz_compress_buffer (SquashCodec* codec, size_t* compressed_size, uint8_t compressed[SQUASH_ARRAY_PARAM(*compressed_size)], size_t uncompressed_size, const uint8_t uncompressed[SQUASH_ARRAY_PARAM(uncompressed_size)], SquashOptions* options) { const char* codec_name = squash_codec_get_name (codec); const uint32_t swap = ((uint32_t) squash_options_get_int_at (options, codec, SQUASH_WFLZ_OPT_ENDIANNESS) != SQUASH_WFLZ_HOST_ORDER); const int level = squash_options_get_int_at (options, codec, SQUASH_WFLZ_OPT_LEVEL); #if UINT32_MAX < SIZE_MAX if (SQUASH_UNLIKELY(UINT32_MAX < uncompressed_size)) return squash_error (SQUASH_RANGE); #endif if (*compressed_size < wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_size)) { return squash_error (SQUASH_BUFFER_FULL); } uint8_t* work_mem = (uint8_t*) malloc (wfLZ_GetWorkMemSize ()); uint32_t wres; if (codec_name[4] == '\0') { if (level == 1) { wres = wfLZ_CompressFast (uncompressed, (uint32_t) uncompressed_size, compressed, work_mem, swap); } else { wres = wfLZ_Compress (uncompressed, (uint32_t) uncompressed_size, compressed, work_mem, swap); } } else { wres = wfLZ_ChunkCompress ((uint8_t*) uncompressed, (uint32_t) uncompressed_size, squash_options_get_size_at (options, codec, SQUASH_WFLZ_OPT_CHUNK_SIZE), compressed, work_mem, swap, level == 1 ? 1 : 0); } #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < wres)) { free (work_mem); return squash_error (SQUASH_RANGE); } #endif *compressed_size = (size_t) wres; free (work_mem); return SQUASH_LIKELY(*compressed_size > 0) ? SQUASH_OK : squash_error (SQUASH_FAILED); }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (strcmp ("fari", name) == 0) { impl->get_max_compressed_size = squash_fari_get_max_compressed_size; impl->decompress_buffer = squash_fari_decompress_buffer; impl->compress_buffer_unsafe = squash_fari_compress_buffer; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
extern "C" SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (SQUASH_LIKELY(strcmp ("csc", name) == 0)) { impl->options = squash_csc_options; impl->splice = squash_csc_splice; impl->get_max_compressed_size = squash_csc_get_max_compressed_size; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { const char* name = squash_codec_get_name (codec); if (strcmp ("compress", name) == 0) { funcs->get_max_compressed_size = squash_ncompress_get_max_compressed_size; funcs->decompress_buffer = squash_ncompress_decompress_buffer; funcs->compress_buffer = squash_ncompress_compress_buffer; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { if (strcmp ("bzip2", squash_codec_get_name (codec)) == 0) { /* Doesn't work—see plugin documentation */ /* impl->info |= SQUASH_CODEC_INFO_CAN_FLUSH; */ impl->options = squash_bz2_options; impl->create_stream = squash_bz2_create_stream; impl->process_stream = squash_bz2_process_stream; impl->get_max_compressed_size = squash_bz2_get_max_compressed_size; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { if (strcmp ("bzip2", squash_codec_get_name (codec)) == 0) { impl->options = squash_bz2_options; impl->create_stream = squash_bz2_create_stream; impl->process_stream = squash_bz2_process_stream; impl->get_max_compressed_size = squash_bz2_get_max_compressed_size; impl->decompress_buffer = squash_bz2_decompress_buffer; impl->compress_buffer = squash_bz2_compress_buffer; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
extern "C" SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { const char* name = squash_codec_get_name (codec); if (strcmp ("doboz", name) == 0) { funcs->get_uncompressed_size = squash_doboz_get_uncompressed_size; funcs->get_max_compressed_size = squash_doboz_get_max_compressed_size; funcs->decompress_buffer = squash_doboz_decompress_buffer; funcs->compress_buffer = squash_doboz_compress_buffer; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
extern "C" SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (strcmp ("zpaq", name) == 0) { impl->info = SQUASH_CODEC_INFO_DECOMPRESS_UNSAFE; impl->options = squash_zpaq_options; impl->splice = squash_zpaq_splice; impl->get_max_compressed_size = squash_zpaq_get_max_compressed_size; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
extern "C" SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (strcmp ("yalz77", name) == 0) { impl->options = squash_yalz77_options; impl->get_max_compressed_size = squash_yalz77_get_max_compressed_size; impl->decompress_buffer = squash_yalz77_decompress_buffer; impl->compress_buffer = squash_yalz77_compress_buffer; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (HEDLEY_LIKELY(strcmp ("deflate", name) == 0)) { impl->options = squash_libdeflate_options; impl->get_max_compressed_size = squash_libdeflate_get_max_compressed_size; impl->decompress_buffer = squash_libdeflate_decompress_buffer; impl->compress_buffer = squash_libdeflate_compress_buffer; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (SQUASH_LIKELY(strcmp ("brieflz", name) == 0)) { impl->get_uncompressed_size = squash_brieflz_get_uncompressed_size; impl->get_max_compressed_size = squash_brieflz_get_max_compressed_size; impl->decompress_buffer = squash_brieflz_decompress_buffer; impl->compress_buffer_unsafe = squash_brieflz_compress_buffer; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (SQUASH_LIKELY(strcmp ("density", name) == 0)) { impl->options = squash_density_options; impl->create_stream = squash_density_create_stream; impl->process_stream = squash_density_process_stream; impl->get_max_compressed_size = squash_density_get_max_compressed_size; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
static SquashStatus squash_wflz_decompress_buffer (SquashCodec* codec, size_t* decompressed_size, uint8_t decompressed[SQUASH_ARRAY_PARAM(*decompressed_size)], size_t compressed_size, const uint8_t compressed[SQUASH_ARRAY_PARAM(compressed_size)], SquashOptions* options) { const char* codec_name = squash_codec_get_name (codec); uint32_t decompressed_s; if (SQUASH_UNLIKELY(compressed_size < 12)) return squash_error (SQUASH_BUFFER_EMPTY); decompressed_s = wfLZ_GetDecompressedSize (compressed); #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < decompressed_s)) return squash_error (SQUASH_RANGE); #endif if (SQUASH_UNLIKELY(decompressed_s == 0)) return squash_error (SQUASH_INVALID_BUFFER); if (SQUASH_UNLIKELY(decompressed_s > *decompressed_size)) return squash_error (SQUASH_BUFFER_FULL); if (codec_name[4] == '\0') { wfLZ_Decompress (compressed, decompressed); } else { uint8_t* dest = decompressed; uint32_t* chunk = NULL; uint8_t* compressed_block; while ( (compressed_block = wfLZ_ChunkDecompressLoop ((uint8_t*) compressed, &chunk)) != NULL ) { const uint32_t chunk_size = wfLZ_GetDecompressedSize (compressed_block); if (SQUASH_UNLIKELY((dest + chunk_size) > (decompressed + *decompressed_size))) return squash_error (SQUASH_BUFFER_FULL); wfLZ_Decompress (compressed_block, dest); dest += chunk_size; } } *decompressed_size = decompressed_s; return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (strcmp ("lz4", name) == 0) { impl->options = squash_lz4_options; impl->get_max_compressed_size = squash_lz4_get_max_compressed_size; impl->decompress_buffer = squash_lz4_decompress_buffer; impl->compress_buffer = squash_lz4_compress_buffer; impl->compress_buffer_unsafe = squash_lz4_compress_buffer_unsafe; } else { return squash_plugin_init_lz4f (codec, impl); } return SQUASH_OK; }
SquashStatus squash_plugin_init_lz4f (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (SQUASH_LIKELY(strcmp ("lz4", name) == 0)) { impl->info = SQUASH_CODEC_INFO_CAN_FLUSH; impl->options = squash_lz4f_options; impl->get_max_compressed_size = squash_lz4f_get_max_compressed_size; impl->create_stream = squash_lz4f_create_stream; impl->process_stream = squash_lz4f_process_stream; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { if (strcmp ("bzip2", squash_codec_get_name (codec)) == 0) { funcs->create_options = squash_bz2_create_options; funcs->parse_option = squash_bz2_parse_option; funcs->create_stream = squash_bz2_create_stream; funcs->process_stream = squash_bz2_process_stream; funcs->get_max_compressed_size = squash_bz2_get_max_compressed_size; funcs->decompress_buffer = squash_bz2_decompress_buffer; funcs->compress_buffer = squash_bz2_compress_buffer; } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
extern "C" SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecFuncs* funcs) { const char* name = squash_codec_get_name (codec); if (strcmp ("csc", name) == 0) { funcs->info = SQUASH_CODEC_INFO_RUN_IN_THREAD; funcs->create_options = squash_csc_create_options; funcs->parse_option = squash_csc_parse_option; funcs->create_stream = squash_csc_create_stream; funcs->process_stream = squash_csc_process_stream; funcs->get_max_compressed_size = squash_csc_get_max_compressed_size; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { bsc_init_full (LIBBSC_DEFAULT_FEATURES, squash_bsc_malloc, squash_bsc_zero_malloc, squash_bsc_free); const char* name = squash_codec_get_name (codec); if (HEDLEY_LIKELY(strcmp ("bsc", name) == 0)) { impl->options = squash_bsc_options; impl->get_uncompressed_size = squash_bsc_get_uncompressed_size; impl->get_max_compressed_size = squash_bsc_get_max_compressed_size; impl->decompress_buffer = squash_bsc_decompress_buffer; impl->compress_buffer_unsafe = squash_bsc_compress_buffer_unsafe; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (SQUASH_LIKELY(strcmp ("brotli", name) == 0)) { impl->info = SQUASH_CODEC_INFO_CAN_FLUSH; impl->options = squash_brotli_options; impl->get_max_compressed_size = squash_brotli_get_max_compressed_size; impl->create_stream = squash_brotli_create_stream; impl->process_stream = squash_brotli_process_stream; impl->decompress_buffer = squash_brotli_decompress_buffer; impl->compress_buffer = squash_brotli_compress_buffer; } else { return squash_error (SQUASH_UNABLE_TO_LOAD); } return SQUASH_OK; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (strcmp ("snappy", name) == 0) { impl->get_uncompressed_size = squash_snappy_get_uncompressed_size; impl->get_max_compressed_size = squash_snappy_get_max_compressed_size; impl->decompress_buffer = squash_snappy_decompress_buffer; impl->compress_buffer = squash_snappy_compress_buffer; #if defined(SQUASH_SNAPPY_ENABLE_FRAMED) } else if (strcmp ("snappy-framed", name) == 0) { return squash_plugin_init_snappy_framed (codec, imp); #endif } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
static size_t squash_wflz_get_max_compressed_size (SquashCodec* codec, size_t uncompressed_size) { const char* codec_name = squash_codec_get_name (codec); #if UINT32_MAX < SIZE_MAX if (SQUASH_UNLIKELY(UINT32_MAX < uncompressed_size)) return (squash_error (SQUASH_RANGE), 0); #endif const uint32_t res = codec_name[4] == '\0' ? wfLZ_GetMaxCompressedSize ((uint32_t) uncompressed_size) : wfLZ_GetMaxChunkCompressedSize ((uint32_t) uncompressed_size, SQUASH_WFLZ_MIN_CHUNK_SIZE); #if SIZE_MAX < UINT32_MAX if (SQUASH_UNLIKELY(SIZE_MAX < res)) return (squash_error (SQUASH_RANGE)); #endif return res; }
SquashStatus squash_plugin_init_codec (SquashCodec* codec, SquashCodecImpl* impl) { const char* name = squash_codec_get_name (codec); if (strcmp ("lznt1", name) == 0 || strcmp ("xpress", name) == 0 || strcmp ("xpress-huffman", name) == 0) { impl->get_max_compressed_size = squash_ms_get_max_compressed_size; impl->decompress_buffer = squash_ms_decompress_buffer; impl->compress_buffer = squash_ms_compress_buffer; if (strcmp ("lznt1", name) == 0) { impl->info = SQUASH_CODEC_INFO_CAN_FLUSH; impl->create_stream = squash_ms_create_stream; impl->process_stream = squash_ms_process_stream; } } else { return SQUASH_UNABLE_TO_LOAD; } return SQUASH_OK; }
static bool benchmark_codec_with_options (struct BenchmarkContext* context, SquashCodec* codec, SquashOptions* opts) { SquashBenchmarkResult result = { 0, 0.0, 0.0, 0.0, 0.0 }; bool success = false; SquashStatus res = SQUASH_OK; const int level = squash_options_get_int (opts, codec, "level"); #if !defined(SQUASH_BENCHMARK_NO_FORK) char fifo_name[] = ".squash-benchmark-fifo-XXXXXX"; assert (mkfifo (mktemp (fifo_name), 0600) == 0); if (fork () == 0) { int out_descriptor = open (fifo_name, O_WRONLY); #else int descriptors[2]; assert (pipe (descriptors) == 0); int out_descriptor = descriptors[1]; #endif FILE* compressed = squash_tmpfile (); FILE* decompressed = squash_tmpfile (); SquashTimer* timer = squash_timer_new (); int iterations = 0; if (level < 0) { fputs (" compressing: ", stdout); } else { fprintf (stdout, " level %d: ", level); } if (fseek (context->input, 0, SEEK_SET) != 0) { perror ("Unable to seek to beginning of input file"); exit (-1); } for ( iterations = 0 ; squash_timer_get_elapsed_cpu (timer) < min_exec_time ; iterations++ ) { fseek (context->input, 0, SEEK_SET); fseek (compressed, 0, SEEK_SET); rewind (compressed); squash_timer_start (timer); res = squash_splice_with_options (codec, SQUASH_STREAM_COMPRESS, compressed, context->input, 0, opts); squash_timer_stop (timer); rewind (context->input); if (res != SQUASH_OK) { fprintf (stderr, "ERROR: %s (%d) squash_splice_with_options (%s, compress, %p, %p, 0, %p)\n", squash_status_to_string (res), res, squash_codec_get_name (codec), compressed, context->input, opts); break; } } if (res == SQUASH_OK) { result.compressed_size = ftell (compressed); result.compress_cpu = squash_timer_get_elapsed_cpu (timer) / iterations; result.compress_wall = squash_timer_get_elapsed_wall (timer) / iterations; squash_timer_reset (timer); if (result.compressed_size == 0) { fprintf (stdout, "failed (0 byte output, %s [%d]).\n", squash_status_to_string (res), res); } else { fprintf (stdout, "compressed (%.6fs CPU, %.6fs wall, %ld bytes)... ", result.compress_cpu, result.compress_wall, result.compressed_size); for ( iterations = 0 ; squash_timer_get_elapsed_cpu (timer) < min_exec_time ; iterations++ ) { fseek (compressed, 0, SEEK_SET); fseek (decompressed, 0, SEEK_SET); squash_timer_start (timer); res = squash_splice_with_options (codec, SQUASH_STREAM_DECOMPRESS, decompressed, compressed, 0, opts); squash_timer_stop (timer); rewind (compressed); if (res != SQUASH_OK) { break; } } if (res != SQUASH_OK) { fprintf (stderr, "Failed (%s [%d]).\n", squash_status_to_string (res), res); } else { result.decompress_cpu = squash_timer_get_elapsed_cpu (timer) / iterations; result.decompress_wall = squash_timer_get_elapsed_wall (timer) / iterations; squash_timer_reset (timer); if (ftell (decompressed) != context->input_size) { /* Should never happen. */ fprintf (stderr, "Failed (size mismatch; expected %ld, got %ld.\n", context->input_size, ftell (decompressed)); } else { fprintf (stdout, "decompressed (%.6fs CPU, %.6fs wall).\n", result.decompress_cpu, result.decompress_wall); write (out_descriptor, &result, sizeof (SquashBenchmarkResult)); } } } } squash_timer_free (timer); fclose (compressed); fclose (decompressed); close (out_descriptor); #if !defined(SQUASH_BENCHMARK_NO_FORK) exit (0); } else { int in_descriptor = open (fifo_name, O_RDONLY); #else int in_descriptor = descriptors[0]; #endif size_t bytes_read = read (in_descriptor, &result, sizeof (SquashBenchmarkResult)); wait (NULL); if (bytes_read == sizeof (SquashBenchmarkResult)) { if (context->csv != NULL) { if (level >= 0) { fprintf (context->csv, "%s,%s,%s,%d,%ld,%f,%f,%f,%f\r\n", context->input_name, squash_plugin_get_name (squash_codec_get_plugin (codec)), squash_codec_get_name (codec), level, result.compressed_size, result.compress_cpu, result.compress_wall, result.decompress_cpu, result.decompress_wall); } else { fprintf (context->csv, "%s,%s,%s,,%ld,%f,%f,%f,%f\r\n", context->input_name, squash_plugin_get_name (squash_codec_get_plugin (codec)), squash_codec_get_name (codec), result.compressed_size, result.compress_cpu, result.compress_wall, result.decompress_cpu, result.decompress_wall); } } success = true; } close (in_descriptor); #if !defined(SQUASH_BENCHMARK_NO_FORK) unlink (fifo_name); } #endif return success; }