Update the file format specification draft. The new one is
authorLasse Collin <lasse.collin@tukaani.org>
Tue, 17 Jun 2008 12:03:46 +0000 (15:03 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Tue, 17 Jun 2008 12:03:46 +0000 (15:03 +0300)
a lot simpler than the previous versions, but it also means
that the existing code will change a lot.

doc/file-format.txt

index 2c8cd48..49c9a75 100644 (file)
@@ -3,82 +3,54 @@ The .lzma File Format
 ---------------------
 
         0. Preface
-          0.1. Copyright Notices
-          0.2. Changes
+           0.1. Copyright Notices
+           0.2. Changes
         1. Conventions
-          1.1. Byte and Its Representation
-          1.2. Multibyte Integers
-        2. Stream
-          2.1. Stream Types
-            2.1.1. Single-Block Stream
-            2.1.2. Multi-Block Stream
-          2.2. Stream Header
-            2.2.1. Header Magic Bytes
-            2.2.2. Stream Flags
-            2.2.3. CRC32
+           1.1. Byte and Its Representation
+           1.2. Multibyte Integers
+        2. Overall Structure of .lzma File
+           2.1. Stream
+                2.1.1. Stream Header
+                       2.1.1.1. Header Magic Bytes
+                       2.1.1.2. Stream Flags
+                       2.1.1.3. CRC32
+                2.1.2. Stream Footer
+                       2.1.2.1. CRC32
+                       2.1.2.2. Backward Size
+                       2.1.2.3. Stream Flags
+                       2.1.2.4. Footer Magic Bytes
+           2.2. Stream Padding
         3. Block
-          3.1. Block Header
-            3.1.1. Block Flags
-            3.1.2. Compressed Size
-            3.1.3. Uncompressed Size
-            3.1.4. List of Filter Flags
-              3.1.4.1. Misc
-              3.1.4.2. External ID
-              3.1.4.3. External Size of Properties
-              3.1.4.4. Filter Properties
-            3.1.5. CRC32
-            3.1.6. Header Padding
-          3.2. Compressed Data
-          3.3. Block Footer
-            3.3.1. Check
-            3.3.2. Stream Footer
-              3.3.2.1. Uncompressed Size
-              3.3.2.2. Backward Size
-              3.3.2.3. Stream Flags
-              3.3.2.4. Footer Magic Bytes
-            3.3.3. Footer Padding
-        4. Filters
-          4.1. Detecting when All Data Has Been Decoded
-            4.1.1. With Uncompressed Size
-            4.1.2. With End of Input
-            4.1.3. With End of Payload Marker
-          4.2. Alignment
-          4.3. Filters
-            4.3.1. Copy
-            4.3.2. Subblock
-              4.3.2.1. Format of the Encoded Output
-            4.3.3. Delta
-              4.3.3.1. Format of the Encoded Output
-            4.3.4. LZMA
-              4.3.4.1. LZMA Properties
-              4.3.4.2. Dictionary Flags
-            4.3.5. Branch/Call/Jump Filters for Executables
-        5. Metadata
-          5.1. Metadata Flags
-          5.2. Size of Header Metadata Block
-          5.3. Total Size
-          5.4. Uncompressed Size
-          5.5. Index
-            5.5.1. Number of Data Blocks
-            5.5.2. Total Sizes
-            5.5.3. Uncompressed Sizes
-          5.6. Extra
-            5.6.1. 0x00: Dummy/Padding
-            5.6.2. 0x01: OpenPGP Signature
-            5.6.3. 0x02: Filter Information
-            5.6.4. 0x03: Comment
-            5.6.5. 0x04: List of Checks
-            5.6.6. 0x05: Original Filename
-            5.6.7. 0x07: Modification Time
-            5.6.8. 0x09: High-Resolution Modification Time
-            5.6.9. 0x0B: MIME Type
-            5.6.10. 0x0D: Homepage URL
-        6. Custom Filter and Extra Record IDs
-          6.1. Reserved Custom Filter ID Ranges
-        7. Cyclic Redundancy Checks
-        8. References
-          8.1. Normative References
-          8.2. Informative References
+           3.1. Block Header
+                3.1.1. Block Header Size
+                3.1.2. Block Flags
+                3.1.3. Compressed Size
+                3.1.4. Uncompressed Size
+                3.1.5. List of Filter Flags
+                3.1.6. Header Padding
+                3.1.7. CRC32
+           3.2. Compressed Data
+           3.3. Check
+        4. Index
+           4.1. Index Indicator
+           4.2. Number of Records
+           4.3. List of Records
+                4.3.1. Total Size
+                4.3.2. Uncompressed Size
+           4.4. Index Padding
+           4.5. CRC32
+        5. Filter Chains
+           5.1. Alignment
+           5.2. Security
+           5.3. Filters
+                5.3.1. LZMA2
+                5.3.2. Branch/Call/Jump Filters for Executables
+                5.3.3. Delta
+                       5.3.3.1. Format of the Encoded Output
+           5.4. Custom Filter IDs
+                5.4.1. Reserved Custom Filter ID Ranges
+        6. Cyclic Redundancy Checks
+        7. References
 
 
 0. Preface
@@ -95,7 +67,7 @@ The .lzma File Format
 
 0.1. Copyright Notices
 
-        Copyright (C) 2006, 2007 Lasse Collin <lasse.collin@tukaani.org>
+        Copyright (C) 2006-2008 Lasse Collin <lasse.collin@tukaani.org>
         Copyright (C) 2006 Ville Koskinen <w-ber@iki.fi>
 
         Copying and distribution of this file, with or without
@@ -106,13 +78,14 @@ The .lzma File Format
         All source code examples given in this document are put into
         the public domain by the authors of this document.
 
-        Thanks for helping with this document goes to Igor Pavlov,
-        Mark Adler and Mikko Pouru.
+        Special thanks for helping with this document goes to
+        Igor Pavlov. Thanks for helping with this document goes to
+        Mark Adler, H. Peter Anvin, and Mikko Pouru.
 
 
 0.2. Changes
 
-        Last modified: 2008-02-01 19:25+0200
+        Last modified: 2008-06-17 14:10+0300
 
         (A changelog will be kept once the first official version
         is made.)
@@ -161,7 +134,7 @@ The .lzma File Format
 
         In this document, a boxed byte or a byte sequence declared
         using this notation is called `a field'. The example field
-        above would be called called `the Foo field' or plain `Foo'.
+        above would be called `the Foo field' or plain `Foo'.
 
 
 1.2. Multibyte Integers
@@ -170,39 +143,22 @@ The .lzma File Format
         are stored in little endian byte order (least significant
         byte first).
 
-        When smaller values are more likely than bigger values (e.g.
-        file sizes), multibyte integers are encoded in a simple
+        When smaller values are more likely than bigger values (for
+        example file sizes), multibyte integers are encoded in a
         variable-length representation:
           - Numbers in the range [0, 127] are copied as is, and take
             one byte of space.
-          - Bigger numbers will occupy two or more bytes. The lowest
-            seven bits of every byte are used for data; the highest
-            (eighth) bit indicates either that
-              0) the byte is in the middle of the byte sequence, or
-              1) the byte is the first or the last byte.
+          - Bigger numbers will occupy two or more bytes. All but the
+            last byte of the multibyte representation have the highest
+            (eighth) bit set.
 
         For now, the value of the variable-length integers is limited
         to 63 bits, which limits the encoded size of the integer to
         nine bytes. These limits may be increased in future if needed.
 
-        Note that the encoding is not as optimal as it could be. For
-        example, it is possible to encode the number 42 using any
-        number of bytes between one and nine. This is convenient
-        for non-streamed encoders, that write Compressed Size or
-        Uncompressed Size fields to the Block Header (see Section 3.1)
-        after the Compressed Data field is written to the disk.
-
-        In several situations, the decoder needs to compare that two
-        fields contain identical information. When comparing fields
-        using the encoding described in this Section, the decoder must
-        consider two fields identical if their decoded values are
-        identical; it does not matter if the encoded variable-length
-        representations differ.
-
-        The following C code illustrates encoding and decoding 63-bit
-        variables; the highest bit of uint64_t must be unset. The
-        functions return the number of bytes occupied by the integer
-        (1-9), or zero on error.
+        The following C code illustrates encoding and decoding of
+        variable-length integers. The functions return the number of
+        bytes occupied by the integer (1-9), or zero on error.
 
             #include <sys/types.h>
             #include <inttypes.h>
@@ -210,20 +166,18 @@ The .lzma File Format
             size_t
             encode(uint8_t buf[static 9], uint64_t num)
             {
-                if (num >= (UINT64_C(1) << (9 * 7)))
+                if (num >= UINT64_MAX / 2)
                     return 0;
-                if (num <= 0x7F) {
-                    buf[0] = num;
-                    return 1;
-                }
-                buf[0] = (num & 0x7F) | 0x80;
-                num >>= 7;
-                size_t i = 1;
+
+                size_t i = 0;
+
                 while (num >= 0x80) {
-                    buf[i++] = num & 0x7F;
+                    buf[i++] = (uint8_t)(num) | 0x80;
                     num >>= 7;
                 }
-                buf[i++] = num | 0x80;
+
+                buf[i++] = (uint8_t)(num);
+
                 return i;
             }
 
@@ -232,46 +186,29 @@ The .lzma File Format
             {
                 if (size_max == 0)
                     return 0;
+
                 if (size_max > 9)
                     size_max = 9;
+
                 *num = buf[0] & 0x7F;
-                if (!(buf[0] & 0x80))
-                    return 1;
-                size_t i = 1;
-                do {
-                    if (i == size_max)
-                        return 0;
-                    *num |= (uint64_t)(buf[i] & 0x7F) << (7 * i);
-                } while (!(buf[i++] & 0x80));
-                return i;
-            }
+                size_t i = 0;
 
-            size_t
-            decode_reverse(const uint8_t buf[], size_t size_max,
-                    uint64_t *num)
-            {
-                if (size_max == 0)
-                    return 0;
-                const size_t end = size_max > 9 ? size_max - 9 : 0;
-                size_t i = size_max - 1;
-                *num = buf[i] & 0x7F;
-                if (!(buf[i] & 0x80))
-                    return 1;
-                do {
-                    if (i-- == end)
+                while (buf[i++] & 0x80) {
+                    if (i > size_max || buf[i] == 0x00)
                         return 0;
-                    *num <<= 7;
-                    *num |= buf[i] & 0x7F;
-                } while (!(buf[i] & 0x80));
-                return size_max - i;
+
+                    *num |= (uint64_t)(buf[i] & 0x7F) << (i * 7);
+                }
+
+                return i;
             }
 
 
-2. Stream
+2. Overall Structure of .lzma File
 
-        +========+========+========+
-        | Stream | Stream | Stream | ...
-        +========+========+========+
+        +========+================+========+================+
+        | Stream | Stream Padding | Stream | Stream Padding | ...
+        +========+================+========+================+
 
         A file contains usually only one Stream. However, it is
         possible to concatenate multiple Streams together with no
@@ -280,53 +217,44 @@ The .lzma File Format
         Stream once the end of the first Stream has been reached.
 
 
-2.1. Stream Types
+2.1. Stream
 
-        There are two types of Streams: Single-Block Streams and
-        Multi-Block Streams. Decoders conforming to this specification
-        must support at least Single-Block Streams. Supporting
-        Multi-Block Streams is optional. If the decoder supports only
-        Single-Block Streams, the documentation of the decoder should
-        mention this fact clearly.
+        +-+-+-+-+-+-+-+-+-+-+-+-+=======+=======+     +=======+
+        |     Stream Header     | Block | Block | ... | Block |
+        +-+-+-+-+-+-+-+-+-+-+-+-+=======+=======+     +=======+
 
+             +=======+-+-+-+-+-+-+-+-+-+-+-+-+
+        ---> | Index |     Stream Footer     |
+             +=======+-+-+-+-+-+-+-+-+-+-+-+-+
 
-2.1.1. Single-Block Stream
+        All the above fields have a size that is a multiple of four. If
+        Stream is used as an internal part of another file format, it
+        is recommended to make the Stream start at an offset that is
+        a multiple of four bytes.
 
-        +===============+============+
-        | Stream Header | Data Block |
-        +===============+============+
+        Stream Header, Index, and Stream Footer are always present in
+        a Stream. The maximum size of the Index field is 16 GiB (2^34).
 
-        As the name says, a Single-Block Stream has exactly one Block.
-        The Block must be a Data Block; Metadata Blocks are not allowed
-        in Single-Block Streams.
+        There are zero or more Blocks. The maximum number of Blocks is
+        limited only by the maximum size of the Index field.
 
+        Total size of a Stream must be less than 8 EiB (2^63 bytes).
+        The same limit applies to the total amount of uncompressed
+        data stored in a Stream.
 
-2.1.2. Multi-Block Stream
+        If an implementation supports handling .lzma files with
+        multiple concatenated Streams, it may apply the above limits
+        to the file as a whole instead of limiting per Stream basis.
 
-        +===============+=======================+
-        | Stream Header | Header Metadata Block |
-        +===============+=======================+
-
-             +============+     +============+=======================+
-        ---> | Data Block | ... | Data Block | Footer Metadata Block |
-             +============+     +============+=======================+
-
-        Notes:
-          - Stream Header is mandatory.
-          - Header Metadata Block is optional.
-          - Each Multi-Block Stream has at least one Data Block. The
-            maximum number of Data Blocks is not limited.
-          - Footer Metadata Block is mandatory.
 
+2.1.1. Stream Header
 
-2.2. Stream Header
-
-        +---+---+---+---+---+---+--------------+--+--+--+--+
+        +---+---+---+---+---+---+-------+------+--+--+--+--+
         |  Header Magic Bytes   | Stream Flags |   CRC32   |
-        +---+---+---+---+---+---+--------------+--+--+--+--+
+        +---+---+---+---+---+---+-------+------+--+--+--+--+
 
 
-2.2.1. Header Magic Bytes
+2.1.1.1. Header Magic Bytes
 
         The first six (6) bytes of the Stream are so called Header
         Magic Bytes. They can be used to identify the file type.
@@ -341,33 +269,47 @@ The .lzma File Format
         Notes:
           - The first byte (0xFF) was chosen so that the files cannot
             be erroneously detected as being in LZMA_Alone format, in
-            which the first byte is in the the range [0x00, 0xE0].
+            which the first byte is in the range [0x00, 0xE0].
           - The sixth byte (0x00) was chosen to prevent applications
             from misdetecting the file as a text file.
 
+        If the Header Magic Bytes don't match, the decoder must
+        indicate an error.
+
+
+2.1.1.2. Stream Flags
+
+        The first byte of Stream Flags is always a nul byte. In future
+        this byte may be used to indicate new Stream version or other
+        Stream properties.
+
+        The second byte of Stream Flags is a bit field:
 
-2.2.2. Stream Flags
-
-        Bit(s)  Mask  Description
-         0-2    0x07  Type of Check (see Section 3.3.1):
-                          ID    Size      Check name
-                          0x00   0 bytes  None
-                          0x01   4 bytes  CRC32
-                          0x02   4 bytes  (Reserved)
-                          0x03   8 bytes  CRC64
-                          0x04  16 bytes  (Reserved)
-                          0x05  32 bytes  SHA-256
-                          0x06  32 bytes  (Reserved)
-                          0x07  64 bytes  (Reserved)
-          3     0x08  The CRC32 field is present in Block Headers.
-          4     0x10  If unset, this is a Single-Block Stream; if set,
-                      this is a Multi-Block Stream.
-         5-7    0xE0  Reserved for future use; must be zero for now.
+            Bit(s)  Mask  Description
+             0-3    0x0F  Type of Check (see Section 3.3):
+                              ID    Size      Check name
+                              0x00   0 bytes  None
+                              0x01   4 bytes  CRC32
+                              0x02   4 bytes  (Reserved)
+                              0x03   4 bytes  (Reserved)
+                              0x04   8 bytes  CRC64
+                              0x05   8 bytes  (Reserved)
+                              0x06   8 bytes  (Reserved)
+                              0x07  16 bytes  (Reserved)
+                              0x08  16 bytes  (Reserved)
+                              0x09  16 bytes  (Reserved)
+                              0x0A  32 bytes  SHA-256
+                              0x0B  32 bytes  (Reserved)
+                              0x0C  32 bytes  (Reserved)
+                              0x0D  64 bytes  (Reserved)
+                              0x0E  64 bytes  (Reserved)
+                              0x0F  64 bytes  (Reserved)
+             4-7    0xF0  Reserved for future use; must be zero for now.
 
         Implementations must support at least the Check IDs 0x00 (None)
-        and 0x01 (CRC32). Supporting other Check IDs is optional. If an
-        unsupported Check is used, the decoder must indicate a warning
-        or error.
+        and 0x01 (CRC32). Supporting other Check IDs is optional. If
+        an unsupported Check is used, the decoder should indicate a
+        warning or error.
 
         If any reserved bit is set, the decoder must indicate an error.
         It is possible that there is a new field present which the
@@ -375,256 +317,259 @@ The .lzma File Format
         incorrectly.
 
 
-2.2.3. CRC32
+2.1.1.3. CRC32
 
         The CRC32 is calculated from the Stream Flags field. It is
         stored as an unsigned 32-bit little endian integer. If the
         calculated value does not match the stored one, the decoder
         must indicate an error.
 
-        Note that this field is always present; the bit in Stream Flags
-        controls only presence of CRC32 in Block Headers.
+        The idea is that Stream Flags would always be two bytes, even
+        if new features are needed. This way old decoders will be able
+        to verify the CRC32 calculated from Stream Flags, and thus
+        distinguish between corrupt files (CRC32 doesn't match) and
+        files that the decoder doesn't support (CRC32 matches but
+        Stream Flags has reserved bits set).
 
 
-3. Block
+2.1.2. Stream Footer
 
-        +==============+=================+==============+
-        | Block Header | Compressed Data | Block Footer |
-        +==============+=================+==============+
+        +-+-+-+-+---+---+---+---+-------+------+----------+---------+
+        | CRC32 | Backward Size | Stream Flags | Footer Magic Bytes |
+        +-+-+-+-+---+---+---+---+-------+------+----------+---------+
 
-        There are two types of Blocks:
-          - Data Blocks hold the actual compressed data.
-          - Metadata Blocks hold the Index, Extra, and a few other
-            non-data fields (see Section 5).
 
-        The type of the Block is indicated by the corresponding bit
-        in the Block Flags field (see Section 3.1.1).
+2.1.2.1. CRC32
 
+        The CRC32 is calculated from the Backward Size and Stream Flags
+        fields. It is stored as an unsigned 32-bit little endian
+        integer. If the calculated value does not match the stored one,
+        the decoder must indicate an error.
 
-3.1. Block Header
+        The reason to have the CRC32 field before the Backward Size and
+        Stream Flags fields is to keep the four-byte fields aligned to
+        a multiple of four bytes.
 
-        +------+------+=================+===================+
-        | Block Flags | Compressed Size | Uncompressed Size |
-        +------+------+=================+===================+
 
-             +======================+--+--+--+--+================+
-        ---> | List of Filter Flags |   CRC32   | Header Padding |
-             +======================+--+--+--+--+================+
+2.1.2.2. Backward Size
 
+        Backward Size is stored as a 32-bit little endian integer,
+        which indicates the size of the Index field as multiple of
+        four bytes, minimum value being four bytes:
 
