From 0d0161549876d1b4600c770c56048ead2f7bdc18 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Fri, 1 Jan 2021 18:06:51 +0100 Subject: [PATCH] PICARD-2089: Support WebP for cover art images --- picard/coverart/providers/local.py | 2 +- picard/ui/coverartbox.py | 2 +- picard/util/imageinfo.py | 32 +++++++- test/data/mb-vp8.webp | Bin 0 -> 6178 bytes test/data/mb-vp8l.webp | Bin 0 -> 9432 bytes test/data/mb-vp8x.webp | Bin 0 -> 6858 bytes test/picardtestcase.py | 8 +- test/test_util_imageinfo.py | 116 +++++++++++++++++++++++++++++ test/test_utils.py | 59 --------------- 9 files changed, 155 insertions(+), 64 deletions(-) create mode 100644 test/data/mb-vp8.webp create mode 100644 test/data/mb-vp8l.webp create mode 100644 test/data/mb-vp8x.webp create mode 100644 test/test_util_imageinfo.py diff --git a/picard/coverart/providers/local.py b/picard/coverart/providers/local.py index a5996a978..c3043997c 100644 --- a/picard/coverart/providers/local.py +++ b/picard/coverart/providers/local.py @@ -42,7 +42,7 @@ class ProviderOptionsLocal(ProviderOptions): """ HELP_URL = '/config/options_local_files.html' - _DEFAULT_LOCAL_COVER_ART_REGEX = r'^(?:cover|folder|albumart)(.*)\.(?:jpe?g|png|gif|tiff?)$' + _DEFAULT_LOCAL_COVER_ART_REGEX = r'^(?:cover|folder|albumart)(.*)\.(?:jpe?g|png|gif|tiff?|webp)$' options = [ config.TextOption("setting", "local_cover_regex", diff --git a/picard/ui/coverartbox.py b/picard/ui/coverartbox.py index 26aef1ca8..50ce5fccd 100644 --- a/picard/ui/coverartbox.py +++ b/picard/ui/coverartbox.py @@ -540,7 +540,7 @@ class CoverArtBox(QtWidgets.QGroupBox): def choose_local_file(self): file_chooser = QtWidgets.QFileDialog(self) file_chooser.setNameFilters([ - _("All supported image formats") + " (*.png *.jpg *.jpeg *.tif *.tiff *.gif *.pdf)", + _("All supported image formats") + " (*.png *.jpg *.jpeg *.tif *.tiff *.gif *.pdf *.webp)", _("All files") + " (*)", ]) if file_chooser.exec_(): diff --git a/picard/util/imageinfo.py b/picard/util/imageinfo.py index a58e5b0df..928fb10ce 100644 --- a/picard/util/imageinfo.py +++ b/picard/util/imageinfo.py @@ -4,6 +4,7 @@ # # Copyright (C) 2014, 2018, 2020 Laurent Monin # Copyright (C) 2017 Sambhav Kothari +# Copyright (C) 2021 Philipp Wolfer # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -23,6 +24,8 @@ from io import BytesIO import struct +from mutagen.tak import _LSBBitReader as LSBBitReader + class IdentificationError(Exception): pass @@ -41,7 +44,7 @@ class UnexpectedError(IdentificationError): def identify(data): - """Parse data for jpg, gif, png metadata + """Parse data for jpg, gif, png, webp and pdf metadata If successfully recognized, it returns a tuple with: - width - height @@ -108,6 +111,33 @@ def identify(data): except ValueError: pass + # WebP + elif data[:4] == b'RIFF' and data[8:12] == b'WEBP': + # See https://developers.google.com/speed/webp/docs/riff_container + format = data[12:16] + # Simple File Format (Lossy) + if format == b'VP8 ': + # TODO: Implement reading width and height + h, w = 0, 0 + # Simple File Format (Lossless) + elif format == b'VP8L': + if len(data) < 25: + raise NotEnoughData('Not enough data for WebP VP8L') + reader = LSBBitReader(BytesIO(data[21:25])) + w = reader.bits(14) + 1 + h = reader.bits(14) + 1 + # Extended File Format + elif format == b'VP8X': + if len(data) < 30: + raise NotEnoughData('Not enough data for WebP VP8X') + reader = LSBBitReader(BytesIO(data[24:30])) + w = reader.bits(24) + 1 + h = reader.bits(24) + 1 + else: + h, w = 0, 0 + mime = 'image/webp' + extension = '.webp' + # PDF elif data[:4] == b'%PDF': h, w = 0, 0 diff --git a/test/data/mb-vp8.webp b/test/data/mb-vp8.webp new file mode 100644 index 0000000000000000000000000000000000000000..584c72b377e1da2aee69768ae557ee138bcdecba GIT binary patch literal 6178 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 AU;qFB literal 0 HcmV?d00001 diff --git a/test/data/mb-vp8l.webp b/test/data/mb-vp8l.webp new file mode 100644 index 0000000000000000000000000000000000000000..836bbd3f38576ac9aabef9868e571cfcd11466d0 GIT binary patch literal 9432 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 literal 0 HcmV?d00001 diff --git a/test/picardtestcase.py b/test/picardtestcase.py index 85a2b19c7..030f20feb 100644 --- a/test/picardtestcase.py +++ b/test/picardtestcase.py @@ -3,7 +3,7 @@ # Picard, the next-generation MusicBrainz tagger # # Copyright (C) 2018 Wieland Hoffmann -# Copyright (C) 2019-2020 Philipp Wolfer +# Copyright (C) 2019-2021 Philipp Wolfer # Copyright (C) 2020 Laurent Monin # # This program is free software; you can redistribute it and/or @@ -115,11 +115,15 @@ class PicardTestCase(unittest.TestCase): os.unlink(filepath) +def get_test_data_path(*paths): + return os.path.join('test', 'data', *paths) + + def create_fake_png(extra): """Creates fake PNG data that satisfies Picard's internal image type detection""" return b'\x89PNG\x0D\x0A\x1A\x0A' + (b'a' * 4) + b'IHDR' + struct.pack('>LL', 100, 100) + extra def load_test_json(filename): - with open(os.path.join('test', 'data', 'ws_data', filename), encoding='utf-8') as f: + with open(get_test_data_path('ws_data', filename), encoding='utf-8') as f: return json.load(f) diff --git a/test/test_util_imageinfo.py b/test/test_util_imageinfo.py new file mode 100644 index 000000000..169c6e2c9 --- /dev/null +++ b/test/test_util_imageinfo.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# +# Picard, the next-generation MusicBrainz tagger +# +# Copyright (C) 2014, 2020 Laurent Monin +# Copyright (C) 2021 Philipp Wolfer +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +from test.picardtestcase import ( + PicardTestCase, + get_test_data_path, +) + +from picard.util import imageinfo + + +class IdentifyTest(PicardTestCase): + + def test_gif(self): + file = get_test_data_path('mb.gif') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (140, 96, 'image/gif', '.gif', 5806) + ) + + def test_png(self): + file = get_test_data_path('mb.png') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (140, 96, 'image/png', '.png', 11137) + ) + + def test_jpeg(self): + file = get_test_data_path('mb.jpg') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (140, 96, 'image/jpeg', '.jpg', 8550) + ) + + def test_webp_vp8(self): + file = get_test_data_path('mb-vp8.webp') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (140, 96, 'image/webp', '.webp', 6178) + ) + + def test_webp_vp8l(self): + file = get_test_data_path('mb-vp8l.webp') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (140, 96, 'image/webp', '.webp', 9432) + ) + + def test_webp_vp8x(self): + file = get_test_data_path('mb-vp8x.webp') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (140, 96, 'image/webp', '.webp', 6858) + ) + + def test_webp_insufficient_data(self): + self.assertRaises(imageinfo.NotEnoughData, imageinfo.identify, b'RIFF\x00\x00\x00\x00WEBPVP8L') + self.assertRaises(imageinfo.NotEnoughData, imageinfo.identify, b'RIFF\x00\x00\x00\x00WEBPVP8X') + + def test_pdf(self): + file = get_test_data_path('mb.pdf') + + with open(file, 'rb') as f: + self.assertEqual( + imageinfo.identify(f.read()), + (0, 0, 'application/pdf', '.pdf', 10362) + ) + + def test_not_enough_data(self): + self.assertRaises(imageinfo.IdentificationError, + imageinfo.identify, "x") + self.assertRaises(imageinfo.NotEnoughData, imageinfo.identify, "x") + + def test_invalid_data(self): + self.assertRaises(imageinfo.IdentificationError, + imageinfo.identify, "x" * 20) + self.assertRaises(imageinfo.UnrecognizedFormat, + imageinfo.identify, "x" * 20) + + def test_invalid_png_data(self): + data = '\x89PNG\x0D\x0A\x1A\x0A' + "x" * 20 + self.assertRaises(imageinfo.IdentificationError, + imageinfo.identify, data) + self.assertRaises(imageinfo.UnrecognizedFormat, + imageinfo.identify, data) diff --git a/test/test_utils.py b/test/test_utils.py index 7456f3e1f..b6ca031aa 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -31,7 +31,6 @@ import builtins from collections import namedtuple from collections.abc import Iterator -import os.path import unittest from unittest.mock import Mock @@ -42,7 +41,6 @@ from picard.const.sys import IS_WIN from picard.util import ( extract_year_from_date, find_best_match, - imageinfo, is_absolute_path, iter_files_from_objects, iter_unique, @@ -290,63 +288,6 @@ class IsAbsolutePathTest(PicardTestCase): self.assertTrue(is_absolute_path('\\\\foo\\bar\\baz')) -class ImageInfoTest(PicardTestCase): - - def test_gif(self): - file = os.path.join('test', 'data', 'mb.gif') - - with open(file, 'rb') as f: - self.assertEqual( - imageinfo.identify(f.read()), - (140, 96, 'image/gif', '.gif', 5806) - ) - - def test_png(self): - file = os.path.join('test', 'data', 'mb.png') - - with open(file, 'rb') as f: - self.assertEqual( - imageinfo.identify(f.read()), - (140, 96, 'image/png', '.png', 11137) - ) - - def test_jpeg(self): - file = os.path.join('test', 'data', 'mb.jpg') - - with open(file, 'rb') as f: - self.assertEqual( - imageinfo.identify(f.read()), - (140, 96, 'image/jpeg', '.jpg', 8550) - ) - - def test_pdf(self): - file = os.path.join('test', 'data', 'mb.pdf') - - with open(file, 'rb') as f: - self.assertEqual( - imageinfo.identify(f.read()), - (0, 0, 'application/pdf', '.pdf', 10362) - ) - - def test_not_enough_data(self): - self.assertRaises(imageinfo.IdentificationError, - imageinfo.identify, "x") - self.assertRaises(imageinfo.NotEnoughData, imageinfo.identify, "x") - - def test_invalid_data(self): - self.assertRaises(imageinfo.IdentificationError, - imageinfo.identify, "x" * 20) - self.assertRaises(imageinfo.UnrecognizedFormat, - imageinfo.identify, "x" * 20) - - def test_invalid_png_data(self): - data = '\x89PNG\x0D\x0A\x1A\x0A' + "x" * 20 - self.assertRaises(imageinfo.IdentificationError, - imageinfo.identify, data) - self.assertRaises(imageinfo.UnrecognizedFormat, - imageinfo.identify, data) - - class CompareBarcodesTest(PicardTestCase): def test_same(self):