Antecedentes
Hay .ZIP
archivos autoextraíbles . Por lo general, tienen la extensión .EXE
(y al ejecutar el archivo se extraerán), pero al cambiarles el nombre .ZIP
, puede abrir el archivo con algún software de extracción ZIP.
(Esto es posible porque los .EXE
archivos requieren un determinado encabezado pero los .ZIP
archivos requieren un cierto avance, por lo que es posible crear un archivo que tenga un .EXE
encabezado y un .ZIP
avance).
Tu tarea:
Cree un programa que cree archivos de imagen "auto-mostrados":
- El programa tomará alguna imagen de 64x64 (se admitirán al menos 4 colores) como entrada y algún archivo "combinado" como salida
- El archivo de salida del programa será reconocido como archivo de imagen por los espectadores de imagen comunes
- Al abrir el archivo de salida con el visor de imágenes, se mostrará la imagen de entrada.
El archivo de salida también se reconocerá como archivo ejecutable para cualquier sistema operativo o tipo de computadora
(Si se produce un archivo para un sistema operativo o computadora poco común, sería bueno que exista un emulador de PC de código abierto. Sin embargo, esto no es necesario).
- Al ejecutar el archivo de salida, también se mostrará la imagen de entrada.
- Es probable que sea necesario cambiar el nombre del archivo (por ejemplo, de
.PNG
a.COM
) - No es necesario que el programa y su archivo de salida se ejecuten en el mismo sistema operativo; el programa puede ser, por ejemplo, un programa de Windows y archivos de salida que se pueden ejecutar en un Commodore C64.
Criterio ganador
- El programa que produce el archivo de salida más pequeño gana
- Si el tamaño del archivo de salida difiere según la imagen de entrada (por ejemplo, porque el programa comprime la imagen), el archivo de salida más grande posible creado por el programa representa una imagen de 64x64 con hasta 4 colores.
Por cierto
Tuve la idea del siguiente rompecabezas de programación al leer esta pregunta en StackOverflow.
fuente
.exe
parte del desafío, y cuando lo vemos como un.png
hay píxeles modificados basados en este.exe
código. ¿Está permitido siempre.png
que podamos verlo? ¿La imagen de salida también debe tener al menos 4 colores?Respuestas:
8086 MS-DOS .COM archivo / BMP, tamaño del archivo de salida = 2192 bytes
Codificador
El codificador está escrito en C. Toma dos argumentos: archivo de entrada y archivo de salida. El archivo de entrada es una imagen RAW RGB de 64x64 (lo que significa que es simplemente 4096 tripletes RGB). El número de colores está limitado a 4, por lo que la paleta puede ser lo más corta posible. Es muy sencillo en sus acciones; simplemente construye una paleta, empaqueta pares de píxeles en bytes y los pega junto con encabezados prefabricados y el programa decodificador.
Archivo de salida
El archivo de salida es un archivo BMP que se puede renombrar como .COM y ejecutarse en un entorno DOS. Tras la ejecución, cambiará al modo de video 13h y mostrará la imagen.
Un archivo BMP tiene un primer encabezado BITMAPFILEHEADER, que contiene entre otras cosas el campo ImageOffset, que indica en qué parte del archivo comienzan los datos de la imagen. Después de esto viene BITMAPINFOHEADER con diversa información de descodificación / codificación, seguida de una paleta, si se usa una. ImageOffset puede tener un valor que apunta más allá del final de cualquier encabezado, lo que nos permite hacer un espacio para que el decodificador resida. Aproximadamente:
Otro problema es ingresar al decodificador. BITMAPFILEHEADER y BITMAPINFOHEADER pueden manipularse para asegurarse de que sean códigos de máquina legales (que no producen un estado no recuperable), pero la paleta es más complicada. Por supuesto, podríamos haber hecho la paleta artificialmente más larga y poner el código de la máquina allí, pero opté por usar los campos biXPelsPerMeter y biYPelsPerMeter, el primero para alinear el código correctamente y el segundo para saltar al decodificador. Por supuesto, estos campos tendrán basura, pero cualquier visor de imágenes que haya probado muestra la imagen bien. Sin embargo, imprimirlo puede producir resultados peculiares.
Es, hasta donde yo sé, cumple con los estándares.
Se podría hacer un archivo más corto si la
JMP
instrucción se coloca en uno de los campos reservados en BITMAPFILEHEADER. Esto nos permitiría almacenar la altura de la imagen como -64 en lugar de 64, lo que en el país de las maravillas mágicas de los archivos BMP significa que los datos de la imagen se almacenan correctamente, lo que a su vez permitiría un decodificador simplificado.Descifrador
No hay trucos particulares en el decodificador. La paleta se completa con el codificador y se muestra aquí con valores ficticios. Podría ser un poco más corto si no volviera a DOS al presionar una tecla, pero no fue divertido probar sin eso. Si cree que debe hacerlo, puede reemplazar las últimas tres instrucciones con
jmp $
para guardar algunos bytes. (¡No olvides actualizar los encabezados de los archivos si lo haces!)BMP almacena paletas como tripletas BGR ( no RGB), rellenadas con ceros. Esto hace que configurar la paleta VGA sea más molesto de lo habitual. El hecho de que las BMP se almacenen al revés solo aumenta el sabor (y el tamaño).
Listado aquí en estilo NASM:
fuente
int 0x20
másret
.