-3.1.1. Block Flags
+            real_backward_size = (stored_backward_size + 1) * 4;
 
-        The first byte of the Block Flags field is a bit field:
+        Using a fixed-size integer to store this value makes it
+        slightly simpler to parse the Stream Footer when the
+        application needs to parse the Stream backwards.
 
-            Bit(s)  Mask  Description
-             0-2    0x07  Number of filters (0-7)
-              3     0x08  Use End of Payload Marker (even if
-                          Uncompressed Size is stored to Block Header).
-              4     0x10  The Compressed Size field is present.
-              5     0x20  The Uncompressed Size field is present.
-              6     0x40  Reserved for future use; must be zero for now.
-              7     0x80  This is a Metadata Block.
 
-        The second byte of the Block Flags field is also a bit field:
+2.1.2.3. Stream Flags
 
-            Bit(s)  Mask  Description
-             0-4    0x1F  Size of the Header Padding field (0-31 bytes)
-             5-7    0xE0  Reserved for future use; must be zero for now.
+        This is a copy of the Stream Flags field from the Stream
+        Header. The information stored to Stream Flags is needed
+        when parsing the Stream backwards. The decoder must compare
+        the Stream Flags fields in both Stream Header and Stream
+        Footer, and indicate an error if they are not identical.
 
-        The decoder must indicate an error if End of Payload Marker
-        is not used and Uncompressed Size is not stored to the Block
-        Header. Because of this, the first byte of Block Flags can
-        never be a nul byte. This is useful when detecting beginning
-        of the Block after Footer Padding (see Section 3.3.3).
 
-        If any reserved bit is set, the decoder must indicate an error.
-        It is possible that there is a new field present which the
-        decoder is not aware of, and can thus parse the Block Header
-        incorrectly.
+2.1.2.4. Footer Magic Bytes
 
+        As the last step of the decoding process, the decoder must
+        verify the existence of Footer Magic Bytes. If they don't
+        match, an error must be indicated.
 
-3.1.2. Compressed Size
+            Using a C array and ASCII:
+            const uint8_t FOOTER_MAGIC[2] = { 'Y', 'Z' };
 
-        This field is present only if the appropriate bit is set in
-        the Block Flags field (see Section 3.1.1).
+            In hexadecimal:
+            59 5A
 
-        This field contains the size of the Compressed Data field.
-        The size is stored using the encoding described in Section 1.2.
-        If the Compressed Size does not match the real size of the
-        Compressed Data field, the decoder must indicate an error.
+        The primary reason to have Footer Magic Bytes is to make
+        it easier to detect incomplete files quickly, without
+        uncompressing. If the file does not end with Footer Magic Bytes
+        (excluding Stream Padding described in Section 2.2), it cannot
+        be undamaged, unless someone has intentionally appended garbage
+        after the end of the Stream.
 
-        Having the Compressed Size field in the Block Header can be
-        useful for multithreaded decoding when seeking is not possible.
-        If the Blocks are small enough, the decoder can read multiple
-        Blocks into its internal buffer, and decode the Blocks in
-        parallel.
 
-        Compressed Size can also be useful when seeking forwards to
-        a specific location in streamed mode: the decoder can quickly
-        skip over irrelevant Blocks, without decoding them.
+2.2. Stream Padding
 
+        Only the decoders that support decoding of concatenated Streams
+        must support Stream Padding.
 
-3.1.3. Uncompressed Size
+        Stream Padding must contain only nul bytes. Any non-nul byte
+        should be considered as the beginning of a new Stream. To
+        preserve the four-byte alignment of consecutive Streams, the
+        size of Stream Padding must be a multiple of four bytes. Empty
+        Stream Padding is allowed.
 
-        This field is present only if the appropriate bit is set in
-        the Block Flags field (see Section 3.1.1).
+        Note that non-empty Stream Padding is allowed at the end of the
+        file; there doesn't need to be a new Stream after non-empty
+        Stream Padding. This can be convenient in certain situations
+        [GNU-tar].
 
-        The Uncompressed Size field contains the size of the Block
-        after uncompressing.
+        The possibility of Padding should be taken into account when
+        designing an application that parses the Stream backwards.
 
-        Storing Uncompressed Size serves several purposes:
-          - The decoder will know when all of the data has been
-            decoded without an explicit End of Payload Marker.
-          - The decoder knows how much memory it needs to allocate
-            for a temporary buffer in multithreaded mode.
-          - Simple error detection: wrong size indicates a broken file.
-          - Sometimes it is useful to know the file size without
-            uncompressing the file.
 
-        It should be noted that the only reliable way to find out what
-        the real uncompressed size is is to uncompress the Block,
-        because the Block Header and Metadata Block fields may contain
-        (intentionally or unintentionally) invalid information.
+3. Block
 
-        Uncompressed Size is stored using the encoding described in
-        Section 1.2. If the Uncompressed Size does not match the
-        real uncompressed size, the decoder must indicate an error.
+        +==============+=================+=======+
+        | Block Header | Compressed Data | Check |
+        +==============+=================+=======+
 
 
-3.1.4. List of Filter Flags
+3.1. Block Header
 
-        +================+================+     +================+
-        | Filter 0 Flags | Filter 1 Flags | ... | Filter n Flags |
-        +================+================+     +================+
+        +-------------------+-------------+=================+
+        | Block Header Size | Block Flags | Compressed Size |
+        +-------------------+-------------+=================+
 
-        The number of Filter Flags fields is stored in the Block Flags
-        field (see Section 3.1.1). As a special case, if the number of
-        Filter Flags fields is zero, it is equivalent to having the
-        Copy filter as the only filter.
+             +===================+======================+
+        ---> | Uncompressed Size | List of Filter Flags |
+             +===================+======================+
 
-        The format of each Filter Flags field is as follows:
+             +================+--+--+--+--+
+        ---> | Header Padding |   CRC32   |
+             +================+--+--+--+--+
 
-            +------+=============+=============================+
-            | Misc | External ID | External Size of Properties |
-            +------+=============+=============================+
 
-                 +===================+
-            ---> | Filter Properties |
-                 +===================+
+3.1.1. Block Header Size
 
-        The list of officially defined Filter IDs and the formats of
-        their Filter Properties are described in Section 4.3.
+        This field overlaps with the Index Indicator field (see
+        Section 4.1).
 
+        This field contains the size of the Block Header field,
+        including the Block Header Size field itself. Valid values are
+        in the range [0x01, 0xFF], which indicate the size of the Block
+        Header as multiples of four bytes, minimum size being eight
+        bytes:
 
-3.1.4.1. Misc
+            real_header_size = (encoded_header_size + 1) * 4;
 
-        To save space, the most commonly used Filter IDs and the
-        Size of Filter Properties are encoded in a single byte.
-        Depending on the contents of the Misc field, Filter ID is
-        the value of the Misc or External ID field.
+        If bigger Block Header is needed in future, a new field can be
+        added between the current Block Header and Compressed Data
+        fields. The presence of this new field would be indicated in
+        the Block Header.
 
-            Value          Filter ID        Size of Filter Properties
-            0x00 - 0x1F    Misc             0 bytes
-            0x20 - 0x3F    Misc             1 byte
-            0x40 - 0x5F    Misc             2 bytes
-            0x60 - 0x7F    Misc             3 bytes
-            0x80 - 0x9F    Misc             4 bytes
-            0xA0 - 0xBF    Misc             5 bytes
-            0xC0 - 0xDF    Misc             6 bytes
-            0xE0 - 0xFE    External ID      0-30 bytes
-            0xFF           External ID      External Size of Properties
 
-        The following code demonstrates parsing the Misc field and,
-        when needed, the External ID and External Size of Properties
-        fields.
+3.1.2. Block Flags
 
-            uint64_t id;
-            uint64_t properties_size;
-            uint8_t misc = read_byte();
+        The first byte of the Block Flags field is a bit field:
 
-            if (misc >= 0xE0) {
-                id = read_variable_length_integer();
+            Bit(s)  Mask  Description
+             0-1    0x03  Number of filters (1-4)
+             2-5    0x3C  Reserved for future use; must be zero for now.
+              6     0x40  The Compressed Size field is present.
+              7     0x80  The Uncompressed Size field is present.
 
-                if (misc == 0xFF)
-                    properties_size = read_variable_length_integer();
-                else
-                    properties_size = misc - 0xE0;
+        If any reserved bit is set, the decoder must indicate an error.
+        It is possible that there is a new field present which the
+        decoder is not aware of, and can thus parse the Block Header
+        incorrectly.
 
-            } else {
-                id = misc;
-                properties_size = misc / 0x20;
-            }
 
+3.1.3. Compressed Size
 
-3.1.4.2. External ID
+        This field is present only if the appropriate bit is set in
+        the Block Flags field (see Section 3.1.2).
 
-        This field is present only if the Misc field contains a value
-        that indicates usage of External ID. The External ID is stored
-        using the encoding described in Section 1.2.
+        This field contains the size of the Compressed Data field as
+        multiple of four bytes, minimum value being four bytes:
 
+            real_compressed_size = (stored_compressed_size + 1) * 4;
 
-3.1.4.3. External Size of Properties
+        The size is stored using the encoding described in Section 1.2.
+        If the Compressed Size does not match the real size of the
+        Compressed Data field, the decoder must indicate an error.
 
-        This field is present only if the Misc field contains a value
-        that indicates usage of External Size of Properties. The size
-        of Filter Properties is stored using the encoding described in
-        Section 1.2.
 
+3.1.4. Uncompressed Size
 
-3.1.4.4. Filter Properties
+        This field is present only if the appropriate bit is set in
+        the Block Flags field (see Section 3.1.2).
 
