Lecture d'un fichier binaire (fichier C3D)

Lecture d'un fichier binaire (fichier C3D) - C++ - Programmation

Marsh Posté le 22-02-2006 à 23:58:32    

Bonsoir à tous,
 
pour un programme que je suis en train de développer, je dois extraire des informations d'un fichier C3D écrit en binaire, et qui contient des renseignements sur le résultat d'une capture de mouvement.
 
Le souci, c'est que je n'ai jamais eu à faire ce genre de lecture, et que je sais pas comment m'y prendre.
 
Pour commencer, je voudrais juste pouvoir extraire les infos de l'entête du fichier.
Dans la doc (http://www.c3d.org/HTML/default.htm), il y est dit que ce fichier est composé de multiples blocs de 512 bytes.
 

All C3D files contain a minimum of three sections of information:
-----------------------------------------------------------------
A single, 512 byte, header section
-----------------------------------------------------------------
A parameter section consisting of one, or more, 512-byte blocks.
-----------------------------------------------------------------
3D point/analog data section consisting of one, or more, 512-byte blocks.


 
Cette page me donne les différentes composantes de cet entête:
http://www.c3d.org/HTML/description.htm
 
On m'a filé un code en C qui lit cet entête, mais j'y pipe rien du tout, je vous la donne...
 

Code :
  1. #define RECORD 512
  2. typedef struct S_C3D {
  3.   int nbr_block_parameter;
  4.   int processor;
  5.   char **nom_block_parameter;
  6. } C3D;   
  7. C3D c3d;
  8. typedef struct matrice {
  9.   double **Mat;
  10. } MATRICE;   
  11.    
  12. typedef struct {
  13.   short cleffich;         // w0 Clef du fichier
  14.   short nbmarqs;          // w1 Nombre de marqueurs
  15.   short nbanalog;         // w2 Nombre de donnees analogiques par image video
  16.   short premimage;        // w3 Premiere image
  17.   short dernimage;        // w4 Derniere image
  18.   short maxinterpol;      // w5 Interpolation maximum (nombre d'images)
  19.   float echelle;          // w6-7 Facteur de conversion des donnees video stockees sous forme d'entiers
  20.   short debutdonnees;     // w8 Enregistrement de debut des donnees 1 enregistrement = 256 * word; 1 word = 16 bits
  21.   short freqanal;         // w9 frequence d'echantillonage analogique/donnees video
  22.   float freqvid;          // w10-11 frequence d'echantillonage video
  23.   short x1[137];          // w12-w148 inutilise
  24.   short clef;             // w149 mot clef (12345 octal typical value)
  25.   short nbevnttps;        // w150 nb d'evenements temps definis
  26.   short x2;               // w151 Number of defined time events
  27.   float fmtevnttps[18];   // w152-w187 dates evenements temporels (max 9-,pas 18!)
  28.   short fmtevntswitch[10];// w188-w197 byte switch de l evenement (0=on,1=off)
  29.   char labelevnt[9][8];   // w198-w233 label de l evenement sur 4 caracteres
  30.   short x3[22];           // w234-w255 inutilise
  31. }ENTETEC3D;
  32. typedef union {
  33.   long lg;
  34.   float flt;
  35.   int in[2];
  36.   char ch[4];
  37. }trans;
  38. int LgLabel,NbTraj;
  39. char *dim_label;
  40. char **p_label; // Labels des points
  41. trans tr;
  42. short Nbimage;
  43. char TempChar;
  44. // Implémentation
  45. float fltdecpc (char byt[4]) //  fonction donnee par Oxford pour transformer DEC en FLOAT .Recopiee integralement donc no comment !
  46. {
  47.   long mantis;
  48.   short exp;
  49.   float flt;
  50.   float *f;
  51.   switch (proc) {
  52.     case 0:
  53.        f = (float *) byt;
  54.        flt = *f;
  55.     break;
  56.    
  57.     case 1:
  58.       mantis = (byt[2] & 0xff) + ((byt[3] & 0xffl) << 8) + (((byt[0] & 0x7fl) | 0x80) << 16);
  59.       exp = (byt[1] & 0x7f) * 2 + ((byt[0] & 0x80) ? 1 : 0);
  60.       if (byt[1] & 0x80) mantis = -mantis;
  61.       flt = (mantis || exp) ? ((float) ldexp (mantis, (exp - 128 - 24))) : 0;
  62.     break;
  63.   }
  64.   return (flt);
  65. }
  66. void litentete (char *nomfich)
  67. {
  68.   char H[sizeof(ENTETEC3D)];     
  69.   ENTETEC3D *header;         
  70.   FILE *fich;
  71.   int i;
  72.   int n, G, m, n2, G2, d;
  73.   char *GroupName=NULL;
  74.   char *GroupDescription=NULL;
  75.   char *ParamName=NULL;
  76.   int *Dimensions=NULL;
  77.   short offset2, offset1;
  78.   if ((fich = OuvreFichier (nomfich, "rb", 0))!=NULL) {
  79.     header = (ENTETEC3D *)H;
  80.  
  81.     for (i=0; i<sizeof(ENTETEC3D); i++) H[i] = fgetc(fich);
  82.    
  83.     tr.flt = header->echelle;
  84.     header->echelle = fltdecpc(tr.ch);
  85.     tr.flt = header->freqvid;
  86.     header->freqvid = fltdecpc(tr.ch); 
  87.     Nbimage = header->dernimage - header->premimage + 1; 
  88.  
  89.     // Lecture des paramètres pour récuperer les noms des marqueurs correspondants à chaque trajectoire*/
  90.     fread (&TempChar, sizeof(char), 1, fich);  // Byte 1  
  91.     fread (&TempChar, sizeof(char), 1, fich);  // Byte 1  
  92.     fread (&TempChar, sizeof(char), 1, fich);  // Byte 1  
  93.     fread (&TempChar, sizeof(char), 1, fich);  // Byte 1  
  94.  
  95.     // header
  96.     // n
  97.     fread (&TempChar, sizeof(char), 1, fich); 
  98.     n = (int)TempChar;
  99.  
  100.     while (n!=0) {
  101.       // G
  102.       fread (&TempChar, sizeof(char), 1, fich);
  103.       G = (int)TempChar;
  104.    
  105.       // Group Name
  106.       GroupName = calloc (n+1, sizeof(*GroupName)); 
  107.       for (i=0;i<n;i++)
  108.         fread ((GroupName+i), sizeof(char), 1, fich);
  109.  
  110.       // offset
  111.       fread (&offset1, sizeof(short), 1, fich); 
  112.    
  113.       // m
  114.       fread (&TempChar, sizeof(char), 1, fich); 
  115.       m = (int)TempChar;
  116.  
  117.       if (m==0) fseek(fich,(offset1-3),SEEK_CUR); 
  118.       else {
  119.         GroupDescription = calloc (m, sizeof(*GroupDescription));  // Group Description
  120.         for (i=0;i<(m);i++)
  121.           fread ((GroupDescription+i), sizeof(char), 1, fich);
  122.         free (GroupDescription);
  123.       }
  124.    
  125.       // Paramètres
  126.       // n2
  127.       fread (&TempChar, sizeof(char), 1, fich); 
  128.       n2 = (int) TempChar;
  129.    
  130.       // G2  
  131.       fread (&TempChar, sizeof(char), 1, fich);   
  132.       G2 = (int) TempChar;
  133.    
  134.       while (G2 == -G) {
  135.         // Param Name  
  136.         ParamName = calloc (n2+1, sizeof(*ParamName));     
  137.         for (i=0; i<n2; i++)
  138.           fread (&ParamName[i], sizeof(ParamName[i]), 1, fich);
  139.      
  140.         // offset2   
  141.         fread (&offset2, sizeof(short), 1, fich);
  142.    
  143.         if ((strcmp(GroupName, "POINT" )==0) &&
  144.             (strcmp(ParamName, "LABELS" )==0)) {
  145.           // T  
  146.           fread (&TempChar, sizeof(char), 1, fich);
  147.      
  148.           // d   
  149.           fread (&TempChar, sizeof(char), 1, fich);
  150.           d = (int) TempChar;
  151.      
  152.           // Dimensions  
  153.           Dimensions = calloc (d, sizeof(*Dimensions));
  154.           for (i=0;i<d;i++) {
  155.             fread (&TempChar, sizeof(char), 1, fich);     
  156.             Dimensions[i] = (int)TempChar;
  157.           } 
  158.        
  159.           // lecture des labels
  160.           LgLabel = Dimensions[0];
  161.           NbTraj = Dimensions[1];
  162.           free (Dimensions);
  163.           fseek (fich, LgLabel*NbTraj, SEEK_CUR);  // on passe les labels  
  164.           // m2  
  165.           fread(&TempChar, sizeof(char), 1, fich);     
  166.           fseek(fich, (int)TempChar, SEEK_CUR); // on passe m2
  167.      
  168.           fread (&TempChar, sizeof(char), 1, fich);   // n2  
  169.           n2 = (int)TempChar;
  170.  
  171.           fread (&TempChar, sizeof(char), 1, fich);  // G2     
  172.           G2 = (int)TempChar;
  173.            
  174.         }
  175.         else {
  176.           free (ParamName);
  177.        
  178.           //  Passage au parametre suivant
  179.           fseek(fich,(offset2-2),SEEK_CUR);   
  180.           fread (&TempChar, sizeof(char), 1, fich);   // n2  
  181.           n2 = (int)TempChar;
  182.  
  183.           fread (&TempChar, sizeof(char), 1, fich);  // G2     
  184.           G2 = (int)TempChar;
  185.         }
  186.       }
  187.      
  188.       fseek (fich,(-2),SEEK_CUR);
  189.       free (GroupName);
  190.      
  191.       fread(&TempChar, sizeof(char), 1, fich);   // n  
  192.       n = (int) TempChar;
  193.     }
  194.     FermeFichier (&fich);
  195.   }
  196. }


 
 
Comment je peux lire correctement cet entête en bon C++?
 
Merci d'avance
 
Mike

Reply

Marsh Posté le 22-02-2006 à 23:58:32   

Reply

Marsh Posté le 23-02-2006 à 09:10:31    

ajoute une fonction int main(int argc, char **argv), appelle la en ligne de commande.
Dans cette fonction, tu dépouilles argv pour récupérer le nom du fichier c3d passé en paramètre, puis tu appelles "litentete(...)" avec le nom du fichier en paramètre.
Ensuite, tu modifies "litentete(...)" en rajoutant à la fin les printf des valeurs que tu souhaites visualiser.
 
C'est du chinois pour toi ou pas?
 
vw

Reply

Marsh Posté le 23-02-2006 à 11:51:06    

Non, c'est pas ça le souci.
 
Je voudrais savoir comment je peux au moins lire l'entête, qui est un bloc de 512 bytes de long, et qui a une structure correspondante à ENTETEC3D donnée dans le code, via la STL par exemple...
 
Je dois utiliser fstream pour lire un buffer de 512 bytes et transtyper tout ça en ENTETEC3D? Ou bien ya plus propre?

Reply

Marsh Posté le 23-02-2006 à 11:59:10    

ton en-tete doit etre une instance d'une classe qui fournit une méthode de déserialisation par exemple ?

Reply

Marsh Posté le 23-02-2006 à 12:57:33    

Ben je pense oui...
 
L'entête correspond à cette structure:
 

Code :
  1. typedef struct {
  2. short cleffich;         // w0 Clef du fichier
  3. short nbmarqs;          // w1 Nombre de marqueurs
  4. short nbanalog;         // w2 Nombre de donnees analogiques par image video
  5. short premimage;        // w3 Premiere image
  6. short dernimage;        // w4 Derniere image
  7. short maxinterpol;      // w5 Interpolation maximum (nombre d'images)
  8. float echelle;          // w6-7 Facteur de conversion des donnees video stockees sous forme d'entiers
  9. short debutdonnees;     // w8 Enregistrement de debut des donnees 1 enregistrement = 256 * word; 1 word = 16 bits
  10. short freqanal;         // w9 frequence d'echantillonage analogique/donnees video
  11. float freqvid;          // w10-11 frequence d'echantillonage video
  12. short x1[137];          // w12-w148 inutilise
  13. short clef;             // w149 mot clef (12345 octal typical value)
  14. short nbevnttps;        // w150 nb d'evenements temps definis
  15. short x2;               // w151 Number of defined time events
  16. float fmtevnttps[18];   // w152-w187 dates evenements temporels (max 9-,pas 18!)
  17. short fmtevntswitch[10];// w188-w197 byte switch de l evenement (0=on,1=off)
  18. char labelevnt[9][8];   // w198-w233 label de l evenement sur 4 caracteres
  19. short x3[22];           // w234-w255 inutilise
  20. }ENTETEC3D;


Message édité par haazheel le 23-02-2006 à 12:58:18
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed