Oui, le bon vieux GIF. Aimé pour sa polyvalence, détesté pour ses brevets et en partie obsolète en raison de ses limites (et brevets), GIF se compose, au cœur, d'une palette de couleurs et d'une image indexée de palette compressée à l'aide de l'algorithme LZW.
Votre tâche consiste à écrire un programme qui lit une image au format ASCII PPM (nombre magique "P3") à partir de l'entrée standard et écrit la même image (pixel par pixel identique) au format GIF sur la sortie standard. La sortie peut être soit sous forme binaire, soit en texte ASCII, chaque octet étant représenté par un nombre compris entre 0 et 255 (inclus), séparé par des espaces.
L'image d'entrée est garantie de ne pas avoir plus de 256 couleurs différentes.
Notation:
Votre programme sera testé sur 3 échantillons d'images et votre score sera calculé comme suit:
taille du programme + somme (taille de sortie - taille de référence pour chaque image d'échantillon)
Le score le plus bas l'emporte.
Exigences:
- Votre programme doit fonctionner avec des types d'images similaires de différentes tailles et ne pas être limité aux exemples d'images. Vous pouvez, par exemple, restreindre les dimensions à des multiples de 2 ou supposer que la couleur maximale en ppm est de 255, mais cela devrait toujours fonctionner avec une grande variété d'images d'entrée.
- La sortie doit être un fichier GIF valide qui peut être chargé avec n'importe quel programme compatible (après la reconversion en binaire si vous utilisez l'option de sortie ASCII).
- Vous ne pouvez utiliser aucune fonction de traitement d'image (intégrée ou tierce), votre programme doit contenir tout le code pertinent.
- Votre programme doit être exécutable sous Linux en utilisant un logiciel disponible gratuitement.
- Le code source doit utiliser uniquement des caractères ASCII.
Exemples d'images:
Voici les 3 exemples d'images qui seront utilisés pour la notation. Vous pouvez télécharger une archive zip avec les fichiers ppm (utilisez le bouton de téléchargement en haut de cette page). Ou vous pouvez les convertir à partir des images png ci-dessous, en utilisant ImageMagick avec la commande suivante:
convert file.png -compress none file.ppm
Je fournis également les sommes de contrôle MD5 des fichiers ppm pour confirmation.
1. ambre
Taille de référence: 38055 Somme de
contrôle MD5 de ppm: d1ad863cb556869332074717eb278080
2. yeux bleus
Taille de référence: 28638 Somme de
contrôle MD5 de ppm: e9ad410057a5f6c25a22a534259dcf3a
3. poivrons
Taille de référence: 53586 Somme de
contrôle MD5 de ppm: 74112dbdbb8b7de5216f9e24c2e1a627
la source
Réponses:
Perl, 515 + -2922 + 0 + -2571 = -4978
Une autre approche. Cette fois, j'essaie d'enregistrer l'image dans des tuiles de taille 64xH. C'est bien selon les spécifications, mais certains logiciels peuvent afficher uniquement la première tuile ou une animation. Les tuiles se compriment mieux grâce à une meilleure localisation spatiale. Je fais également une compression normale pour la deuxième image et je choisis celle qui est la plus courte. Comme cela comprime deux fois l'image, elle est deux fois plus lente que ma solution précédente.
Perl, 354 + 12 + 0 + -1 = 365
418 9521 51168 56639Soit il y a un bug dans mon code, soit la deuxième image est optimisée pour un encodeur spécifique car un changement apparemment insignifiant a réduit la taille à la référence exactement. Prend environ 30s-60s par image.
Version golfée.
La seule décision qu'un compresseur GIF peut prendre est de réinitialiser le dictionnaire LZW. En général, en raison de la façon dont les images pour cette tâche ont été choisies, le meilleur moment pour le faire est chaque 4096 codes, c'est-à-dire le moment où le dictionnaire déborderait. Avec une telle limite, le dictionnaire ne déborde jamais, ce qui économise quelques octets dans l'implémentation. Voici comment cela fonctionne en détail:
Perl, 394 + -8 + 0 + -12 = 374
L'ajout d'une heuristique pour deviner le point de réinitialisation améliore un peu la compression mais pas assez pour justifier le code supplémentaire:
la source
CJam, score 155 + 35306 + 44723 + 21518 = 101702
Juste une implémentation de référence stupide. C'est lent, ne fait aucune compression réelle et ce n'est pas du golf.
la source