-        Size of this field depends on the Misc field (Section 3.1.4.1)
-        and, if present, External Size of Properties field (Section
-        3.1.4.3). The format of this field is depends on the selected
-        filter; see Section 4.3 for details.
+        The Uncompressed Size field contains the size of the Block
+        after uncompressing. Uncompressed Size is stored using the
+        encoding described in Section 1.2. If the Uncompressed Size
+        does not match the real uncompressed size, the decoder must
+        indicate an error.
 
+        Storing the Compressed Size and Uncompressed Size fields serves
+        several purposes:
+          - The decoder knows how much memory it needs to allocate
+            for a temporary buffer in multithreaded mode.
+          - Simple error detection: wrong size indicates a broken file.
+          - Seeking forwards to a specific location in streamed mode.
 
-3.1.5. CRC32
+        It should be noted that the only reliable way to determine
+        the real uncompressed size is to uncompress the Block,
+        because the Block Header and Index fields may contain
+        (intentionally or unintentionally) invalid information.
 
-        This field is present only if the appropriate bit is set in
-        the Stream Flags field (see Section 2.2.2).
 
-        The CRC32 is calculated over everything in the Block Header
-        field except the Header Padding field and the CRC32 field
-        itself. It is stored as an unsigned 32-bit little endian
-        integer. If the calculated value does not match the stored
-        one, the decoder must indicate an error.
+3.1.5. List of Filter Flags
+
+        +================+================+     +================+
+        | Filter 0 Flags | Filter 1 Flags | ... | Filter n Flags |
+        +================+================+     +================+
+
+        The number of Filter Flags fields is stored in the Block Flags
+        field (see Section 3.1.2).
+
+        The format of each Filter Flags field is as follows:
+
+            +===========+====================+===================+
+            | Filter ID | Size of Properties | Filter Properties |
+            +===========+====================+===================+
+
+        Both Filter ID and Size of Properties are stored using the
+        encoding described in Section 1.2. Size of Properties indicates
+        the size of the Filter Properties field as bytes. The list of
+        officially defined Filter IDs and the formats of their Filter
+        Properties are described in Section 5.3.
 
 
 3.1.6. Header Padding
 
-        This field contains as many nul bytes as indicated by the value
-        stored in the Header Flags field. If the Header Padding field
-        contains any non-nul bytes, the decoder must indicate an error.
+        This field contains as many nul byte as it is needed to make
+        the Block Header have the size specified in Block Header Size.
+        If any of the bytes are not nul bytes, the decoder must
+        indicate an error. It is possible that there is a new field
+        present which the decoder is not aware of, and can thus parse
+        the Block Header incorrectly.
 
-        The intent of the Header Padding field is to allow alignment
-        of Compressed Data. The usefulness of alignment is described
-        in Section 4.3.
 
+3.1.7. CRC32
 
-3.2. Compressed Data
+        The CRC32 is calculated over everything in the Block Header
+        field except the CRC32 field itself. It is stored as an
+        unsigned 32-bit little endian integer. If the calculated
+        value does not match the stored one, the decoder must indicate
+        an error.
 
-        The format of Compressed Data depends on Block Flags and List
-        of Filter Flags. Excluding the descriptions of the simplest
-        filters in Section 4, the format of the filter-specific encoded
-        data is out of scope of this document.
+        By verifying the CRC32 of the Block Header before parsing the
+        actual contents allows the decoder to distinguish between
+        corrupt and unsupported files.
 
-        Note a special case: if End of Payload Marker (see Section
-        3.1.1) is not used and Uncompressed Size is zero, the size
-        of the Compressed Data field is always zero.
 
+3.2. Compressed Data
 
-3.3. Block Footer
+        The format of Compressed Data depends on Block Flags and List
+        of Filter Flags. Excluding the descriptions of the simplest
+        filters in Section 5.3, the format of the filter-specific
+        encoded data is out of scope of this document.
 
-        +=======+===============+================+
-        | Check | Stream Footer | Footer Padding |
-        +=======+===============+================+
+        If the natural size of Compressed Data is not a multiple of
+        four bytes, it must be padded with 1-3 nul bytes to make it
+        a multiple of four bytes.
 
 
-3.3.1. Check
+3.3. Check
 
         The type and size of the Check field depends on which bits
-        are set in the Stream Flags field (see Section 2.2.2).
+        are set in the Stream Flags field (see Section 2.1.1.2).
 
         The Check, when used, is calculated from the original
         uncompressed data. If the calculated Check does not match the
@@ -633,101 +578,106 @@ The .lzma File Format
         a warning or error.
 
 
-3.3.2. Stream Footer
+4. Index
 
-        +===================+===============+--------------+
-        | Uncompressed Size | Backward Size | Stream Flags |
-        +===================+===============+--------------+
+        +-----------------+=========================+
+        | Index Indicator | Number of Index Records |
+        +-----------------+=========================+
 
-             +----------+---------+
-        ---> | Footer Magic Bytes |
-             +----------+---------+
+             +=================+=========+-+-+-+-+
+        ---> | List of Records | Padding | CRC32 |
+             +=================+=========+-+-+-+-+
 
-        Stream Footer is present only in
-          - Data Block of a Single-Block Stream; and
-          - Footer Metadata Block of a Multi-Block Stream.
+        Index serves several purporses. Using it, one can
+          - verify that all Blocks in a Stream have been processed;
+          - find out the uncompressed size of a Stream; and
+          - quickly access the beginning of any Block (random access).
 
-        The Stream Footer field is placed inside Block Footer, because
-        no padding is allowed between Check and Stream Footer.
 
+4.1. Index Indicator
 
-3.3.2.1. Uncompressed Size
+        This field overlaps with the Block Header Size field (see
+        Section 3.1.1). The value of Index Indicator is always 0x00.
 
-        This field is present only in the Data Block of a Single-Block
-        Stream if Uncompressed Size is not stored to the Block Header
-        (see Section 3.1.1). Without the Uncompressed Size field in
-        Stream Footer it would not be possible to quickly find out
-        the Uncompressed Size of the Stream in all cases.
 
-        Uncompressed Size is stored using the encoding described in
-        Section 1.2. If the stored value does not match the real
-        uncompressed size of the Single-Block Stream, the decoder must
-        indicate an error.
+4.2. Number of Records
 
+        This field indicates how many Records there are in the List
+        of Records field, and thus how many Blocks there are in the
+        Stream. The value is stored using the encoding described in
+        Section 1.2. If the decoder has decoded all the Blocks of the
+        Stream, and then notices that the Number of Records doesn't
+        match the real number of Blocks, the decoder must indicate an
+        error.
 
-3.3.2.2. Backward Size
 
-        This field contains the total size of the Block Header,
-        Compressed Data, Check, and Uncompressed Size fields. The
-        value is stored using the encoding described in Section 1.2.
-        If the Backward Size does not match the real total size of
-        the appropriate fields, the decoder must indicate an error.
+4.3. List of Records
 
-        Implementations reading the Stream backwards should notice
-        that the value in this field can never be zero.
+        List of Records consists of as many Records as indicated by the
+        Number of Records field:
 
+            +========+========+
+            | Record | Record | ...
+            +========+========+
 
-3.3.2.3. Stream Flags
+        Each Record contains two fields:
 
-        This is a copy of the Stream Flags field from the Stream
-        Header. The information stored to Stream Flags is needed
-        when parsing the Stream backwards.
+            +============+===================+
+            | Total Size | Uncompressed Size |
+            +============+===================+
 
+        If the decoder has decoded all the Blocks of the Stream, it
+        must verify that the contents of the Records match the real
+        Total Size and Uncompressed Size of the respective Blocks.
 
-3.3.2.4. Footer Magic Bytes
+        Implementation hint: It is possible to verify the Index with
+        constant memory usage by calculating for example SHA256 of both
+        the real size values and the List of Records, then comparing
+        the check values. Implementing this using non-cryptographic
+        check like CRC32 should be avoided unless small code size is
+        important.
 
-        As the last step of the decoding process, the decoder must
-        verify the existence of Footer Magic Bytes. If they are not
-        found, an error must be indicated.
+        If the decoder supports random-access reading, it must verify
+        that Total Size and Uncompressed Size of every completely
+        decoded Block match the sizes stored in the Index. If only
+        partial Block is decoded, the decoder must verify that the
+        processed sizes don't exceed the sizes stored in the Index.
 
-            Using a C array and ASCII:
-            const uint8_t FOOTER_MAGIC[2] = { 'Y', 'Z' };
 
-            In hexadecimal:
-            59 5A
+4.3.1. Total Size
 
-        The primary reason to have Footer Magic Bytes is to make
-        it easier to detect incomplete files quickly, without
-        uncompressing. If the file does not end with Footer Magic Bytes
-        (excluding Footer Padding described in Section 3.3.3), it
-        cannot be undamaged, unless someone has intentionally appended
-        garbage after the end of the Stream. (Appending garbage at the
-        end of the file does not prevent uncompressing the file, but
-        may give a warning or error depending on the decoder
-        implementation.)
+        This field indicates the encoded size of the respective Block
+        as multiples of four bytes, minimum value being four bytes:
 
+            real_total_size = (stored_total_size + 1) * 4;
 
-3.3.3. Footer Padding
+        The value is stored using the encoding described in Section
+        1.2.
 
-        In certain situations it is convenient to be able to pad
-        Blocks or Streams to be multiples of, for example, 512 bytes.
-        Footer Padding makes this possible. Note that this is in no
-        way required to enforce alignment in the way described in
-        Section 4.3; the Header Padding field is enough for that.
 
-        When Footer Padding is used, it must contain only nul bytes.
-        Any non-nul byte should be considered as the beginning of
-        a new Block or Stream.
+4.3.2. Uncompressed Size
 
-        The possibility of Padding should be taken into account when
-        designing an application that wants to find out information
-        about a Stream by parsing Footer Metadata Block.
+        This field indicates the Uncompressed Size of the respective
+        Block as bytes. The value is stored using the encoding
+        described in Section 1.2.
 
