From 79a785d9282a2fc9afa1437701f7bd9100099405 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Tue, 13 Feb 2018 13:03:00 +0100 Subject: [PATCH] LZMA executable filter parameter WIP completed, LZMA filters can now be used --- contrib/liblzma/compress_easy_mt.cpp | 46 +++++++++++++++++++++------- contrib/liblzma/precomp_xz.h | 2 +- precomp.cpp | 44 ++++++++++---------------- 3 files changed, 53 insertions(+), 39 deletions(-) diff --git a/contrib/liblzma/compress_easy_mt.cpp b/contrib/liblzma/compress_easy_mt.cpp index 32afc9b..a2ca589 100644 --- a/contrib/liblzma/compress_easy_mt.cpp +++ b/contrib/liblzma/compress_easy_mt.cpp @@ -52,8 +52,10 @@ lzma_filter get_filter(lzma_vli filter_id) { return result; } -bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64_t &memory_usage, uint64_t &block_size) +bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64_t &memory_usage, uint64_t &block_size, bool* filter_enabled, bool filter_delta_enabled, int filter_delta_distance, int filter_count) { + lzma_vli filter_to_lzma_vli[6] = { LZMA_FILTER_X86, LZMA_FILTER_POWERPC, LZMA_FILTER_IA64, LZMA_FILTER_ARM, LZMA_FILTER_ARMTHUMB, LZMA_FILTER_SPARC }; + // The threaded encoder takes the options as pointer to // a lzma_mt structure. lzma_mt mt; @@ -114,16 +116,36 @@ bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64 filterLzma2.id = LZMA_FILTER_LZMA2; filterLzma2.options = &opt_lzma2; - const lzma_filter filters[] = { - get_filter(LZMA_FILTER_X86), - get_filter(LZMA_FILTER_POWERPC), - //get_filter(LZMA_FILTER_IA64), - get_filter(LZMA_FILTER_ARM), - //get_filter(LZMA_FILTER_ARMTHUMB), - //get_filter(LZMA_FILTER_SPARC), - filterLzma2, - get_filter(LZMA_VLI_UNKNOWN) - }; + lzma_filter filterDelta; + lzma_options_delta delta_options; + delta_options.type = LZMA_DELTA_TYPE_BYTE; + delta_options.dist = filter_delta_distance; + filterDelta.id = LZMA_FILTER_DELTA; + filterDelta.options = &delta_options; + + lzma_filter* filters; + if (filter_count == 0) { + filters = new lzma_filter[2] { + filterLzma2, + get_filter(LZMA_VLI_UNKNOWN) + }; + } else { + filters = new lzma_filter[filter_count + 2]; + int filter_idx = 0; + if (filter_delta_enabled) { + + filters[filter_idx] = filterDelta; + filter_idx++; + } + for (int i = 0; i < 6; i++) { + if (filter_enabled[i]) { + filters[filter_idx] = get_filter(filter_to_lzma_vli[i]); + filter_idx++; + } + } + filters[filter_count] = filterLzma2; + filters[filter_count + 1] = get_filter(LZMA_VLI_UNKNOWN); + } mt.filters = filters; @@ -133,5 +155,7 @@ bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64 // Determine memory usage and block size memory_usage = lzma_stream_encoder_mt_memusage(&mt, &block_size); + delete[] filters; + return check(ret); } \ No newline at end of file diff --git a/contrib/liblzma/precomp_xz.h b/contrib/liblzma/precomp_xz.h index 09e080f..f9bddd6 100644 --- a/contrib/liblzma/precomp_xz.h +++ b/contrib/liblzma/precomp_xz.h @@ -3,7 +3,7 @@ #include "api/lzma.h" -bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64_t &memory_usage, uint64_t &block_size); +bool init_encoder_mt(lzma_stream *strm, int threads, uint64_t max_memory, uint64_t &memory_usage, uint64_t &block_size, bool* filter_enabled, bool filter_delta_enabled, int filter_delta_distance, int filter_count); bool init_decoder(lzma_stream *strm); diff --git a/precomp.cpp b/precomp.cpp index 6d0447a..1c018b9 100644 --- a/precomp.cpp +++ b/precomp.cpp @@ -773,29 +773,24 @@ int init(int argc, char* argv[]) { case 'D': { argindex++; - if ((argv[i][argindex]) == 0) { + char nextchar = argv[i][argindex]; + if ((nextchar < '0') || (nextchar > '9')) { printf("ERROR: LZMA delta filter must be followed by a distance (1..256)\n"); exit(1); } otf_xz_filter_delta_enabled = true; - int multiplicator = 1; - for (j = strlen(argv[i]) - (argindex + 1); j >= 0; j--) { - if ((argv[i][j + argindex] < '0') || (argv[i][j + argindex] > '9')) { - printf("ERROR: Only numbers allowed for LZMA delta filter distance\n"); - exit(1); - } - otf_xz_filter_delta_distance += ((unsigned int)(argv[i][j + argindex]) - '0') * multiplicator; - if ((multiplicator * 10) < multiplicator) { - exit(1); - } - multiplicator *= 10; + while ((argv[i][argindex] > '0') && (argv[i][argindex] < '9')) { + otf_xz_filter_delta_distance *= 10; + otf_xz_filter_delta_distance += (argv[i][argindex] - '0'); + argindex++; } if ((otf_xz_filter_delta_distance < 1) || (otf_xz_filter_delta_distance > 256)) { printf("ERROR: LZMA delta filter distance must be in range 1..256\n"); exit(1); } - break; + argindex--; } + break; default: printf("ERROR: Unknown LZMA filter type \"%c\"\n", argv[i][argindex]); exit(1); @@ -1646,27 +1641,22 @@ int init_comfort(int argc, char* argv[]) { break; case 'D': j++; - if ((argv[i][j]) == 0) { + char nextchar = argv[i][j]; + if ((nextchar < '0') || (nextchar > '9')) { printf("ERROR: LZMA delta filter must be followed by a distance (1..256)\n"); exit(1); } otf_xz_filter_delta_enabled = true; - int multiplicator = 1; - for (k = (strlen(value) - (j + 1); k >= 0; k--) { - if ((argv[i][j + k] < '0') || (argv[i][j + k] > '9')) { - printf("ERROR: Only numbers allowed for LZMA delta filter distance\n"); - exit(1); - } - otf_xz_filter_delta_distance += ((unsigned int)(argv[i][j + k]) - '0') * multiplicator; - if (multiplicator * 10) < multiplicator) { - exit(1); - } - multiplicator *= 10; + while ((argv[i][j] > '0') && (argv[i][j] < '9')) { + otf_xz_filter_delta_distance *= 10; + otf_xz_filter_delta_distance += (argv[i][j] - '0'); + j++; } if ((otf_xz_filter_delta_distance < 1) || (otf_xz_filter_delta_distance > 256)) { - printf("ERROR: LZMA delta filter distance must be in range 1..256\n); + printf("ERROR: LZMA delta filter distance must be in range 1..256\n"); exit(1); } + j--; break; default: printf("ERROR: Unknown LZMA filter type \"%c\"\n", argv[i][j]); @@ -9746,7 +9736,7 @@ void init_compress_otf() { threads = auto_detected_thread_count(); } - if (!init_encoder_mt(&otf_xz_stream_c, threads, max_memory, memory_usage, block_size)) { + if (!init_encoder_mt(&otf_xz_stream_c, threads, max_memory, memory_usage, block_size, otf_xz_filter_enabled, otf_xz_filter_delta_enabled, otf_xz_filter_delta_distance, otf_xz_filter_used_count)) { printf("ERROR: xz Multi-Threaded init failed\n"); exit(1); }