Фон
Есть самораспаковывающиеся .ZIP
файлы. Обычно они имеют расширение .EXE
(и, выполнив файл, они будут извлечены), но при переименовании их .ZIP
можно открыть файл с помощью некоторого программного обеспечения для извлечения ZIP.
(Это возможно, потому что для .EXE
файлов требуется определенный заголовок, но для .ZIP
файлов требуется определенный трейлер, поэтому можно создать файл, который имеет как .EXE
заголовок, так и .ZIP
трейлер.)
Твое задание:
Создайте программу, которая создает «самоотображаемые» файлы изображений:
- Программа должна взять некоторое изображение 64x64 (должно поддерживаться не менее 4 цветов) в качестве входных данных и некоторый «комбинированный» файл в качестве выходных
- Выходной файл программы должен быть распознан как файл изображения обычными программами просмотра изображений.
- При открытии выходного файла с помощью средства просмотра изображений, входное изображение должно отображаться
Выходной файл также должен распознаваться как исполняемый файл для любой операционной системы или типа компьютера.
(Если создается файл для необычной операционной системы или компьютера, было бы неплохо, если бы существовал эмулятор ПК с открытым исходным кодом. Однако это не требуется.)
- При выполнении выходного файла, входное изображение также должно отображаться
- Вероятно, необходимо переименовать файл (например, из
.PNG
в.COM
) - Не обязательно, чтобы программа и ее выходной файл работали в одной и той же ОС; программа может, например, быть программой Windows и выходными файлами, которые могут быть выполнены на Commodore C64.
Критерий победы
- Программа, которая производит наименьший выходной файл, выигрывает
- Если размер выходного файла различается в зависимости от входного изображения (например, из-за того, что программа сжимает изображение), создается максимально большой выходной файл, созданный программой, представляющий изображение размером 64x64 с количеством цветов до 4
Кстати
При чтении этого вопроса в StackOverflow у меня возникла идея следующей головоломки программирования .
источник
.exe
части задачи, и при просмотре его в виде.png
измененных пикселей на основе этого.exe
кода. Разрешено ли это до тех пор, пока.png
мы можем его просматривать? У выходного изображения также должно быть как минимум 4 цвета?Ответы:
8086 MS-DOS .COM файл / BMP, размер выходного файла = 2192 байта
кодировщик
Кодировщик написан на C. Он принимает два аргумента: входной файл и выходной файл. Входной файл представляет собой изображение RAW RGB размером 64x64 (то есть это просто 4096 триплетов RGB). Количество цветов ограничено 4, поэтому палитра может быть как можно короче. Это очень прямолинейно в своих действиях; он просто строит палитру, упаковывает пары пикселей в байты и склеивает ее вместе с заранее созданными заголовками и программой декодера.
Выходной файл
Выходной файл представляет собой файл BMP, который можно переименовать в .COM и запустить в среде DOS. После выполнения он переключится в режим видео 13h и отобразит изображение.
Файл BMP имеет первый заголовок BITMAPFILEHEADER, который содержит среди прочего поле ImageOffset, которое указывает, где в файле начинаются данные изображения. После этого идет BITMAPINFOHEADER с различной информацией о дешифровании / кодировании, за которой следует палитра, если она используется. ImageOffset может иметь значение, которое указывает за пределы конца любых заголовков, что позволяет нам сделать промежуток для декодера, чтобы находиться в нем. Примерно:
Другая проблема заключается в том, чтобы войти в декодер. С BITMAPFILEHEADER и BITMAPINFOHEADER можно совместить, чтобы убедиться, что они являются допустимым машинным кодом (который не создает невосстановимое состояние), но палитра более хитрая. Конечно, мы могли бы искусственно увеличить палитру и поместить туда машинный код, но вместо этого я решил использовать поля biXPelsPerMeter и biYPelsPerMeter, первые для правильного выравнивания кода, а последние - для перехода в декодер. Эти поля, конечно, будут содержать мусор, но любой просмотрщик изображений, с которым я тестировал, отображает изображение нормально. Однако печать может привести к особым результатам.
Насколько я знаю, он соответствует стандартам.
Можно создать более короткий файл, если
JMP
инструкция была помещена в одно из зарезервированных полей в BITMAPFILEHEADER. Это позволило бы нам сохранить высоту изображения как -64 вместо 64, что в волшебной стране чудес BMP-файлов означает, что данные изображения хранятся правильно, что, в свою очередь, позволило бы упростить декодер.дешифратор
Никаких особых хитростей в декодере. Палитра заполняется кодером и отображается здесь с фиктивными значениями. Он может быть немного короче, если он не вернется в DOS после нажатия клавиши, но без этого тестирование было неинтересным. Если вы чувствуете, что должны, вы можете заменить последние три инструкции,
jmp $
чтобы сохранить несколько байтов. (Не забудьте обновить заголовки файлов, если вы это сделаете!)BMP хранит палитры как триплеты BGR ( не RGB), дополненные нулями. Это делает настройку VGA-палитры более раздражающей, чем обычно. Тот факт, что BMP хранятся в обратном порядке, только добавляет вкуса (и размера).
Перечислено здесь в стиле NASM:
источник
int 0x20
болееret
.