A PBM file is built from IFF chunks, as Electronic Arts’ standard EA IFF 85 (Jerry
Morrison, 14 January 1985) defines them. The whole file is one FORM chunk,
and the chunks inside it hold the picture. All numbers are big-endian, high byte first,
even though Deluxe Paint wrote these files on Intel PCs. On these pages UBYTE, UWORD and
ULONG are unsigned 8-, 16- and 32-bit numbers, and WORD and LONG signed 16- and 32-bit
ones.
Chunks
Every chunk has the same 8-byte header, followed by its data:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | 4 ASCII characters | ckID | The chunk ID, such as BMHD or BODY. |
| 4 | 4 | ULONG | ckSize | The number of data bytes that follow. It does not count this 8-byte header or the pad byte. |
| 8 | ckSize | bytes | ckData | The data. |
8 + ckSize | 0 or 1 | byte | pad | A pad byte, only when ckSize is odd. |
- An ID is four characters from space (
0x20) to~(0x7E). It may not start with a space, but may end with spaces, as inPBMandDPI. IDs are compared exactly, upper and lower case being different. - A form type, such as
PBM, is stricter: no lower-case letters and no punctuation. - The smallest chunk is 8 bytes, a header with a
ckSizeof 0. - A reader skips any chunk it does not know, using
ckSize.
Padding
When a chunk’s size is odd, one pad byte follows its data, and ckSize
does not count it. So every chunk starts at an even offset. The pad byte is written
as zero, but the standard says “don’t count on that when reading”.
Deluxe Paint’s TINY and BODY chunks often have odd sizes.
In the file on the overview, the
TINY holds 267 bytes, so a pad byte follows it and the BODY
starts one byte later; the BODY holds 2,417 bytes and its pad byte is the
last byte of the file.
In some files the FORM’s size leaves out the pad byte of its last chunk.
The explorer then shows that byte as a pad byte outside the FORM.
The FORM
The file is one FORM chunk whose data starts with a form type:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 4 | 4 ASCII characters | ID | FORM (46 4F 52 4D). |
| 4 | 4 | ULONG | size | The bytes that follow: the form type and every chunk, with their pad bytes. The file is normally this plus 8 bytes long. |
| 8 | 4 | 4 ASCII characters | form type | PBM , with a space (50 42 4D 20). |
| 12 | … | chunks | The bitmap header, the other chunks and the pixel data. |
There is no document for PBM, so the rules of ILBM, whose chunks it uses, are the best guide:
BMHD, the bitmap header, is required and comes first.- Every property chunk must come before the
BODY. If one appears twice, the last one before theBODYcounts. - Readers stop at the
BODY. In the files seen, nothing follows it. - Anything after the end of the
FORMis not part of the picture. The explorer reports such bytes.
Deluxe Paint for the PC writes BMHD, CMAP,
DPPS, sixteen CRNG, TINY and BODY,
in that order; some files have no DPPS.
00000000 46 4F 52 4D 00 00 0F 2C 50 42 4D 20 42 4D 48 44
00000010 00 00 00 14 …
FORM, size 3,884, form type PBM , then the first chunk: BMHD, size 20Group chunks
EA IFF 85 defines four group chunks, whose data starts with a type and then holds other chunks:
| ID | Its type field | What it holds |
|---|---|---|
FORM | the form type | One object, such as a picture. A FORM can also hold other FORMs, LISTs and CAT s. |
LIST | a contents type | Several FORMs that share properties. Its PROP chunks come first. |
PROP | the form type the properties are for | Property chunks shared by the FORMs of that type in the LIST; at most one PROP for each form type. |
CAT | a contents type, only a hint | Chunks put one after another, with nothing shared. The type may be JJJJ, meaning none. |
Reserved IDs, which no ordinary chunk may use: FORM, LIST,
PROP, CAT , four spaces (filler), FOR1 to
FOR9, LIS1 to LIS9, CAT1 to
CAT9, and JJJJ.
Deluxe Paint writes a single FORM and no groups. The explorer reads only
files that start with FORM and PBM . A group found inside the
picture’s FORM is shown with its type and its chunks.
Reading the chunks
- Read 12 bytes. Check for
FORMand the form typePBM, space included, and take the end of the form as 8 plus its size. - At each offset until the end of the form, read the 4-byte ID and 4-byte size.
- Handle the chunk if you know its ID; otherwise skip it.
- Move on by 8 plus the size, plus 1 if the size is odd.
- Remember the last
BMHDandCMAPseen. At theBODY, decode the pixels with them.