-        Support for Padding was inspired by a related note in
-        [GNU-tar].
 
+4.4. Index Padding
 
-4. Filters
+        This field must contain 0-3 nul bytes to pad the Index to
+        a multiple of four bytes.
+
+
+4.5. CRC32
+
+        The CRC32 is calculated over everything in the Index field
+        except the CRC32 field itself. The CRC32 is stored as an
+        unsigned 32-bit little endian integer. If the calculated
+        value does not match the stored one, the decoder must indicate
+        an error.
+
+
+5. Filter Chains
 
         The Block Flags field defines how many filters are used. When
         more than one filter is used, the filters are chained; that is,
@@ -737,116 +687,11 @@ The .lzma File Format
                     v   Uncompressed Data   ^
                     |       Filter 0        |
             Encoder |       Filter 1        | Decoder
-                    |         ...           |
                     |       Filter n        |
                     v    Compressed Data    ^
 
-        The filters are independent from each other, except that they
-        must cooperate a little to make it possible, in all cases, to
-        detect when all of the data has been decoded. In addition, the
-        filters should cooperate in the encoder to keep the alignment
-        optimal.
-
-
-4.1. Detecting when All Data Has Been Decoded
-
-        There must be a way for the decoder to detect when all of the
-        Compressed Data has been decoded. This is simple when only
-        one filter is used, but a bit more complex when multiple
-        filters are chained.
 
-        This file format supports three methods to detect when all of
-        the data has been decoded:
-          - Uncompressed size
-          - End of Input
-          - End of Payload Marker
-
-        In both encoder and decoder, filters are initialized starting
-        from the first filter in the chain. For each filter, one of
-        these three methods is used.
-
-
-4.1.1. With Uncompressed Size
-
-        This method is the only method supported by all filters.
-        It must be used when uncompressed size is known by the
-        filter-specific encoder or decoder. In practice this means
-        that Uncompressed Size has been stored to the Block Header.
-
-        In case of the first filter in the chain, the uncompressed size
-        given to the filter-specific encoder or decoder equals the
-        Uncompressed Size stored in the Block Header. For the rest of
-        the filters in the chain, uncompressed size is the size of the
-        output data of the previous filter in the chain.
-
-        Note that when Use End of Payload Marker bit is set in Block
-        Flags, Uncompressed Size is considered to be unknown even if
-        it was present in the Block Header. Thus, if End of Payload
-        Marker is used, uncompressed size of all of the filters in
-        the chain is unknown, and can never be used to detect when
-        all of the data has been decoded.
-
-        Once the correct number of bytes has been written out, the
-        filter-specific decoder indicates to its caller that all of
-        the data has been decoded. If the filter-specific decoder
-        detects End of Input or End of Payload Marker before the
-        correct number of bytes is decoded, the decoder must indicate
-        an error.
-
-
-4.1.2. With End of Input
-
-        Most filters will know that all of the data has been decoded
-        when the End of Input data has been reached. Once the filter
-        knows that it has received the input data in its entirety,
-        it finishes its job, and indicates to its caller that all of
-        the data has been decoded. The filter-specific decoder must
-        indicate an error if it detects End of Payload Marker.
-
-        Note that this method can work only when the filter is not
-        the last filter in the chain, because only another filter
-        can indicate the End of Input data. In practice this means,
-        that a filter later in the chain must support embedding
-        End of Payload Marker.
-
-        When a filter that cannot embed End of Payload Marker is the
-        last filter in the chain, Subblock filter is appended to the
-        chain as an implicit filter. In the simplest case, this occurs
-        when no filters are specified, and the End of Payload Marker
-        bit is set in Block Flags.
-
-
-4.1.3. With End of Payload Marker
-
-        End of Payload Marker is a filter-specific bit sequence that
-        indicates the end of data. It is supported by only a few
-        filters. It is used when uncompressed size is unknown, and
-        the filter
-          - doesn't support End of Input; or
-          - is the last filter in the chain.
-
-        End of Payload Marker is embedded at the end of the encoded
-        data by the filter-specific encoder. When the filter-specific
-        decoder detects the embedded End of Payload Marker, the decoder
-        knows that all of the data has been decoded. Then it finishes
-        its job, and indicates to its caller that all of the data has
-        been decoded. If the filter-specific decoder detects End of
-        Input before End of Payload Marker, the decoder must indicate
-        an error.
-
-        If the filter supports both End of Input and End of Payload
-        Marker, the former is used, unless the filter is the last
-        filter in the chain.
-
-
-4.2. Alignment
-
-        Some filters give better compression ratio or are faster
-        when the input or output data is aligned. For optimal results,
-        the encoder should try to enforce proper alignment when
-        possible. Not enforcing alignment in the encoder is not
-        an error. Thus, the decoder must be able to handle files with
-        suboptimal alignment.
+5.1. Alignment
 
         Alignment of uncompressed input data is usually the job of
         the application producing the data. For example, to get the
@@ -866,8 +711,9 @@ The .lzma File Format
         four-byte-aligned input data.
 
         The output of the last filter in the chain is stored to the
-        Compressed Data field. Aligning Compressed Data appropriately
-        can increase
+        Compressed Data field, which is is guaranteed to be aligned
+        to a multiple of four bytes relative to the beginning of the
+        Stream. This can increase
           - speed, if the filtered data is handled multiple bytes at
             a time by the filter-specific encoder and decoder,
             because accessing aligned data in computer memory is
@@ -875,308 +721,67 @@ The .lzma File Format
           - compression ratio, if the output data is later compressed
             with an external compression tool.
 
-        Compressed Data in a Stream can be aligned by using the Header
-        Padding field in the Block Header.
-
-
-4.3. Filters
-
-4.3.1. Copy
-
-        This is a dummy filter that simply copies all data from input
-        to output unmodified.
-
-            Filter ID:                  0x00
-            Size of Filter Properties:  0 bytes
-            Changes size of data:       No
-
-            Detecting when all of the data has been decoded:
-                Uncompressed size:      Yes
-                End of Payload Marker:  No
-                End of Input:           Yes
-
-            Preferred alignment:
-                Input data:             1 byte
-                Output data:            1 byte
-
-
-4.3.2. Subblock
-
-        The Subblock filter can be used to
-          - embed End of Payload Marker when the otherwise last
-            filter in the chain does not support embedding it; and
-          - apply additional filters in the middle of a Block.
 
-            Filter ID:                  0x01
-            Size of Filter Properties:  0 bytes
-            Changes size of data:       Yes, unpredictably
+5.2. Security
 
-            Detecting when all of the data has been decoded:
-                Uncompressed size:      Yes
-                End of Payload Marker:  Yes
-                End of Input:           Yes
+        If filters would be allowed to be chained freely, it would be
+        possible to create malicious files, that would be very slow to
+        decode. Such files could be used to create denial of service
+        attacks.
 
-            Preferred alignment:
-                Input data:             1 byte
-                Output data:            Freely adjustable
+        Slow files could occur when multiple filters are chained:
 
+            v   Compressed input data
+            |   Filter 1 decoder (last filter)
+            |   Filter 0 decoder (non-last filter)
+            v   Uncompressed output data
 
-4.3.2.1. Format of the Encoded Output
+        The decoder of the last filter in the chain produces a lot of
+        output from little input. Another filter in the chain takes the
+        output of the last filter, and produces very little output
+        while consuming a lot of input. As a result, a lot of data is
+        moved inside the filter chain, but the filter chain as a whole
+        gets very little work done.
 
-        The encoded data from the Subblock filter consist of zero or
-        more Subblocks:
+        To prevent this kind of slow files, there are restrictions on
+        how the filters can be chained. These restrictions must be
+        taken into account when designing new filters.
 
-            +==========+==========+
-            | Subblock | Subblock | ...
-            +==========+==========+
+        The maximum number of filters in the chain has been limited to
+        four, thus there can be at maximum of three non-last filters.
+        Of these three non-last filters, only two are allowed to change
+        the size of the data.
 
-        Each Subblock contains two fields:
+        The non-last filters, that change the size of the data, must
+        have a limit how much the decoder can compress the data: the
+        decoder should produce at least n bytes of output when the
+        filter is given 2n bytes of input. This  limit is not
+        absolute, but significant deviations must be avoided.
 
-            +----------------+===============+
-            | Subblock Flags | Subblock Data |
-            +----------------+===============+
+        The above limitations guarantee that if the last filter in the
+        chain produces 4n bytes of output, the chain as a whole will
+        produce at least n bytes of output.
 
-        Subblock Flags is a bitfield:
 
-            Bits   Mask   Description
-            0-3    0x0F   The interpretation of these bits depend on
-                          the Subblock Type:
-                            - 0x20    Bits 0-3 for Size
-                            - 0x30    Bits 0-3 for Repeat Count
-                            - Other   These bits must be zero.
-            4-7    0xF0   Subblock Type:
-                            - 0x00: Padding
-                            - 0x10: End of Payload Marker
-                            - 0x20: Data
-                            - 0x30: Repeating Data
-                            - 0x40: Set Subfilter
-                            - 0x50: Unset Subfilter
-                          If some other value is detected, the decoder
-                          must indicate an error.
-
-        The format of the Subblock Data field depends on Subblock Type.
-
-        Subblocks with the Subblock Type 0x00 (Padding) don't have a
-        Subblock Data field. These Subblocks can be useful for fixing
-        alignment. There can be at maximum of 31 consecutive Subblocks
-        with this Subblock Type; if there are more, the decoder must
-        indicate an error.
+5.3. Filters
 
-        Subblock with the Subblock Type 0x10 (End of Payload Marker)
-        doesn't have a Subblock Data field. The decoder must indicate
-        an error if this Subblock Type is detected when Subfilter is
-        enabled, or when the Subblock filter is not supposed to embed
-        the End of Payload Marker.
-
-        Subblocks with the Subblock Type 0x20 (Data) contain the rest
-        of the Size, which is followed by Size + 1 bytes in the Data
-        field (that is, Data can never be empty):
-
-            +------+------+------+======+
-            | Bits 4-27 for Size | Data |
-            +------+------+------+======+
-
-        Subblocks with the Subblock Type 0x30 (Repeating Data) contain
-        the rest of the Repeat Count, the Size of the Data, and finally
-        the actual Data to be repeated:
-
-            +---------+---------+--------+------+======+
-            | Bits 4-27 for Repeat Count | Size | Data |
-            +---------+---------+--------+------+======+
-
-        The size of the Data field is Size + 1. It is repeated Repeat
-        Count + 1 times. That is, the minimum size of Data is one byte;
-        the maximum size of Data is 256 bytes. The minimum number of
-        repeats is one; the maximum number of repeats is 2^28.
-
-        If Subfilter is not used, the Data field of Subblock Types 0x20
-        and 0x30 is the output of the decoded Subblock filter. If
-        Subfilter is used, Data is the input of the Subfilter, and the
-        decoded output of the Subfilter is the decoded output of the
-        Subblock filter.
-
-        Subblocks with the Subblock Type 0x40 (Set Subfilter) contain
-        a Filter Flags field in Subblock Data:
-
-            +==============+
-            | Filter Flags |
-            +==============+
-
-        It is an error to set the Subfilter to Filter ID 0x00 (Copy)
-        or 0x01 (Subblock). All the other Filter IDs are allowed.
-        The decoder must indicate an error if this Subblock Type is
-        detected when a Subfilter is already enabled.
-
-        Subblocks with the Subblock Type 0x50 (Unset Subfilter) don't
-        have a Subblock Data field. There must be at least one Subblock
-        with Subblock Type 0x20 or 0x30 between Subblocks with Subblock
-        Type 0x40 and 0x50; if there isn't, the decoder must indicate
-        an error.
-
-        Subblock Types 0x40 and 0x50 are always used as a pair: If the
-        Subblock filter has been enabled with Subblock Type 0x40, it
-        must always be disabled later with Subblock Type 0x50.
-        Disabling must be done even if the Subfilter used End of
-        Payload Marker; after the Subfilter has detected End of Payload
-        Marker, the next Subblock that is not Padding must unset the
-        Subfilter.
-
-        When the Subblock filter is used as an implicit filter to embed
-        End of Payload marker, the Subblock Types 0x40 and 0x50 (Set or
-        Unset Subfilter) must not be used. The decoder must indicate an
-        error if it detects any of these Subblock Types in an implicit
-        Subblock filter.
-
-        The following code illustrates the basic structure of a
-        Subblock decoder.
-
-            uint32_t consecutive_padding = 0;
-            bool got_output_with_subfilter = false;
-
-            while (true) {
-                uint32_t size;
-                uint32_t repeat;
-                uint8_t flags = read_byte();
-
-                if (flags != 0)
-                    consecutive_padding = 0;
-
-                switch (flags >> 4) {
-                    case 0:
-                        // Padding
-                        if (flags & 0x0F)
-                            return DATA_ERROR;
-                        if (++consecutive_padding == 32)
-                            return DATA_ERROR;
-                        break;
-
-                    case 1:
-                        // End of Payload Marker
-                        if (flags & 0x0F)
-                            return DATA_ERROR;
-                        if (subfilter_enabled || !allow_eopm)
-                            return DATA_ERROR;
-                        break;
-
-                    case 2:
-                        // Data
-                        size = flags & 0x0F;
-                        for (size_t i = 4; i < 28; i += 8)
-                            size |= (uint32_t)(read_byte()) << i;
-
-                        // If any output is produced, this will
-                        // set got_output_with_subfilter to true.
-                        copy_data(size);
-                        break;
-
-                    case 3:
-                        // Repeating Data
-                        repeat = flags & 0x0F;
-                        for (size_t i = 4; i < 28; i += 8)
-                            repeat |= (uint32_t)(read_byte()) << i;
-                        size = read_byte();
-
-                        // If any output is produced, this will
-                        // set got_output_with_subfilter to true.
-                        copy_repeating_data(size, repeat);
-                        break;
-
-                    case 4:
-                        // Set Subfilter
-                        if (flags & 0x0F)
-                            return DATA_ERROR;
-                        if (subfilter_enabled)
-                            return DATA_ERROR;
-                        got_output_with_subfilter = false;
-                        set_subfilter();
-                        break;
-
-                    case 5:
-                        // Unset Subfilter
-                        if (flags & 0x0F)
-                            return DATA_ERROR;
-                        if (!subfilter_enabled)
-                            return DATA_ERROR;
-                        if (!got_output_with_subfilter)
-                            return DATA_ERROR;
-                        unset_subfilter();
-                        break;
-
-                    default:
-                        return DATA_ERROR;
-                }
-            }
-
-
-4.3.3. Delta
-
-        The Delta filter may increase compression ratio when the value
-        of the next byte correlates with the value of an earlier byte
-        at specified distance.
-
-            Filter ID:                  0x20
-            Size of Filter Properties:  1 byte
-            Changes size of data:       No
-
-            Detecting when all of the data has been decoded:
-                Uncompressed size:      Yes
-                End of Payload Marker:  No
-                End of Input:           Yes
-
-            Preferred alignment:
-                Input data:             1 byte
-                Output data:            Same as the original input data
-
-        The Properties byte indicates the delta distance, which can be
-        1-256 bytes backwards from the current byte: 0x00 indicates
-        distance of 1 byte and 0xFF distance of 256 bytes.
-
-
-4.3.3.1. Format of the Encoded Output
-
-        The code below illustrates both encoding and decoding with
-        the Delta filter.
-
-            // Distance is in the range [1, 256].
-            const unsigned int distance = get_properties_byte() + 1;
-            uint8_t pos = 0;
-            uint8_t delta[256];
-
-            memset(delta, 0, sizeof(delta));
-
-            while (1) {
-                const int byte = read_byte();
-                if (byte == EOF)
-                    break;
-
-                uint8_t tmp = delta[(uint8_t)(distance + pos)];
-                if (is_encoder) {
-                    tmp = (uint8_t)(byte) - tmp;
-                    delta[pos] = (uint8_t)(byte);
-                } else {
-                    tmp = (uint8_t)(byte) + tmp;
-                    delta[pos] = tmp;
-                }
-
-                write_byte(tmp);
-                --pos;
-            }
-
-
-4.3.4. LZMA
+5.3.1. LZMA2
 
         LZMA (Lempel-Ziv-Markov chain-Algorithm) is a general-purporse
         compression algorithm with high compression ratio and fast
-        decompression. LZMA based on LZ77 and range coding algorithms.
+        decompression. LZMA is based on LZ77 and range coding
+        algorithms.
 
-            Filter ID:                  0x40
-            Size of Filter Properties:  2 bytes
-            Changes size of data:       Yes, unpredictably
+        LZMA2 uses LZMA internally, but adds support for uncompressed
+        chunks, eases stateful decoder implementations, and improves
+        support for multithreading. Thus, the plain LZMA will not be
+        supported in this file format.
 
-            Detecting when all of the data has been decoded:
-                Uncompressed size:      Yes
-                End of Payload Marker:  Yes
-                End of Input:           No
+            Filter ID:                  0x21
+            Size of Filter Properties:  1 byte
+            Changes size of data:       Yes
+            Allow as a non-last filter: No
+            Allow as the last filter:   Yes
 
             Preferred alignment:
                 Input data:             Adjustable to 1/2/4/8/16 byte(s)
@@ -1188,88 +793,45 @@ The .lzma File Format
         a separate document, because including the documentation here
         would lengthen this document considerably.
 
-        The format of the Filter Properties field is as follows:
-
-            +-----------------+------------------+
-            | LZMA Properties | Dictionary Flags |
-            +-----------------+------------------+
-
-
-4.3.4.1. LZMA Properties
-
-        The LZMA Properties field contains three properties. An
-        abbreviation is given in parentheses, followed by the value
-        range of the property. The field consists of
-
-            1) the number of literal context bits (lc, [0, 8]);
-            2) the number of literal position bits (lp, [0, 4]); and
-            3) the number of position bits (pb, [0, 4]).
-
-        They are encoded using the following formula:
-
-            LZMA Properties = (pb * 5 + lp) * 9 + lc
-
-        The following C code illustrates a straightforward way to
-        decode the properties:
-
-            uint8_t lc, lp, pb;
-            uint8_t prop = get_lzma_properties() & 0xFF;
-            if (prop > (4 * 5 + 4) * 9 + 8)
-                return LZMA_PROPERTIES_ERROR;
-
-            pb = prop / (9 * 5);
-            prop -= pb * 9 * 5;
-            lp = prop / 9;
-            lc = prop - lp * 9;
-
-
-4.3.4.2. Dictionary Flags
-
-        Currently the lowest six bits of the Dictionary Flags field
-        are in use:
+        The format of the one-byte Filter Properties field is as
+        follows:
 
             Bits   Mask   Description
             0-5    0x3F   Dictionary Size
             6-7    0xC0   Reserved for future use; must be zero for now.
 
         Dictionary Size is encoded with one-bit mantissa and five-bit
-        exponent. To avoid wasting space, one-byte dictionary has its
-        own special value.
+        exponent. The smallest dictionary size is 4 KiB and the biggest
+        is 4 GiB.
 
             Raw value   Mantissa   Exponent   Dictionary size
-                0           1          0      1 byte
-                1           2          0      2 bytes
-                2           3          0      3 bytes
-                3           2          1      4 bytes
-                4           3          1      6 bytes
-                5           2          2      8 bytes
-                6           3          2      12 bytes
-                7           2          3      16 bytes
-                8           3          3      24 bytes
-                9           2          4      32 bytes
+                0           2         11         4 KiB
+                1           3         11         6 KiB
+                2           2         12         8 KiB
+                3           3         12        12 KiB
+                4           2         13        16 KiB
+                5           3         13        24 KiB
+                6           2         14        32 KiB
               ...         ...        ...      ...
-               61           2         30      2 GiB
-               62           3         30      3 GiB
-               63           2         31      4 GiB (*)
-
-            (*) The real maximum size of the dictionary is one byte
-                less than 4 GiB, because the distance of 4 GiB is
-                reserved for End of Payload Marker.
+               35           3         27       768 MiB
+               36           2         28      1024 MiB
+               37           3         29      1536 MiB
+               38           2         30      2048 MiB
+               39           3         30      3072 MiB
+               40           2         31      4096 MiB
 
         Instead of having a table in the decoder, the dictionary size
         can be decoded using the following C code:
 
-            uint64_t dictionary_size;
             const uint8_t bits = get_dictionary_flags() & 0x3F;
-            if (bits == 0) {
-                dictionary_size = 1;
-            } else {
-                dictionary_size = 2 | ((bits + 1) & 1);
-                dictionary_size = dictionary_size << ((bits - 1)  / 2);
-            }
+            if (bits > 40)
+                return DICTIONARY_TOO_BIG; // Bigger than 4 GiB
+
+            uint32_t dictionary_size = 2 | (bits & 1);
+            dictionary_size <<= bits / 2 + 11;
 
 
-4.3.5. Branch/Call/Jump Filters for Executables
+5.3.2. Branch/Call/Jump Filters for Executables
 
         These filters convert relative branch, call, and jump
         instructions to their absolute counterparts in executable
@@ -1278,6 +840,8 @@ The .lzma File Format
 
             Size of Filter Properties:  0 or 4 bytes
             Changes size of data:       No
+            Allow as a non-last filter: Yes
+            Allow as the last filter:   No
 
             Detecting when all of the data has been decoded:
                 Uncompressed size:      Yes
@@ -1307,378 +871,63 @@ The .lzma File Format
         the Subblock filter.
 
 
-5. Metadata
-
-        Metadata is stored in Metadata Blocks, which can be in the
-        beginning or at the end of a Multi-Block Stream. Because of
-        Blocks, it is possible to compress Metadata in the same way
-        as the actual data is compressed. This Section describes the
-        format of the data stored in Metadata Blocks.
-
-            +----------------+===============================+
-            | Metadata Flags | Size of Header Metadata Block |
-            +----------------+===============================+
-
-                 +============+===================+=======+=======+
-            ---> | Total Size | Uncompressed Size | Index | Extra |
-                 +============+===================+=======+=======+
-
-        Stream must be parseable backwards. That is, there must be
-        a way to locate the beginning of the Stream by starting from
-        the end of the Stream. Thus, the Footer Metadata Block must
-        contain the Total Size field or the Index field. If the Stream
-        has Header Metadata Block, also the Size of Header Metadata
-        Block field must be present in Footer Metadata Block.
-
-        It must be possible to quickly locate the Blocks in
-        non-streamed mode. Thus, the Index field must be present
-        at least in one Metadata Block.
-
-        If the above conditions are not met, the decoder must indicate
-        an error.
-
-        There should be no additional data after the last field. If
-        there is, the the decoder should indicate an error.
-
-
-5.1. Metadata Flags
-
-        This field describes which fields are present in a Metadata
-        Block:
-
-            Bit(s)  Mask   Desription
-              0     0x01   Size of Header Metadata Block is present.
-              1     0x02   Total Size is present.
-              2     0x04   Uncompressed Size is present.
-              3     0x08   Index is present.
-             4-6    0x70   Reserve for future use; must be zero for now.
-              7     0x80   Extra is present.
-
-        If any reserved bit is set, the decoder must indicate an error.
-        It is possible that there is a new field present which the
-        decoder is not aware of, and can thus parse the Metadata
-        incorrectly.
-
-
-5.2. Size of Header Metadata Block
-
-        This field is present only if the appropriate bit is set in
-        the Metadata Flags field (see Section 5.1).
-
-        Size of Header Metadata Block is needed to make it possible to
-        parse the Stream backwards. The size is stored using the
-        encoding described in Section 1.2. The decoder must verify that
-        that the value stored in this field is non-zero. In Footer
-        Metadata Block, the decoder must also verify that the stored
-        size matches the real size of Header Metadata Block. In the
-        Header Meatadata Block, the value of this field is ignored as
-        long as it is not zero.
-
-
-5.3. Total Size
-
-        This field is present only if the appropriate bit is set in the
-        Metadata Flags field (see Section 5.1).
-
-        This field contains the total size of the Data Blocks in the
-        Stream. Total Size is stored using the encoding described in
-        Section 1.2. If the stored value does not match the real total
-        size of the Data Blocks, the decoder must indicate an error.
-        The value of this field must be non-zero.
-
-        Total Size can be used to quickly locate the beginning or end
-        of the Stream. This can be useful for example when doing
-        random-access reading, and the Index field is not in the
-        Metadata Block currently being read.
-
-        It is useless to have both Total Size and Index in the same
-        Metadata Block, because Total Size can be calculated from the
-        Index field.
-
-
-5.4. Uncompressed Size
-
-        This field is present only if the appropriate bit is set in the
-        Metadata Flags field (see Section 5.1).
-
-        This field contains the total uncompressed size of the Data
-        Blocks in the Stream. Uncompresssed Size is stored using the
-        encoding described in Section 1.2. If the stored value does not
-        match the real uncompressed size of the Data Blocks, the
-        decoder must indicate an error.
-
-        It is useless to have both Uncompressed Size and Index in
-        the same Metadata Block, because Uncompressed Size can be
-        calculated from the Index field.
-
-
-5.5. Index
-
-        +=======================+=============+====================+
-        | Number of Data Blocks | Total Sizes | Uncompressed Sizes |
-        +=======================+=============+====================+
-
-        Index serves several purporses. Using it, one can
-          - verify that all Blocks in a Stream have been processed;
-          - find out the Uncompressed Size of a Stream; and
-          - quickly access the beginning of any Block (random access).
-
-
-5.5.1. Number of Data Blocks
-
-        This field contains the number of Data Blocks in the Stream.
-        The value is stored using the encoding described in Section
-        1.2. If the decoder has decoded all the Data Blocks of the
-        Stream, and then notices that the Number of Records doesn't
-        match the real number of Data Blocks, the decoder must
-        indicate an error. The value of this field must be non-zero.
-
-
-5.5.2. Total Sizes
-
-        +============+============+
-        | Total Size | Total Size | ...
-        +============+============+
-
-        This field lists the Total Sizes of every Data Block in the
-        Stream. There are as many Total Size fields as indicated by
-        the Number of Data Blocks field.
-
-        Total Size is the size of Block Header, Compressed Data, and
-        Block Footer. It is stored using the encoding described in
-        Section 1.2. If the Total Sizes do not match the real sizes
-        of respective Blocks, the decoder should indicate an error.
-        All the Total Size fields must have a non-zero value.
-
-
-5.5.3. Uncompressed Sizes
-
-        +===================+===================+
-        | Uncompressed Size | Uncompressed Size | ...
-        +===================+===================+
-
-        This field lists the Uncompressed Sizes of every Data Block
-        in the Stream. There are as many Uncompressed Size fields as
-        indicated by the Number of Records field.
-
-        Uncompressed Sizes are stored using the encoding described
-        in Section 1.2. If the Uncompressed Sizes do not match the
-        real sizes of respective Blocks, the decoder shoud indicate
-        an error.
-
-
-5.6. Extra
-
-        This field is present only if the appropriate bit is set in the
-        Metadata Flags field (see Section 5.1). Note that the bit does
-        not indicate that there is any data in the Extra field; it only
-        indicates that Extra may be non-empty.
-
-        The Extra field contains only information that is not required
-        to properly uncompress the Stream or to do random-access
-        reading. Supporting the Extra field is optional. In case the
-        decoder doesn't support the Extra field, it should silently
-        ignore it.
-
-        Extra consists of zero or more Records:
-
-            +========+========+
-            | Record | Record | ...
-            +========+========+
-
-        Excluding Records with Record ID 0x00, each Record contains
-        three fields:
-
-            +==========+==============+======+
-            | Reord ID | Size of Data | Data |
-            +==========+==============+======+
-
-        The Record ID and Size of Data are stored using the encoding
-        described in Section 1.2. Data can be binary or UTF-8
-        [RFC-3629] strings. Non-UTF-8 strings should be avoided.
-        Because the Size of Data is known, there is no need to
-        terminate strings with a nul byte, although doing so should
-        not be considered an error.
-
-        The Record IDs are divided in two categories:
-          - Safe-to-Copy Records may be preserved as is when the
-            Stream is modified in ways that don't change the actual
-            uncompressed data. Examples of such operatings include
-            recompressing and adding, modifying, or deleting unrelated
-            Extra Records.
-          - Unsafe-to-Copy Records should be removed (and possibly
-            recreated) when any kind of changes are made to the Stream.
-
-        When the actual uncompressed data is modified, all Records
-        should be removed (and possibly recreated), unless the
-        application knows that the Data stored to the Record(s) is
-        still valid.
-
-        The following subsections describe the standard Record IDs and
-        the format of their Data fields. Safe-to-Copy Records have an
-        odd ID, while Unsafe-to-Copy Records have an even ID.
-
-
-5.6.1. 0x00: Dummy/Padding
-
-        This Record is special, because it doesn't have the Size of
-        Data or Data fields.
-
-        Dummy Records can be used, for example, to fill Metadata Block
-        when a few bytes of extra space has been reserved for it. There
-        can be any number of Dummy Records.
-
-
-5.6.2. 0x01: OpenPGP Signature
-
-        OpenPGP signature is computed from uncompressed data. The
-        signature can be used to verify that the contents of a Stream
-        has been created by a trustworthy source.
-
-        If the decoder supports decoding concatenated Streams, it
-        must indicate an error when verifying OpenPGP signatures if
-        there is more than one Stream.
-
-        OpenPGP format is documented in [RFC-2440].
-
-
-5.6.3. 0x02: Filter Information
-
-        The Filter Information Record contains information about the
-        filters used in the Stream. This field can be used to quickly
-          - display which filters are used in each Block;
-          - check if all the required filters are supported by the
-            current decoder version; and
-          - check how much memory is required to decode each Block.
-
-        The format of the Filter Information field is as follows:
-
-            +=================+=================+
-            | Block 0 Filters | Block 1 Filters | ...
-            +=================+=================+
-
-        There can be at maximum of as many Block Filters fields as
-        there are Data Blocks in the Stream. The format of the Block
-        Filters field is as follows:
-
-            +------------------+======================+============+
-            | Block Properties | List of Filter Flags | Subfilters |
-            +------------------+======================+============+
-
-        Block Properties is a bitfield:
-
-            Bit(s)  Mask  Description
-             0-2    0x07  Number of filters (0-7)
-              3     0x08  End of Payload Marker is used.
-              4     0x10  The Subfilters field is present.
-             5-7    0xE0  Reserved for future use; must be zero for now.
-
-        The contents of the List of Filter Flags field must match the
-        List of Filter Flags field in the respective Block Header.
-
-        The Subfilters field may be present only if the List of Filter
-        Flags contains a Filter Flags field for a Subblock filter. The
-        format of the Subfilters field is as follows:
-
-            +======================+=========================+
-            | Number of Subfilters | List of Subfilter Flags |
-            +======================+=========================+
-
-        The value stored in the Number of Subfilters field is stored
-        using the encoding described in Section 1.2. The List of
-        Subfilter Flags field contains as many Filter Flags fields
-        as indicated by the Number of Subfilters field. These Filter
-        Flags fields list some or all the Subfilters used via the
-        Subblock filter. The order of the listed Subfilters is not
-        significant.
-
-        Decoders supporting this Record should indicate a warning or
-        error if this Record contains Filter Flags that are not
-        actually used by the respective Blocks.
-
-
-5.6.4. 0x03: Comment
-
-        Free-form comment is stored in UTF-8 [RFC-3629] encoding.
-
-        The beginning of a new line should be indicated using the
-        ASCII Line Feed character (0x0A). When the Line Feed character
-        is not the native way to indicate new line in the underlying
-        operating system, the encoder and decoder should convert the
-        newline characters to and from Line Feeds.
-
-
-5.6.5. 0x04: List of Checks
-
-        +=======+=======+
-        | Check | Check | ...
-        +=======+=======+
-
-        There are as many Check fields as there are Blocks in the
-        Stream. The size of Check fields depend on Stream Flags
-        (see Section 2.2.2).
-
-        Decoders supporting this Record should indicate a warning or
-        error if the Checks don't match the respective Blocks.
-
-
-5.6.6. 0x05: Original Filename
-
-        Original filename is stored in UTF-8 [RFC-3629] encoding.
-
-        The filename must not include any path, only the filename
-        itself. Special care must be taken to prevent directory
-        traversal vulnerabilities.
-
-        When files are moved between different operating systems, it
-        is possible that filename valid in the source system is not
-        valid in the target system. It is implementation defined how
-        the decoder handles this kind of situations.
-
-
-5.6.7. 0x07: Modification Time
-
-        Modification time is stored as POSIX time, as an unsigned
-        little endian integer. The number of bits depends on the
-        Size of Data field. Note that the usage of unsigned integer
-        limits the earliest representable time to 1970-01-01T00:00:00.
+5.3.3. Delta
 
+        The Delta filter may increase compression ratio when the value
+        of the next byte correlates with the value of an earlier byte
+        at specified distance.
 
-5.6.8. 0x09: High-Resolution Modification Time
+            Filter ID:                  0x03
+            Size of Filter Properties:  1 byte
+            Changes size of data:       No
+            Allow as a non-last filter: Yes
+            Allow as the last filter:   No
 
-        This Record extends the `0x04: Modification time' Record with
-        a subsecond time information. There are two supported formats
-        of this field, which can be distinguished by looking at the
-        Size of Data field.
+            Preferred alignment:
+                Input data:             1 byte
+                Output data:            Same as the original input data
 
-        Size  Data
-          3   [0; 9,999,999] times 100 nanoseconds
-          4   [0; 999,999,999] nanoseconds
+        The Properties byte indicates the delta distance, which can be
+        1-256 bytes backwards from the current byte: 0x00 indicates
+        distance of 1 byte and 0xFF distance of 256 bytes.
 
-        The value is stored as an unsigned 24-bit or 32-bit little
-        endian integer.
 
+5.3.3.1. Format of the Encoded Output
 
-5.6.9. 0x0B: MIME Type
+        The code below illustrates both encoding and decoding with
+        the Delta filter.
 
-        MIME type of the uncompressed Stream. This can be used to
-        detect the content type. [IANA-MIME]
+            // Distance is in the range [1, 256].
+            const unsigned int distance = get_properties_byte() + 1;
+            uint8_t pos = 0;
+            uint8_t delta[256];
 
+            memset(delta, 0, sizeof(delta));
 
-5.6.10. 0x0D: Homepage URL
+            while (1) {
+                const int byte = read_byte();
+                if (byte == EOF)
+                    break;
 
-        This field can be used, for example, when distributing software
-        packages (sources or binaries). The field would indicate the
-        homepage of the program.
+                uint8_t tmp = delta[(uint8_t)(distance + pos)];
+                if (is_encoder) {
+                    tmp = (uint8_t)(byte) - tmp;
+                    delta[pos] = (uint8_t)(byte);
+                } else {
+                    tmp = (uint8_t)(byte) + tmp;
+                    delta[pos] = tmp;
+                }
 
-        For details on how to encode URLs, see [RFC-1738].
+                write_byte(tmp);
+                --pos;
+            }
 
 
-6. Custom Filter and Extra Record IDs
+5.4. Custom Filter IDs
 
-        If a developer wants to use custom Filter or Extra Record IDs,
-        he has two choices. The first choice is to contact Lasse Collin
-        and ask him to allocate a range of IDs for the developer.
+        If a developer wants to use custom Filter IDs, he has two
+        choices. The first choice is to contact Lasse Collin and ask
+        him to allocate a range of IDs for the developer.
 
         The second choice is to generate a 40-bit random integer,
         which the developer can use as his personal Developer ID.
@@ -1690,10 +939,10 @@ The .lzma File Format
             dd if=/dev/urandom bs=5 count=1 | hexdump
 
         The developer can then use his Developer ID to create unique
-        (well, hopefully unique) Filter and Extra Record IDs.
+        (well, hopefully unique) Filter IDs.
 
             Bits    Mask                    Description
-             0-15   0x0000_0000_0000_FFFF   Filter or Extra Record ID
+             0-15   0x0000_0000_0000_FFFF   Filter ID
             16-55   0x00FF_FFFF_FFFF_0000   Developer ID
             56-62   0x7F00_0000_0000_0000   Static prefix: 0x7F
 
@@ -1702,21 +951,15 @@ The .lzma File Format
         a shorter ID, see the beginning of this Section how to
         request a custom ID range.
 
-        Note that Filter and Metadata Record IDs are in their own
-        namespaces. That is, you can use the same ID value as Filter ID
-        and Metadata Record ID, and the meanings of the IDs do not need
-        to be related to each other.
 
-
-6.1. Reserved Custom Filter ID Ranges
+5.4.1. Reserved Custom Filter ID Ranges
 
         Range                       Description
-        0x0000_0000 - 0x0000_00DF   IDs fitting into the Misc field
         0x0002_0000 - 0x0007_FFFF   Reserved to ease .7z compatibility
         0x0200_0000 - 0x07FF_FFFF   Reserved to ease .7z compatibility
 
 
-7. Cyclic Redundancy Checks
+6. Cyclic Redundancy Checks
 
         There are several incompatible variations to calculate CRC32
         and CRC64. For simplicity and clarity, complete examples are
@@ -1811,32 +1054,7 @@ The .lzma File Format
             }
 
 
-8. References
-
-8.1. Normative References
-
-        [RFC-1738]
-        Uniform Resource Locators (URL)
-        http://www.ietf.org/rfc/rfc1738.txt
-
-        [RFC-2119]
-        Key words for use in RFCs to Indicate Requirement Levels
-        http://www.ietf.org/rfc/rfc2119.txt
-
-        [RFC-2440]
-        OpenPGP Message Format
-        http://www.ietf.org/rfc/rfc2440.txt
-
-        [RFC-3629]
-        UTF-8, a transformation format of ISO 10646
-        http://www.ietf.org/rfc/rfc3629.txt
-
-        [IANA-MIME]
-        MIME Media Types
-        http://www.iana.org/assignments/media-types/
-
-
-8.2. Informative References
+7. References
 
         LZMA SDK - The original LZMA implementation
         http://7-zip.org/sdk.html
@@ -1849,6 +1067,10 @@ The .lzma File Format
         http://www.ietf.org/rfc/rfc1952.txt
           - Notation of byte boxes in section `2.1. Overall conventions'
 
+        [RFC-2119]
+        Key words for use in RFCs to Indicate Requirement Levels
+        http://www.ietf.org/rfc/rfc2119.txt
+
         [GNU-tar]
         GNU tar 1.16.1 manual
         http://www.gnu.org/software/tar/manual/html_node/Blocking-Factor.html