diff --git a/src/calibre/ebooks/mobi/writer2/resources.py b/src/calibre/ebooks/mobi/writer2/resources.py index 33b1a17d80..82c34828b7 100644 --- a/src/calibre/ebooks/mobi/writer2/resources.py +++ b/src/calibre/ebooks/mobi/writer2/resources.py @@ -88,6 +88,9 @@ class Resources(object): for item in self.oeb.manifest.values(): if item.media_type not in OEB_RASTER_IMAGES: continue + if item.media_type.lower() == 'image/webp': + self.log.info(f'Converting WebP image {item.href} to PNG') + item.convert_webp() try: data = self.process_image(item.data) except: diff --git a/src/calibre/ebooks/oeb/base.py b/src/calibre/ebooks/oeb/base.py index 957ded7bd1..e5298169bb 100644 --- a/src/calibre/ebooks/oeb/base.py +++ b/src/calibre/ebooks/oeb/base.py @@ -321,6 +321,7 @@ GIF_MIME = types_map['.gif'] JPEG_MIME = types_map['.jpeg'] PNG_MIME = types_map['.png'] SVG_MIME = types_map['.svg'] +WEBP_MIME = types_map['.webp'] BINARY_MIME = 'application/octet-stream' XHTML_CSS_NAMESPACE = '@namespace "%s";\n' % XHTML_NS @@ -328,7 +329,7 @@ XHTML_CSS_NAMESPACE = '@namespace "%s";\n' % XHTML_NS OEB_STYLES = {CSS_MIME, OEB_CSS_MIME, 'text/x-oeb-css', 'xhtml/css'} OEB_DOCS = {XHTML_MIME, 'text/html', OEB_DOC_MIME, 'text/x-oeb-document'} -OEB_RASTER_IMAGES = {GIF_MIME, JPEG_MIME, PNG_MIME} +OEB_RASTER_IMAGES = {GIF_MIME, JPEG_MIME, PNG_MIME, WEBP_MIME} OEB_IMAGES = {GIF_MIME, JPEG_MIME, PNG_MIME, SVG_MIME} MS_COVER_TYPE = 'other.ms-coverimage-standard' @@ -1144,6 +1145,13 @@ class Manifest(object): href = os.path.normpath(href).replace('\\', '/') return href + def convert_webp(self): + from calibre.utils.img import image_and_format_from_data, image_to_data + img, fmt = image_and_format_from_data(self.data) + if fmt == 'webp' and not img.isNull(): + self.data = image_to_data(img, fmt='PNG') + self.media_type = 'image/png' + def __init__(self, oeb): self.oeb = oeb self.items = set() diff --git a/src/calibre/test_build.py b/src/calibre/test_build.py index f3a0e626ed..799bc02179 100644 --- a/src/calibre/test_build.py +++ b/src/calibre/test_build.py @@ -303,7 +303,7 @@ class BuildTest(unittest.TestCase): # hard-coded paths of the Qt installation should work. If they do not, # then it is a distro problem. fmts = set(map(lambda x: x.data().decode('utf-8'), QImageReader.supportedImageFormats())) # no2to3 - testf = {'jpg', 'png', 'svg', 'ico', 'gif'} + testf = {'jpg', 'png', 'svg', 'ico', 'gif', 'webp'} self.assertEqual(testf.intersection(fmts), testf, "Qt doesn't seem to be able to load some of its image plugins. Available plugins: %s" % fmts) data = P('images/blank.png', allow_user_override=False, data=True) img = image_from_data(data)