This section describes how pzdb databases basically look like. Depending on your pzdbView version, several extensions might be supported as well. These extensions use "unused" parts in the file format to store their information. Text in italics is used to mark notes about possible unused parts.
pzdb databases are Palm databases with Version 1, Type ID "data" and Creator ID "pzDB". The database name must start with "pzDB" - this will be stripped in the viewer. Its records are 32K chunks of data (The last chunk may be shorter than 32K). All these chunks concatenated form a long zlib stream (that means they have to be decompressed in order). The format of the decompressed stream is described in the next part.
Note that the zlib stream may contain arbitrary data after the last record. The file may, as well, contain additional records at the end that are not part of the zlib stream.
The decompressed data starts with a header. The first byte gives the number of visible columns. There must be at least one column and at most 8 columns.
Each column adds two additional bytes to the header, so that the header is 1 + 2 * columns bytes long. The first byte added is the width of that column. All columns together can use 150 pixels, so all widths should sum up to 150. The second byte is the buffer size needed to store this field uncompressed. This must be one byte longer than its longest entry; the extra byte is needed for the zero byte at the end. Note that the column headers are an ordinary record as well, so don't forget to include the header's width in calculation.
The rest of the file are records. Each record starts with a byte giving its payload length (1-255) and then the payload. The first record is used as a column header. The last record is followed by a zero byte (a record without payload).
The payload consists of all fields, separated by zeroes. If after the last field (which must be zero-terminated) there is extra text, it is shown in the details view below the records.
The extra text in the very first record (the column header) is used as "database information" and shown when that command is selected. It may include database extensions just like the real records.
The extra text of the real records needs not be zero-terminated. However, if it is, all bytes after the first zero byte in it should be ignored.
Consider this small database:
This database will be encoded as follows:
|0x02||Number of columns|
|0x32 0x07||Column 1: 50 pixels wide, 7 bytes buffer|
|0x64 0x0B||Column 2: 100 pixels wide, 11 bytes buffer|
|0x0F "Number" 0x00 "English" 0x00||header|
|0x06 "1" 0x00 "One" 0x00||First record|
|0x06 "2" 0x00 "Two" 0x00|
|0x08 "3" 0x00 "Three" 0x00|
|0x07 "4" 0x00 "Four" 0x00|
|0x07 "5" 0x00 "Five" 0x00|
|0x0E "42" 0x00 "Fourty-two" 0x00|
|0x00||End of records|
In the basic format, the length of a record is restricted to 255 bytes. Some databases contain extra information about a record which is longer. To store this information, the "long memos" extension (which is present in all pzdbVersion except the lite version) can be used.
If the extra data of a record is exactly 8 bytes long, and these 8 bytes look like 00 00 xx xx xx xx yy yy, the real extra data (which may be up to 65535 bytes long) is read from offset xxxxxxxx in the zlib stream (counting from the beginning of the stream). Its length is yyyy. This extra data is used instead of these 8 bytes -- it is checked for other supported extensions as well.
Map marks allow to embed a black-and-white version-0 bitmap or a 4-bit grayscale or 16-bit color bitmap (the so called "map") which is at most 150x130 pixels large into a database. Each record may mark a pixel on this map. In the details view, the map can be shown; the marked pixel's column and row are shown inverted. When clicking this map, the record whose mark is closest to the clicked pixel will be displayed.
The map is embedded into a separate zlib stream in the last record. The map must fit into this record. The first two bytes of the zlib stream give the size of the bitmap in bytes. The rest of the stream is the bitmap itself.
If the extra data of a record ends with 00 00 xx yy, it represents the pixel (xx/yy) on the map. Records without extra data do not represent a pixel on the map.
Note: If the map mark is stored into a long memo, it can still be used to view the map. Due to technical reasons, it is not possible to do a reverse search, however.
If a record does not use a map pixel or if no map is there at all, the record may reference another image. This image is stored like the map and may be in the same formats, but obviously it will not necessarily be in the last record.
If the extra data of a record ends with 00 00 FE xx, it references the image stored in the xx-th record (counted from the end, i. e. 01 is the last, 02 is the one before the last, etc.). Every image may be referenced by only one record. If the database uses a map as well, the image 1 is used for the map and cannot be used for other records.
For displaying images (and the map), the Palm will use 16-bit color if available; if not, it will try 4-bit grayscale and if that does not work either, it will use the device's default color depth.