]> icculus.org git repositories - icculus/xz.git/blob - src/xz/coder.c
Allow extra commas in filter-specific options on xz command line.
[icculus/xz.git] / src / xz / coder.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       coder.c
4 /// \brief      Compresses or uncompresses a file
5 //
6 //  Author:     Lasse Collin
7 //
8 //  This file has been put into the public domain.
9 //  You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #include "private.h"
14
15
16 /// Return value type for coder_init().
17 enum coder_init_ret {
18         CODER_INIT_NORMAL,
19         CODER_INIT_PASSTHRU,
20         CODER_INIT_ERROR,
21 };
22
23
24 enum operation_mode opt_mode = MODE_COMPRESS;
25
26 enum format_type opt_format = FORMAT_AUTO;
27
28
29 /// Stream used to communicate with liblzma
30 static lzma_stream strm = LZMA_STREAM_INIT;
31
32 /// Filters needed for all encoding all formats, and also decoding in raw data
33 static lzma_filter filters[LZMA_FILTERS_MAX + 1];
34
35 /// Input and output buffers
36 static uint8_t in_buf[IO_BUFFER_SIZE];
37 static uint8_t out_buf[IO_BUFFER_SIZE];
38
39 /// Number of filters. Zero indicates that we are using a preset.
40 static size_t filters_count = 0;
41
42 /// Number of the preset (0-9)
43 static size_t preset_number = 6;
44
45 /// True if we should auto-adjust the compression settings to use less memory
46 /// if memory usage limit is too low for the original settings.
47 static bool auto_adjust = true;
48
49 /// Indicate if no preset has been explicitly given. In that case, if we need
50 /// to auto-adjust for lower memory usage, we won't print a warning.
51 static bool preset_default = true;
52
53 /// If a preset is used (no custom filter chain) and preset_extreme is true,
54 /// a significantly slower compression is used to achieve slightly better
55 /// compression ratio.
56 static bool preset_extreme = false;
57
58 /// Integrity check type
59 #ifdef HAVE_CHECK_CRC64
60 static lzma_check check = LZMA_CHECK_CRC64;
61 #else
62 static lzma_check check = LZMA_CHECK_CRC32;
63 #endif
64
65
66 extern void
67 coder_set_check(lzma_check new_check)
68 {
69         check = new_check;
70         return;
71 }
72
73
74 extern void
75 coder_set_preset(size_t new_preset)
76 {
77         preset_number = new_preset;
78         preset_default = false;
79         return;
80 }
81
82
83 extern void
84 coder_set_extreme(void)
85 {
86         preset_extreme = true;
87         return;
88 }
89
90
91 extern void
92 coder_add_filter(lzma_vli id, void *options)
93 {
94         if (filters_count == LZMA_FILTERS_MAX)
95                 message_fatal(_("Maximum number of filters is four"));
96
97         filters[filters_count].id = id;
98         filters[filters_count].options = options;
99         ++filters_count;
100
101         return;
102 }
103
104
105 static void lzma_attribute((noreturn))
106 memlimit_too_small(uint64_t memory_usage, uint64_t memory_limit)
107 {
108         message_fatal(_("Memory usage limit (%" PRIu64 " MiB) is too small "
109                         "for the given filter setup (%" PRIu64 " MiB)"),
110                         memory_limit >> 20, memory_usage >> 20);
111 }
112
113
114 extern void
115 coder_set_compression_settings(void)
116 {
117         // Options for LZMA1 or LZMA2 in case we are using a preset.
118         static lzma_options_lzma opt_lzma;
119
120         if (filters_count == 0) {
121                 // We are using a preset. This is not a good idea in raw mode
122                 // except when playing around with things. Different versions
123                 // of this software may use different options in presets, and
124                 // thus make uncompressing the raw data difficult.
125                 if (opt_format == FORMAT_RAW) {
126                         // The message is shown only if warnings are allowed
127                         // but the exit status isn't changed.
128                         message(V_WARNING, _("Using a preset in raw mode "
129                                         "is discouraged."));
130                         message(V_WARNING, _("The exact options of the "
131                                         "presets may vary between software "
132                                         "versions."));
133                 }
134
135                 // Get the preset for LZMA1 or LZMA2.
136                 if (preset_extreme)
137                         preset_number |= LZMA_PRESET_EXTREME;
138
139                 if (lzma_lzma_preset(&opt_lzma, preset_number))
140                         message_bug();
141
142                 // Use LZMA2 except with --format=lzma we use LZMA1.
143                 filters[0].id = opt_format == FORMAT_LZMA
144                                 ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2;
145                 filters[0].options = &opt_lzma;
146                 filters_count = 1;
147         } else {
148                 preset_default = false;
149         }
150
151         // Terminate the filter options array.
152         filters[filters_count].id = LZMA_VLI_UNKNOWN;
153
154         // If we are using the LZMA_Alone format, allow exactly one filter
155         // which has to be LZMA.
156         if (opt_format == FORMAT_LZMA && (filters_count != 1
157                         || filters[0].id != LZMA_FILTER_LZMA1))
158                 message_fatal(_("With --format=lzma only the LZMA1 filter "
159                                 "is supported"));
160
161         // Print the selected filter chain.
162         message_filters(V_DEBUG, filters);
163
164         // If using --format=raw, we can be decoding. The memusage function
165         // also validates the filter chain and the options used for the
166         // filters.
167         const uint64_t memory_limit = hardware_memlimit_get();
168         uint64_t memory_usage;
169         if (opt_mode == MODE_COMPRESS)
170                 memory_usage = lzma_raw_encoder_memusage(filters);
171         else
172                 memory_usage = lzma_raw_decoder_memusage(filters);
173
174         if (memory_usage == UINT64_MAX)
175                 message_fatal("Unsupported filter chain or filter options");
176
177         // Print memory usage info.
178         message(V_DEBUG, _("%s MiB (%s B) of memory is required per thread, "
179                         "limit is %s MiB (%s B)"),
180                         uint64_to_str(memory_usage >> 20, 0),
181                         uint64_to_str(memory_usage, 1),
182                         uint64_to_str(memory_limit >> 20, 2),
183                         uint64_to_str(memory_limit, 3));
184
185         if (memory_usage > memory_limit) {
186                 // If --no-auto-adjust was used or we didn't find LZMA1 or
187                 // LZMA2 as the last filter, give an error immediatelly.
188                 // --format=raw implies --no-auto-adjust.
189                 if (!auto_adjust || opt_format == FORMAT_RAW)
190                         memlimit_too_small(memory_usage, memory_limit);
191
192                 assert(opt_mode == MODE_COMPRESS);
193
194                 // Look for the last filter if it is LZMA2 or LZMA1, so
195                 // we can make it use less RAM. With other filters we don't
196                 // know what to do.
197                 size_t i = 0;
198                 while (filters[i].id != LZMA_FILTER_LZMA2
199                                 && filters[i].id != LZMA_FILTER_LZMA1) {
200                         if (filters[i].id == LZMA_VLI_UNKNOWN)
201                                 memlimit_too_small(memory_usage, memory_limit);
202
203                         ++i;
204                 }
205
206                 // Decrease the dictionary size until we meet the memory
207                 // usage limit. First round down to full mebibytes.
208                 lzma_options_lzma *opt = filters[i].options;
209                 const uint32_t orig_dict_size = opt->dict_size;
210                 opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
211                 while (true) {
212                         // If it is below 1 MiB, auto-adjusting failed. We
213                         // could be more sophisticated and scale it down even
214                         // more, but let's see if many complain about this
215                         // version.
216                         //
217                         // FIXME: Displays the scaled memory usage instead
218                         // of the original.
219                         if (opt->dict_size < (UINT32_C(1) << 20))
220                                 memlimit_too_small(memory_usage, memory_limit);
221
222                         memory_usage = lzma_raw_encoder_memusage(filters);
223                         if (memory_usage == UINT64_MAX)
224                                 message_bug();
225
226                         // Accept it if it is low enough.
227                         if (memory_usage <= memory_limit)
228                                 break;
229
230                         // Otherwise 1 MiB down and try again. I hope this
231                         // isn't too slow method for cases where the original
232                         // dict_size is very big.
233                         opt->dict_size -= UINT32_C(1) << 20;
234                 }
235
236                 // Tell the user that we decreased the dictionary size.
237                 // However, omit the message if no preset or custom chain
238                 // was given. FIXME: Always warn?
239                 if (!preset_default)
240                         message(V_WARNING, "Adjusted LZMA%c dictionary size "
241                                         "from %s MiB to %s MiB to not exceed "
242                                         "the memory usage limit of %s MiB",
243                                         filters[i].id == LZMA_FILTER_LZMA2
244                                                 ? '2' : '1',
245                                         uint64_to_str(orig_dict_size >> 20, 0),
246                                         uint64_to_str(opt->dict_size >> 20, 1),
247                                         uint64_to_str(memory_limit >> 20, 2));
248         }
249
250 /*
251         // Limit the number of worker threads so that memory usage
252         // limit isn't exceeded.
253         assert(memory_usage > 0);
254         size_t thread_limit = memory_limit / memory_usage;
255         if (thread_limit == 0)
256                 thread_limit = 1;
257
258         if (opt_threads > thread_limit)
259                 opt_threads = thread_limit;
260 */
261
262         return;
263 }
264
265
266 /// Return true if the data in in_buf seems to be in the .xz format.
267 static bool
268 is_format_xz(void)
269 {
270         return strm.avail_in >= 6 && memcmp(in_buf, "\3757zXZ", 6) == 0;
271 }
272
273
274 /// Return true if the data in in_buf seems to be in the .lzma format.
275 static bool
276 is_format_lzma(void)
277 {
278         // The .lzma header is 13 bytes.
279         if (strm.avail_in < 13)
280                 return false;
281
282         // Decode the LZMA1 properties.
283         lzma_filter filter = { .id = LZMA_FILTER_LZMA1 };
284         if (lzma_properties_decode(&filter, NULL, in_buf, 5) != LZMA_OK)
285                 return false;
286
287         // A hack to ditch tons of false positives: We allow only dictionary
288         // sizes that are 2^n or 2^n + 2^(n-1) or UINT32_MAX. LZMA_Alone
289         // created only files with 2^n, but accepts any dictionary size.
290         // If someone complains, this will be reconsidered.
291         lzma_options_lzma *opt = filter.options;
292         const uint32_t dict_size = opt->dict_size;
293         free(opt);
294
295         if (dict_size != UINT32_MAX) {
296                 uint32_t d = dict_size - 1;
297                 d |= d >> 2;
298                 d |= d >> 3;
299                 d |= d >> 4;
300                 d |= d >> 8;
301                 d |= d >> 16;
302                 ++d;
303                 if (d != dict_size || dict_size == 0)
304                         return false;
305         }
306
307         // Another hack to ditch false positives: Assume that if the
308         // uncompressed size is known, it must be less than 256 GiB.
309         // Again, if someone complains, this will be reconsidered.
310         uint64_t uncompressed_size = 0;
311         for (size_t i = 0; i < 8; ++i)
312                 uncompressed_size |= (uint64_t)(in_buf[5 + i]) << (i * 8);
313
314         if (uncompressed_size != UINT64_MAX
315                         && uncompressed_size > (UINT64_C(1) << 38))
316                 return false;
317
318         return true;
319 }
320
321
322 /// Detect the input file type (for now, this done only when decompressing),
323 /// and initialize an appropriate coder. Return value indicates if a normal
324 /// liblzma-based coder was initialized (CODER_INIT_NORMAL), if passthru
325 /// mode should be used (CODER_INIT_PASSTHRU), or if an error occurred
326 /// (CODER_INIT_ERROR).
327 static enum coder_init_ret
328 coder_init(file_pair *pair)
329 {
330         lzma_ret ret = LZMA_PROG_ERROR;
331
332         if (opt_mode == MODE_COMPRESS) {
333                 switch (opt_format) {
334                 case FORMAT_AUTO:
335                         // args.c ensures this.
336                         assert(0);
337                         break;
338
339                 case FORMAT_XZ:
340                         ret = lzma_stream_encoder(&strm, filters, check);
341                         break;
342
343                 case FORMAT_LZMA:
344                         ret = lzma_alone_encoder(&strm, filters[0].options);
345                         break;
346
347                 case FORMAT_RAW:
348                         ret = lzma_raw_encoder(&strm, filters);
349                         break;
350                 }
351         } else {
352                 const uint32_t flags = LZMA_TELL_UNSUPPORTED_CHECK
353                                 | LZMA_CONCATENATED;
354
355                 // We abuse FORMAT_AUTO to indicate unknown file format,
356                 // for which we may consider passthru mode.
357                 enum format_type init_format = FORMAT_AUTO;
358
359                 switch (opt_format) {
360                 case FORMAT_AUTO:
361                         if (is_format_xz())
362                                 init_format = FORMAT_XZ;
363                         else if (is_format_lzma())
364                                 init_format = FORMAT_LZMA;
365                         break;
366
367                 case FORMAT_XZ:
368                         if (is_format_xz())
369                                 init_format = FORMAT_XZ;
370                         break;
371
372                 case FORMAT_LZMA:
373                         if (is_format_lzma())
374                                 init_format = FORMAT_LZMA;
375                         break;
376
377                 case FORMAT_RAW:
378                         init_format = FORMAT_RAW;
379                         break;
380                 }
381
382                 switch (init_format) {
383                 case FORMAT_AUTO:
384                         // Uknown file format. If --decompress --stdout
385                         // --force have been given, then we copy the input
386                         // as is to stdout. Checking for MODE_DECOMPRESS
387                         // is needed, because we don't want to do use
388                         // passthru mode with --test.
389                         if (opt_mode == MODE_DECOMPRESS
390                                         && opt_stdout && opt_force)
391                                 return CODER_INIT_PASSTHRU;
392
393                         ret = LZMA_FORMAT_ERROR;
394                         break;
395
396                 case FORMAT_XZ:
397                         ret = lzma_stream_decoder(&strm,
398                                         hardware_memlimit_get(), flags);
399                         break;
400
401                 case FORMAT_LZMA:
402                         ret = lzma_alone_decoder(&strm,
403                                         hardware_memlimit_get());
404                         break;
405
406                 case FORMAT_RAW:
407                         // Memory usage has already been checked in
408                         // coder_set_compression_settings().
409                         ret = lzma_raw_decoder(&strm, filters);
410                         break;
411                 }
412         }
413
414         if (ret != LZMA_OK) {
415                 message_error("%s: %s", pair->src_name, message_strm(ret));
416                 return CODER_INIT_ERROR;
417         }
418
419         return CODER_INIT_NORMAL;
420 }
421
422
423 /// Compress or decompress using liblzma.
424 static bool
425 coder_normal(file_pair *pair)
426 {
427         // Encoder needs to know when we have given all the input to it.
428         // The decoders need to know it too when we are using
429         // LZMA_CONCATENATED. We need to check for src_eof here, because
430         // the first input chunk has been already read, and that may
431         // have been the only chunk we will read.
432         lzma_action action = pair->src_eof ? LZMA_FINISH : LZMA_RUN;
433
434         lzma_ret ret;
435
436         // Assume that something goes wrong.
437         bool success = false;
438
439         strm.next_out = out_buf;
440         strm.avail_out = IO_BUFFER_SIZE;
441
442         while (!user_abort) {
443                 // Fill the input buffer if it is empty and we haven't reached
444                 // end of file yet.
445                 if (strm.avail_in == 0 && !pair->src_eof) {
446                         strm.next_in = in_buf;
447                         strm.avail_in = io_read(pair, in_buf, IO_BUFFER_SIZE);
448
449                         if (strm.avail_in == SIZE_MAX)
450                                 break;
451
452                         if (pair->src_eof)
453                                 action = LZMA_FINISH;
454                 }
455
456                 // Let liblzma do the actual work.
457                 ret = lzma_code(&strm, action);
458
459                 // Write out if the output buffer became full.
460                 if (strm.avail_out == 0) {
461                         if (opt_mode != MODE_TEST && io_write(pair, out_buf,
462                                         IO_BUFFER_SIZE - strm.avail_out))
463                                 break;
464
465                         strm.next_out = out_buf;
466                         strm.avail_out = IO_BUFFER_SIZE;
467                 }
468
469                 if (ret != LZMA_OK) {
470                         // Determine if the return value indicates that we
471                         // won't continue coding.
472                         const bool stop = ret != LZMA_NO_CHECK
473                                         && ret != LZMA_UNSUPPORTED_CHECK;
474
475                         if (stop) {
476                                 // Write the remaining bytes even if something
477                                 // went wrong, because that way the user gets
478                                 // as much data as possible, which can be good
479                                 // when trying to get at least some useful
480                                 // data out of damaged files.
481                                 if (opt_mode != MODE_TEST && io_write(pair,
482                                                 out_buf, IO_BUFFER_SIZE
483                                                         - strm.avail_out))
484                                         break;
485                         }
486
487                         if (ret == LZMA_STREAM_END) {
488                                 // Check that there is no trailing garbage.
489                                 // This is needed for LZMA_Alone and raw
490                                 // streams.
491                                 if (strm.avail_in == 0 && !pair->src_eof) {
492                                         // Try reading one more byte.
493                                         // Hopefully we don't get any more
494                                         // input, and thus pair->src_eof
495                                         // becomes true.
496                                         strm.avail_in = io_read(
497                                                         pair, in_buf, 1);
498                                         if (strm.avail_in == SIZE_MAX)
499                                                 break;
500
501                                         assert(strm.avail_in == 0
502                                                         || strm.avail_in == 1);
503                                 }
504
505                                 if (strm.avail_in == 0) {
506                                         assert(pair->src_eof);
507                                         success = true;
508                                         break;
509                                 }
510
511                                 // We hadn't reached the end of the file.
512                                 ret = LZMA_DATA_ERROR;
513                                 assert(stop);
514                         }
515
516                         // If we get here and stop is true, something went
517                         // wrong and we print an error. Otherwise it's just
518                         // a warning and coding can continue.
519                         if (stop) {
520                                 message_error("%s: %s", pair->src_name,
521                                                 message_strm(ret));
522                         } else {
523                                 message_warning("%s: %s", pair->src_name,
524                                                 message_strm(ret));
525
526                                 // When compressing, all possible errors set
527                                 // stop to true.
528                                 assert(opt_mode != MODE_COMPRESS);
529                         }
530
531                         if (ret == LZMA_MEMLIMIT_ERROR) {
532                                 // Figure out how much memory it would have
533                                 // actually needed.
534                                 uint64_t memusage = lzma_memusage(&strm);
535                                 uint64_t memlimit = hardware_memlimit_get();
536
537                                 // Round the memory limit down and usage up.
538                                 // This way we don't display a ridiculous
539                                 // message like "Limit was 9 MiB, but 9 MiB
540                                 // would have been needed".
541                                 memusage = (memusage + 1024 * 1024 - 1)
542                                                 / (1024 * 1024);
543                                 memlimit /= 1024 * 1024;
544
545                                 message_error(_("Limit was %s MiB, "
546                                                 "but %s MiB would "
547                                                 "have been needed"),
548                                                 uint64_to_str(memlimit, 0),
549                                                 uint64_to_str(memusage, 1));
550                         }
551
552                         if (stop)
553                                 break;
554                 }
555
556                 // Show progress information under certain conditions.
557                 message_progress_update();
558         }
559
560         return success;
561 }
562
563
564 /// Copy from input file to output file without processing the data in any
565 /// way. This is used only when trying to decompress unrecognized files
566 /// with --decompress --stdout --force, so the output is always stdout.
567 static bool
568 coder_passthru(file_pair *pair)
569 {
570         while (strm.avail_in != 0) {
571                 if (user_abort)
572                         return false;
573
574                 if (io_write(pair, in_buf, strm.avail_in))
575                         return false;
576
577                 strm.total_in += strm.avail_in;
578                 strm.total_out = strm.total_in;
579                 message_progress_update();
580
581                 strm.avail_in = io_read(pair, in_buf, IO_BUFFER_SIZE);
582                 if (strm.avail_in == SIZE_MAX)
583                         return false;
584         }
585
586         return true;
587 }
588
589
590 extern void
591 coder_run(const char *filename)
592 {
593         // Try to open the input and output files.
594         file_pair *pair = io_open(filename);
595         if (pair == NULL)
596                 return;
597
598         // Initialize the progress indicator.
599         const uint64_t in_size = pair->src_st.st_size <= (off_t)(0)
600                         ? 0 : (uint64_t)(pair->src_st.st_size);
601         message_progress_start(&strm, pair->src_name, in_size);
602
603         // Assume that something goes wrong.
604         bool success = false;
605
606         // Read the first chunk of input data. This is needed to detect
607         // the input file type (for now, only for decompression).
608         strm.next_in = in_buf;
609         strm.avail_in = io_read(pair, in_buf, IO_BUFFER_SIZE);
610
611         switch (coder_init(pair)) {
612         case CODER_INIT_NORMAL:
613                 success = coder_normal(pair);
614                 break;
615
616         case CODER_INIT_PASSTHRU:
617                 success = coder_passthru(pair);
618                 break;
619
620         case CODER_INIT_ERROR:
621                 break;
622         }
623
624         message_progress_end(success);
625
626         // Close the file pair. It needs to know if coding was successful to
627         // know if the source or target file should be unlinked.
628         io_close(pair, success);
629
630         return;
631 }