Everything after the 512-byte header is the picture: 720 rows, each compressed on its own with PackBits. The picture size never changes, so the file stores no width or height.
The picture
| Property | Value |
|---|---|
| Width | 576 pixels, 72 bytes per row |
| Height | 720 rows, top row first |
| Depth | 1 bit per pixel: 1 is black, 0 is white |
| Bit order | the most significant bit of each byte is the leftmost pixel |
| Resolution | 72 dots per inch: 8 × 10 inches, the printable area of an ImageWriter page |
| Unpacked size | 72 × 720 = 51,840 bytes |
Unpacked, the rows form a QuickDraw bitmap with rowBytes 72 and bounds
(0, 0) to (576, 720), which is how Apple’s sample code draws it.
PackBits
Each row of 72 bytes was passed to the Toolbox routine PackBits on its
own, and the 720 results are stored one after the other with nothing between them.
The packed data is a series of runs, each starting with a signed flag-counter byte:
| Flag-counter n | Bytes | Meaning |
|---|---|---|
| 0 to 127 | 00 to 7F | literal: the next n + 1 bytes (1 to 128) are copied as they are |
| −1 to −127 | FF to 81 | repeat: the next byte is repeated 1 − n times (2 to 128) |
| −128 | 80 | no operation: skip it and read the next byte as a flag-counter |
Apple’s PackBits never writes −128, but some programs’ own packers do,
and UnpackBits skips it, so a reader must too. PackBits only
makes a repeat run for three or more equal bytes; shorter runs go into literals.
Rows and file size
Every row must unpack to exactly 72 bytes. Apple’s sample reader unpacks one row at a time and stops if a row comes out at any other length; a run never continues into the next row.
In the worst case PackBits makes a row one byte longer than it started,
73 bytes. The largest possible file is therefore 512 + 51,840 + 720 = 53,072 bytes.
A typical picture is about 10 KB, because most of a page is white.
Because there is no index, the only way to find row k is to unpack the rows before it.
Examples
| Row | Packed bytes | How it unpacks |
|---|---|---|
| all white | B9 00 | B9 is −71: 00 72 times |
| all black | B9 FF | FF 72 times |
| left half black | DD FF DD 00 | DD is −35: FF 36 times, then 00 36 times |
| a short pattern, then white | 02 AA 55 AA BC 00 | 02: three literal bytes AA 55 AA; BC is −68: 00 69 times |
A blank page is the header followed by B9 00 720 times: 512 + 1,440 =
1,952 bytes.
Apple’s own example of PackBits output, from Technical Note TN1023:
FE AA ; −2: AA three times
02 80 00 2A ; 2: three literal bytes
FD AA ; −3: AA four times
03 80 00 2A 22 ; 3: four literal bytes
F7 AA ; −9: AA ten times
Here the 80 bytes are data inside literal runs, not flag-counters.