Многобайтовые символьные константы и константы типа заголовка растрового файла - PullRequest
2 голосов
/ 02 марта 2009

У меня есть некоторый существующий код, который я использовал для записи изображения в файл растрового изображения. Одна из строк кода выглядит так:

bfh.bfType='MB';

Я думаю, что, вероятно, скопировал это откуда-то. Один из других разработчиков говорит мне: «это выглядит неправильно, разве это не должно быть« BM »?» В любом случае, кажется, что все работает нормально, но при проверке кода это переформулируется так:

bfh.bfType=*(WORD*)"BM";

Поиск в Google показывает, что большую часть времени, кажется, используется первая строка, а иногда люди делают это:

bfh.bfType=0x4D42;

Так в чем же разница? Как все они могут дать правильный результат? Что означает многобайтовая символьная константа? Они действительно одинаковы?

Ответы [ 3 ]

5 голосов
/ 02 марта 2009

Все три (вероятно) эквивалентны, но по разным причинам.

bfh.bfType=0x4D42;

Это проще всего понять, он просто загружает bfType числом, которое соответствует ASCII 'M' в битах 8-15 и ASCII 'B' в битах 0-7. Если вы записываете это в поток в формате с прямым порядком байтов, тогда поток будет содержать «B», «M».

bfh.bfType='MB';

Это по сути эквивалентно первому утверждению - это просто другой способ выражения целочисленной константы. Вероятно, это зависит от того, что именно с ним делает компилятор, но он, вероятно, сгенерирует значение в соответствии с порядком номера машины, на которой вы компилируете. Если вы компилируете и выполняете на машине с тем же порядком байтов, то когда вы записываете значение в поток, вы должны получить «B», «M».

bfh.bfType=*(WORD*)"BM";

Здесь "BM" заставляет компилятор создать блок данных, который выглядит как 'B', 'M', '\ 0', и получает символ *, указывающий на него. Затем он преобразуется в WORD *, чтобы при разыменовании он считывал память как WORD. Следовательно, он читает «B», «M» в bfType в любой последовательности, в которой находится машина. Запись этого с использованием того же порядка байтов, очевидно, поместит «B», «M» в ваш поток. Пока вы используете только bfType для записи в поток, это самая переносимая версия. Однако, если вы выполняете какие-либо сравнения / etc с bfType, то, вероятно, лучше выбрать для него порядок байтов и при необходимости преобразовать при чтении или записи значения.

1 голос
/ 02 марта 2009

Я не нашел API, но согласно http://cboard.cprogramming.com/showthread.php?t=24453, bfType является растровым заголовком. Значение BM, скорее всего, будет означать «растровое изображение».

0x4D42 - шестнадцатеричное значение (0x4D для M и 0x42 для B). В способе записи little endian (сначала байт с наименьшим значением) это будет то же самое, что и "BM" (не "MB"). Если он также работает с «МБ», то, вероятно, используется какое-то значение по умолчанию.

0 голосов
/ 02 марта 2009

Добавление к сообщению tehvan :

Из записи Википедии о BMP :

Заголовок файла Обратите внимание, что первые два байта формата файла BMP (таким образом, заголовок BMP) хранятся в порядке с прямым порядком байтов. Это магическое число «БМ». Все остальные целочисленные значения хранятся в формате с прямым порядком байтов (т. Е. Сначала младший байт).

Таким образом, похоже, что измененный код является правильным в соответствии со спецификацией.

Вы пытались открыть файл с «МБ» в качестве магического числа в нескольких разных фоторедакторах?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...