Skip to content

Commit

Permalink
Added check for progressive JPEG
Browse files Browse the repository at this point in the history
  • Loading branch information
djokeur committed Feb 5, 2023
1 parent cf31888 commit 14ccf9e
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ IMPORTANT : FORMAT DES FICHIERS.
La playlist en tant que telle est le fichier nommé 'playlist.bin', qui doit se trouver dans le dossier racine de la carte micro-SD de la Merlin.
Les fichiers sons et images doivent aussi se trouver dans le même dossier. Les extensions des noms de fichiers doivent être '.mp3' pour les sons et '.jpg' pour les images. Pour s'afficher sur l'enceinte, une image doit avoir le même nom de fichier (à l'exception de l'extension) que le son correspondant.
Les noms de fichiers sont limités à 64 octets en encodage utf-8 (compter un octet par caractère simple et deux par caractère accentué).
D'après mes observations, les fichiers images sont au format jpeg avec une résolution de 128x128, et les sons sont au format mp3 en stéréo à 128ko/s. Je sais pas si d'autres formats sont supportés. En revanche, il semblerait que les images au format "progressive JPEG" ne sont pas supportées.
Dans sa version actuelle, merlinator ne vérifie pas si les conditions mentionnée ci-dessus sont vérifiées. Il se contente de créer le fichier de playlist.


D'après mes observations, les fichiers images sont au format jpeg avec une résolution de 128x128, et les sons sont au format mp3 en stéréo à 128ko/s. Je sais pas si d'autres formats sont supportés.
En revanche, les images au format "progressive JPEG" ne sont pas supportées par toutes les versions de l'enceinte.
Dans sa version actuelle, merlinator crée le fichier de playlist, mais ne vérifie pas si toutes les conditions mentionnée ci-dessus sont remplies.
26 changes: 26 additions & 0 deletions src/io_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import zipfile
import os.path
import json
import struct


bytezero = b'\x00'
Expand Down Expand Up @@ -193,3 +194,28 @@ def export_merlin_to_zip(items, zfile):

return files_not_found


def IsImageProgressive(stream):
#with open(filename, "rb") as stream:
while True:
blockStart = struct.unpack('B', stream.read(1))[0]
if blockStart != 0xff:
raise ValueError('Invalid char code ' + blockStart + ' - not a JPEG file: ' + filename)
return False

blockType = struct.unpack('B', stream.read(1))[0]
if blockType == 0xd8: # Start Of Image
continue
elif blockType == 0xc0: # Start of baseline frame
return False
elif blockType == 0xc2: # Start of progressive frame
return True
elif blockType >= 0xd0 and blockType <= 0xd7: # Restart
continue
elif blockType == 0xd9: # End Of Image
break
else: # Variable-size block, just skip it
blockSize = struct.unpack('2B', stream.read(2))
blockSize = blockSize[0] * 256 + blockSize[1] - 2
stream.seek(blockSize, 1)
return False
10 changes: 10 additions & 0 deletions src/main_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ def load_thumbnails(self, items, overwrite=True):
if item['uuid'] in self.thumbnails:
continue
if os.path.exists(imagepath):
with open(imagepath, "rb") as imagestream:
if IsImageProgressive(imagestream):
tk.messagebox.showwarning(title="Problème de format", message=f"Le format de l'image '{imagepath}' est JPEG 'progressive'. Ce format n'est pas pris en charge par toutes les Merlin.")
self.thumbnails[item['uuid']] = ''
continue
with Image.open(imagepath) as image:
image_small = image.resize((40, 40), Image.ANTIALIAS)
self.thumbnails[item['uuid']] = PhotoImage(image_small)
Expand All @@ -239,6 +244,11 @@ def load_thumbnails_from_zip(self, items, zfile, overwrite=True):
filename = item['uuid'] + '.jpg'
zippath = zipfile.Path(zfile, at=filename)
if zippath.exists():
with zfile.open(filename, 'rb', pwd=info) as imagestream:
if IsImageProgressive(imagestream):
tk.messagebox.showwarning(title="Problème de format", message=f"Le format de l'image '{filename}' est JPEG 'progressive'. Ce format n'est pas pris en charge par toutes les Merlin.")
self.thumbnails[item['uuid']] = ''
continue
with zfile.open(filename, 'r', pwd=info) as imagefile:
with Image.open(imagefile) as image:
image_small = image.resize((40, 40), Image.ANTIALIAS)
Expand Down
3 changes: 3 additions & 0 deletions src/treeviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ def select_image(self):
filepath = filedialog.askopenfilename(initialdir=playlist_dirname, initialfile=initfile, filetypes=[('images jpg', '*.jpg')])
if not filepath:
return
with open(filepath, 'rb') as stream:
if IsImageProgressive(stream):
tk.messagebox.showwarning(title="Problème de format", message=f"Le format de l'image est JPEG 'progressive'. Ce format n'est pas pris en charge par toutes les Merlin.")
dirname, basename = os.path.split(filepath)
root, ext = os.path.splitext(basename)
# check length
Expand Down

0 comments on commit 14ccf9e

Please sign in to comment.