Each run in a block table says how its sectors are stored. A run decompresses by itself: nothing carries over from one run to the next, so a reader can decompress any run without the others. The output is always the run’s sector count × 512 bytes.
Raw, zero and ignore
| Type | Stored | Reads as |
|---|---|---|
0x00000001 raw | The sectors, one for one | The bytes stored |
0x00000000 zero | Nothing | Zeros, counted in the checksum |
0x00000002 ignore | Nothing | Zeros, not counted in the checksum; used for free space |
zlib (UDZO)
A run of type 0x80000005 is one zlib stream
(RFC 1950): a two-byte header,
Deflate data and an Adler-32 of the output.
A zlib run usually starts with 78 01, 78 5E,
78 9C or 78 DA.
bzip2 (UDBZ)
A run of type 0x80000006 is one bzip2 stream. It starts with
BZh, a digit giving the block size in hundreds of kilobytes, then the
block magic 31 41 59 26 53 59. Each block carries a CRC-32 of its own data
(with bzip2’s most-significant-bit-first polynomial), and the stream’s end carries a
combined CRC.
LZFSE (ULFO)
A run of type 0x80000007 is an LZFSE stream, Apple’s compressor, which
Apple published as open source. It is a series of blocks, each with a four-byte
magic:
| Magic | Block |
|---|---|
bvx- | Stored bytes |
bvxn | An LZVN stream, for small or awkward data |
bvx1 | LZFSE with its frequency tables written out plain |
bvx2 | LZFSE with compact frequency tables, the usual form |
bvx$ | End of the stream |
An LZFSE block holds literal bytes and match descriptions (literal length, match length, distance), each coded with Finite State Entropy and read backwards from the end of its payload. LZVN uses simple opcodes for the same three values and needs no tables.
LZMA (ULMO)
A run of type 0x80000008 is one
xz stream, starting with
FD 37 7A 58 5A 00. Inside it is LZMA2, which wraps LZMA in chunks that
can store incompressible data directly. In the images checked, the streams use no
integrity check.
Apple Data Compression (UDCO)
A run of type 0x80000004 uses ADC, a simple byte-oriented method.
It is a sequence of chunks, each starting with a control byte:
| Control byte | Chunk |
|---|---|
1LLLLLLL | A literal of L + 1 bytes, which follow |
01LLLLLL | A match of L + 4 bytes; a 16-bit big-endian distance follows |
00LLLLDD | A match of L + 3 bytes; the 10-bit distance is DD and the next byte |
A distance of 0 means the byte just written, so a match can repeat one byte across its whole length. ADC appears on old images; none of the images checked for this page used it.
Ratio and what a run holds
The block table gives each run’s stored length and its sector count, so the ratio of a run is its compressed length ÷ (sector count × 512). What a run holds is the sectors of the disk it covers, whatever lies there: part of an HFS+ catalogue, the middle of a file. The explorer’s Runs table lists each with its ratio, and maps it to the file system where it can, and each run opens to show its decompressed sectors.