Record 0 of a KF8 book (the first record of a stand-alone AZW3, or the record after
BOUNDARY in a joint file)
holds the PalmDOC header, the MOBI header in its version 8 form, the EXTH metadata, the
full title and padding. Offsets here are from the start of the record, and record
numbers count from this record. All numbers are big-endian. Amazon has not published
the format; field names follow KindleUnpack and calibre, and fields marked unknown are
not understood.
PalmDOC header
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0x00 | 2 | UInt16 | compression | 1 none, 2 PalmDOC, 17480 HUFF/CDIC. KindleGen writes 2 for KF8. The methods are those of MOBI text records. |
0x02 | 2 | UInt16 | unused | 0. |
0x04 | 4 | UInt32 | textLength | The uncompressed length of all flows together. |
0x08 | 2 | UInt16 | textRecordCount | The number of text records, which follow this record. |
0x0A | 2 | UInt16 | textRecordSize | 4,096. |
0x0C | 2 | UInt16 | encryption | 0 none, 1 old Mobipocket, 2 Mobipocket (Kindle DRM). |
0x0E | 2 | UInt16 | unknown | 0. |
MOBI header, version 8
KF8 files use a MOBI header of 0xE8 (232) or 0x108 (264) bytes, counted from the identifier. Up to offset 0xBC the fields are those of a MOBI version 6 header; from 0xC0 on, version 8 replaces some fields with the KF8 indexes.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0x10 | 4 | char[4] | identifier | MOBI. |
0x14 | 4 | UInt32 | headerLength | Length of the MOBI header from the identifier; EXTH starts at 16 + this. |
0x18 | 4 | UInt32 | mobiType | 2 for a book; 248 is written by KindleGen 2 for KF8. The full list is on the MOBI page. |
0x1C | 4 | UInt32 | textEncoding | 65001, UTF-8. KF8 text is always UTF-8. |
0x20 | 4 | UInt32 | uniqueID | A random ID. |
0x24 | 4 | UInt32 | fileVersion | 8: this is what marks a KF8 header. |
0x28 | 4 | UInt32 | orthographicIndex | Dictionary headword index, or 0xFFFFFFFF. |
0x2C | 4 | UInt32 | inflectionIndex | Dictionary inflection index, or 0xFFFFFFFF. |
0x30 | 4 | UInt32 | indexNames | 0xFFFFFFFF. |
0x34 | 4 | UInt32 | indexKeys | 0xFFFFFFFF. |
0x38–0x4C | 6 × 4 | UInt32 | extraIndex0–5 | 0xFFFFFFFF each. |
0x50 | 4 | UInt32 | firstNonBookRecord | The first record after the text records. |
0x54 | 4 | UInt32 | fullNameOffset | Offset of the full title in this record. |
0x58 | 4 | UInt32 | fullNameLength | Its length in bytes. |
0x5C | 4 | UInt32 | locale | Windows language code, such as 2057 for British English; see the MOBI page. |
0x60 | 4 | UInt32 | inputLanguage | Dictionaries only. |
0x64 | 4 | UInt32 | outputLanguage | Dictionaries only. |
0x68 | 4 | UInt32 | minVersion | 8. |
0x6C | 4 | UInt32 | firstResourceRecord | The first resource record: kindle:embed numbers count from here. |
0x70 | 4 | UInt32 | huffmanRecordOffset | First HUFF record, with compression 17480. |
0x74 | 4 | UInt32 | huffmanRecordCount | HUFF and CDIC record count. |
0x78 | 4 | UInt32 | huffmanTableOffset | Unknown use. |
0x7C | 4 | UInt32 | huffmanTableLength | Unknown use. |
0x80 | 4 | UInt32 | exthFlags | Bit 6 (0x40): EXTH present. |
0x84 | 32 | bytes | unknown | Usually 0. |
0xA4 | 4 | UInt32 | unknown | 0xFFFFFFFF. |
0xA8 | 4 | UInt32 | drmOffset | Offset of DRM data in this record, or 0xFFFFFFFF. |
0xAC | 4 | UInt32 | drmCount | Number of DRM entries, or 0xFFFFFFFF. |
0xB0 | 4 | UInt32 | drmSize | Size of DRM data. |
0xB4 | 4 | UInt32 | drmFlags | Not public. |
0xB8 | 8 | bytes | unknown | 0. |
0xC0 | 4 | UInt32 | fdstRecord | The record of the FDST flow table. (In version 6 these four bytes are the first and last content record numbers.) |
0xC4 | 4 | UInt32 | fdstFlowCount | The number of flows in the FDST. When it is 1 or less, there is only the main text and readers ignore the FDST. |
0xC8 | 4 | UInt32 | fcisRecord | The FCIS record. |
0xCC | 4 | UInt32 | fcisCount | 1. |
0xD0 | 4 | UInt32 | flisRecord | The FLIS record. |
0xD4 | 4 | UInt32 | flisCount | 1. |
0xD8 | 8 | bytes | unknown | 0. |
0xE0 | 4 | UInt32 | srcsRecord | First SRCS record (zipped source), or 0xFFFFFFFF. |
0xE4 | 4 | UInt32 | srcsCount | Number of SRCS records. |
0xE8 | 4 | UInt32 | unknown | 0xFFFFFFFF. |
0xEC | 4 | UInt32 | unknown | 0xFFFFFFFF. |
0xF0 | 2 | UInt16 | unknown | 0. |
0xF2 | 2 | UInt16 | extraDataFlags | Trailing entries on each text record: bit 0 multibyte, bit 1 TBS indexing, bit 2 uncrossable breaks. See trailing entries. |
0xF4 | 4 | UInt32 | ncxIndex | First record of the NCX index (table of contents), or 0xFFFFFFFF. |
0xF8 | 4 | UInt32 | fragmentIndex | First record of the fragment index (also called the chunk or div index). |
0xFC | 4 | UInt32 | skeletonIndex | First record of the skeleton index. Set (not 0xFFFFFFFF) in every KF8 book. |
0x100 | 4 | UInt32 | datpRecord | A DATP record of unknown purpose, or 0xFFFFFFFF. |
0x104 | 4 | UInt32 | guideIndex | First record of the guide index, or 0xFFFFFFFF. |
0x108–0x117 | 4 × 4 | UInt32 | unknown | Present in 264-byte headers; usually 0xFFFFFFFF, the last often 0. |
calibre reads the KF8 index fields only when the version is 8 and record 0 is long enough to hold them; without a skeleton index the book cannot be rebuilt as KF8.
EXTH records
The EXTH block has the same layout as in MOBI: EXTH, a UInt32 length, a
UInt32 count, then records of a UInt32 type, a UInt32 length (including those 8 bytes)
and the data, padded to 4 bytes. The full list of types is on the MOBI
EXTH page. These are the ones that belong to
KF8 or matter most to it:
| Type | Data | Meaning |
|---|---|---|
| 121 | UInt32 | In the version 6 record 0 of a joint file: the record number of the KF8 record 0. Not present in a stand-alone KF8 file. |
| 122 | text | Fixed layout: true. |
| 123 | text | Book type, such as comic. |
| 124 | text | Orientation lock: none, portrait or landscape. |
| 125 | UInt32 | The number of resource records. |
| 126 | text | Original page resolution, such as 1072x1448. |
| 127, 128 | text | Zero gutter and zero margin: true. |
| 129 | text | Metadata resource URI: points at a resource with more metadata; details unknown. |
| 132 | text | Region magnification: true. |
| 201, 202 | UInt32 | Cover and thumbnail, as resource numbers from 0, counted from firstResourceRecord. |
| 501 | 4 bytes | Document type: EBOK, EBSP or PDOC. |
| 524 | text | Language tag, such as en-GB. |
| 525 | text | Primary writing mode, such as horizontal-lr or vertical-rl. |
| 527 | text | Page progression direction: ltr or rtl. |
| 528 | text | Override Kindle fonts: true. |
| 535 | text | The build of KindleGen or Kindle Previewer that made the file. |
| 536 | text | Information on the high-resolution image container that goes with the book. |
Full title and padding
The title, in UTF-8, sits at fullNameOffset, followed by two zero bytes
and zeros to a multiple of 4. The rest of record 0 is padding, usually zeros, and may
hold DRM data at drmOffset.