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 WRITE_UNCROSSABLE_BREAKS = False
NULL_INDEX = 0xffffffff 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): class MobiWriter(object):
def __init__(self, opts, resources, kf8, write_page_breaks_after_item=True): 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) # FCIS/FLIS (Seems to serve no purpose)
flis_number = len(self.records) flis_number = len(self.records)
self.records.append( self.records.append(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)
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'
fcis_number = len(self.records) fcis_number = len(self.records)
self.records.append(fcis) self.records.append(fcis(self.text_length))
# EOF record # EOF record
self.records.append(b'\xE9\x8E\x0D\x0A') self.records.append(b'\xE9\x8E\x0D\x0A')
@ -379,6 +383,12 @@ class MobiWriter(object):
self.resources.serialize(self.records, used_images) self.resources.serialize(self.records, used_images)
resource_record_count = len(self.records) - old 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 # Insert KF8 records
self.records.append(b'BOUNDARY') self.records.append(b'BOUNDARY')
kf8_header_index = len(self.records) kf8_header_index = len(self.records)
@ -398,6 +408,8 @@ class MobiWriter(object):
header_fields['exth_flags'] = 0b100001010000 # Kinglegen uses this header_fields['exth_flags'] = 0b100001010000 # Kinglegen uses this
header_fields['fdst_record'] = NULL_INDEX header_fields['fdst_record'] = NULL_INDEX
header_fields['fdst_count'] = 1 # Why not 0? Kindlegen uses 1 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 extra_data_flags = 0b1 # Has multibyte overlap bytes
if self.primary_index_record_idx is not None: if self.primary_index_record_idx is not None:
extra_data_flags |= 0b10 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 from calibre.utils.filenames import ascii_filename
NULL_INDEX = 0xffffffff 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): # {{{ class MOBIHeader(Header): # {{{
''' '''
@ -115,7 +123,10 @@ class MOBIHeader(Header): # {{{
exth_flags = DYN exth_flags = DYN
# 132: Unknown # 132: Unknown
unknown = zeroes(36) unknown = zeroes(32)
# 164: Unknown
unknown_index = NULL
# 168: DRM # 168: DRM
drm_offset = NULL drm_offset = NULL
@ -130,13 +141,13 @@ class MOBIHeader(Header): # {{{
fdst_record = DYN fdst_record = DYN
fdst_count = DYN fdst_count = DYN
# 200: FCI # 200: FCIS
fcis_record = NULL fcis_record = DYN
fcis_count fcis_count = 1
# 208: FLIS # 208: FLIS
flis_record = NULL flis_record = DYN
flis_count flis_count = 1
# 216: Unknown # 216: Unknown
unknown3 = zeroes(8) unknown3 = zeroes(8)
@ -193,7 +204,7 @@ HEADER_FIELDS = {'compression', 'text_length', 'last_text_record', 'book_type',
'first_resource_record', 'exth_flags', 'fdst_record', 'first_resource_record', 'exth_flags', 'fdst_record',
'fdst_count', 'ncx_index', 'chunk_index', 'skel_index', 'fdst_count', 'ncx_index', 'chunk_index', 'skel_index',
'guide_index', 'exth', 'full_title', 'extra_data_flags', 'guide_index', 'exth', 'full_title', 'extra_data_flags',
'uid'} 'flis_record', 'fcis_record', 'uid'}
class KF8Book(object): class KF8Book(object):
@ -241,6 +252,12 @@ class KF8Book(object):
self.fdst_record = len(self.records) self.fdst_record = len(self.records)
self.records.extend(writer.fdst_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 # EOF
self.records.append(b'\xe9\x8e\r\n') # EOF record self.records.append(b'\xe9\x8e\r\n') # EOF record