Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- As of the beta of Battlefield 4, all individual files are compressed with an LZ77 algorithm.
- A compressed file consists of several blocks, with no global metadata.
- The blocks are set to have a size of 0x010000 when decompressed, except for the last one which is usually smaller.
- Structure of a compressed block (big endian):
- 4 bytes: decompressed size (0x10000 or less)
- 2 bytes: compression type (0970 for LZ77, 0070/0071 for uncompressed data, 0000 for empty payload)
- 2 bytes: compressed size (null for type 0071 and type 0000) of the payload (i.e. without the header)
- compressed payload
- Decompress each block and glue the decompressed parts together to obtain the file.
- The compression is an LZ77 variant. It requires 3 parameters:
- Copy offset: Move backwards by this amount of bytes and start copying a certain number of bytes following that position.
- Copy length: How many bytes to copy. If the length is larger than the offset, start at the offset again and copy the same values again.
- Proceed length: The number of bytes that were not compressed and can be read directly.
- Note that the offset is defined in regards to the already decompressed data which e.g. does not contain any compression metadata.
- The three values are split up however; while the copy length and proceed length are
- stated together in a single byte, before an uncompressed section, the relevant offset
- is given after the uncompressed section:
- Use the proceed length to read the uncompressed data, at which point you arrive at the start of the offset value.
- Read this value, then move to the offset and copy a number of bytes (given by copy length)
- to the decompressed data. Afterwards, the next copy and proceed length are given and the process starts anew.
- The offset has a constant size of 2 bytes, in little endian.
- The two lengths share the same byte. The first half of the byte belongs to the proceed length,
- whereas the second half belongs to the copy length.
- When the half-byte of the proceed length is f, then the length is extended by another byte,
- which is placed directly after the byte that contains both lengths. The value of that byte
- is added to the value of the proceed length (i.e. f). However, if the extra byte is ff, one more
- byte is read (and so on) and all values are added together.
- The copy length can be extended in the same manner. However, the possible extra bytes are
- located at the end, right after the offset.
- Additionally, a constant value of 4 is added to obtain the actual copy length.
- Finally, it is possible that a file ends without specifying an offset (as the last few bytes
- in the file were not compressed). The proceed length is not affected by that (and the copy
- length is of no relevance).
- As an example, consider the length byte B2:
- Proceed length: B
- Copy length: 2 + 4 = 6
- Another example, F23C:
- Proceed length: F + 3C = 4B
- Copy length: 2 + 4 = 6
- A full example (the whitespace is there to separate hex from ascii; it doesn't count):
- 0000001a 0970 0018 80 minimap. 0800 51 ature 0a00 40 mize
- Header:
- Decompressed size 1a
- LZ77 compression (due to 0970)
- Compressed size 18
- Payload:
- Compressed stream: 80 minimap. 0800 51 ature 0a00 40 mize
- Decompressed stream: *empty*
- The decompression is sequential, start with the left part:
- 80 minimap. 0800
- Read 8 uncompressed bytes into the decompressed stream.
- Decompressed stream: minimap.
- Move back by 8 bytes in the decompressed stream (to the start)
- and copy 4 bytes (mini) to the decompressed stream.
- Compressed stream: 51 ature 0a00 40 mize
- Decompressed stream: minimap.mini
- Perform the same step again:
- 51 ature 0a00
- Read 5 uncompressed bytes into the decompressed stream.
- Decompressed stream: minimap.miniature
- Move back by 0a bytes in the decompressed stream
- and copy 5 bytes (.mini) to the decompressed stream.
- Compressed stream: 40 mize
- Decompressed stream: minimap.miniature.mini
- Read 4 uncompressed bytes into the decompressed stream (with no offset specified).
- Decompressed stream: minimap.miniature.minimize
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement