Чтение заголовка TGA с помощью QDataStream

Я пытаюсь прочитать заголовок файла TGA с помощью Qt QDataStream. У меня есть следующая структура из спецификации с фиксированными типами:

#pragma pack(push, 1)
/* TGA header */
struct tga_header_t
{
quint8   id_lenght;            /* size of image id */
quint8   colormap_type;        /* 1 is has a colormap */
quint8   image_type;           /* compression type */

/* Color Map Specification */
quint16  cm_origin;            /* colormap origin */
quint16  cm_length;            /* colormap length */
quint8   cm_size;              /* colormap size */

/* Image Specification */
quint16  x_origin;           /* bottom left x coord origin */
quint16  y_origin;           /* bottom left y coord origin */
quint16  width;              /* picture width (in pixels) */
quint16  height;             /* picture height (in pixels) */
quint8   pixel_depth;        /* bits per pixel: 8, 16, 24 or 32 */
quint8   image_descriptor;   /* 24 bits = 0x00; 32 bits = 0x80 */
};
#pragma pack(pop)

Я открываю файл с помощью QFile, а затем создаю с ним QDataStream:

QFile file(path);
tga_header_t header;

file.open(QIODevice::ReadOnly);
QDataStream stream(&file);
stream >> header.id_lenght >>
header.colormap_type >>
header.image_type >>
header.cm_origin >>
header.cm_length >>
header.cm_size >>
header.x_origin >>
header.y_origin >>
header.width >>
header.height >>
header.pixel_depth >>
header.image_descriptor;
qDebug() << header.id_lenght << "id_lenght" <<
header.colormap_type << "colormap_type" <<
header.image_type << "image_type" <<
header.cm_origin << "cm_origin" <<
header.cm_length << "cm_length" <<
header.cm_size << "cm_size" <<
header.x_origin << "x_origin" <<
header.y_origin << "y_origin" <<
header.width << "width" <<
header.height << "height" <<
header.pixel_depth << "pixel_depth" <<
header.image_descriptor << "image_descriptor" <<
"SIZE:" << sizeof(header);

Проблема с шириной и высотой я получаю:

0 id_lenght 0 colormap_type 2 image_type 0 cm_origin 0 cm_length 0 cm_size 0 x_origin 0 y_origin 22021 width 3 height 24 pixel_depth 0 image_descriptor SIZE: 18

И я должен получить 1366 и 768. Если я hexdump файл, я получаю:

0000000 0000 0002 0000 0000 0000 0000 0556 0300
0000010 0018 0000 0000 0000 0000 0000 0000 0000

Что странно, потому что у него есть дополнительный байт в начале, а другой отсутствует где-то между 0x0002 а также 0x0556,

Обновить:
Использование fstream работает, так что поправьте меня, если я ошибаюсь, но я думаю, что << Оператор не работает так, как я ожидаю (читайте только размер, необходимый для заполнения переменной struct).

    stream.read((char*)&header.id_lenght, sizeof(header.id_lenght));
stream.read((char*)&header.colormap_type, sizeof(header.colormap_type));
stream.read((char*)&header.image_type, sizeof(header.image_type));
stream.read((char*)&header.cm_origin, sizeof(header.cm_origin));
stream.read((char*)&header.cm_length, sizeof(header.cm_length));
stream.read((char*)&header.cm_size, sizeof(header.cm_size));
stream.read((char*)&header.x_origin, sizeof(header.x_origin));
stream.read((char*)&header.y_origin, sizeof(header.y_origin));
stream.read((char*)&header.width, sizeof(header.width));
stream.read((char*)&header.height, sizeof(header.height));
stream.read((char*)&header.pixel_depth, sizeof(header.pixel_depth));
stream.read((char*)&header.image_descriptor, sizeof(header.image_descriptor));

Использование QDataStream :: readRawData также работает:

stream.readRawData((char*)&header.id_lenght, sizeof(header.id_lenght));
stream.readRawData((char*)&header.colormap_type, sizeof(header.colormap_type));
stream.readRawData((char*)&header.image_type, sizeof(header.image_type));
stream.readRawData((char*)&header.cm_origin, sizeof(header.cm_origin));
stream.readRawData((char*)&header.cm_length, sizeof(header.cm_length));
stream.readRawData((char*)&header.cm_size, sizeof(header.cm_size));
stream.readRawData((char*)&header.x_origin, sizeof(header.x_origin));
stream.readRawData((char*)&header.y_origin, sizeof(header.y_origin));
stream.readRawData((char*)&header.width, sizeof(header.width));
stream.readRawData((char*)&header.height, sizeof(header.height));
stream.readRawData((char*)&header.pixel_depth, sizeof(header.pixel_depth));
stream.readRawData((char*)&header.image_descriptor, sizeof(header.image_descriptor));

0

Решение

Данные в порядке. Ваш компьютер интерпретирует 16-битные слова как little-endian. В файле они хранятся как большие порядковые номера.

Для всех 16-битных типов вы должны поменять местами младшие / старшие байты. Вы также можете использовать вспомогательные функции из Qt: http://doc.qt.io/qt-4.8/qtendian.html

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]