Чтение файла с прямым порядком байтов 8 бит за раз и выполнение над ним двоичных операций
Я хочу читать по 8 бит за раз из файла в формате с прямым порядком байтов, я думаю, что мой процессор тоже с прямым порядком байтов, поэтому мне не нужно беспокоиться о порядке байтов, верно?
я читаю цифры, значения интенсивности RGGB CFA из файла RAW12.
Вот мой код -
uint8_t first8bits, second8bits, third8bits;
file.read((char*)&first8bits, sizeof(uint8_t));
file.read((char*)&second8bits, sizeof(uint8_t));
file.read((char*)&third8bits, sizeof(uint8_t));
Red_channel = (first8bits) << 4 | (second8bits & 0xF0) >> 4;
Green_channel = (second8bits & 0x0F) | (third8bits);
Я видел, как другие читали 8 бит в массив символов, а затем преобразовывали его в число, как мне это сделать? Поскольку машина, код которой я тестирую, имеет младший порядок байтов, я думаю, что мне не нужно делать байт-своп, но что, если кто-то другой тестирует этот код на машине с прямым порядком байтов, как мне найти во время выполнения, если машина имеет порядковый номер с прямым порядком байтов или порядковый номер?
Любая помощь мне бы очень понравилась.
2 ответа
Если вы на платформе posix, вы, вероятно, <endian.h>
Который наряду с этими функциями http://man7.org/linux/man-pages/man3/htole32.3.html предлагает макроопределения: __LITTLE_ENDIAN
, __BIG_ENDIAN
, __BYTE_ORDER
(вероятно, включен из glib / types.h или bits / types.h)
Таким образом, вы можете использовать препроцессор
#if __BYTE_ORDER == __LITTLE_ENDIAN
определить шаблоны или типы, которые при необходимости приводят к той или иной операции. Endiannes означает, что вы должны наблюдать: а) порядок байтов б) порядок битовых полей в структуре. Порядковый порядковый номер соответствует "байтовому" сетевому порядку, но в случае битовых полей на платформе с прямым порядком байтов первое определенное поле является наименее значимым, а при старшем порядке - наиболее значимым. Технически это не определено стандартом, но этот порядок "канонизируется" кодом ядра Linux и других ОС.
Если вы работаете в Windows, вы используете платформу с прямым порядком байтов. В ARM и MIPS все сложнее, поскольку CPU может в некоторой степени переключать свои байты. Вот почему эти библиотечные функции существуют.
Операции сдвига битов позволяют игнорировать порядок и могут использоваться, если вы будете иметь в виду, что операция сдвига битов автоматически переводит свой операнд в int
,
Код, который я использовал, правильный, другой способ сделать это может быть
char inBuf [3];
intputfile.read(inBuf, 3);
cfa[i][cnt] = ((uint8_t)inBuf[0]) << 4 | ((uint8_t)inBuf[1] & 0xF0) >> 4;
cfa[i][cnt+1] = ((uint8_t)inBuf[1] & 0x0F) << 8 | ((uint8_t)inBuf[2]);