Hintergrund
Es gibt selbstextrahierende .ZIP
Dateien. Normalerweise haben sie die Erweiterung .EXE
(und durch Ausführen der Datei werden sie extrahiert), aber wenn Sie sie umbenennen .ZIP
, können Sie die Datei mit einer ZIP-Extraktionssoftware öffnen.
(Dies ist möglich, weil für .EXE
Dateien ein bestimmter Header .ZIP
erforderlich ist, für Dateien jedoch ein bestimmter Trailer erforderlich ist, sodass eine Datei erstellt werden kann, die sowohl einen .EXE
Header als auch einen .ZIP
Trailer enthält.)
Deine Aufgabe:
Erstellen Sie ein Programm, das "selbstanzeigende" Bilddateien erstellt:
- Das Programm muss ein 64x64-Bild (mindestens 4 Farben werden unterstützt) als Eingabe und eine "kombinierte" Datei als Ausgabe verwenden
- Die Ausgabedatei des Programms wird von herkömmlichen Bildbetrachtern als Bilddatei erkannt
- Beim Öffnen der Ausgabedatei mit dem Bildbetrachter soll das Eingabebild angezeigt werden
Die Ausgabedatei muss auch als ausführbare Datei für jedes Betriebssystem oder jeden Computertyp erkannt werden
(Wenn eine Datei für ein ungewöhnliches Betriebssystem oder einen ungewöhnlichen Computer erstellt wird, wäre es schön, wenn ein Open-Source-PC-Emulator vorhanden wäre. Dies ist jedoch nicht erforderlich.)
- Bei der Ausführung der Ausgabedatei soll auch das Eingabebild angezeigt werden
- Es ist wahrscheinlich, dass die Datei umbenannt werden muss (z. B. von
.PNG
nach.COM
) - Es ist nicht erforderlich, dass das Programm und seine Ausgabedatei auf demselben Betriebssystem ausgeführt werden. Das Programm kann beispielsweise ein Windows-Programm und Ausgabedateien sein, die auf einem Commodore C64 ausgeführt werden können.
Gewinnkriterium
- Das Programm, das die kleinste Ausgabedatei erzeugt, gewinnt
- Wenn sich die Größe der Ausgabedatei je nach Eingabebild unterscheidet (z. B. weil das Programm das Bild komprimiert), zählt die vom Programm erstellte größtmögliche Ausgabedatei, die ein 64 x 64-Bild mit bis zu 4 Farben darstellt
Apropos
Ich hatte die Idee für das folgende Programmierpuzzle, als ich diese Frage auf StackOverflow las .
quelle
.exe
Teil der Herausforderung eine Art Code hinzu , und wenn wir ihn als betrachten,.png
gibt es modifizierte Pixel, die auf diesem.exe
Code basieren . Ist das erlaubt, solange.png
wir es noch sehen können? Muss das Ausgabebild auch mindestens 4 Farben haben?Antworten:
8086 MS-DOS .COM-Datei / BMP, Ausgabedateigröße = 2192 Byte
Encoder
Der Encoder ist in C geschrieben. Er benötigt zwei Argumente: Eingabedatei und Ausgabedatei. Die Eingabedatei ist ein 64 x 64 RAW-RGB-Bild (dh es handelt sich einfach um 4096 RGB-Triplets). Die Anzahl der Farben ist auf 4 begrenzt, damit die Palette so kurz wie möglich ist. Es ist sehr unkompliziert in seinen Handlungen; Es erstellt lediglich eine Palette, packt Pixelpaare in Bytes und klebt sie mit vorgefertigten Headern und dem Decoderprogramm zusammen.
Ausgabedatei
Die Ausgabedatei ist eine BMP-Datei, die in .COM umbenannt und in einer DOS-Umgebung ausgeführt werden kann. Nach der Ausführung wechselt es in den Videomodus 13h und zeigt das Bild an.
Eine BMP-Datei hat einen ersten Header BITMAPFILEHEADER, der unter anderem das Feld ImageOffset enthält, das angibt, wo in der Datei die Bilddaten beginnen. Danach folgt BITMAPINFOHEADER mit verschiedenen Ent- / Kodierungsinformationen, gefolgt von einer Palette, falls eine verwendet wird. ImageOffset kann einen Wert haben, der über das Ende von Headern hinaus zeigt, sodass wir eine Lücke für den Decoder schließen können. Grob:
Ein weiteres Problem ist die Eingabe des Decoders. BITMAPFILEHEADER und BITMAPINFOHEADER können bearbeitet werden, um sicherzustellen, dass es sich um legalen Maschinencode handelt (der keinen nicht wiederherstellbaren Status erzeugt), aber die Palette ist schwieriger. Wir hätten die Palette natürlich künstlich verlängern und den Maschinencode dort platzieren können, aber ich habe mich dafür entschieden, stattdessen die Felder biXPelsPerMeter und biYPelsPerMeter zu verwenden, wobei erstere den Code richtig ausrichten und letztere in den Decoder springen. Diese Felder enthalten dann natürlich Müll, aber jeder Bildbetrachter, mit dem ich getestet habe, zeigt das Bild einwandfrei an. Das Drucken kann jedoch zu besonderen Ergebnissen führen.
Soweit ich weiß, ist es standardkonform.
Man könnte eine kürzere Datei erstellen, wenn die
JMP
Anweisung in eines der reservierten Felder in BITMAPFILEHEADER gestellt würde. Dies würde es uns ermöglichen, die Bildhöhe als -64 anstelle von 64 zu speichern, was im magischen Wunderland der BMP-Dateien bedeutet, dass die Bilddaten richtig hoch gespeichert werden, was wiederum einen vereinfachten Decoder ermöglichen würde.Decoder
Keine besonderen Tricks im Decoder. Die Palette wird vom Encoder ausgefüllt und hier mit Dummy-Werten angezeigt. Es könnte etwas kürzer sein, wenn es bei einem Tastendruck nicht zu DOS zurückkehrt, aber es hat keinen Spaß gemacht, ohne das zu testen. Wenn Sie dies für erforderlich halten, können Sie die letzten drei Anweisungen durch ersetzen
jmp $
, um einige Bytes zu sparen. (Vergessen Sie nicht, die Datei-Header zu aktualisieren, wenn Sie dies tun!)BMP speichert Paletten als BGR- Triplets ( nicht RGB-Triplets), die mit Nullen aufgefüllt sind. Dies macht das Einrichten der VGA-Palette ärgerlicher als gewöhnlich. Die Tatsache, dass BMPs verkehrt herum gelagert werden, trägt nur zum Geschmack (und zur Größe) bei.
Hier im NASM-Stil aufgeführt:
quelle
int 0x20
ret