KF8 Output: Write useless FLIS/FCIS records as older kindles refuse to open joint MOBI files without them

This commit is contained in:
Kovid Goyal 2012-04-30 14:16:45 +05:30
parent 8a046ddff1
commit 92c757f0ee
2 changed files with 43 additions and 14 deletions

View File

@ -25,6 +25,15 @@ from calibre.ebooks.mobi.writer2.indexer import Indexer
WRITE_UNCROSSABLE_BREAKS = False
NULL_INDEX = 0xffffffff
FLIS = (b'FLIS\0\0\0\x08\0\x41\0\0\0\0\0\0\xff\xff\xff\xff\0\x01\0\x03\0\0\0\x03\0\0\0\x01'+
b'\xff'*4)
def fcis(text_length):
fcis = b'FCIS\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x00'
fcis += pack(b'>I', text_length)
fcis += b'\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x08\x00\x01\x00\x01\x00\x00\x00\x00'
return fcis
class MobiWriter(object):
def __init__(self, opts, resources, kf8, write_page_breaks_after_item=True):
@ -208,14 +217,9 @@ class MobiWriter(object):
# FCIS/FLIS (Seems to serve no purpose)
flis_number = len(self.records)
self.records.append(
b'FLIS\0\0\0\x08\0\x41\0\0\0\0\0\0\xff\xff\xff\xff\0\x01\0\x03\0\0\0\x03\0\0\0\x01'+
b'\xff'*4)
fcis = b'FCIS\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x00'
fcis += pack(b'>I', self.text_length)
fcis += b'\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x08\x00\x01\x00\x01\x00\x00\x00\x00'
self.records.append(FLIS)
fcis_number = len(self.records)
self.records.append(fcis)
self.records.append(fcis(self.text_length))
# EOF record
self.records.append(b'\xE9\x8E\x0D\x0A')
@ -379,6 +383,12 @@ class MobiWriter(object):
self.resources.serialize(self.records, used_images)
resource_record_count = len(self.records) - old
# FCIS/FLIS (Seems to serve no purpose)
flis_number = len(self.records)
self.records.append(FLIS)
fcis_number = len(self.records)
self.records.append(fcis(self.text_length))
# Insert KF8 records
self.records.append(b'BOUNDARY')
kf8_header_index = len(self.records)
@ -398,6 +408,8 @@ class MobiWriter(object):
header_fields['exth_flags'] = 0b100001010000 # Kinglegen uses this
header_fields['fdst_record'] = NULL_INDEX
header_fields['fdst_count'] = 1 # Why not 0? Kindlegen uses 1
header_fields['flis_record'] = flis_number
header_fields['fcis_record'] = fcis_number
extra_data_flags = 0b1 # Has multibyte overlap bytes
if self.primary_index_record_idx is not None:
extra_data_flags |= 0b10

View File

@ -18,6 +18,14 @@ from calibre.ebooks.mobi.writer8.exth import build_exth
from calibre.utils.filenames import ascii_filename
NULL_INDEX = 0xffffffff
FLIS = b'FLIS\0\0\0\x08\0\x41\0\0\0\0\0\0\xff\xff\xff\xff\0\x01\0\x03\0\0\0\x03\0\0\0\x01'+ b'\xff'*4
def fcis(text_length):
fcis = b'FCIS\x00\x00\x00\x14\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x00'
fcis += pack(b'>L', text_length)
fcis += b'\x00\x00\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00'
fcis += b'\x28\x00\x00\x00\x08\x00\x01\x00\x01\x00\x00\x00\x00'
return fcis
class MOBIHeader(Header): # {{{
'''
@ -115,7 +123,10 @@ class MOBIHeader(Header): # {{{
exth_flags = DYN
# 132: Unknown
unknown = zeroes(36)
unknown = zeroes(32)
# 164: Unknown
unknown_index = NULL
# 168: DRM
drm_offset = NULL
@ -130,13 +141,13 @@ class MOBIHeader(Header): # {{{
fdst_record = DYN
fdst_count = DYN
# 200: FCI
fcis_record = NULL
fcis_count
# 200: FCIS
fcis_record = DYN
fcis_count = 1
# 208: FLIS
flis_record = NULL
flis_count
flis_record = DYN
flis_count = 1
# 216: Unknown
unknown3 = zeroes(8)
@ -193,7 +204,7 @@ HEADER_FIELDS = {'compression', 'text_length', 'last_text_record', 'book_type',
'first_resource_record', 'exth_flags', 'fdst_record',
'fdst_count', 'ncx_index', 'chunk_index', 'skel_index',
'guide_index', 'exth', 'full_title', 'extra_data_flags',
'uid'}
'flis_record', 'fcis_record', 'uid'}
class KF8Book(object):
@ -241,6 +252,12 @@ class KF8Book(object):
self.fdst_record = len(self.records)
self.records.extend(writer.fdst_records)
# FLIS/FCIS
self.flis_record = len(self.records)
self.records.append(FLIS)
self.fcis_record = len(self.records)
self.records.append(fcis(self.text_length))
# EOF
self.records.append(b'\xe9\x8e\r\n') # EOF record