OLD | NEW |
1 /////////////////////////////////////////////////////////////////////////////// | 1 /////////////////////////////////////////////////////////////////////////////// |
2 // | 2 // |
3 /// \file coder.c | 3 /// \file coder.c |
4 /// \brief Compresses or uncompresses a file | 4 /// \brief Compresses or uncompresses a file |
5 // | 5 // |
6 // Author: Lasse Collin | 6 // Author: Lasse Collin |
7 // | 7 // |
8 // This file has been put into the public domain. | 8 // This file has been put into the public domain. |
9 // You can do whatever you want with this file. | 9 // You can do whatever you want with this file. |
10 // | 10 // |
(...skipping 19 matching lines...) Expand all Loading... |
30 static lzma_stream strm = LZMA_STREAM_INIT; | 30 static lzma_stream strm = LZMA_STREAM_INIT; |
31 | 31 |
32 /// Filters needed for all encoding all formats, and also decoding in raw data | 32 /// Filters needed for all encoding all formats, and also decoding in raw data |
33 static lzma_filter filters[LZMA_FILTERS_MAX + 1]; | 33 static lzma_filter filters[LZMA_FILTERS_MAX + 1]; |
34 | 34 |
35 /// Input and output buffers | 35 /// Input and output buffers |
36 static io_buf in_buf; | 36 static io_buf in_buf; |
37 static io_buf out_buf; | 37 static io_buf out_buf; |
38 | 38 |
39 /// Number of filters. Zero indicates that we are using a preset. | 39 /// Number of filters. Zero indicates that we are using a preset. |
40 static size_t filters_count = 0; | 40 static uint32_t filters_count = 0; |
41 | 41 |
42 /// Number of the preset (0-9) | 42 /// Number of the preset (0-9) |
43 static size_t preset_number = 6; | 43 static uint32_t preset_number = LZMA_PRESET_DEFAULT; |
44 | |
45 /// If a preset is used (no custom filter chain) and preset_extreme is true, | |
46 /// a significantly slower compression is used to achieve slightly better | |
47 /// compression ratio. | |
48 static bool preset_extreme = false; | |
49 | 44 |
50 /// Integrity check type | 45 /// Integrity check type |
51 static lzma_check check; | 46 static lzma_check check; |
52 | 47 |
53 /// This becomes false if the --check=CHECK option is used. | 48 /// This becomes false if the --check=CHECK option is used. |
54 static bool check_default = true; | 49 static bool check_default = true; |
55 | 50 |
56 | 51 |
57 extern void | 52 extern void |
58 coder_set_check(lzma_check new_check) | 53 coder_set_check(lzma_check new_check) |
59 { | 54 { |
60 check = new_check; | 55 check = new_check; |
61 check_default = false; | 56 check_default = false; |
62 return; | 57 return; |
63 } | 58 } |
64 | 59 |
65 | 60 |
66 extern void | 61 static void |
67 coder_set_preset(size_t new_preset) | 62 forget_filter_chain(void) |
68 { | 63 { |
69 preset_number = new_preset; | |
70 | |
71 // Setting a preset makes us forget a possibly defined custom | 64 // Setting a preset makes us forget a possibly defined custom |
72 // filter chain. | 65 // filter chain. |
73 while (filters_count > 0) { | 66 while (filters_count > 0) { |
74 --filters_count; | 67 --filters_count; |
75 free(filters[filters_count].options); | 68 free(filters[filters_count].options); |
76 filters[filters_count].options = NULL; | 69 filters[filters_count].options = NULL; |
77 } | 70 } |
78 | 71 |
79 return; | 72 return; |
80 } | 73 } |
81 | 74 |
82 | 75 |
83 extern void | 76 extern void |
| 77 coder_set_preset(uint32_t new_preset) |
| 78 { |
| 79 preset_number &= ~LZMA_PRESET_LEVEL_MASK; |
| 80 preset_number |= new_preset; |
| 81 forget_filter_chain(); |
| 82 return; |
| 83 } |
| 84 |
| 85 |
| 86 extern void |
84 coder_set_extreme(void) | 87 coder_set_extreme(void) |
85 { | 88 { |
86 » preset_extreme = true; | 89 » preset_number |= LZMA_PRESET_EXTREME; |
| 90 » forget_filter_chain(); |
87 return; | 91 return; |
88 } | 92 } |
89 | 93 |
90 | 94 |
91 extern void | 95 extern void |
92 coder_add_filter(lzma_vli id, void *options) | 96 coder_add_filter(lzma_vli id, void *options) |
93 { | 97 { |
94 if (filters_count == LZMA_FILTERS_MAX) | 98 if (filters_count == LZMA_FILTERS_MAX) |
95 message_fatal(_("Maximum number of filters is four")); | 99 message_fatal(_("Maximum number of filters is four")); |
96 | 100 |
97 filters[filters_count].id = id; | 101 filters[filters_count].id = id; |
98 filters[filters_count].options = options; | 102 filters[filters_count].options = options; |
99 ++filters_count; | 103 ++filters_count; |
100 | 104 |
| 105 // Setting a custom filter chain makes us forget the preset options. |
| 106 // This makes a difference if one specifies e.g. "xz -9 --lzma2 -e" |
| 107 // where the custom filter chain resets the preset level back to |
| 108 // the default 6, making the example equivalent to "xz -6e". |
| 109 preset_number = LZMA_PRESET_DEFAULT; |
| 110 |
101 return; | 111 return; |
102 } | 112 } |
103 | 113 |
104 | 114 |
105 static void lzma_attribute((__noreturn__)) | 115 static void lzma_attribute((__noreturn__)) |
106 memlimit_too_small(uint64_t memory_usage) | 116 memlimit_too_small(uint64_t memory_usage) |
107 { | 117 { |
108 message(V_ERROR, _("Memory usage limit is too low for the given " | 118 message(V_ERROR, _("Memory usage limit is too low for the given " |
109 "filter setup.")); | 119 "filter setup.")); |
110 message_mem_needed(V_ERROR, memory_usage); | 120 message_mem_needed(V_ERROR, memory_usage); |
(...skipping 16 matching lines...) Expand all Loading... |
127 // The message is shown only if warnings are allowed | 137 // The message is shown only if warnings are allowed |
128 // but the exit status isn't changed. | 138 // but the exit status isn't changed. |
129 message(V_WARNING, _("Using a preset in raw mode " | 139 message(V_WARNING, _("Using a preset in raw mode " |
130 "is discouraged.")); | 140 "is discouraged.")); |
131 message(V_WARNING, _("The exact options of the " | 141 message(V_WARNING, _("The exact options of the " |
132 "presets may vary between software " | 142 "presets may vary between software " |
133 "versions.")); | 143 "versions.")); |
134 } | 144 } |
135 | 145 |
136 // Get the preset for LZMA1 or LZMA2. | 146 // Get the preset for LZMA1 or LZMA2. |
137 if (preset_extreme) | |
138 preset_number |= LZMA_PRESET_EXTREME; | |
139 | |
140 if (lzma_lzma_preset(&opt_lzma, preset_number)) | 147 if (lzma_lzma_preset(&opt_lzma, preset_number)) |
141 message_bug(); | 148 message_bug(); |
142 | 149 |
143 // Use LZMA2 except with --format=lzma we use LZMA1. | 150 // Use LZMA2 except with --format=lzma we use LZMA1. |
144 filters[0].id = opt_format == FORMAT_LZMA | 151 filters[0].id = opt_format == FORMAT_LZMA |
145 ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2; | 152 ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2; |
146 filters[0].options = &opt_lzma; | 153 filters[0].options = &opt_lzma; |
147 filters_count = 1; | 154 filters_count = 1; |
148 } | 155 } |
149 | 156 |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 } | 664 } |
658 } | 665 } |
659 } | 666 } |
660 | 667 |
661 // Close the file pair. It needs to know if coding was successful to | 668 // Close the file pair. It needs to know if coding was successful to |
662 // know if the source or target file should be unlinked. | 669 // know if the source or target file should be unlinked. |
663 io_close(pair, success); | 670 io_close(pair, success); |
664 | 671 |
665 return; | 672 return; |
666 } | 673 } |
OLD | NEW |