Contexte
Il existe des .ZIP
fichiers auto-extractibles . En règle générale, ils ont l'extension .EXE
(et en exécutant le fichier, ils seront extraits), mais lorsque vous les renommez .ZIP
, vous pouvez ouvrir le fichier avec un logiciel d'extraction ZIP.
(Cela est possible car les .EXE
fichiers nécessitent un certain en-tête mais les .ZIP
fichiers nécessitent une certaine bande-annonce, il est donc possible de créer un fichier qui possède à la fois un en- .EXE
tête et une .ZIP
bande - annonce.)
Ta tâche:
Créez un programme qui crée des fichiers image "auto-affichés":
- Le programme doit prendre une image 64x64 (au moins 4 couleurs doivent être prises en charge) en entrée et un fichier "combiné" en sortie
- Le fichier de sortie du programme doit être reconnu comme fichier image par les visionneuses d'images courantes
- Lors de l'ouverture du fichier de sortie avec la visionneuse d'images, l'image d'entrée doit être affichée
Le fichier de sortie doit également être reconnu comme fichier exécutable pour tout système d'exploitation ou type d'ordinateur
(Si un fichier pour un système d'exploitation ou un ordinateur inhabituel est produit, ce serait bien si un émulateur de PC open source existe. Cependant, ce n'est pas nécessaire.)
- Lors de l'exécution du fichier de sortie, l'image d'entrée doit également être affichée
- Il est probable que renommer le fichier (par exemple de
.PNG
à.COM
) est nécessaire - Il n'est pas nécessaire que le programme et son fichier de sortie s'exécutent sur le même système d'exploitation; le programme peut par exemple être un programme Windows et des fichiers de sortie pouvant être exécutés sur un Commodore C64.
Critère gagnant
- Le programme qui produit le plus petit fichier de sortie gagne
- Si la taille du fichier de sortie diffère en fonction de l'image d'entrée (par exemple parce que le programme comprime l'image), le plus grand fichier de sortie possible créé par le programme représentant une image 64x64 avec jusqu'à 4 couleurs compte
Au fait
J'ai eu l'idée du puzzle de programmation suivant en lisant cette question sur StackOverflow.
la source
.exe
partie du défi, et lorsque vous le voyez comme.png
il y a des pixels modifiés basés sur ce.exe
code. Est-ce autorisé tant qu'il est encore.png
possible de le voir? L'image de sortie doit-elle également avoir au moins 4 couleurs?Réponses:
8086 Fichier .COM MS-DOS / BMP, taille du fichier de sortie = 2192 octets
Encodeur
L'encodeur est écrit en C. Il prend deux arguments: fichier d'entrée et fichier de sortie. Le fichier d'entrée est une image RVB 64x64 RAW (ce qui signifie qu'il s'agit simplement de 4096 triplets RVB). Le nombre de couleurs est limité à 4, afin que la palette puisse être aussi courte que possible. Il est très simple dans ses actions; il construit simplement une palette, regroupe des paires de pixels en octets et les colle avec des en-têtes prédéfinis et le programme de décodeur.
Fichier de sortie
Le fichier de sortie est un fichier BMP qui peut être renommé .COM et exécuté dans un environnement DOS. Lors de l'exécution, il passera en mode vidéo 13h et affichera l'image.
Un fichier BMP a un premier en-tête BITMAPFILEHEADER, qui contient entre autres le champ ImageOffset, qui indique où dans le fichier les données d'image commencent. Après cela vient BITMAPINFOHEADER avec diverses informations de décodage / encodage, suivies d'une palette, si une est utilisée. ImageOffset peut avoir une valeur qui pointe au-delà de la fin de tous les en-têtes, ce qui nous permet de faire un écart pour que le décodeur réside. En gros:
Un autre problème est d'entrer dans le décodeur. BITMAPFILEHEADER et BITMAPINFOHEADER peuvent être bricolés pour s'assurer qu'ils sont du code machine légal (qui ne produit pas un état non récupérable), mais la palette est plus délicate. Nous aurions bien sûr pu allonger artificiellement la palette et y mettre le code machine, mais j'ai choisi d'utiliser à la place les champs biXPelsPerMeter et biYPelsPerMeter, le premier pour aligner correctement le code et le second pour sauter dans le décodeur. Ces champs contiendront bien sûr des ordures, mais tout visualiseur d'images que j'ai testé affiche bien l'image. L'imprimer peut cependant produire des résultats particuliers.
Il est, pour autant que je sache, conforme aux normes.
On pourrait créer un fichier plus court si l'
JMP
instruction était placée dans l'un des champs réservés dans BITMAPFILEHEADER. Cela nous permettrait de stocker la hauteur de l'image sous -64 au lieu de 64, ce qui dans le monde magique des fichiers BMP signifie que les données d'image sont stockées dans le bon sens, ce qui permettrait à son tour un décodeur simplifié.Décodeur
Aucune astuce particulière dans le décodeur. La palette est remplie par l'encodeur et affichée ici avec des valeurs fictives. Il pourrait être légèrement plus court s'il ne revenait pas à DOS lors d'une pression sur une touche, mais ce n'était pas amusant de tester sans cela. Si vous le jugez nécessaire, vous pouvez remplacer les trois dernières instructions par
jmp $
pour économiser quelques octets. (N'oubliez pas de mettre à jour les en-têtes de fichier si vous le faites!)BMP stocke les palettes sous forme de triplets BGR (et non RVB), remplis de zéros. Cela rend la configuration de la palette VGA plus ennuyeuse que d'habitude. Le fait que les BMP soient stockés à l'envers ne fait qu'ajouter à la saveur (et à la taille).
Listé ici dans le style NASM:
la source
int 0x20
plusret
.