Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The 7z command-line tool lets you specify multiple compression methods, e.g.:

# 7-zip archive type, strongest (9) compression, methods PPMd, BCJ2, LZMA2
$ 7z a -t7z -mx=9 -m0=PPMd -m1=BCJ2 -m2=LZMA2 myarchive.7z somefile.xml

All methods get used in some way, or at least specified in the metadata:

$ 7z l -slt myarchive.7z

7-Zip [64] 9.22 beta  Copyright (c) 1999-2011 Igor Pavlov  2011-04-18

Listing archive: myarchive.

Path = myarchive.7z
Type = 7z
Method = LZMA2 PPMD BCJ2

Path = somefile.xml
Method = PPMD:o32:mem192m BCJ2 LZMA2:48m
Block = 0

It does not appear to run the file through all three methods, picking the best. Rather, it apparently always picks the first, as changing the order of the method affects the file size significantly.

Even if I add multiple files, such as one XML file (PPMd yields best compression) and one binary file (LZMA2 does), it still lists all methods for both files, and doesn't appear to switch dynamically per file.

In fact, the documentation specifically says that "You can use any number of methods.", but it does not say wherefore.

What I'm trying to achieve is a per-file "try multiple methods, pick whichever is best" archive. I can of course manually achieve this with a little scripting, but presumably, chaining compression methods should do exactly that?

share|improve this question
Changing the order of compression methods should change the compressed size even if all methods are applied in sequence. Most compression typically comes from the first method applied. The result from that typically has high entropy, so is hard to compress further. There are exceptions for tranforms that aren't expected to compress the data themselves, but which encode it to be more compressible - e.g. the sequence 1, 2, 3, 4, 5 has no repetition of values, but has repetition of differences, so a delta transform improves compressibility. That's what Daniel B's answer is about. – Steve314 Aug 7 '14 at 21:11
I don't actually know what 7zip does, though - just commenting on your "as changing the order of the method affects the file size significantly" logic. – Steve314 Aug 7 '14 at 21:14
up vote 3 down vote accepted

Generally, compressed data cannot be compressed (further) efficiently. After the first compression method has been applied, the file size cannot be decreased significantly.

The -mN=X is mainly for specifying filters (taken from Windows help file):

Supported filters:

Delta Delta filter (“It's possible to set delta offset in bytes. For example, to compress 16-bit stereo WAV files, you can set "0=Delta:4". Default delta offset is 1.”)

BCJ converter for x86 executables

BCJ2 converter for x86 executables (version 2) (“BCJ2 is a Branch converter for 32-bit x86 executables (version 2). It converts some branch instructions for increasing further compression.”)

ARM converter for ARM (little endian) executables

ARMT converter for ARM Thumb (little endian) executables

IA64 converter for IA-64 executables

PPC converter for PowerPC (big endian) executables

SPARC converter for SPARC executables

Also from the help file, an advanced example leveraging multiple output streams of the BCJ2 filter:

7z a -t7z archive.7z *.exe *.dll -m0=BCJ2 -m1=LZMA:d23 -m2=LZMA:d19 -m3=LZMA:d19      -mb0:1 -mb0s1:2 -mb0s2:3

adds *.exe and *.dll files to archive archive.7z using BCJ2 converter, LZMA with 8 MB dictionary for main output stream (s0), and LZMA with 512 KB dictionary for s1 and s2 output streams of BCJ2.

share|improve this answer
"After the first compression method has been applied, the file size cannot be decreased significantly." — Sure. My hope was that specifying multiple methods would make it try, per-file, each specified method and pick the most efficient. Naturally, this would make compression quite a lot slower. – Sören Kuklau Aug 18 '14 at 12:39

It seems you can apply filters in a sequence.

This post from last year has a nice explanation:

What does the number after 7-zip's -m switch mean?

That number lets you set the order of the compression operations if you are using more than one at once.

This is an example from the documentation:

7z a a.7z *.exe *.dll -m0=BCJ2 -m1=LZMA:d25 -m2=LZMA:d19 -m3=LZMA:d19 -mb0:1 -mb0s1:2 -mb0s2:3

adds *.exe and *.dll files to archive a.7z using BCJ2 filter, LZMA with 32 MB dictionary for main output stream (s0), and LZMA with 512 KB dictionary for s1 and s2 output streams of BCJ2.

The first compression is the lowest number, which is zero. In this example, zero is set to BCJ2. Then comes one, which is LZMA. Two and three are also LZMA, but they are using different d parameters.

The -mb option is used to "bind" the output from one compression to the input of another one. In this example, BCJ2 has one input and four outputs. Output zero is going to compression number one. Output one is going to compression number two. Output two goes to compression number three. Output three is not bound (because it does not need to be compressed again).

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .