openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
IGBheader.cc
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // openCARP is an open cardiac electrophysiology simulator.
3 //
4 // Copyright (C) 2020 openCARP project
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <https://www.gnu.org/licenses/>.
18 // ----------------------------------------------------------------------------
19 
20 
23 #include<cstdlib>
24 #include<cstdio>
25 #include<iostream>
26 #include "IGBheader.h"
27 #include <cassert>
28 #include <cmath>
29 #include <cfloat>
30 
31 using namespace std;
32 
33 // -------------- Bits de statut pour Header_Read et Header_Write ------ */
34 #define MOT_CLEF_INV 2
35 #define GRANDEUR_INV 4
36 
37 /*
38  * Types de trames
39  */
40 #define MIN_TRAME 0
41 #define C8 0
42 #define C4 1
43 #define HEX 2
44 #define HEXEDGES 3
45 #define HEXBRIDGES 4
46 #define HEXLINES 5
47 #define HEX2 6
48 #define MAX_TRAME 6
49 #define NTRAMES 7
50 
51 #define LF 0x0A
52 #define FF 0x0C
53 #define CR 0x0D
54 
55 /*---------------------------------------------------------------------------*\
56 
57  y x-> 1 2 3 4 5
58  |
59  v
60  X|X|X|X|X|X
61  1 -o-o-o-o-o-
62  X|X|X|X|X|X
63  2 -o-o-o-o-o-
64  \|/ X|X|X|X|X|X
65 C8: -o- 3 -o-o-o-o-o-
66  /|\ X|X|X|X|X|X
67  4 -o-o-o-o-o-
68  X|X|X|X|X|X
69  5 -o-o-o-o-o-
70  X|X|X|X|X|X
71 
72 \*---------------------------------------------------------------------------*/
73 /*---------------------------------------------------------------------------*\
74 
75  y x-> 1 2 3 4 5
76  |
77  v
78  | | | | |
79  1 -o-o-o-o-o-
80  | | | | |
81  2 -o-o-o-o-o-
82  | | | | | |
83 C4: -o- 3 -o-o-o-o-o-
84  | | | | | |
85  4 -o-o-o-o-o-
86  | | | | |
87  5 -o-o-o-o-o-
88  | | | | |
89 
90 \*---------------------------------------------------------------------------*/
91 /*---------------------------------------------------------------------------*\
92 
93  y x-> 1 2 3 4 5 1 2 3 4 5
94  |
95  v 1 2 3 4 5
96 
97  \|\|\|\|\| \ / \ / \ / \ / \ /
98  1 -o-o-o-o-o- -o---o---o---o---o---
99  \| /|/|/|/|/|/ / \ / \ / \ / \ / \ /
100  y impair -o- 2 -o-o-o-o-o- ---o---o---o---o---o-
101  /| \|\|\|\|\|\ \ / \ / \ / \ / \ / \
102 HEX: 3 -o-o-o-o-o- -o---o---o---o---o---
103  |/ /|/|/|/|/|/ / \ / \ / \ / \ / \ /
104  y pair -o- 4 -o-o-o-o-o- ---o---o---o---o---o-
105  |\ \|\|\|\|\|\ \ / \ / \ / \ / \ / \
106  5 -o-o-o-o-o- -o---o---o---o---o---
107  /|/|/|/|/| / \ / \ / \ / \ / \
108 
109 \*---------------------------------------------------------------------------*/
110 /*---------------------------------------------------------------------------*\
111 
112  x x-> 1 2 3 4 5 1 2 3 4 5 6
113 
114  impair pair 1 2 3 4 5
115 
116  y 1 2 3 4 5
117  |
118  \| v 1 2 3 4 5
119  y%4==1 -o- -o-
120  /| \| \| \| \ / . \ / . \ / .
121  1 -o-o-o-o-o- -o---o---o---o---o---o
122  | / /| /| /| / \ . / \ . / \ .
123  y%4==2 o o 2 o o o o o o o o o o
124  | / |/ |/ |/ . \ / . \ / . \
125 HEXEDGES: 3 -o-o-o-o-o- -o---o---o---o---o---o
126  |/ |\ |\ |\ . / \ . / \ . /
127  y%4==3 -o- -o- 4 o o o o o o o o o o
128  |\ \| \| \| \ / . \ / . \ / .
129  5 -o-o-o-o-o- -o---o---o---o---o---o
130  | \ /| /| /| / \ . / \ . / \ .
131  y%4==0 o o 6 o o o o o o o o o o
132  | \ |/ |/ | . \ / . \ / . \
133 
134 \*---------------------------------------------------------------------------*/
135 /*---------------------------------------------------------------------------*\
136 
137  x x-> 1 2 3 4 5 1 2 3 4 5 6
138 
139 
140  impair pair 1 2 3 4 5
141 
142 
143  y 1 2 3 4 5
144  |
145  v
146  y%4==1 o -o- 1 2 3 4 5
147  . . .
148  1 o -o- o -o- o o -o- o -o- o -o
149  . . .
150  | / | / | / | \ . . / \ . . / \ .
151  y%4==2 o o 2 o o o o o o o o o o
152  | / | / | / | . \ / . . \ / . . \
153  . . .
154 HEXBRIDGES: 3 o -o- o -o- o -o- o -o- o -o- o
155  . . .
156  | \ | \ | . / \ . . / \ . . /
157  y%4==3 o -o- 4 o o o o o o o o o o
158  | \ | \ | / . . \ / . . \ / .
159  . . .
160  5 o -o- o -o- o o -o- o -o- o -o
161  . . .
162  | \ | / | / | \ . . / \ . . / \ .
163  y%4==0 o o 6 o o o o o o o o o o
164  | \ | / | / | . \ / . . \ / . . \
165 
166 \*---------------------------------------------------------------------------*/
167 /*---------------------------------------------------------------------------*\
168 
169  x x-> 1 2 3 4 5 1 2 3 4 5 6
170 
171  impair pair 1 2 3 4 5
172 
173  y 1 2 3 4 5
174  |
175  \| v 1 2 3 4 5
176  y%4==1 o o
177  /| \| \| \./ \./ \./
178  1 o o o o o o o o o o o
179  / | /| /| / /.\ /.\ /.\
180  y%4==2 -o- -o- 2 -o-o-o-o-o- ---o---o---o---o---o---
181  / | / |/ |/ \./ \./ \./
182 HEXLINES: 3 o o o o o o o o o o o
183  |/ |\ |\ /.\ /.\ /.\
184  y%4==3 o o 4 -o-o-o-o-o- ---o---o---o---o---o---
185  |\ \| \| \./ \./ \./
186  5 o o o o oo o o o o o o
187  \ | /| /| / /.\ /.\ /.\
188  y%4==0 -o- -o- 6 -o-o-o-o-o- ---o---o---o---o---o---
189  \ | / |/ |/ / \./ \./
190 
191 \*---------------------------------------------------------------------------*/
192 /*---------------------------------------------------------------------------*\
193 
194  x-> 1 2 3 4 5 1 2 3 4 5 6
195 
196  y 1 2 3 4 5
197  |
198  v 1 2 3 4 5
199 
200  \| 1 2 3 4 5
201  y%4==1 -o-
202  /| \|\|\|\|\| \ / \ / \ / \ / \ /
203  1 -o-o-o-o-o- -o---o---o---o---o---o
204  |/ /|/|/|/|/| / \ / \ / \ / \ / \ /
205  y%4==2 -o- 2 -o-o-o-o-o- ---o---o---o---o---o-
206  /| /|/|/|/|/|/ \ / \ / \ / \ / \ / \
207 HEX2: 3 -o-o-o-o-o- -o---o---o---o---o---o
208  |/ \|\|\|\|\| / \ / \ / \ / \ / \ /
209  y%4==3 -o- 4 -o-o-o-o-o- ---o---o---o---o---o-
210  |\ \|\|\|\|\| \ / \ / \ / \ / \ / \
211  5 -o-o-o-o-o- -o---o---o---o---o---o
212  \| /|/|/|/|/| / \ / \ / \ / \ / \ /
213  y%4==0 -o- 6 -o-o-o-o-o- ---o---o---o---o---o-
214  |\ /|/|/|/|/| / \ / \ / \ / \ / \
215 
216 \*---------------------------------------------------------------------------*/
217 
218 // -------------- Definitions pour conv_date --------------------------- */
219 
220 #define FRANCAIS 0
221 #define ANGLAIS 1
222 #define NUMERIQUE 2
223 #define IGB_DATE 0
224 
225 // -------------- Constantes diverses ---------------------------------- */
226 
227 #define MAXL 80 // Longueur maximale d'une ligne d'entete */
228 #define N_MAX_ITEMS 30 // Nombre maximal d'items optionnels */
229 #define L_MAX_ITEM 49 // Longueur maximale pour un item
230 #ifndef VRAI
231 #define VRAI 1
232 #endif
233 #ifndef FAUX
234 #define FAUX 0
235 #endif
236 
237 
238 int my_fputs( FILE *, char * );
239 
240 bool Header_Quiet = false;
241 char Header_Message[256];
242 
243 const char *Header_Type[] =
244  {
245  "", "byte", "char", "short", "long", "float", "double", "complex",
246  "double_complex", "rgba", "structure", "pointer", "list","int","uint",
247  "ushort",
248  "vec3f","vec3d","vec4f","vec4d","hfloat","vec9f","vec9d"
249  };
250 
251 
253 const char *deprecated[] = {
254  "fac_x", "fac_y", "fac_z", "fac_t"
255  };
256 
257 //* size of the stored data, not the variable type
258 const size_t Data_Size[] =
259  {
260  0, sizeof(Byte), sizeof(char), sizeof(short), sizeof(long), sizeof(float),
261  sizeof(double), 0, 0, 0, 0, sizeof(void *), 0, sizeof(int), sizeof(UInt),
262  sizeof(unsigned short),
263  3*sizeof(float), 3*sizeof(double), 4*sizeof(float), 4*sizeof(double),
264  sizeof(short_float), 9*sizeof(float), 9*sizeof(double)
265  };
266 
267 
269 const unsigned short Num_Components[] =
270  {
271  0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 3, 3, 4, 4, 1, 9, 9
272  };
273 
274 
275 const unsigned long
277  {
280  };
281 
282 const char
284  {
285  "big_endian",
286  "little_endian"
287  };
288 
289 
290 static bool
291 is_deprecated( char *s ) {
292  for( size_t i=0; i<sizeof(deprecated)/sizeof(deprecated[0]); i++ )
293  if( !strcmp( s, deprecated[i] ) )
294  return true;
295  return false;
296 }
297 
298 #define MAKE_CONSISTENT( D ) \
299  if( bool_dim_##D && bool_inc_##D && bool_##D ) \
300  if( !almost_equal(v_dim_##D, v_inc_##D * (v_##D-1) ) ) { \
301  fprintf( stderr, "Adjusting dim_%s to make dimensions consistent\n", #D ); \
302  v_dim_##D = v_inc_##D * (v_##D-1);\
303  }
304 
305 
306 IGBheader::IGBheader( FILE *f, bool _read, bool quiet )
307 {
308  fileptr(f);
309  if( _read )
310  if( read( quiet ) )
311  throw 1;
312 }
313 
314 
315 IGBheader::IGBheader( gzFile f, bool _read, bool quiet )
316 {
317  fileptr(f);
318  if( _read )
319  if( read( quiet ) )
320  throw 1;
321 }
322 
323 
325 {}
326 
327 
328 // set gzip-compressed input
329 void IGBheader::fileptr( gzFile fp )
330 {
331  file = fp;
332  gzipping = true;
333 }
334 
335 // set uncompressed input/output
336 void IGBheader::fileptr( FILE* fp )
337 {
338  file = fp;
339  gzipping = false;
340 }
341 
342 
344 {
345  int statut = 1;
346 
347  if (getenv("HEADER_QUIET")) Header_Quiet = VRAI;
348 
349  if (file==NULL) {
350  if (!Header_Quiet)
351  cerr<< "\nERREUR: descripteur de fichier nul\n";
352  snprintf(Header_Message, sizeof Header_Message, "\nERREUR: descripteur de fichier nul\n");
353  return(0) ;
354  }
355 
356  if (gzipping) {
357  if (!Header_Quiet)
358  cerr << "\nCompressed IGB output is not supported\n";
359  snprintf(Header_Message, sizeof Header_Message,
360  "\nCompressed IGB output is not supported\n");
361  return 0;
362  }
363 
364  if (v_type<IGB_MIN_TYPE || v_type>IGB_MAX_TYPE) {
365  if (!Header_Quiet)
366  cerr<< "\nHeader_Write: type inconnu: "<< v_type;
367  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: type inconnu: %d\n",
368  v_type);
369  return (0);
370  }
371  const char *type = Header_Type[v_type];
372 
373  if (v_type==IGB_STRUCTURE && v_taille<1) {
374  if (!Header_Quiet)
375  cerr << "\nHeader_Write: taille invalide:" << v_taille << endl;
376  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: taille invalide: %d\n",
377  v_taille);
378  return (0);
379  }
380 
381  if (v_trame<MIN_TRAME || v_trame>MAX_TRAME) {
382  if (!Header_Quiet)
383  fprintf(stderr, "\nHeader_Write: trame inconnue: %d\n", v_trame);
384  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: trame inconnue: %d\n",
385  v_trame);
386  return (0);
387  }
388 
389  MAKE_CONSISTENT( x );
390  MAKE_CONSISTENT( y );
391  MAKE_CONSISTENT( z );
392  MAKE_CONSISTENT( t );
393 
394  char ligne[1024];
395  if (bool_t) {
396  if (bool_z) {
397  snprintf(ligne, sizeof ligne, "x:%zu y:%zu z:%zu t:%zu type:%s systeme:%s ",
398  v_x, v_y, v_z, v_t, type, systemestr());
399  } else {
400  snprintf(ligne, sizeof ligne, "x:%zu y:%zu t:%zu type:%s systeme:%s ",
401  v_x, v_y, v_t, type, systemestr());
402  }
403  } else {
404  if (bool_z) {
405  snprintf(ligne, sizeof ligne, "x:%zu y:%zu z:%zu type:%s systeme:%s ",
406  v_x, v_y, v_z, type, systemestr());
407  } else {
408  snprintf(ligne, sizeof ligne, "x:%zu y:%zu type:%s systeme:%s ",
409  v_x, v_y, type, systemestr());
410  }
411  }
412  int n_car = strlen(ligne);
413 
414  int n_lignes = 1;
415  int n_items = 0;
416  int l_item[N_MAX_ITEMS+1];
417  char items[N_MAX_ITEMS+1][L_MAX_ITEM];
418  /*
419  Le mot-clef "taille" n'est ecrit que pour le type STRUCTURE mais il est
420  obligatoire pour ce cas.
421  */
422  if (v_type==IGB_STRUCTURE) {
423  snprintf(&items[n_items][0], L_MAX_ITEM, "taille:%d ", v_taille);
424  l_item[n_items] = strlen(&items[n_items][0]);
425  n_items++;
426  }
427  if (bool_org_x) {
428  snprintf(&items[n_items][0], L_MAX_ITEM, "org_x:%g ", v_org_x);
429  l_item[n_items] = strlen(&items[n_items][0]);
430  n_items++;
431  }
432  if (bool_org_y) {
433  snprintf(&items[n_items][0], L_MAX_ITEM, "org_y:%g ", v_org_y);
434  l_item[n_items] = strlen(&items[n_items][0]);
435  n_items++;
436  }
437  if (bool_org_z) {
438  snprintf(&items[n_items][0], L_MAX_ITEM, "org_z:%g ", v_org_z);
439  l_item[n_items] = strlen(&items[n_items][0]);
440  n_items++;
441  }
442  if (bool_org_t) {
443  snprintf(&items[n_items][0], L_MAX_ITEM, "org_t:%g ", v_org_t);
444  l_item[n_items] = strlen(&items[n_items][0]);
445  n_items++;
446  }
447  if (bool_dim_x) {
448  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_x:%g ", v_dim_x);
449  l_item[n_items] = strlen(&items[n_items][0]);
450  n_items++;
451  }
452  if (bool_inc_x) {
453  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_x:%g ", v_inc_x);
454  l_item[n_items] = strlen(&items[n_items][0]);
455  n_items++;
456  }
457  if (bool_dim_y) {
458  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_y:%g ", v_dim_y);
459  l_item[n_items] = strlen(&items[n_items][0]);
460  n_items++;
461  }
462  if (bool_inc_y) {
463  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_y:%g ", v_inc_y);
464  l_item[n_items] = strlen(&items[n_items][0]);
465  n_items++;
466  }
467  if (bool_dim_z) {
468  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_z:%g ", v_dim_z);
469  l_item[n_items] = strlen(&items[n_items][0]);
470  n_items++;
471  }
472  if (bool_inc_z) {
473  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_z:%g ", v_inc_z);
474  l_item[n_items] = strlen(&items[n_items][0]);
475  n_items++;
476  }
477  if (bool_dim_t) {
478  snprintf(&items[n_items][0], L_MAX_ITEM, "dim_t:%g ", v_dim_t);
479  l_item[n_items] = strlen(&items[n_items][0]);
480  n_items++;
481  }
482  if (bool_inc_t) {
483  snprintf(&items[n_items][0], L_MAX_ITEM, "inc_t:%g ", v_inc_t);
484  l_item[n_items] = strlen(&items[n_items][0]);
485  n_items++;
486  }
487  if (bool_vect_z) {
488  snprintf(&items[n_items][0], L_MAX_ITEM, "vect_z:1 ");
489  l_item[n_items] = strlen(&items[n_items][0]);
490  n_items++;
491  }
492  if (bool_unites_x) {
493  snprintf(&items[n_items][0], L_MAX_ITEM, "unites_x:%.40s ", v_unites_x);
494  l_item[n_items] = strlen(&items[n_items][0]);
495  n_items++;
496  }
497  if (bool_unites_y) {
498  snprintf(&items[n_items][0], L_MAX_ITEM, "unites_y:%.40s ", v_unites_y);
499  l_item[n_items] = strlen(&items[n_items][0]);
500  n_items++;
501  }
502  if (bool_unites_z) {
503  snprintf(&items[n_items][0], L_MAX_ITEM, "unites_z:%.40s ", v_unites_z);
504  l_item[n_items] = strlen(&items[n_items][0]);
505  n_items++;
506  }
507  if (bool_unites_t) {
508  snprintf(&items[n_items][0], L_MAX_ITEM, "unites_t:%.40s ", v_unites_t);
509  l_item[n_items] = strlen(&items[n_items][0]);
510  n_items++;
511  }
512  if (bool_num) {
513  snprintf(&items[n_items][0], L_MAX_ITEM, "num:%d ", v_num);
514  l_item[n_items] = strlen(&items[n_items][0]);
515  n_items++;
516  }
517  if (bool_bin) {
518  snprintf(&items[n_items][0], L_MAX_ITEM, "bin:%d ", v_bin);
519  l_item[n_items] = strlen(&items[n_items][0]);
520  n_items++;
521  }
522  if (bool_trame) {
523  switch (v_trame) {
524  case C8:
525  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:c8 ");
526  break;
527  case C4:
528  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:c4 ");
529  break;
530  case HEX:
531  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:hex ");
532  break;
533  case HEXEDGES:
534  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:hexedges ");
535  break;
536  case HEXBRIDGES:
537  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:hexbridges ");
538  break;
539  case HEXLINES:
540  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:hexlines ");
541  break;
542  case HEX2:
543  snprintf(&items[n_items][0], L_MAX_ITEM, "trame:hex2 ");
544  break;
545  }
546  l_item[n_items] = strlen(&items[n_items][0]);
547  n_items++;
548  }
549  if (bool_lut) {
550  snprintf(&items[n_items][0], L_MAX_ITEM, "lut:%d ", v_lut);
551  l_item[n_items] = strlen(&items[n_items][0]);
552  n_items++;
553  }
554  if (bool_comp) {
555  snprintf(&items[n_items][0], L_MAX_ITEM, "comp:%d ", v_comp);
556  l_item[n_items] = strlen(&items[n_items][0]);
557  n_items++;
558  }
559  if (bool_epais) {
560  snprintf(&items[n_items][0], L_MAX_ITEM, "epais:%g ", v_epais);
561  l_item[n_items] = strlen(&items[n_items][0]);
562  n_items++;
563  }
564  if (bool_unites) {
565  snprintf(&items[n_items][0], L_MAX_ITEM, "unites:%.40s ", v_unites);
566  l_item[n_items] = strlen(&items[n_items][0]);
567  n_items++;
568  }
569  if (bool_facteur) {
570  snprintf(&items[n_items][0], L_MAX_ITEM, "facteur:%g ", v_facteur);
571  l_item[n_items] = strlen(&items[n_items][0]);
572  n_items++;
573  }
574  if (bool_zero) {
575  snprintf(&items[n_items][0], L_MAX_ITEM, "zero:%g ", v_zero);
576  l_item[n_items] = strlen(&items[n_items][0]);
577  n_items++;
578  }
579  if ( v_transparent != NULL ) {
580  char *p=(char *)v_transparent, value[MAXL];
581  int a;
582  for ( a=0; a<Data_Size[v_type]; a++ )
583  snprintf( value+a*2, MAXL, "%0.2x", *(p++) );
584  value[2*Data_Size[v_type]] = '\0';
585  snprintf(&items[n_items][0], L_MAX_ITEM, "transparent:%s ", value );
586  l_item[n_items] = strlen(&items[n_items][0]);
587  n_items++;
588  }
589  if (bool_struct_desc) {
590  snprintf(&items[n_items][0], L_MAX_ITEM, "struct:%.40s ", v_struct_desc);
591  l_item[n_items] = strlen(&items[n_items][0]);
592  n_items++;
593  }
594  if (bool_aut_name) {
595  snprintf(&items[n_items][0], L_MAX_ITEM, "aut:%.40s ", v_aut_name);
596  l_item[n_items] = strlen(&items[n_items][0]);
597  n_items++;
598  }
599  int n_car_total = 0;
600  int n_comment = 0;
601  char **comment;
602  if (bool_comment) {
603  comment = v_comment;
604  while (*comment != NULL) {
605  n_comment++;
606  n_car_total += strlen(*comment++) + 3;
607  }
608  }
609 
610  /*
611  Ecrit tous les items, sauf les commentaires
612  */
613  for (int i=0;i<n_items;i++) {
614  if (n_car+l_item[i]<71) { /* Ajoute a la ligne courante s'il reste de la place */
615  strcat(ligne, &items[i][0]);
616  n_car += l_item[i];
617  } else { /* Sinon, ecrit cette ligne et commence-en une autre */
618  ligne[n_car++] = '\r';
619  ligne[n_car++] = '\n';
620  ligne[n_car] = '\000';
621  n_car_total += n_car;
622  if (puts_fcn( ligne)==-1) {
623  if (!Header_Quiet) {
624  fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n");
625  perror("\n *** ");
626  fprintf(stderr, "\n");
627  }
628  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: Erreur a l'ecriture \n");
629  return (0);
630  }
631  strcpy(ligne, &items[i][0]);
632  n_car = l_item[i];
633  n_lignes++;
634  }
635  }
636 
637  /*
638  Termine la derniere ligne
639  */
640  ligne[n_car++] = '\r';
641  ligne[n_car++] = '\n';
642  ligne[n_car] = '\000';
643  n_car_total += n_car;
644  if (puts_fcn( ligne )==-1) {
645  if (!Header_Quiet) {
646  fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n");
647  perror("\n *** ");
648  fprintf(stderr, "\n");
649  }
650  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: Erreur a l'ecriture \n");
651  return (0);
652  }
653  n_lignes++;
654 
655  /*
656  Determine le nombre de caracteres et de lignes supplementaires
657  necessaires
658  */
659  int n_blocs = 1 + (n_car_total-1)/1024;
660  int n_car_sup = n_blocs*1024 - n_car_total;
661  int n_lig_sup;
662  if (n_car_sup>0) {
663  n_lig_sup = 1 + (n_car_sup-1)/72;
664  } else {
665  n_lig_sup = 0;
666  }
667  int n_car_dl = 1 + (n_car_sup-1)%72;
668 
669  /*
670  Ecrit les commentaires
671  */
672  if (bool_comment) {
673  comment = v_comment;
674  while (*comment != NULL) {
675  n_car = fprintf((FILE*)file, "#%.80s\r\n", *comment++);
676  if (n_car==0) {
677  if (!Header_Quiet) {
678  fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n");
679  perror("\n *** ");
680  fprintf(stderr, "\n");
681  }
682  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: Erreur a l'ecriture \n");
683  return (0);
684  }
685  }
686  }
687 
688  /*
689  Complete l'entete a un multiple de 1024 caracteres
690  */
691  for (int i=0;i<70;i++) ligne[i] = ' ';
692  ligne[70] = '\r';
693  ligne[71] = '\n';
694  ligne[72] = '\000';
695  for (int i=0;i<n_lig_sup-1;i++) {
696  if (puts_fcn( ligne)==-1) {
697  if (!Header_Quiet) {
698  fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n");
699  perror("\n *** ");
700  fprintf(stderr, "\n");
701  }
702  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: Erreur a l'ecriture \n");
703  return 0;
704  }
705  }
706 
707  /*
708  La derniere ligne se termine par un saut de page (FF)
709  */
710  for (int i=0;i<n_car_dl-2;i++) ligne[i] = ' ';
711  if (n_car_dl>2) ligne[n_car_dl-3] = '\r';
712  if (n_car_dl>1) ligne[n_car_dl-2] = '\n';
713  ligne[n_car_dl-1] = FF;
714  ligne[n_car_dl] = '\000';
715  if (puts_fcn( ligne )==-1) {
716  if (!Header_Quiet) {
717  fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n");
718  perror("\n *** ");
719  fprintf(stderr, "\n");
720  }
721  snprintf(Header_Message, sizeof Header_Message, "\nHeader_Write: Erreur a l'ecriture \n");
722  return (0);
723  }
724 
725  if (n_car_total>1024) {
726  if (!Header_Quiet)
727  fprintf(stderr,
728  "\nHeader_Write ATTENTION: etiquette de grandeur non-standard \n");
729  snprintf(Header_Message, sizeof Header_Message,
730  "\nHeader_Write ATTENTION: etiquette de grandeur non-standard \n");
731  statut |= GRANDEUR_INV;
732  } else {
733  snprintf(Header_Message, sizeof Header_Message,
734  "\nHeader_Write: Entete transcrite sans problemes\n");
735  }
736 
737  return (statut);
738 
739 }
740 
741 
750 int IGBheader::read( bool quiet )
751 {
752  int go=VRAI, nosup=VRAI;
753  int in, com=0;
754  char str[MAXL+1];
755  int statut=0;
756  float v_fac_t;
757  bool bool_fac_t = false;
758 
759  Header_Quiet = quiet;
760 
761  /* --- pour toutes les lignes de l'entete (def=8) ou jusqu'a un <FF> -- */
762  for ( int s=8; (s>0 || nosup) && go; s-- ) {
763 
764  /* --- lit la ligne dans le fichier --- */
765  int i = 0 ;
766  if( tell()<0 ) return 2;
767 
768  while (1) {
769 
770  /* --- (ligne trop longue) --> erreur --- */
771  if ( i >= 80 ) {
772  if (!Header_Quiet)
773  fprintf(stderr,
774  "\nERREUR ligne trop longue (>80) dans l'entete !\n" ) ;
775  snprintf(Header_Message, sizeof Header_Message,
776  "\nERREUR ligne trop longue (>80) dans l'entete !\n" ) ;
777  return ERR_LINE_TOO_LONG;
778  }
779 
780  /* --- lit le caractere suivant --- */
781  in = get_character() ;
782 
783  /* --- (EOF dans l'entete) --> erreur --- */
784  if ( in == -1 ) {
785  if (!Header_Quiet)
786  fprintf(stderr,
787  "\nERREUR Fin de fichier dans l'entete !\n" ) ;
788  snprintf(Header_Message, sizeof Header_Message,
789  "\nERREUR Fin de fichier dans l'entete !\n" ) ;
790  return ERR_EOF_IN_HEADER;
791  }
792 
793  /* --- FF --> termine le header --- */
794  else if ( in == FF ) {
795  str[i] = '\000' ;
796  go = FAUX ;
797  break ;
798  }
799 
800  /* --- CR et LF --> termine la ligne --- */
801  else if ( in == CR ) {
802  str[i] = '\000' ;
803  } else if ( in == LF ) {
804  str[i] = '\000' ;
805  break ;
806  }
807 
808  /* --- (0x20 < caractere > 0x7E) si non --> erreur --- */
809  else if ( in && ! isprint(in) ) {
810  if (!Header_Quiet)
811  fprintf(stderr,
812  "\nERREUR caract. non imprim. 0x%.2X dans "
813  "l'entete at byte number %ld\n", in, tell() );
814  snprintf(Header_Message, sizeof Header_Message,
815  "\nERREUR caract. non imprim. 0x%.2X dans l'entete !\n", in );
816  return ERR_UNPRINTABLE_CHAR;
817  } else {
818  str[i++] = (char) in ;
819  }
820 
821  }
822 
823  /* --- ----- ----- ----- sauve les commentaires ----- ----- --- */
824  for ( char* pt_1=str; *pt_1; pt_1++ ) {
825 
826  /* --- '*' ou '#' = commentaires ------> dans comment --- */
827  if ( *pt_1 == '*' || *pt_1 == '#') {
828  if ( *(pt_1+1) ) {
829  v_comment[com] = (char *)malloc( strlen(pt_1+1) + 1 ) ;
830  strcpy( v_comment[com++], pt_1+1 ) ;
831  if (com%NALLOC == 0)
832  v_comment = (char **)
833  realloc(v_comment, (com+NALLOC)*sizeof(char *));
834  v_comment[com] = NULL ;
835  bool_comment = VRAI;
836  }
837  *pt_1 = '\000' ;
838  break ;
839  }
840 
841  /* --- convertit majuscule un minuscules --- */
842  if (isupper(*pt_1)) *pt_1 = tolower( *pt_1 ) ;
843 
844  }
845 
846 
847  /* --- ----- ----- ----- analyse la ligne ----- ----- ----- --- */
848  for ( char *pt_1=strtok(str," ,;\t"); pt_1; pt_1=strtok(NULL," ,;\t") ) {
849 
850  /* --- separe la chaine de caract. --- */
851  /* --- pt_1 pointe au key_word ---- */
852  /* --- pt_2 pointe a la donne ---- */
853  char *pt_2;
854  for ( pt_2 = pt_1; *pt_2 != ':'; pt_2 ++ )
855  if ( ! *pt_2 ) {
856  if (!Header_Quiet)
857  fprintf(stderr,
858  "\nERREUR de syntaxe dans l'entete (%s)\n", pt_1);
859  snprintf(Header_Message, sizeof Header_Message,
860  "\nERREUR de syntaxe dans l'entete (%s)\n", pt_1);
861  return ERR_IGB_SYNTAX;
862  }
863 
864  *pt_2++ = '\000' ;
865 
866  /* --- recherche le mot-clef --- */
867  if ( ! strcmp( pt_1, "x" ) ) {
868  v_x = strtoul(pt_2, NULL, 10);
869  bool_x = VRAI;
870 
871  } else if ( ! strcmp( pt_1, "y" ) ) {
872  v_y = strtoul(pt_2, NULL, 10) ;
873  bool_y = VRAI;
874 
875  } else if ( ! strcmp( pt_1, "z" ) ) {
876  v_z = strtoul(pt_2, NULL, 10) ;
877  bool_z = VRAI;
878 
879  } else if ( ! strcmp( pt_1, "t" ) ) {
880  v_t = strtoul(pt_2, NULL, 10) ;
881  bool_t = VRAI;
882 
883  /* Pour compatibilite avec les vielles images */
884  } else if ( ! strcmp( pt_1, "sup" ) ) {
885  s += atoi( pt_2 ) ;
886  nosup = FAUX;
887 
888  } else if ( ! strcmp( pt_1, "type" ) ) {
889 
890  for( int htype=IGB_MIN_TYPE; htype<=IGB_MAX_TYPE; htype++ )
891  if ( !strcmp( pt_2, Header_Type[htype] ) ) {
892  v_type = htype;
893  }
894  bool_type = VRAI;
895 
896  } else if ( ! strcmp( pt_1, "taille" ) ) {
897  v_taille = atoi( pt_2 ) ;
898  bool_taille = VRAI;
899 
900  } else if ( ! strcmp( pt_1, "systeme" ) ) {
901  v_systeme = INCONNU;
902  for (i=0;i<N_SYSTEMES;i++) {
903  if ( ! strcmp( pt_2, Header_Systeme[i] ) ) {
904  v_systeme = Header_Systeme_No[i] ;
905  break;
906  }
907  }
908 
909  } else if ( ! strcmp( pt_1, "bin" ) ) {
910  v_bin = atoi( pt_2 ) ;
911  bool_bin = VRAI;
912 
913  } else if ( ! strcmp( pt_1, "trame" ) ) {
914 
915  if ( ! strcmp( pt_2, "c8" ) ) {
916  v_trame = C8 ;
917  } else if ( ! strcmp( pt_2, "c4" ) ) {
918  v_trame = C4 ;
919  } else if ( ! strcmp( pt_2, "hex" ) ) {
920  v_trame = HEX ;
921  } else if ( ! strcmp( pt_2, "hexedges" ) ) {
922  v_trame = HEXEDGES ;
923  } else if ( ! strcmp( pt_2, "hexbridges" ) ) {
924  v_trame = HEXBRIDGES ;
925  } else if ( ! strcmp( pt_2, "hexlines" ) ) {
926  v_trame = HEXLINES ;
927  } else if ( ! strcmp( pt_2, "hex2" ) ) {
928  v_trame = HEX2 ;
929  }
930  bool_trame = VRAI;
931 
932  } else if ( ! strcmp( pt_1, "num" ) ) {
933  v_num = atoi( pt_2 ) ;
934  bool_num = VRAI;
935 
936  } else if ( ! strcmp( pt_1, "comp" ) ) {
937  v_comp = atoi( pt_2 ) ;
938  bool_comp = VRAI;
939 
940  } else if ( ! strcmp( pt_1, "lut" ) ) {
941  v_lut = atoi( pt_2 ) ;
942  bool_lut = VRAI;
943 
944  } else if ( ! strcmp( pt_1, "dim_x" ) ) {
945  v_dim_x = atof( pt_2 ) ;
946  bool_dim_x = VRAI;
947 
948  } else if ( ! strcmp( pt_1, "dim_y" ) ) {
949  v_dim_y = atof( pt_2 ) ;
950  bool_dim_y = VRAI;
951 
952  } else if ( ! strcmp( pt_1, "dim_z" ) ) {
953  v_dim_z = atof( pt_2 ) ;
954  bool_dim_z = VRAI;
955 
956  } else if ( ! strcmp( pt_1, "dim_t" ) ) {
957  v_dim_t = atof( pt_2 ) ;
958  bool_dim_t = VRAI;
959 
960  } else if ( ! strcmp( pt_1, "inc_x" ) ) {
961  v_inc_x = atof( pt_2 ) ;
962  bool_inc_x = VRAI;
963 
964  } else if ( ! strcmp( pt_1, "inc_y" ) ) {
965  v_inc_y = atof( pt_2 ) ;
966  bool_inc_y = VRAI;
967 
968  } else if ( ! strcmp( pt_1, "inc_z" ) ) {
969  v_inc_z = atof( pt_2 ) ;
970  bool_inc_z = VRAI;
971 
972  } else if ( ! strcmp( pt_1, "inc_t" ) ) {
973  v_inc_t = atof( pt_2 ) ;
974  bool_inc_t = VRAI;
975 
976  } else if ( ! strcmp( pt_1, "org_x" ) ) {
977  v_org_x = atof( pt_2 ) ;
978  bool_org_x = VRAI;
979 
980  } else if ( ! strcmp( pt_1, "org_y" ) ) {
981  v_org_y = atof( pt_2 ) ;
982  bool_org_y = VRAI;
983 
984  } else if ( ! strcmp( pt_1, "org_z" ) ) {
985  v_org_z = atof( pt_2 ) ;
986  bool_org_z = VRAI;
987 
988  } else if ( ! strcmp( pt_1, "org_t" ) ) {
989  v_org_t = atof( pt_2 ) ;
990  bool_org_t = VRAI;
991 
992  } else if ( ! strcmp( pt_1, "vect_z" ) ) {
993  bool_vect_z = VRAI;
994 
995  } else if ( ! strcmp( pt_1, "unites_x" ) ) {
996  strncpy( v_unites_x, pt_2, 40 ) ;
997  bool_unites_x = VRAI;
998 
999  } else if ( ! strcmp( pt_1, "unites_y" ) ) {
1000  strncpy( v_unites_y, pt_2, 40 ) ;
1001  bool_unites_y = VRAI;
1002 
1003  } else if ( ! strcmp( pt_1, "unites_z" ) ) {
1004  strncpy( v_unites_z, pt_2, 40 ) ;
1005  bool_unites_z = VRAI;
1006 
1007  } else if ( ! strcmp( pt_1, "unites_t" ) ) {
1008  strncpy( v_unites_t, pt_2, 40 ) ;
1009  bool_unites_t = VRAI;
1010 
1011  } else if ( ! strcmp( pt_1, "epais" ) ) {
1012  v_epais = atof( pt_2 ) ;
1013  bool_epais = VRAI;
1014 
1015  } else if ( ! strcmp( pt_1, "unites" ) ) {
1016  strncpy( v_unites, pt_2, 40 ) ;
1017  bool_unites = VRAI;
1018 
1019  } else if ( ! strcmp( pt_1, "facteur" ) ) {
1020  v_facteur = atof( pt_2 ) ;
1021  bool_facteur = VRAI;
1022 
1023  } else if ( ! strcmp( pt_1, "zero" ) ) {
1024  v_zero = atof( pt_2 ) ;
1025  bool_zero = VRAI;
1026 
1027  } else if ( ! strcmp( pt_1, "struct" ) ) {
1028  strncpy( v_struct_desc, pt_2, 40 ) ;
1029  bool_struct_desc = VRAI;
1030 
1031  } else if ( ! strcmp( pt_1, "aut" ) ) {
1032  strncpy( v_aut_name, pt_2, 40 ) ;
1033  bool_aut_name = VRAI;
1034 
1035  } else if ( !strcmp( pt_1, "transparent" ) ) {
1036  strcpy( transstr, pt_2 );
1037  bool_transparent = VRAI;
1038 
1039  } else {
1040  if( is_deprecated( pt_1 ) ){
1041  if (!Header_Quiet)
1042  fprintf(stderr,"\nATTENTION: mot-clef %s obsolete !\n", pt_1 ) ;
1043  if( !strcmp( pt_1, "fac_t" ) ){
1044  v_fac_t = atof( pt_2 );
1045  bool_fac_t = VRAI;
1046  }
1047  } else {
1048  if (!Header_Quiet)
1049  fprintf(stderr,"\nATTENTION: mot-clef %s non reconnu !\n", pt_1 );
1050  snprintf(Header_Message, sizeof Header_Message,
1051  "\nATTENTION: mot-clef %s non reconnu !\n", pt_1 ) ;
1052  statut |= MOT_CLEF_INV;
1053  }
1054  }
1055  }
1056  }
1057  /* determine the transparent value if one was chosen */
1058  if ( bool_transparent ) {
1059  if ( strlen(transstr) != 2*Data_Size[v_type] ) {
1060  fprintf(stderr,"ATTENTION: ignoring invalid transparent value !\n");
1061  } else {
1062  char s[3], *p, *v;
1063  s[2] = '\0';
1064  v = (char *)(v_transparent = calloc( Data_Size[v_type], 1 ));
1065  for ( int i=0; i<Data_Size[v_type]; i++ ) {
1066  s[0] = transstr[i*2];
1067  s[1] = transstr[i*2+1];
1068  v[i] = strtol( s, &p, 16 );
1069  }
1070  }
1071  }
1072 
1073  /* --- l'info x y et type est obligatoire --- */
1074  if ( !bool_x || !bool_y || !bool_type ) {
1075  if (!Header_Quiet)
1076  fprintf(stderr, "\nERREUR x, y ou type non definis\n") ;
1077  snprintf(Header_Message, sizeof Header_Message, "\nERREUR x, y ou type non definis\n") ;
1078  return ERR_UNDEFINED_X_Y_TYPE ;
1079  }
1080 
1081  /* --- calcul des inc et dim --- */
1082  if ( bool_dim_x )
1083  if ( bool_inc_x ) {
1084  float dim_x = v_inc_x * v_x ;
1085  if ( !almost_equal(dim_x, v_dim_x) ) {
1086  if (!Header_Quiet) {
1087  fprintf(stderr, "\nATTENTION:\n") ;
1088  fprintf(stderr,
1089  "conflit entre x (%zu) * inc_x (%.12g) = %.12g et dim_x (%.12g)\n",
1090  v_x, v_inc_x, dim_x, v_dim_x) ;
1091  }
1092  snprintf(Header_Message, sizeof Header_Message,
1093  "conflit entre x (%zu) * inc_x (%.12g) = %.12g et dim_x (%.12g)\n",
1094  v_x, v_inc_x, dim_x, v_dim_x) ;
1095  statut = WARN_DIM_INCONSISTENT ;
1096  }
1097  } else {
1098  v_inc_x = v_dim_x / v_x ;
1099  bool_inc_x = VRAI;
1100  }
1101  else {
1102  v_dim_x = v_x * v_inc_x ;
1103  if ( bool_inc_x ) bool_dim_x = VRAI;
1104  }
1105 
1106  if ( bool_dim_y )
1107  if ( bool_inc_y ) {
1108  float dim_y = v_inc_y * v_y ;
1109  if ( !almost_equal(dim_y, v_dim_y) ) {
1110  if (!Header_Quiet) {
1111  fprintf(stderr, "\nATTENTION:\n") ;
1112  fprintf(stderr,
1113  "conflit entre y (%zu) * inc_y (%.12g) = %.12g et dim_y (%.12g)\n",
1114  v_y, v_inc_y, dim_y, v_dim_y) ;
1115  }
1116  snprintf(Header_Message, sizeof Header_Message,
1117  "conflit entre y (%zu) * inc_y (%.12g) = %.12g et dim_y (%.12g)\n",
1118  v_y, v_inc_y, dim_y, v_dim_y) ;
1119  statut = WARN_DIM_INCONSISTENT ;
1120  }
1121  } else {
1122  v_inc_y = v_dim_y / v_y ;
1123  bool_inc_y = VRAI;
1124  }
1125  else {
1126  v_dim_y = v_y * v_inc_y ;
1127  if ( bool_inc_y ) bool_dim_y = VRAI;
1128  }
1129 
1130  if ( bool_dim_z )
1131  if ( bool_inc_z ) {
1132  float dim_z = v_inc_z * v_z ;
1133  if ( !almost_equal(dim_z, v_dim_z) ) {
1134  if (!Header_Quiet) {
1135  fprintf(stderr, "\nATTENTION:\n") ;
1136  fprintf(stderr,
1137  "conflit entre z (%zu) * inc_z (%.12g) = %.12g et dim_z (%.12g)\n",
1138  v_z, v_inc_z, dim_z, v_dim_z) ;
1139  }
1140  snprintf(Header_Message, sizeof Header_Message,
1141  "conflit entre z (%zu) * inc_z (%.12g) = %.12g et dim_z (%.12g)\n",
1142  v_z, v_inc_z, dim_z, v_dim_z) ;
1143  statut = WARN_DIM_INCONSISTENT ;
1144  }
1145  } else {
1146  v_inc_z = v_dim_z / v_z ;
1147  bool_inc_z = VRAI;
1148  }
1149  else {
1150  v_dim_z = v_z * v_inc_z ;
1151  if ( bool_inc_z ) bool_dim_z = VRAI;
1152  }
1153 
1154  if( !bool_inc_t && bool_fac_t ) {
1155  bool_inc_t = VRAI;
1156  v_inc_t = v_fac_t;
1157  }
1158  if ( bool_dim_t )
1159  if ( bool_inc_t ) {
1160  float dim_t = v_inc_t * (v_t-1) ;
1161  if ( !almost_equal(dim_t, v_dim_t) ) {
1162  if (!Header_Quiet) {
1163  fprintf(stderr, "\nATTENTION:\n") ;
1164  fprintf(stderr,
1165  "conflit entre t (%zu) * inc_t (%.12g) = %.12g et dim_t (%.12g)\n",
1166  v_t, v_inc_t, dim_t, v_dim_t) ;
1167  }
1168  snprintf(Header_Message, sizeof Header_Message,
1169  "conflit entre t (%zu) * inc_t (%.12g) = %.12g et dim_t (%.12g)\n",
1170  v_t, v_inc_t, dim_t, v_dim_t) ;
1171  v_dim_t = dim_t;
1172  //statut = WARN_DIM_INCONSISTENT ;
1173  }
1174  } else {
1175  v_inc_t = v_dim_t / (v_t - 1) ;
1176  bool_inc_t = VRAI;
1177  }
1178  else {
1179  v_dim_t = (v_t-1) * v_inc_t ;
1180  if ( bool_inc_t )
1181  bool_dim_t = VRAI;
1182  }
1183 
1184  if ( bool_taille ) {
1185  if (v_type!=IGB_STRUCTURE) {
1186  if (!Header_Quiet)
1187  fprintf(stderr,
1188  "\nERREUR taille redefinie pour type autre que structure\n") ;
1189  snprintf(Header_Message, sizeof Header_Message,
1190  "\nERREUR taille redefinie pour type autre que structure\n") ;
1191  return ERR_SIZE_REDEFINED;
1192  }
1193  } else {
1194  if (v_type==IGB_STRUCTURE) {
1195  if (!Header_Quiet)
1196  fprintf(stderr,
1197  "\nERREUR taille non definie pour type structure\n") ;
1198  snprintf(Header_Message, sizeof Header_Message,
1199  "\nERREUR taille non definie pour type structure\n") ;
1200  return ERR_SIZE_NOT_DEFINED;
1201  } else {
1202  v_taille = Data_Size[v_type];
1203  }
1204  }
1205 
1206  if (tell()!=1024) {
1207  seek( 1024, SEEK_SET );
1208  if (!Header_Quiet) {
1209  fprintf(stderr,
1210  "\nATTENTION: etiquette de grandeur non-standard: %ld \n", tell());
1211  }
1212  snprintf(Header_Message, sizeof Header_Message,
1213  "\nATTENTION: etiquette de grandeur non-standard \n");
1214  statut |= GRANDEUR_INV;
1215  } else {
1216  snprintf(Header_Message, sizeof Header_Message,
1217  "\nHeader_Read: Etiquette lue sans problemes\n");
1218  }
1219 
1220  if (bool_vect_z) {
1221  v_vect_z = (float *)malloc(v_z*sizeof(float));
1222  read_vz(v_vect_z, sizeof(float)*v_z);
1223  }
1224 
1225  return statut;
1226 }
1227 
1228 /*
1229  * add a comment line
1230  * clear comments is NULL is passed
1231  */
1232 void IGBheader::comment(const char *ligne)
1233 {
1234  const int maxln = 78;
1235  int i = 0, n_lignes = 0;
1236 
1237  if ( ligne == NULL ) {
1238  while ( v_comment[n_lignes] != NULL )
1239  free( v_comment[n_lignes++] );
1240  return;
1241  }
1242 
1243  int newlines = (strlen(ligne)+maxln-1)/maxln;
1244  while (v_comment[i++]!=NULL) n_lignes++;
1245  v_comment = (char **)realloc(v_comment, (n_lignes+newlines+1)*sizeof(char *));
1246 
1247  for( int j=0; j<newlines; j++ ){
1248  v_comment[n_lignes] = (char *)malloc(maxln+2) ;
1249  v_comment[n_lignes][maxln] = '\0';
1250  strncpy(v_comment[n_lignes++], ligne+j*maxln, maxln);
1251  }
1252  v_comment[n_lignes] = NULL;
1253  bool_comment = true;
1254 }
1255 
1256 const char *IGBheader::systemestr( void )
1257 {
1258  int i;
1259 
1260  for ( i=0; i<N_SYSTEMES; i++ )
1261  if ( Header_Systeme_No[i] == v_systeme )
1262  break;
1263 
1264  if ( i<N_SYSTEMES )
1265  return Header_Systeme[i];
1266  else
1267  return NULL;
1268 }
1269 
1270 
1271 void IGBheader::systeme( const char* s )
1272 {
1273  int i;
1274  for ( i=0; i<N_SYSTEMES; i++ )
1275  if ( !strncmp( Header_Systeme[i], s, strlen(s) ) )
1276  break;
1277 
1278  if ( i<N_SYSTEMES )
1279  v_systeme = Header_Systeme_No[i];
1280 }
1281 
1282 
1283 void IGBheader::type( char *datatype )
1284 {
1285  int tn=IGB_MIN_TYPE;
1286  while ( tn<=IGB_MAX_TYPE && strcmp(Header_Type[tn],datatype) )
1287  tn++;
1288  if ( tn<=IGB_MAX_TYPE )
1289  v_type = tn;
1290  else {
1291  cerr << "illegal data type specified for IGB header" << endl;
1292  exit(1);
1293  }
1294  bool_type = true;
1295 }
1296 
1297 
1298 // simple wrapper for ftell/gztell
1300 {
1301  if( gzipping )
1302  return gztell( (gzFile)file );
1303  else {
1304  if( file==stdin )
1305  return bytes_read; //tricked to think a proper sized header has been read
1306  else
1307  return ftell( (FILE*)file );
1308  }
1309 }
1310 
1311 
1312 int IGBheader::puts_fcn( char* s )
1313 {
1314  return fputs(s, (FILE*)file);
1315 }
1316 
1317 
1323 void IGBheader :: swab( void *data, int nd )
1324 {
1325  if ( data_size()==1 || v_type==IGB_RGBA )
1326  return;
1327 
1328  unsigned char *bp = (unsigned char *)data;
1329  int ds = data_size()/num_components();
1330 
1331  if ( nd<0 ) nd = v_x*v_y*v_z*v_t;
1332 
1333  nd *= num_components();
1334 
1335  switch ( ds ) {
1336  case 2:
1337  for ( int i=0; i<nd; i++ ) {
1338  unsigned char tmpb = bp[0];
1339  bp[0] = bp[1];
1340  bp[1] = tmpb;
1341  bp += data_size();
1342  }
1343  break;
1344  case 4:
1345  for ( int i=0; i<nd; i++ ) {
1346  unsigned char tmpb = bp[0];
1347  bp[0] = bp[3];
1348  bp[3] = tmpb;
1349  tmpb = bp[1];
1350  bp[1] = bp[2];
1351  bp[2] = tmpb;
1352  bp += data_size();
1353  }
1354  break;
1355  case 8:
1356  for ( int i=0; i<nd; i++ ) {
1357  unsigned char tmpb = bp[0];
1358  bp[0] = bp[7];
1359  bp[7] = tmpb;
1360  tmpb = bp[1];
1361  bp[1] = bp[6];
1362  bp[6] = tmpb;
1363  tmpb = bp[2];
1364  bp[2] = bp[5];
1365  bp[5] = tmpb;
1366  tmpb = bp[3];
1367  bp[3] = bp[4];
1368  bp[4] = tmpb;
1369  bp += data_size();
1370  }
1371  break;
1372  }
1373 }
1374 
1375 
1378 {
1379  float val=IGB_ENDIAN_VAL;
1380  unsigned char le_val[] = { IGB_LITTLE_END_REP },
1381  *pval = (unsigned char *)(&val);
1382 
1383  assert( sizeof(float) == 4 );
1384 
1385  if ( *pval == le_val[0] )
1386  return IGB_LITTLE_ENDIAN;
1387  else
1388  return IGB_BIG_ENDIAN;
1389 }
1390 
1391 int IGBheader::get_character()
1392 {
1393  if( gzipping )
1394  return gzgetc( (gzFile)file );
1395  else {
1396  if( file==stdin ) bytes_read++;
1397  return fgetc( (FILE*)file );
1398  }
1399 }
1400 
1401 
1402 int IGBheader::seek(size_t offset, int whence)
1403 {
1404  if( gzipping )
1405  return gzseek( (gzFile)file, offset, whence );
1406  else {
1407  if( file == stdin ) {
1408  size_t pos;
1409  if(whence==SEEK_SET) {
1410  if( offset < bytes_read )
1411  return -1;
1412  pos = offset - bytes_read;
1413  } else if(whence==SEEK_CUR)
1414  pos = offset;
1415  else
1416  return -1;
1417  for( int i=0; i<pos; i++ ) getchar();
1418  bytes_read += pos;
1419  return 0;
1420  } else
1421  return fseek( (FILE*)file, offset, whence );
1422  }
1423 }
1424 
1425 int IGBheader::read_vz( float *vz, int sz )
1426 {
1427  if( gzipping )
1428  return gzread( (gzFile)file, vz, sz );
1429  else {
1430  bytes_read += sz;
1431  return fread( vz, sz, 1, (FILE*)file );
1432  }
1433 }
1434 
1435 
1446 {
1447  s *= slice_sz() * data_size();
1448  s += 1024;
1449  return seek( s, SEEK_SET );
1450 }
1451 
1452 
1454 bool IGBheader::data_frame( size_t frame ) {
1455  if( frame >= v_t )
1456  return false;
1457 
1458  if( gzipping ) {
1459  gzseek( (gzFile)file, 1024L+frame*slice_sz()*data_size(), SEEK_SET );
1460  } else {
1461  fseek( (FILE*)file, 1024L+frame*slice_sz()*data_size(), SEEK_SET );
1462  }
1463  return true;
1464 }
int read(bool quiet=false)
Definition: IGBheader.cc:750
int type(void)
Definition: IGBheader.h:280
int systeme(void)
Definition: IGBheader.h:297
const char * systemestr(void)
Definition: IGBheader.cc:1256
IGBheader(gzFile a=NULL, bool read=false, bool quiet=false)
Definition: IGBheader.cc:315
int endian()
Definition: IGBheader.cc:1377
int write()
Definition: IGBheader.cc:343
char ** comment(void)
Definition: IGBheader.h:266
bool data_frame(size_t)
Definition: IGBheader.cc:1454
void * fileptr(void)
Definition: IGBheader.h:258
long tell()
Definition: IGBheader.cc:1299
void swab(void *, int nd=-1)
Definition: IGBheader.cc:1323
int go2slice(size_t s)
go to a slice
Definition: IGBheader.cc:1445
#define ERR_IGB_SYNTAX
Definition: IGBheader.h:103
#define IGB_LITTLE_ENDIAN
Definition: IGBheader.h:50
#define IGB_ENDIAN_VAL
Definition: IGBheader.h:96
#define N_SYSTEMES
Definition: IGBheader.h:51
#define ERR_UNDEFINED_X_Y_TYPE
Definition: IGBheader.h:104
#define IGB_RGBA
Definition: IGBheader.h:63
#define IGB_MAX_TYPE
Definition: IGBheader.h:78
#define IGB_STRUCTURE
Definition: IGBheader.h:64
#define WARN_DIM_INCONSISTENT
Definition: IGBheader.h:107
#define INCONNU
Definition: IGBheader.h:47
#define IGB_BIG_ENDIAN
Definition: IGBheader.h:49
#define ERR_EOF_IN_HEADER
Definition: IGBheader.h:100
#define IGB_MIN_TYPE
Definition: IGBheader.h:77
#define ERR_SIZE_NOT_DEFINED
Definition: IGBheader.h:106
#define ERR_LINE_TOO_LONG
Definition: IGBheader.h:101
#define NALLOC
Definition: IGBheader.h:44
#define ERR_UNPRINTABLE_CHAR
Definition: IGBheader.h:102
#define ERR_SIZE_REDEFINED
Definition: IGBheader.h:105
#define IGB_LITTLE_END_REP
Definition: IGBheader.h:97
#define GRANDEUR_INV
Definition: IGBheader.cc:35
const char * Header_Systeme[]
Definition: IGBheader.cc:283
bool Header_Quiet
Definition: IGBheader.cc:240
#define FF
Definition: IGBheader.cc:52
const char * Header_Type[]
Definition: IGBheader.cc:243
#define LF
Definition: IGBheader.cc:51
#define N_MAX_ITEMS
Definition: IGBheader.cc:228
#define MAX_TRAME
Definition: IGBheader.cc:48
const size_t Data_Size[]
Definition: IGBheader.cc:258
char Header_Message[256]
Definition: IGBheader.cc:241
#define C8
Definition: IGBheader.cc:41
#define HEXLINES
Definition: IGBheader.cc:46
#define CR
Definition: IGBheader.cc:53
#define HEX
Definition: IGBheader.cc:43
#define L_MAX_ITEM
Definition: IGBheader.cc:229
const unsigned short Num_Components[]
Definition: IGBheader.cc:269
const char * deprecated[]
Definition: IGBheader.cc:253
#define HEXEDGES
Definition: IGBheader.cc:44
#define HEXBRIDGES
Definition: IGBheader.cc:45
#define MAXL
Definition: IGBheader.cc:227
int my_fputs(FILE *, char *)
const unsigned long Header_Systeme_No[]
Definition: IGBheader.cc:276
#define C4
Definition: IGBheader.cc:42
#define MAKE_CONSISTENT(D)
Definition: IGBheader.cc:298
#define HEX2
Definition: IGBheader.cc:47
#define VRAI
Definition: IGBheader.cc:231
#define FAUX
Definition: IGBheader.cc:234
#define MOT_CLEF_INV
Definition: IGBheader.cc:34
unsigned int UInt
Definition: IGBheader.h:138
std::enable_if<!std::numeric_limits< T >::is_integer, bool >::type almost_equal(T x, T y, int ulp=2)
Definition: IGBheader.h:40
unsigned char Byte
Definition: IGBheader.h:128
uint16_t short_float
Definition: short_float.h:58