Разбор файла BMP

forfrends
Offline
Зарегистрирован: 24.02.2015
Всем привет!
Пытаюсь разобраться в структуре файла BMP, но что-то не сходится. Прикрепляю архив с двумя BMP файлами, с которыми провожу эксперименты. https://radiokot.ru/forum/download/file.php?id=335351
Файлы идентичны, с той лишь разницей, что o1.bmp создан в фотошопе. Потом я его открыл в Паинте и без редактирования сохранил под другим именем: o0.bmp.
Открываю обе картинки в Блокноте и вижу что они разные:
Смотрю в таблицу:
 
Пробую узнать размер файла (6 494 байт o0.bmp, и 6 496 байт o1.bmp):
Size: длина: 4 байта, смещение 2 байта:
o0.bmp : "^ "
o1.bmp : "` "
 
Для o0.bmp это символы в таблице ASCII https://istarik.ru/blog/programmirovanie/53.html:
94 - 01011110
25 - 00011001
32 - 00100000
32 - 00100000
 
Для o1.bmp это символы в таблице ASCII:
96 - 01100000
25 - 00011001
32 - 00100000
32 - 00100000
 
Как из этого набора символов получить размер файла?
Дальше интереснее и не понятнее (для меня). Пробую узнать ширину и высоту (384х134 пикселя):
 
Width: длина 4 байта, смещение 18 байт
Height: длина 4 байта, смещение 22 байт
Отсчитываю байты, получаю (они одинаковы у обоих файлов):
Width: "Ђ "
128 - 10000000
1 - 00000001
32 - 00100000
32 - 00100000
 
Height: "† "
134 - 10000110
32 - 00100000
32 - 00100000
32 - 00100000
 
Как из этого набора символов получить Ширину и высоту?
И т.д... На пример, Смещение изображения от начала файла: "> ", символ ASCII "64" и еще несколько "32"... как из этого высчитать начало самой картинки???
Если можете, разъясните мне. Спасибо
sadman41
Offline
Зарегистрирован: 19.10.2016

 

forfrends
Offline
Зарегистрирован: 24.02.2015

Спасибо, разобрался, сначала идет младший байт, а потом старший, а я считал наоборот, из-за этого и не сходилось

kalapanga
Offline
Зарегистрирован: 23.10.2016

Для начала размер. 4 байта со смещения 2 это в шестнадцатеричной системе:

1) 60 19 00 00 -> читать так -> 00 00 19 60 -> в десятичной -> 6496

2) 5E 19 00 00 -> читать так -> 00 00 19 5E -> в десятичной -> 6494

Ну и остальное наверное как-то в таком же духе.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

kalapanga пишет:

Для начала размер. 4 байта со смещения 2 это в шестнадцатеричной системе:

1) 60 19 00 00 -> читать так -> 00 00 19 60 -> в десятичной -> 6496

2) 5E 19 00 00 -> читать так -> 00 00 19 5E -> в десятичной -> 6494

Ну и остальное наверное как-то в таком же духе.

Вот эти 4 со смещением два - единственная шляпа в бмпешке. Все остальное легко разруливается с помощью структур. Найти вменяемый мануал сильно сложно. Кроме того 3-3-3 и 3-4-3 отличаются единственным флагом, об этом вообще мало где упоминают.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Афигеть!

Я бы начал с того, что в строке поиска набрал "bmp file format", После чего, вероятно, почитал бы https://ru.wikipedia.org/wiki/BMP

PS. Честно говоря, с BMP работаю уже не первый десяток лет и могу сказать, что среди десятков форматов, для которых я писал ридеры, BMP - один из самых простых. И самое главно, этот формат - лучше всего описанный.

forfrends
Offline
Зарегистрирован: 24.02.2015

Продолжая тему.

Конечно, тем кто работал с данным форматом, будет проще. А вот я столкнулся с непонятками. Вот Картинка, размеры 4х4 пикселя. Битовый формат (глубина цвета - 1 бит): https://drive.google.com/file/d/1t16BW-vl-S1LOHdhHzaIns5lHlK3myx5/view?usp=sharing

Картинка выглядит так:

Содержимое файла:

 

Байт №2 - размер файла (в байтах): 50 - 80 байт
Байт №10 - начальная позиция массива картинки: 3E - 62-й байт
Байт №18 - ширина картинки: 04 - 4 пикселя
Байт №22 - высота картинки:  04 - 4 пикселя

вроде все правильно и совпадает.
Начинаю читать содержимое массива, и получаем не 16 байт (4х4 пикселя) а 18 (до конца файла)! Откуда лишние 2 байта?
Что еще мне не понятно, если взять байты 62, 66, 70 и 74 (и посмотреть их битовое представление), то получим нашу картинку. А для чего тогда остальные, нулевые байты? Я правильно понимаю что таблица создается кратной 4-м байтам?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Если правильно помню - строки кратно некоторому количеству байт.

forfrends
Offline
Зарегистрирован: 24.02.2015

Да, только что проверил, создал файл по-больше и посмотрел его содержимое. Все верно, строки создаются кратными 4-м байтам, вне зависимости от размера картинки. Вот из-за этого не мог понять откуда взялись  нулевые байты. Теперь придется как-то в алгоритме это учесть.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

forfrends пишет:

Байт №2 - размер файла (в байтах): 50 - 80 байт

...

Начинаю читать содержимое массива, и получаем не 16 байт (4х4 пикселя) а 18 (до конца файла)! Откуда лишние 2 байта?

Что еще мне не понятно, если взять байты 62, 66, 70 и 74 (и посмотреть их битовое представление), то получим нашу картинку. А для чего тогда остальные, нулевые байты? Я правильно понимаю что таблица создается кратной 4-м байтам?

Вот только что специально создал в Пэйнте такой файл. Длина - 78 байтов.

 

forfrends
Offline
Зарегистрирован: 24.02.2015

Все зависит от того в какой программе создаете. Проверял: разные программы создают оду и ту же картинку, но с разными размерами файла

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Это странно. Формат не предусматривает свободы в определении размера файла. Свобода есть в том, что считать цветом 0, а что - цветом 1. Соответственно, меняется содержимое палитры и содержимое данных (и, кстати, это в Вашем и моем файлах решено по-разному), но на длину это влиять не должно.

PS. Помнится, я как-то в своей программе, пишущей BMP файлы, допустил ошибку, и как раз связанную с длиной. Так вот, обнаружил я ее не сразу, т.к. программы отображения вполне себе показывали мои файлы, хотя они и содержали ошибки. Возможно, здесь тот же случай.