From 22a6b2200cd8b5fe721842245a9a9a346f0d34b6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 16 Apr 2012 09:41:27 +0530 Subject: [PATCH] Fix image duplication for rasterized SVGs in pure Mobi 6 output --- .../ebooks/conversion/plugins/mobi_output.py | 5 ----- src/calibre/ebooks/mobi/reader/index.py | 1 + src/calibre/ebooks/mobi/writer2/main.py | 11 ++++++---- src/calibre/ebooks/mobi/writer2/resources.py | 21 +++++++++++++++++++ src/calibre/ebooks/mobi/writer2/serializer.py | 2 ++ src/calibre/ebooks/mobi/writer8/main.py | 1 + 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/calibre/ebooks/conversion/plugins/mobi_output.py b/src/calibre/ebooks/conversion/plugins/mobi_output.py index 86c9b6b7fd..726ae2a1d0 100644 --- a/src/calibre/ebooks/conversion/plugins/mobi_output.py +++ b/src/calibre/ebooks/conversion/plugins/mobi_output.py @@ -199,11 +199,6 @@ class MOBIOutput(OutputFormatPlugin): self.log.warn('SVG rasterizer unavailable, SVG will not be converted') else: # Add rasterized SVG images - # Note that this means for SVG images that are simple wrappers - # around raster images, there will now be two copies of the image - # in the MOBI file. This could probably be fixed for common cases - # by detecting it and replacing the SVG with the raster image, but - # it isn't worth the effort to me. resources.add_extra_images() mobimlizer = MobiMLizer(ignore_tables=opts.linearize_tables) mobimlizer(oeb, opts) diff --git a/src/calibre/ebooks/mobi/reader/index.py b/src/calibre/ebooks/mobi/reader/index.py index f5add94eac..c732d8862e 100644 --- a/src/calibre/ebooks/mobi/reader/index.py +++ b/src/calibre/ebooks/mobi/reader/index.py @@ -114,6 +114,7 @@ class CNCX(object): # {{{ def __bool__(self): return bool(self.records) + __nonzero__ = __bool__ def iteritems(self): return self.records.iteritems() diff --git a/src/calibre/ebooks/mobi/writer2/main.py b/src/calibre/ebooks/mobi/writer2/main.py index d21482f8e2..b7a0d76424 100644 --- a/src/calibre/ebooks/mobi/writer2/main.py +++ b/src/calibre/ebooks/mobi/writer2/main.py @@ -152,13 +152,13 @@ class MobiWriter(object): def generate_images(self): resources = self.resources - self.image_records = resources.records + image_records = resources.records self.image_map = resources.item_map self.masthead_offset = resources.masthead_offset self.cover_offset = resources.cover_offset self.thumbnail_offset = resources.thumbnail_offset - if self.image_records and self.image_records[0] is None: + if image_records and image_records[0] is None: raise ValueError('Failed to find masthead image in manifest') # }}} @@ -265,9 +265,12 @@ class MobiWriter(object): exth = self.build_exth(bt) first_image_record = None - if self.image_records: + if self.resources: + used_images = self.serializer.used_images + if self.kf8 is not None: + used_images |= self.kf8.used_images first_image_record = len(self.records) - self.records.extend(self.image_records) + self.resources.serialize(self.records, used_images) last_content_record = len(self.records) - 1 # FCIS/FLIS (Seems to serve no purpose) diff --git a/src/calibre/ebooks/mobi/writer2/resources.py b/src/calibre/ebooks/mobi/writer2/resources.py index 44d8a6d0e5..2b065f9a81 100644 --- a/src/calibre/ebooks/mobi/writer2/resources.py +++ b/src/calibre/ebooks/mobi/writer2/resources.py @@ -12,6 +12,8 @@ from calibre.ebooks.mobi.utils import (rescale_image, mobify_image) from calibre.ebooks import generate_masthead from calibre.ebooks.oeb.base import OEB_RASTER_IMAGES +PLACEHOLDER_GIF = b'GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\xff\xff\xff!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00@\x02\x01D\x00;' + class Resources(object): def __init__(self, oeb, opts, is_periodical, add_fonts=False): @@ -21,6 +23,8 @@ class Resources(object): self.item_map = {} self.records = [] self.masthead_offset = 0 + self.used_image_indices = set() + self.image_indices = set() self.cover_offset = self.thumbnail_offset = None self.add_resources(add_fonts) @@ -39,10 +43,14 @@ class Resources(object): mh_href = oeb.guide['masthead'].href self.records.append(None) index += 1 + self.used_image_indices.add(0) + self.image_indices.add(0) elif self.is_periodical: # Generate a default masthead data = generate_masthead(unicode(self.oeb.metadata['title'][0])) self.records.append(data) + self.used_image_indices.add(0) + self.image_indices.add(0) index += 1 cover_href = self.cover_offset = self.thumbnail_offset = None @@ -64,20 +72,24 @@ class Resources(object): self.records[0] = data continue + self.image_indices.add(len(self.records)) self.records.append(data) self.item_map[item.href] = index index += 1 if cover_href and item.href == cover_href: self.cover_offset = self.item_map[item.href] - 1 + self.used_image_indices.add(self.cover_offset) try: data = rescale_image(item.data, dimen=MAX_THUMB_DIMEN, maxsizeb=MAX_THUMB_SIZE) except: self.log.warn('Failed to generate thumbnail') else: + self.image_indices.add(len(self.records)) self.records.append(data) self.thumbnail_offset = index - 1 + self.used_image_indices.add(self.thumbnail_offset) index += 1 finally: item.unload_data_from_memory() @@ -99,5 +111,14 @@ class Resources(object): finally: item.unload_data_from_memory() + def serialize(self, records, used_images): + used_image_indices = self.used_image_indices | { + v-1 for k, v in self.item_map.iteritems() if k in used_images} + for i in self.image_indices-used_image_indices: + self.records[i] = PLACEHOLDER_GIF + records.extend(self.records) + def __bool__(self): + return bool(self.records) + __nonzero__ = __bool__ diff --git a/src/calibre/ebooks/mobi/writer2/serializer.py b/src/calibre/ebooks/mobi/writer2/serializer.py index b35f33439b..d8d63bcff4 100644 --- a/src/calibre/ebooks/mobi/writer2/serializer.py +++ b/src/calibre/ebooks/mobi/writer2/serializer.py @@ -39,6 +39,7 @@ class Serializer(object): self.oeb = oeb # Map of image hrefs to image index in the MOBI file self.images = images + self.used_images = set() self.logger = oeb.logger self.is_periodical = is_periodical self.write_page_breaks_after_item = write_page_breaks_after_item @@ -329,6 +330,7 @@ class Serializer(object): href = urlnormalize(item.abshref(val)) if href in self.images: index = self.images[href] + self.used_images.add(href) buf.write(b'recindex="%05d"' % index) continue buf.write(attr.encode('utf-8')) diff --git a/src/calibre/ebooks/mobi/writer8/main.py b/src/calibre/ebooks/mobi/writer8/main.py index 3a24490faa..8d643deb75 100644 --- a/src/calibre/ebooks/mobi/writer8/main.py +++ b/src/calibre/ebooks/mobi/writer8/main.py @@ -19,6 +19,7 @@ class KF8Writer(object): def __init__(self, oeb, opts): self.oeb, self.opts, self.log = oeb, opts, oeb.log + self.used_images = set() self.dup_data() self.create_pieces()