Реализуйте приложение ./hw-01_bmp
, которое вырезает прямоугольник из BMP-файла с изображением,
поворачивает этот прямоугольник на 90 градусов по часовой стрелке и сохраняет результат в отдельный
файл.
Все изображения (изначальное для чтения и сохранённый результат) хранятся в заданном формате:
- Общий формат — BMP.
- В рамках формата BMP используется формат DIB с заголовком
BITMAPINFOHEADER
(версия 3). - Значение поля
biHeight
(высота изображения) строго больше нуля. - Используются 24 бита цвета на пиксель (один байт на цветовой канал).
- Палитра (таблица цветов) не используется.
- Сжатие не используется.
Вам гарантируется, что система, для которой вы пишете решение, little endian, а также то, что прямое обращение к полям структур заголовков без выравнивания корректно (вы можете читать заголовки одной операцией чтения).
Таким образом, вам требуется обработать лишь один конкретный вид BMP-файлов, не требуется поддерживать все возможности формата.
В этом задании действуют стандартные и дополнительные требования:
- Программа обязана проверить корректность аргументов (смотри
консольное приложение).
- Достаточно проверить относительно тривиальные ошибки: выход за границы изображения и нехватку аргументов.
- Если один из аргументов оказывается не-числом вместо числа, поведение программы не определено (то есть вам не требуется это обрабатывать).
- При проблемах с аргументами, открытием файла, выделением памяти и прочим, программа должна корректно завершить работу и вернуть ненулевой код возврата.
- Тесты реализовывать не требуется.
- Поведение программы не определено, если либо входное, либо выходное изображение не является квадратом со стороной, делящейся на 4.
- Отклонения от формата не допускаются.
- Допускается отсутствие проверок аргументов.
- Допускаются утечки памяти, неидеальное разделение по файлам.
- Нельзя UB (но на усмотрение преподавателя иногда можно, уточняйте).
В качестве примера входного файла вам даны изображения lena_512.bmp
и
small-one.bmp
.
Также некоторые графические редакторы могут генерировать изображение в нужном формате
(«24-битное изображение BMP»), проверяйте поля в заголовках.
Гарантируется, что требования ниже выполняются для входного файла (в противном случае поведение вашей программы не определено):
- Если файл существует, то он строго следует формату.
- Файл помещается в память целиком с запасом хотя бы в три раза.
Требования к сохранённому изображению:
- Сохранённое изображение должно содержать ту же информацию в заголовках, что и исходное изображение, кроме необоходимых для изменения (например, размеры).
- При необходимости выравнивания данных, дописывайте именно нули.
- Файл не должен содержать избыточной информации или информации не в каноническом порядке.
Подсказки:
- Убедитесь, что вы корректно работаете с неквадратными изображениями.
- Убедитесь, что вы корректно работаете с изображениями со стороной, не делящейся на 4 (и при чтении, и при записи).
- Убедитесь, что вы открываете файл в режиме для бинарного ввода-вывода (
rb
иwb
вместоr
иw
), это влияет на корректность под Windows и на баллы за корректность.
Приложение запускается следующей командой:
./hw-01_bmp crop-rotate ‹in-bmp› ‹out-bmp› ‹x› ‹y› ‹w› ‹h›
Используемые параметры:
crop-rotate
— обязательный параметр, означающий выполняемое действие.in-bmp
— имя входного файла с изображением.out-bmp
— имя выходного файла с изображением.x
,y
— координаты левого верхнего угла области, которую необходимо вырезать и повернуть. Координаты начинаются с нуля, таким образом (0, 0) — это верхний левый угол.w
,h
— соотвественно, ширина и высота области до поворота.
Таким образом, если обозначить ширину и высоту исходного изображения за W
и H
, соответственно,
для корректных аргументов верны следующие неравенства:
0 <= x < x + w <= W
0 <= y < y + h <= H
- Файлы
bmp.c
иbmp.h
должны содержать работу с изображением, а именно функции:load_bmp
(заргузка изображения).crop
(вырезание фрагмента).rotate
(поворот).save_bmp
(сохранение изображения).
- Работу с аргументами и точку входа реализовать в
main.c
.
Если вам нужны дополнительные файлы (например, тестовые изображения), кладите их в папку samples
.
<корень-личного-репозитория>
|--hw-01_bmp
|--include
| |-- bmp.h
|--samples
| |-- test.bmp
|--src
| |-- bmp.c
| |-- main.c
|--Makefile
Папку obj
, объектные и исполняемые файлы класть в репозиторий не разрешается.
В дополнение к команде crop-rotate
реализуйте команды insert
и extract
,
позволяющие спрятать внутри изображения сообщение
(стеганография).
Команда insert
сохраняет в изображение сообщение, а extract
— извлекает его оттуда.
Идея следующая: если менять только самые младшие биты в цветовых компонентах, то сторонний наблюдатель не заметит искажения. Этим искажением можно скрыто передавать информацию.
Исходное сообщение состоит только из заглавных латинских букв, пробела, точки и запятой.
Каждый символ преобразовывается в число от 0 до 28, соответственно (всего 29 различных значений),
а число — в пять бит, записанных от младших к старшим.
Всего сообщение из N
символов кодируется при помощи 5N
Бит.
Для передачи сообщения, помимо изображения-носителя, потребуется ключ — текстовый файл, описывающий, в каких пикселях кодируются биты сообщения. В этом файле на отдельных строчках записаны:
- Координаты
x
иy
(0 <= x < W
,0 <= y < H
) пикселя, в который надо сохранить соответствующий бит. - Буква
R
/G
/B
обозначающая цветовой канал, в младшем бите которого требуется записать бит сообщения.
Если ключ записывает больше бит, чем нужно сообщению, последние строчки игнорируются.
Для сохранения секретной строчки в изображение приложение запускается следующей командой:
./hw-01_bmp insert ‹in-bmp› ‹out-bmp› ‹key-txt› ‹msg-txt›
Для извлечения секретной строчки из изображения приложение запускается следующей командой:
./hw-01_bmp extract ‹in-bmp› ‹key-txt› ‹msg-txt›
Используемые параметры:
in-bmp
— имя входного файла с изображением.out-bmp
— имя выходного файла с изображением.key-txt
— тестовый файл с ключом.msg-txt
— текстовый файл с секретным сообщением.
При этом остаются все остальные требования корректности: команда crop-rotate
, проверка аргументов
и прочие.
Реализуйте функции для стеганографии в отдельных файлах stego.h
/stego.c
.
Задание выдано 14.12.2020 (четверг). На задание даётся ровно три попытки сдачи. Сроки попыток уточняйте у преподавателя.
Ко второй попытке действуют требования к промежуточной попытке, чтобы получить возможность сдавать до крайнего срока.
Учтите, что в отличие от лабораторных:
- Это домашнее задание больше по сложности и объёму кода. Пожалуйста, не откладывайте даже до промежуточного срока сдачи.
- Вы можете сделать не больше трёх полноценных попыток за всё время сдачи. На усмотрение преподавателя могут добавляться промежуточные попытки, которые будут проверяться частично.
- Из-за объёма кода решения могут проверяться с существенной задержкой, особенно при наличии стилистических замечаний.
- Задание оценивается в 30 баллов: 20 за корректность, 10 за стиль.
- Вы можете получить ещё +10 баллов за бонусное задание, итого 40.