diff --git a/src/calibre/ebooks/conversion/plugins/mobi_input.py b/src/calibre/ebooks/conversion/plugins/mobi_input.py index 144158e966..a6aa05a574 100644 --- a/src/calibre/ebooks/conversion/plugins/mobi_input.py +++ b/src/calibre/ebooks/conversion/plugins/mobi_input.py @@ -7,6 +7,22 @@ import os from calibre.customize.conversion import InputFormatPlugin +def run_mobi_unpack(stream, options, log, accelerators): + from mobiunpack.mobi_unpack import Mobi8Reader + from calibre.customize.ui import plugin_for_input_format + from calibre.ptempfile import PersistentTemporaryDirectory + + wdir = PersistentTemporaryDirectory('_unpack_space') + m8r = Mobi8Reader(stream, wdir) + if m8r.isK8(): + epub_path = m8r.processMobi8() + epub_input = plugin_for_input_format('epub') + for opt in epub_input.options: + setattr(options, opt.option.name, opt.recommended_value) + options.input_encoding = m8r.getCodec() + return epub_input.convert(open(epub_path,'rb'), options, + 'epub', log, accelerators) + class MOBIInput(InputFormatPlugin): name = 'MOBI Input' @@ -18,21 +34,8 @@ class MOBIInput(InputFormatPlugin): accelerators): if os.environ.get('USE_MOBIUNPACK', None) is not None: - from calibre.ptempfile import PersistentTemporaryDirectory try: - from mobiunpack.mobi_unpack import Mobi8Reader - from calibre.customize.ui import plugin_for_input_format - - wdir = PersistentTemporaryDirectory('_unpack_space') - m8r = Mobi8Reader(stream, wdir) - if m8r.isK8(): - epub_path = m8r.processMobi8() - epub_input = plugin_for_input_format('epub') - for opt in epub_input.options: - setattr(options, opt.option.name, opt.recommended_value) - options.input_encoding = m8r.getCodec() - return epub_input.convert(open(epub_path,'rb'), options, - 'epub', log, accelerators) + return run_mobi_unpack(stream, options, log, accelerators) except Exception: log.exception('mobi_unpack code not working') diff --git a/src/calibre/ebooks/conversion/plugins/mobi_output.py b/src/calibre/ebooks/conversion/plugins/mobi_output.py index 2bde83e0e3..7288f095d7 100644 --- a/src/calibre/ebooks/conversion/plugins/mobi_output.py +++ b/src/calibre/ebooks/conversion/plugins/mobi_output.py @@ -56,7 +56,16 @@ class MOBIOutput(OutputFormatPlugin): help=_('Enable sharing of book content via Facebook etc. ' ' on the Kindle. WARNING: Using this feature means that ' ' the book will not auto sync its last read position ' - ' on multiple devices. Complain to Amazon.')) + ' on multiple devices. Complain to Amazon.') + ), + OptionRecommendation(name='mobi_keep_original_images', + recommended_value=False, + help=_('By default calibre converts all images to JPEG format ' + 'in the output MOBI file. This is for maximum compatibility ' + 'as some older MOBI viewers have problems with other image ' + 'formats. This option tells calibre not to do this. ' + 'Useful if your document contains lots of GIF/PNG images that ' + 'become very large when converted to JPEG.')), ]) def check_for_periodical(self): diff --git a/src/calibre/ebooks/mobi/utils.py b/src/calibre/ebooks/mobi/utils.py index cc30991392..3a9cf1c0ba 100644 --- a/src/calibre/ebooks/mobi/utils.py +++ b/src/calibre/ebooks/mobi/utils.py @@ -7,7 +7,7 @@ __license__ = 'GPL v3' __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import struct, string +import struct, string, imghdr from collections import OrderedDict from calibre.utils.magick.draw import Image, save_cover_data_to, thumbnail @@ -363,3 +363,14 @@ def to_base(num, base=32): ans.reverse() return ''.join(ans) +def mobify_image(data): + 'Convert PNG images to GIF as the idiotic Kindle cannot display some PNG' + what = imghdr.what(None, data) + + if what == 'png': + im = Image() + im.load(data) + data = im.export('gif') + return data + + diff --git a/src/calibre/ebooks/mobi/writer2/main.py b/src/calibre/ebooks/mobi/writer2/main.py index 27f8bec54d..99321fab12 100644 --- a/src/calibre/ebooks/mobi/writer2/main.py +++ b/src/calibre/ebooks/mobi/writer2/main.py @@ -18,7 +18,7 @@ from calibre.ebooks.compression.palmdoc import compress_doc from calibre.ebooks.mobi.langcodes import iana2mobi from calibre.utils.filenames import ascii_filename from calibre.ebooks.mobi.writer2 import (PALMDOC, UNCOMPRESSED, RECORD_SIZE) -from calibre.ebooks.mobi.utils import (rescale_image, encint, +from calibre.ebooks.mobi.utils import (rescale_image, encint, mobify_image, encode_trailing_data, align_block, detect_periodical) from calibre.ebooks.mobi.writer2.indexer import Indexer from calibre.ebooks.mobi import MAX_THUMB_DIMEN, MAX_THUMB_SIZE @@ -179,7 +179,11 @@ class MobiWriter(object): for item in self.oeb.manifest.values(): if item.media_type not in OEB_RASTER_IMAGES: continue try: - data = rescale_image(item.data) + data = item.data + if self.opts.mobi_keep_original_images: + data = mobify_image(data) + else: + data = rescale_image(data) except: oeb.logger.warn('Bad image file %r' % item.href) continue diff --git a/src/calibre/gui2/convert/mobi_output.py b/src/calibre/gui2/convert/mobi_output.py index bff9598e6e..50b67008d9 100644 --- a/src/calibre/gui2/convert/mobi_output.py +++ b/src/calibre/gui2/convert/mobi_output.py @@ -22,6 +22,7 @@ class PluginWidget(Widget, Ui_Form): def __init__(self, parent, get_option, get_help, db=None, book_id=None): Widget.__init__(self, parent, ['prefer_author_sort', 'toc_title', + 'mobi_keep_original_images', 'mobi_ignore_margins', 'mobi_toc_at_start', 'dont_compress', 'no_inline_toc', 'share_not_sync', 'personal_doc']#, 'mobi_navpoints_only_deepest'] diff --git a/src/calibre/gui2/convert/mobi_output.ui b/src/calibre/gui2/convert/mobi_output.ui index dd3fdd49be..2c62b8c27a 100644 --- a/src/calibre/gui2/convert/mobi_output.ui +++ b/src/calibre/gui2/convert/mobi_output.ui @@ -14,7 +14,7 @@ Form - + Kindle options @@ -57,7 +57,7 @@ - + Qt::Vertical @@ -104,7 +104,7 @@ - + Disable compression of the file contents @@ -118,6 +118,13 @@ + + + + Do not convert all images to &JPEG (may result in images not working in older viewers) + + + diff --git a/src/calibre/manual/faq.rst b/src/calibre/manual/faq.rst index f6e293013e..a6d1467cab 100644 --- a/src/calibre/manual/faq.rst +++ b/src/calibre/manual/faq.rst @@ -29,6 +29,7 @@ It can convert every input format in the following list, to every output format. PRC is a generic format, |app| supports PRC files with TextRead and MOBIBook headers. PDB is also a generic format. |app| supports eReder, Plucker, PML and zTxt PDB files. DJVU support is only for converting DJVU files that contain embedded text. These are typically generated by OCR software. + MOBI books can be of two types Mobi6 and KF8. |app| currently fully supports Mobi6 and supports conversion from, but not to, KF8 .. _best-source-formats: