Добрый день.
Помогите разобраться в вопросе определения длины файла BMP.
Суть вот в чем, по каналу связи принимается байтовый поток(данные) от сервера. Данные представляют собой команды и последовательность данных. Приняв порцию данных, определяем тип команды. В зависимости от типа команды сохраняем полученные данные в файл.
Одной из команд сервера является передача растрового файла в формате BMP. И вот возникла проблема с сохранением данных в файл формата BMP.
Алгоритм такой, анализируем первые 54 байта. В поле bfSize указывается весь размер данных(размер файла BMP). На основании этого числа за вычетом (54) считываем из потока нужное количество байт. Записываем заголовок + считанные данные в файл и должен получиться графический файл в формате BMP.
Но что-то не так получается. Просмотреть файл в графическом вьювере не получается, пишет ошибка.
Предполагаю, что неправильно определяю длину данных.
На основании данных из заголовка пытаюсь альтернативным способом определить длину данных и результат вычисления не совпадает с bfSize.
bfSize = biSizeImage + 54
Как правильно определить длину.
К серверу доступа нет. Посмотреть файл BMP до передачи по сети тоже нет возможности.
Первое, что бросается в глаза: неверный порядок байт. В оригинале должен быть 0x42 0x4D. Может не переводите (или наоборот, переводите) из/в сетевого порядка в обычный?
Здравствуйте, wbear, Вы писали:
W>Суть вот в чем, по каналу связи принимается байтовый поток(данные) от сервера. Данные представляют собой команды и последовательность данных. Приняв порцию данных, определяем тип команды. В зависимости от типа команды сохраняем полученные данные в файл.
W>Одной из команд сервера является передача растрового файла в формате BMP. И вот возникла проблема с сохранением данных в файл формата BMP.
W>Алгоритм такой, анализируем первые 54 байта. В поле bfSize указывается ...
А нафига козе баян? Если вы принимаете поток данных от сервера там и должна быть длинна. Зачем вы анализируете принятые данные? Это же совсем другой уровень.
W>Как правильно определить длину.
Она должна приходить от сервера, и не зависить от того bmp это или webp или какой еще тип данных.
W>К серверу доступа нет. Посмотреть файл BMP до передачи по сети тоже нет возможности.
Могу предположить что вы записываете данные в файл не так как они пришли. В C++ для этого есть множество возможностей
W>>0x4D42 ; bfType DP>Первое, что бросается в глаза: неверный порядок байт. В оригинале должен быть 0x42 0x4D. Может не переводите (или наоборот, переводите) из/в сетевого порядка в обычный?
это же обычный uint16 считанный как LE
W>Алгоритм такой, анализируем первые 54 байта. В поле bfSize указывается весь размер данных(размер файла BMP). На основании этого числа за вычетом (54) считываем из потока нужное количество байт. Записываем заголовок + считанные данные в файл и должен получиться графический файл в формате BMP.
Зачем 54 байта? Проверить первые два байта подходящие 0x42 и 0x4D, затем взять следующие 4 байта длины, и сохранить указанное количество включая эти первые 6 байт. Типа такого:
1. копим буфер пока не наберётся как минимум 6 байт, допустим считалось len
2. проверяем 0x4D42 == (uint16_t&)buf[0]
3. получаем total = (uint32_t&)buf[2]
4. записываем в файл содержимое буфера длиной min(total, len)
5. копируем из потока в файл ещё total — min(total, len) байт
W>На основании данных из заголовка пытаюсь альтернативным способом определить длину данных и результат вычисления не совпадает с bfSize. W>bfSize = biSizeImage + 54
Конечно не совпадает, ибо bfSize = bfOffBits + biSizeImage. Там после заголовка ещё палитра может быть и какой-то ещё хлам.
Здравствуйте, wbear, Вы писали:
W>Добрый день. W>Помогите разобраться в вопросе определения длины файла BMP.
W>Суть вот в чем, по каналу связи принимается байтовый поток(данные) от сервера. Данные представляют собой команды и последовательность данных. Приняв порцию данных, определяем тип команды. В зависимости от типа команды сохраняем полученные данные в файл.
W>Одной из команд сервера является передача растрового файла в формате BMP. И вот возникла проблема с сохранением данных в файл формата BMP.
W>Приведу пример первых 54 байт получаемых данных из потока: W>0x4D42 ; bfType W>0x0000518E ; bfSize W>0x00000000 ; bfReserved W>0x00000436 ; bfOffBits W>0x00000028 ; biSize W>0x0000018A ; biWidth W>0x00000032 ; biHeght W>0x0001 ; biPlanes W>0x0008 ; biBitCount W>0x00000000 ; biCompression W>0x00004D58 ; biSizeImage W>0x00000EC4 ; biXPilsPerMeter W>0x00000EC4 ; biYPilsPerMeter W>0x00000000 ; biClrUsed W>0x00000000 ; biClrImportant
W>Алгоритм такой, анализируем первые 54 байта. В поле bfSize указывается весь размер данных(размер файла BMP). На основании этого числа за вычетом (54) считываем из потока нужное количество байт. Записываем заголовок + считанные данные в файл и должен получиться графический файл в формате BMP.
W>Но что-то не так получается. Просмотреть файл в графическом вьювере не получается, пишет ошибка.
W>Предполагаю, что неправильно определяю длину данных.
W>На основании данных из заголовка пытаюсь альтернативным способом определить длину данных и результат вычисления не совпадает с bfSize. W>bfSize = biSizeImage + 54
W>Как правильно определить длину.
W>К серверу доступа нет. Посмотреть файл BMP до передачи по сети тоже нет возможности.
bfOffBits
The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
bfSize = bfOffBits + biSizeImage
20878 = 1078 + 19800 те. весь файл 20878, заголовок 1078, rgb 19800, все вроде бы сходится
можно попробовать сохранить данные без заголовка и потом посмотреть их каким нибудь редактором в сыром виде
W>>Алгоритм такой, анализируем первые 54 байта. В поле bfSize указывается ... _>А нафига козе баян? Если вы принимаете поток данных от сервера там и должна быть длинна. Зачем вы анализируете принятые данные? Это же совсем другой уровень.
Сервер просто отправляет в сеть информацию. Разработчика создали вот такой протокол со своей спецификой передаваемых данных. Задача стоит в том чтобы разобраться с передаваемыми данными.
W>>Как правильно определить длину. _>Она должна приходить от сервера, и не зависить от того bmp это или webp или какой еще тип данных.
Общий пакет содержит и длину данных и CRC для проверки целостности данных. Там все впорядке.
W>>К серверу доступа нет. Посмотреть файл BMP до передачи по сети тоже нет возможности. _>Могу предположить что вы записываете данные в файл не так как они пришли. В C++ для этого есть множество возможностей
Как оказалось делаю все правильно. Просто разработчики системы определили что файл BMP является контейнером для хранения структурированных данных. О чем на момент написания первичного поста я не знал. И предолагал что должен после записи данных в файл увидеть что то "внятное". Оказалось что это не так
DS>Зачем 54 байта? Проверить первые два байта подходящие 0x42 и 0x4D, затем взять следующие 4 байта длины, и сохранить указанное количество включая эти первые 6 байт. Типа такого:
Анализ первых 54 байт делается в отладочных целях. Просто можно сразуже на глаз определить что считанные данные являются заголовком BMP файла или же это является мусором.
Здравствуйте, alexander_r, Вы писали:
_>bfSize = bfOffBits + biSizeImage
_>20878 = 1078 + 19800 те. весь файл 20878, заголовок 1078, rgb 19800, все вроде бы сходится
Спасибо. Просто за несколько дней глаз замылился на данных и коде.
Хороший сон и кружка горячего шоколада позволили оценить свою бестолковость.
_>можно попробовать сохранить данные без заголовка и потом посмотреть их каким нибудь редактором в сыром виде
Разработчики системы определили что файл BMP является контейнером для хранения структурированных данных. О чем на момент написания первичного поста я не знал. И предолагал что должен после записи данных в файл увидеть что то "внятное". Оказалось что это не так.