2017-07-23 4 views
0

J'essaie de lire un en-tête de fichier TGA avec Qt QDataStream. J'ai la structure suivante à partir des spécifications avec des types fixes:En-tête de lecture TGA avec 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) 

ouvrir un fichier avec QFile puis construire un QDataStream avec comme tel:

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); 

Le problème est avec la largeur et la hauteur que je reçois :

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 

et je devrais 1366 et 768. Si je HexDump le fichier que je reçois:

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

Ce qui est bizarre, car il a un octet supplémentaire au début et un autre manquant entre 0x0002 et 0x0556.

Mise à jour:
Utilisation des œuvres fstream, corrigez-moi si je me trompe, mais je pense que l'opérateur << ne fonctionne pas comme je l'attends à (lecture seule la taille nécessaire pour remplir la variable 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)); 

En utilisant QDataStream :: readRawData fonctionne aussi:

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

'stream >> header.id_lenght; ... est-ce une faute de frappe? Je crois que cela devrait être 'stream >> header.id_lenght >> ...'. – DimChtz

+0

Oui c'était une faute de frappe (corrigé) –

Répondre

0

Les données sont OK. Votre PC interprète les mots de 16 bits comme little-endian. Dans le fichier, ils sont stockés en tant que gros endians.

Pour tous les types de 16 bits, vous devez permuter les octets faible et élevé. Vous pouvez également utiliser les fonctions d'assistance à partir de Qt: http://doc.qt.io/qt-4.8/qtendian.html