/*---------------------------------------------------------------------------*\ header.c: contient les fonctions necessaires a la lecture et a l'ecriture des etiquettes format "igb" et quelques utilitaires. Auteurs: Yves Martel Andre Bleau, ing. Laboratoire de Modelisation Biomedicale (LMB) Institut de Genie Biomedical Ecole Polytechnique / Faculte de Medecine Universite de Montreal Revision: 2 avril 1998 \*---------------------------------------------------------------------------*/ #include /* --- fopen(), fgets(), fclose() ---------- */ #include /* --- pour strtok(), strcpy(), strcmp() --- */ #include /* --- pour isprint(), tolower() ----------- */ #define HEADER_GLOBALS /* #include "Header/gzheader.h" #include "Header/im_alloc.h" #include "Header/trame.h" */ #include "igb.h" #if (MODELE&MODELE)==IRIS_3000 /* --- Sous certains systemes n'existe pas --- */ float atof() ; int atoi() ; char *getenv() ; char *malloc() ; char *realloc() ; void free() ; #else #include /* --- pour atoi() atof() malloc() realloc() */ #endif /* * Types de trames */ #define MIN_TRAME 0 #define C8 0 #define C4 1 #define HEX 2 #define HEXEDGES 3 #define HEXBRIDGES 4 #define HEXLINES 5 #define HEX2 6 #define MAX_TRAME 6 #define NTRAMES 7 #define LF 0x0A #define FF 0x0C #define CR 0x0D #define NALLOC 100 /* --- Nombre de lignes allouees a la fois */ /* Header_Type contient les noms des differents types */ char *Header_Type[] = { "", "byte", "char", "short", "long", "float", "double", "complex", "double_complex", "rgba", "structure", "pointer", "list", "int", "uint" }; /* Header_Size contient l'espace-memoire utilise par les differents types */ short Header_Size[] = { 0, sizeof(byte), sizeof(char), sizeof(short), sizeof(long), sizeof(float), sizeof(Double), sizeof(complex), sizeof(d_complex), sizeof(rgba), 0, sizeof(char *), sizeof(List), sizeof(int), sizeof(unsigned int) }; /* Header_Message contient le dernier message-diagnostic emis par les fonctions Header_Read et Header_Write ci-dessous */ char Header_Message[256]; /* Header_Quiet gouverne l'affichage des erreurs sur stderr; 0 Les erreurs seront affichees sur stderr autre Les erreurs ne seront pas affichees sur stderr */ int Header_Quiet = 0; /*---------------------------------------------------------------------------*\ fonction: Header_Read() (int) description:Lit le header d'un fichier d'image l'information est place dans une structure de type Header parametres: file (gzFile) input stream head (Header *) pointeur a la structure bool_head (Bool_Header *) indique les membres de la structure trouves dans l'etiquette lue retour: (int) 0 si erreur bit 1 si etiquette lisible bit MOT_CLEF_INV si mot-clef non-reconnu bit GRANDEUR_INV si la grandeur de l'etiquette est invalide revision: 23/03/1988 y.m. 02/04/1998 Andre Bleau, ing. \*---------------------------------------------------------------------------*/ int Header_Read( file, head, bool_head ) gzFile file ; Header *head ; Bool_Header *bool_head ; { char str[MAXL+1]; char transstr[MAXL+1]; char *pt_1, *pt_2 ; int go = VRAI; int nosup = VRAI; /* Vrai tant que l'on n'a pas rencontre le mot-clef "sup" */ int i ; unsigned char in ; int com = 0; int s ; int statut = 1; int bytes_read, total_bytes_read=0; float dim_x, dim_y, dim_z, dim_t ; if (getenv("HEADER_QUIET")) Header_Quiet = VRAI; if (file==NULL) { if (!Header_Quiet) fprintf(stderr, "\nERREUR: descripteur de fichier nul\n"); sprintf(Header_Message, "\nERREUR: descripteur de fichier nul\n"); return( 0 ) ; } /* --- initialisation des variables --- */ head->x = head->y = head->type = 0 ; head->systeme = SYSTEME; head->comp = head->lut = head->num = head->bin = 0 ; head->trame = C8 ; head->z = head->t = 1 ; head->epais = 0.0 ; head->inc_x = head->inc_y = head->inc_z = head->inc_t = 1.0 ; head->org_x = head->org_y = head->org_z = head->org_t = 1.0 ; head->fac_x = head->fac_y = head->fac_z = head->fac_t = 1.0 ; head->vect_z = NULL ; head->unites_x[0] = head->unites_x[40] = '\000' ; head->unites_y[0] = head->unites_y[40] = '\000' ; head->unites_z[0] = head->unites_z[40] = '\000' ; head->unites_t[0] = head->unites_t[40] = '\000' ; head->unites[0] = head->unites[40] = '\000' ; head->facteur = 1.0 ; head->zero = 0.0 ; head->aut_name[0] = head->aut_name[40] = '\000' ; head->struct_desc[0] = head->struct_desc[40] = '\000' ; head->comment = (char **) malloc( NALLOC*sizeof(char *) ) ; head->comment[0] = NULL ; head->transparent = NULL; bool_head->x = bool_head->y = bool_head->type = FAUX; bool_head->z = bool_head->t = FAUX; bool_head->taille = FAUX; bool_head->systeme = FAUX; bool_head->num = FAUX; bool_head->bin = FAUX; bool_head->trame = FAUX; bool_head->lut = FAUX; bool_head->comp = FAUX; bool_head->epais = FAUX; bool_head->org_x = bool_head->org_y = bool_head->org_z = bool_head->org_t = FAUX; bool_head->inc_x = bool_head->inc_y = bool_head->inc_z = bool_head->inc_t = FAUX; bool_head->dim_x = bool_head->dim_y = bool_head->dim_z = bool_head->dim_t = FAUX; bool_head->fac_x = bool_head->fac_y = bool_head->fac_z = bool_head->fac_t = FAUX; bool_head->vect_z = FAUX; bool_head->unites_x = bool_head->unites_y = bool_head->unites_z = bool_head->unites_t = FAUX; bool_head->unites = FAUX; bool_head->facteur = bool_head->zero = FAUX; bool_head->aut_name = FAUX; bool_head->comment = FAUX; bool_head->transparent = FAUX; /* --- pour toutes les lignes de l'entete (def=8) ou jusqu'a un -- */ for ( s=8; (s>0 || nosup) && go; s-- ) { /* --- lit la ligne dans le fichier --- */ i = 0 ; while(1) { /* --- (ligne trop longue) --> erreur --- */ if ( i >= 80 ) { if (!Header_Quiet) fprintf(stderr, "\nERREUR ligne trop longue (>80) dans l'entete !\n" ) ; sprintf(Header_Message, "\nERREUR ligne trop longue (>80) dans l'entete !\n" ) ; return( 0 ) ; } /* --- lit le caractere suivant --- */ /* in = getc( file ) ;*/ /* --- (EOF dans l'entete) --> erreur --- */ /* if ( in == EOF ) { */ if( (bytes_read = gzread( file, &in, 1 )) == 0 ) { if (!Header_Quiet) fprintf(stderr, "\nERREUR Fin de fichier dans l'entete !\n" ) ; sprintf(Header_Message, "\nERREUR Fin de fichier dans l'entete !\n" ) ; return( 0 ) ; } else { total_bytes_read += bytes_read; /* --- FF --> termine le header --- */ if ( in == FF ) { str[i] = '\000' ; go = FAUX ; break ; } /* --- CR et LF --> termine la ligne --- */ else if ( in == CR ) { str[i] = '\000' ; } else if ( in == LF ) { str[i] = '\000' ; break ; } /* --- (0x20 < caractere > 0x7E) si non --> erreur --- */ else if ( in && ! isprint(in) ) { if (!Header_Quiet) fprintf(stderr, "\nERREUR caract. non imprim. 0x%.2X dans l'entete ! (%d char read)\n", in, total_bytes_read ); sprintf(Header_Message, "\nERREUR caract. non imprim. 0x%.2X dans l'entete ! (%d char read)\n", in, total_bytes_read); return( 0 ) ; } else { str[i++] = (char) in ; } } } /* --- ----- ----- ----- sauve les commentaires ----- ----- --- */ for ( pt_1=str; *pt_1; pt_1++ ) { /* --- '*' ou '#' = commentaires ------> dans comment --- */ if ( *pt_1 == '*' || *pt_1 == '#') { if ( *(pt_1+1) ) { head->comment[com] = malloc( strlen(pt_1+1) + 1 ) ; strcpy( head->comment[com++], pt_1+1 ) ; if (com%NALLOC == 0) head->comment = (char **) realloc(head->comment, (com+NALLOC)*sizeof(char *)); head->comment[com] = NULL ; bool_head->comment = VRAI; } *pt_1 = '\000' ; break ; } /* --- convertit majuscule un minuscules --- */ if (isupper(*pt_1)) *pt_1 = tolower( *pt_1 ) ; } /* --- ----- ----- ----- analyse la ligne ----- ----- ----- --- */ for ( pt_1=strtok(str," ,;\t"); pt_1; pt_1=strtok(NULL," ,;\t") ) { /* --- separe la chaine de caract. --- */ /* --- pt_1 pointe au key_word ---- */ /* --- pt_2 pointe a la donne ---- */ for ( pt_2 = pt_1; *pt_2 != ':'; pt_2 ++ ) if ( ! *pt_2 ) { if (!Header_Quiet) fprintf(stderr, "\nERREUR de syntaxe dans l'entete (%s)\n", pt_1); sprintf(Header_Message, "\nERREUR de syntaxe dans l'entete (%s)\n", pt_1); return( 0 ) ; } *pt_2++ = '\000' ; /* --- recherche le mot-clef --- */ if ( ! strcmp( pt_1, "x" ) ) { head->x = atoi( pt_2 ) ; bool_head->x = VRAI; } else if ( ! strcmp( pt_1, "y" ) ) { head->y = atoi( pt_2 ) ; bool_head->y = VRAI; } else if ( ! strcmp( pt_1, "z" ) ) { head->z = atoi( pt_2 ) ; bool_head->z = VRAI; } else if ( ! strcmp( pt_1, "t" ) ) { head->t = atoi( pt_2 ) ; bool_head->t = VRAI; /* Pour compatibilite avec les vielles images */ } else if ( ! strcmp( pt_1, "sup" ) ) { s += atoi( pt_2 ) ; nosup = FAUX; } else if ( ! strcmp( pt_1, "type" ) ) { if ( ! strcmp( pt_2, "byte" ) ) { head->type = IGB_BYTE ; } else if ( ! strcmp( pt_2, "char" ) ) { head->type = IGB_CHAR ; } else if ( ! strcmp( pt_2, "short" ) ) { head->type = IGB_SHORT ; } else if ( ! strcmp( pt_2, "long" ) ) { head->type = IGB_LONG ; } else if ( ! strcmp( pt_2, "float" ) ) { head->type = IGB_FLOAT ; } else if ( ! strcmp( pt_2, "double" ) ) { head->type = IGB_DOUBLE ; } else if ( ! strcmp( pt_2, "complex" ) ) { head->type = IGB_COMPLEX ; } else if ( ! strcmp( pt_2, "double_complex" ) ) { head->type = IGB_D_COMPLEX ; } else if ( ! strcmp( pt_2, "rgba" ) ) { head->type = IGB_RGBA ; } else if ( ! strcmp( pt_2, "structure" ) ) { head->type = IGB_STRUCTURE ; } else if ( ! strcmp( pt_2, "int" ) ) { head->type = IGB_INT; } else if ( ! strcmp( pt_2, "uint" ) ) { head->type = IGB_UINT; } bool_head->type = VRAI; } else if ( ! strcmp( pt_1, "taille" ) ) { head->taille = atoi( pt_2 ) ; bool_head->taille = VRAI; } else if ( ! strcmp( pt_1, "systeme" ) ) { head->systeme = INCONNU; for (i=0;isysteme = Header_Systeme_No[i] ; break; } } } else if ( ! strcmp( pt_1, "bin" ) ) { head->bin = atoi( pt_2 ) ; bool_head->bin = VRAI; } else if ( ! strcmp( pt_1, "trame" ) ) { if ( ! strcmp( pt_2, "c8" ) ) { head->trame = C8 ; } else if ( ! strcmp( pt_2, "c4" ) ) { head->trame = C4 ; } else if ( ! strcmp( pt_2, "hex" ) ) { head->trame = HEX ; } else if ( ! strcmp( pt_2, "hexedges" ) ) { head->trame = HEXEDGES ; } else if ( ! strcmp( pt_2, "hexbridges" ) ) { head->trame = HEXBRIDGES ; } else if ( ! strcmp( pt_2, "hexlines" ) ) { head->trame = HEXLINES ; } else if ( ! strcmp( pt_2, "hex2" ) ) { head->trame = HEX2 ; } bool_head->trame = VRAI; } else if ( ! strcmp( pt_1, "num" ) ) { head->num = atoi( pt_2 ) ; bool_head->num = VRAI; } else if ( ! strcmp( pt_1, "comp" ) ) { head->comp = atoi( pt_2 ) ; bool_head->comp = VRAI; } else if ( ! strcmp( pt_1, "lut" ) ) { head->lut = atoi( pt_2 ) ; bool_head->lut = VRAI; } else if ( ! strcmp( pt_1, "dim_x" ) ) { head->dim_x = atof( pt_2 ) ; bool_head->dim_x = VRAI; } else if ( ! strcmp( pt_1, "dim_y" ) ) { head->dim_y = atof( pt_2 ) ; bool_head->dim_y = VRAI; } else if ( ! strcmp( pt_1, "dim_z" ) ) { head->dim_z = atof( pt_2 ) ; bool_head->dim_z = VRAI; } else if ( ! strcmp( pt_1, "dim_t" ) ) { head->dim_t = atof( pt_2 ) ; bool_head->dim_t = VRAI; } else if ( ! strcmp( pt_1, "fac_x" ) ) { head->fac_x = atof( pt_2 ) ; bool_head->fac_x = VRAI; } else if ( ! strcmp( pt_1, "fac_y" ) ) { head->fac_y = atof( pt_2 ) ; bool_head->fac_y = VRAI; } else if ( ! strcmp( pt_1, "fac_z" ) ) { head->fac_z = atof( pt_2 ) ; bool_head->fac_z = VRAI; } else if ( ! strcmp( pt_1, "fac_t" ) ) { head->fac_t = atof( pt_2 ) ; bool_head->fac_t = VRAI; } else if ( ! strcmp( pt_1, "inc_x" ) ) { head->inc_x = atof( pt_2 ) ; bool_head->inc_x = VRAI; } else if ( ! strcmp( pt_1, "inc_y" ) ) { head->inc_y = atof( pt_2 ) ; bool_head->inc_y = VRAI; } else if ( ! strcmp( pt_1, "inc_z" ) ) { head->inc_z = atof( pt_2 ) ; bool_head->inc_z = VRAI; } else if ( ! strcmp( pt_1, "inc_t" ) ) { head->inc_t = atof( pt_2 ) ; bool_head->inc_t = VRAI; } else if ( ! strcmp( pt_1, "org_x" ) ) { head->org_x = atof( pt_2 ) ; bool_head->org_x = VRAI; } else if ( ! strcmp( pt_1, "org_y" ) ) { head->org_y = atof( pt_2 ) ; bool_head->org_y = VRAI; } else if ( ! strcmp( pt_1, "org_z" ) ) { head->org_z = atof( pt_2 ) ; bool_head->org_z = VRAI; } else if ( ! strcmp( pt_1, "org_t" ) ) { head->org_t = atof( pt_2 ) ; bool_head->org_t = VRAI; } else if ( ! strcmp( pt_1, "vect_z" ) ) { bool_head->vect_z = VRAI; } else if ( ! strcmp( pt_1, "unites_x" ) ) { strncpy( head->unites_x, pt_2, 40 ) ; bool_head->unites_x = VRAI; } else if ( ! strcmp( pt_1, "unites_y" ) ) { strncpy( head->unites_y, pt_2, 40 ) ; bool_head->unites_y = VRAI; } else if ( ! strcmp( pt_1, "unites_z" ) ) { strncpy( head->unites_z, pt_2, 40 ) ; bool_head->unites_z = VRAI; } else if ( ! strcmp( pt_1, "unites_t" ) ) { strncpy( head->unites_t, pt_2, 40 ) ; bool_head->unites_t = VRAI; } else if ( ! strcmp( pt_1, "epais" ) ) { head->epais = atof( pt_2 ) ; bool_head->epais = VRAI; } else if ( ! strcmp( pt_1, "unites" ) ) { strncpy( head->unites, pt_2, 40 ) ; bool_head->unites = VRAI; } else if ( ! strcmp( pt_1, "facteur" ) ) { head->facteur = atof( pt_2 ) ; bool_head->facteur = VRAI; } else if ( ! strcmp( pt_1, "zero" ) ) { head->zero = atof( pt_2 ) ; bool_head->zero = VRAI; } else if ( ! strcmp( pt_1, "struct" ) ) { strncpy( head->struct_desc, pt_2, 40 ) ; bool_head->struct_desc = VRAI; } else if ( ! strcmp( pt_1, "aut" ) ) { strncpy( head->aut_name, pt_2, 40 ) ; bool_head->aut_name = VRAI; } else if( !strcmp( pt_1, "transparent" ) ) { strcpy( transstr, pt_2 ); bool_head->transparent = VRAI; } else { if (!Header_Quiet) fprintf(stderr, "\nATTENTION: mot-clef %s non reconnu !\n", pt_1 ) ; sprintf(Header_Message, "\nATTENTION: mot-clef %s non reconnu !\n", pt_1 ) ; statut |= MOT_CLEF_INV; } } } /* determine the transparent value if one was chosen */ if( bool_head->transparent == VRAI ) { if( strlen(transstr) != 2*Header_Size[head->type] ) { fprintf(stderr,"ATTENTION: ignoring invalid transparent value !\n"); } else { char s[3], *p, *v; int i; s[2] = '\0'; v = head->transparent = calloc( Header_Size[head->type], 1 ); for( i=0; itype]; i++ ){ s[0] = transstr[i*2]; s[1] = transstr[i*2+1]; v[i] = strtol( s, &p, 16 ); } } } /* --- l'info x y et type est obligatoire --- */ if ( !bool_head->x || !bool_head->y || !bool_head->type ) { if (!Header_Quiet) fprintf(stderr, "\nERREUR x, y ou type non definis\n") ; sprintf(Header_Message, "\nERREUR x, y ou type non definis\n") ; return( 0 ) ; } /* --- calcul des inc et dim --- */ if ( bool_head->dim_x ) if ( bool_head->inc_x ) { dim_x = head->inc_x * head->x ; if ( dim_x != head->dim_x ) { if (!Header_Quiet) { fprintf(stderr, "\nATTENTION:\n") ; fprintf(stderr, "conflit entre x (%d) * inc_x (%.12g) = %.12g et dim_x (.12g)\n", head->x, head->inc_x, dim_x, head->dim_x) ; } sprintf(Header_Message, "conflit entre x (%d) * inc_x (%.12g) = %.12g et dim_x (.12g)\n", head->x, head->inc_x, dim_x, head->dim_x) ; statut = 0 ; } } else { head->inc_x = head->dim_x / head->x ; bool_head->inc_x = VRAI; } else { head->dim_x = head->x * head->inc_x ; if ( bool_head->inc_x ) bool_head->dim_x = VRAI; } if ( bool_head->dim_y ) if ( bool_head->inc_y ) { dim_y = head->inc_y * head->y ; if ( dim_y != head->dim_y ) { if (!Header_Quiet) { fprintf(stderr, "\nATTENTION:\n") ; fprintf(stderr, "conflit entre y (%d) * inc_y (%.12g) = %.12g et dim_y (.12g)\n", head->y, head->inc_y, dim_y, head->dim_y) ; } sprintf(Header_Message, "conflit entre y (%d) * inc_y (%.12g) = %.12g et dim_y (.12g)\n", head->y, head->inc_y, dim_y, head->dim_y) ; statut = 0 ; } } else { head->inc_y = head->dim_y / head->y ; if ( bool_head->inc_y ) bool_head->inc_y = VRAI; } else { head->dim_y = head->y * head->inc_y ; bool_head->dim_y = VRAI; } if ( bool_head->dim_z ) if ( bool_head->inc_z ) { dim_z = head->inc_z * head->z ; if ( dim_z != head->dim_z ) { if (!Header_Quiet) { fprintf(stderr, "\nATTENTION:\n") ; fprintf(stderr, "conflit entre z (%d) * inc_z (%.12g) = %.12g et dim_z (.12g)\n", head->z, head->inc_z, dim_z, head->dim_z) ; } sprintf(Header_Message, "conflit entre z (%d) * inc_z (%.12g) = %.12g et dim_z (.12g)\n", head->z, head->inc_z, dim_z, head->dim_z) ; statut = 0 ; } } else { head->inc_z = head->dim_z / head->z ; bool_head->inc_z = VRAI; } else { head->dim_z = head->z * head->inc_z ; if ( bool_head->inc_z ) bool_head->dim_z = VRAI; } if ( bool_head->dim_t ) if ( bool_head->inc_t ) { dim_t = head->inc_t * head->t ; if ( dim_t != head->dim_t ) { if (!Header_Quiet) { fprintf(stderr, "\nATTENTION:\n") ; fprintf(stderr, "conflit entre t (%d) * inc_t (%.12g) = %.12g et dim_t (.12g)\n", head->t, head->inc_t, dim_t, head->dim_t) ; } sprintf(Header_Message, "conflit entre t (%d) * inc_t (%.12g) = %.12g et dim_t (.12g)\n", head->t, head->inc_t, dim_t, head->dim_t) ; statut = 0 ; } } else { head->inc_t = head->dim_t / head->t ; bool_head->inc_t = VRAI; } else { head->dim_t = head->t * head->inc_t ; if ( bool_head->inc_t ) bool_head->dim_t = VRAI; } if ( bool_head->taille ) { if (head->type!=IGB_STRUCTURE) { if (!Header_Quiet) fprintf(stderr, "\nERREUR taille redefinie pour type autre que structure\n") ; sprintf(Header_Message, "\nERREUR taille redefinie pour type autre que structure\n") ; return( 0 ) ; } } else { if (head->type==IGB_STRUCTURE) { if (!Header_Quiet) fprintf(stderr, "\nERREUR taille non definie pour type structure\n") ; sprintf(Header_Message, "\nERREUR taille non definie pour type structure\n") ; return( 0 ) ; } else { head->taille = Header_Size[head->type]; } } /* if (ftell(file)!=1024) {} */ if( total_bytes_read != 1024 ) { if (!Header_Quiet) { fprintf(stderr, "\nATTENTION: etiquette de grandeur non-standard \n"); } sprintf(Header_Message, "\nATTENTION: etiquette de grandeur non-standard \n"); statut |= GRANDEUR_INV; } else { sprintf(Header_Message, "\nHeader_Read: Etiquette lue sans problemes\n"); } if (bool_head->vect_z) { head->vect_z = (float *)malloc(head->z*sizeof(float)); /* fread(head->vect_z, sizeof(float), head->z, file); */ gzread(file, head->vect_z, sizeof(float)*head->z); } return( statut ) ; } /*---------------------------------------------------------------------------*\ fonction: Header_Write() (int) description:Ecrit le header d'un fichier d'image l'information vient dans une structure de type Header les elements a transcrire sont indiques par une structure de type Bool_Header parametres: file (gzFile) output stream header (Header *) information bool_header (Bool_Header *) ce qui sera ecrit retour: (int) 0 si erreur bit 1 si etiquette ecrite bit GRANDEUR_INV si grandeur de l'etiquette >1024 revision: 09/10/1997 Andre Bleau, ing. \*---------------------------------------------------------------------------*/ int Header_Write( file, header, bool_header ) gzFile file ; Header *header; Bool_Header *bool_header; { register long i; auto char **comment, items[N_MAX_ITEMS+1][L_MAX_ITEM], ligne[73], *systeme, *type; auto int l_item[N_MAX_ITEMS+1], n_blocs, n_car, n_car_dl, n_car_sup, n_car_total, n_comment, n_items, n_lignes, n_lig_sup, statut = 1; if (getenv("HEADER_QUIET")) Header_Quiet = VRAI; if (file==NULL) { if (!Header_Quiet) fprintf(stderr, "\nERREUR: descripteur de fichier nul\n"); sprintf(Header_Message, "\nERREUR: descripteur de fichier nul\n"); return(0) ; } if (header->typetype>IGB_MAX_TYPE) { if (!Header_Quiet) fprintf(stderr, "\nHeader_Write: type inconnu: %d\n", header->type); sprintf(Header_Message, "\nHeader_Write: type inconnu: %d\n", header->type); return (0); } type = Header_Type[header->type]; if (header->type==IGB_STRUCTURE && header->taille<1) { if (!Header_Quiet) fprintf(stderr, "\nHeader_Write: taille invalide: %d\n", header->taille); sprintf(Header_Message, "\nHeader_Write: taille invalide: %d\n", header->taille); return (0); } if (header->trametrame>MAX_TRAME) { if (!Header_Quiet) fprintf(stderr, "\nHeader_Write: trame inconnue: %d\n", header->trame); sprintf(Header_Message, "\nHeader_Write: trame inconnue: %d\n", header->trame); return (0); } if (bool_header->systeme) { for (i=0;isysteme) == Header_Systeme_No[i] ) { systeme = Header_Systeme[i] ; break; } } if (i == N_SYSTEMES) { if (!Header_Quiet) fprintf(stderr, "\nHeader_Write: systeme inconnu: %d\n", header->systeme); sprintf(Header_Message, "\nHeader_Write: systeme inconnu: %d\n", header->systeme); systeme = "inconnu"; } } else { for (i=0;isysteme); sprintf(Header_Message, "\nHeader_Write: systeme inconnu: %d\n", header->systeme); systeme = "inconnu"; } } if (bool_header->t) { if (bool_header->z) { sprintf(ligne, "x:%d y:%d z:%d t:%d type:%s systeme:%s ", header->x, header->y, header->z, header->t, type, systeme); } else { sprintf(ligne, "x:%d y:%d t:%d type:%s systeme:%s ", header->x, header->y, header->t, type, systeme); } } else { if (bool_header->z) { sprintf(ligne, "x:%d y:%d z:%d type:%s systeme:%s ", header->x, header->y, header->z, type, systeme); } else { sprintf(ligne, "x:%d y:%d type:%s systeme:%s ", header->x, header->y, type, systeme); } } n_car = strlen(ligne); n_lignes = 1; n_items = 0; /* Le mot-clef "taille" n'est ecrit que pour le type STRUCTURE mais il est obligatoire pour ce cas. */ if (header->type==IGB_STRUCTURE) { sprintf(&items[n_items][0], "taille:%d ", header->taille); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->org_x) { sprintf(&items[n_items][0], "org_x:%g ", header->org_x); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->org_y) { sprintf(&items[n_items][0], "org_y:%g ", header->org_y); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->org_z) { sprintf(&items[n_items][0], "org_z:%g ", header->org_z); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->org_t) { sprintf(&items[n_items][0], "org_t:%g ", header->org_t); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->fac_x) { sprintf(&items[n_items][0], "fac_x:%g ", header->fac_x); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->fac_y) { sprintf(&items[n_items][0], "fac_y:%g ", header->fac_y); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->fac_z) { sprintf(&items[n_items][0], "fac_z:%g ", header->fac_z); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->fac_t) { sprintf(&items[n_items][0], "fac_t:%g ", header->fac_t); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->dim_x) { sprintf(&items[n_items][0], "dim_x:%g ", header->dim_x); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } else if (bool_header->inc_x) { sprintf(&items[n_items][0], "dim_x:%g ", header->inc_x); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->dim_y) { sprintf(&items[n_items][0], "dim_y:%g ", header->dim_y); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } else if (bool_header->inc_y) { sprintf(&items[n_items][0], "inc_y:%g ", header->inc_y); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->dim_z) { sprintf(&items[n_items][0], "dim_z:%g ", header->dim_z); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } else if (bool_header->inc_z) { sprintf(&items[n_items][0], "dim_z:%g ", header->inc_z); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->dim_t) { sprintf(&items[n_items][0], "dim_t:%g ", header->dim_t); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } else if (bool_header->inc_t) { sprintf(&items[n_items][0], "dim_t:%g ", header->inc_t); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->vect_z) { sprintf(&items[n_items][0], "vect_z:1 "); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->unites_x) { sprintf(&items[n_items][0], "unites_x:%.40s ", header->unites_x); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->unites_y) { sprintf(&items[n_items][0], "unites_y:%.40s ", header->unites_y); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->unites_z) { sprintf(&items[n_items][0], "unites_z:%.40s ", header->unites_z); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->unites_t) { sprintf(&items[n_items][0], "unites_t:%.40s ", header->unites_t); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->num) { sprintf(&items[n_items][0], "num:%d ", header->num); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->bin) { sprintf(&items[n_items][0], "bin:%d ", header->bin); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->trame) { switch(header->trame) { case C8: sprintf(&items[n_items][0], "trame:c8 "); break; case C4: sprintf(&items[n_items][0], "trame:c4 "); break; case HEX: sprintf(&items[n_items][0], "trame:hex "); break; case HEXEDGES: sprintf(&items[n_items][0], "trame:hexedges "); break; case HEXBRIDGES: sprintf(&items[n_items][0], "trame:hexbridges "); break; case HEXLINES: sprintf(&items[n_items][0], "trame:hexlines "); break; case HEX2: sprintf(&items[n_items][0], "trame:hex2 "); break; } l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->lut) { sprintf(&items[n_items][0], "lut:%d ", header->lut); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->comp) { sprintf(&items[n_items][0], "comp:%d ", header->comp); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->epais) { sprintf(&items[n_items][0], "epais:%g ", header->epais); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->unites) { sprintf(&items[n_items][0], "unites:%.40s ", header->unites); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->facteur) { sprintf(&items[n_items][0], "facteur:%g ", header->facteur); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->zero) { sprintf(&items[n_items][0], "zero:%g ", header->zero); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if( bool_header->transparent ) { char *p=(char *)header->transparent, value[MAXL]; int a; for( a=0; atype]; a++ ) sprintf( value+a, "%x", *(p++) ); *(value+a) = '\0'; sprintf(&items[n_items][0], "transparent:%s ", value ); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->struct_desc) { sprintf(&items[n_items][0], "struct:%.40s ", header->struct_desc); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } if (bool_header->aut_name) { sprintf(&items[n_items][0], "aut:%.40s ", header->aut_name); l_item[n_items] = strlen(&items[n_items][0]); n_items++; } n_car_total = n_comment = 0; if (bool_header->comment) { comment = header->comment; while (*comment != NULL) { n_comment++; n_car_total += strlen(*comment++) + 3; } } /* Ecrit tous les items, sauf les commentaires */ for (i=0;i0) { n_lig_sup = 1 + (n_car_sup-1)/72; } else { n_lig_sup = 0; } n_car_dl = 1 + (n_car_sup-1)%72; /* Ecrit les commentaires */ if (bool_header->comment) { comment = header->comment; while (*comment != NULL) { char tmpstr[2048]; /* n_car = fprintf(file, "#%.80s\r\n", *comment++); if (n_car<0) { */ sprintf(tmpstr, "#%.80s\r\n", *comment++); if( gzwrite( file, tmpstr, strlen(tmpstr) ) == 0 ) { if (!Header_Quiet) { fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n"); perror("\n *** "); fprintf(stderr, "\n"); } sprintf(Header_Message, "\nHeader_Write: Erreur a l'ecriture \n"); return (0); } } } /* Complete l'entete a un multiple de 1024 caracteres */ for (i=0;i<70;i++) ligne[i] = ' '; ligne[70] = '\r'; ligne[71] = '\n'; ligne[72] = '\000'; for (i=0;i2) ligne[n_car_dl-3] = '\r'; if (n_car_dl>1) ligne[n_car_dl-2] = '\n'; ligne[n_car_dl-1] = FF; ligne[n_car_dl] = '\000'; /* if (EOF==fputs(ligne, file)) { */ if ( gzwrite(file, ligne, strlen(ligne)) == 0 ) { if (!Header_Quiet) { fprintf(stderr, "\nHeader_Write: Erreur a l'ecriture \n"); perror("\n *** "); fprintf(stderr, "\n"); } sprintf(Header_Message, "\nHeader_Write: Erreur a l'ecriture \n"); return (0); } if (n_car_total>1024) { if (!Header_Quiet) fprintf(stderr, "\nHeader_Write ATTENTION: etiquette de grandeur non-standard \n"); sprintf(Header_Message, "\nHeader_Write ATTENTION: etiquette de grandeur non-standard \n"); statut |= GRANDEUR_INV; } else { sprintf(Header_Message, "\nHeader_Write: Entete transcrite sans problemes\n"); } if (bool_header->vect_z) { if (header->vect_z==NULL) { if (!Header_Quiet) fprintf(stderr,"\nERREUR: vect_z nul\n"); sprintf(Header_Message, "\nERREUR: vect_z nul\n"); return(0) ; } /* fwrite(header->vect_z, sizeof(float), header->z, file);*/ gzwrite(file, header->vect_z, sizeof(float)*header->z); } return (statut); } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Ini_comment (void) */ /* */ /* description:Initialise le membre ".comment" d'une structure Header */ /* */ /* parametres: header_ptr (Header *) pointeur a la structure */ /* de type Header */ /* */ /* revision: 25/03/88 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ void Ini_comment(header_ptr) Header *header_ptr; { header_ptr->comment = (char **) malloc( sizeof(char *) ) ; header_ptr->comment[0] = NULL ; } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Ajoute_ligne (void) */ /* */ /* description:Ajoute une ligne de commentaire a une structure Header */ /* */ /* parametres: header_ptr (Header *) pointeur a la structure */ /* de type Header */ /* ligne (*char) la ligne ajoutee */ /* */ /* revision: 25/03/88 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ void Ajoute_ligne(header_ptr, ligne) Header *header_ptr; char *ligne; { register int i = 0, n_lignes = 0; while (header_ptr->comment[i++]!=NULL) n_lignes++; header_ptr->comment[n_lignes] = malloc(strlen(ligne) + 1) ; strcpy(header_ptr->comment[n_lignes++], ligne) ; header_ptr->comment = (char **)realloc(header_ptr->comment, (n_lignes+1)*sizeof(char *)); header_ptr->comment[n_lignes] = NULL; } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Aj_ligne_com (int) */ /* */ /* description:Ajoute un vecteur de chaines aux commentaires d' une */ /* structure Header */ /* */ /* parametres: header_ptr (Header *) pointeur a la structure */ /* de type Header */ /* argc (int) le nombre d'elements du vecteur */ /* argv (char **) le vecteurs de chaines */ /* */ /* retour: le nombre de lignes ajoutees */ /* */ /* revision: 13/06/88 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ int Aj_ligne_com(header_ptr, argc, argv) Header *header_ptr; int argc; char *argv[]; { auto int i, longueur, n_lignes = 0; auto char ligne[81]; if (argc<1) return(0); strcpy(ligne, argv[0]); for (i=1;i 72) { strcat(ligne, " \\"); Ajoute_ligne(header_ptr, ligne); sprintf(ligne, " %s", argv[i]); n_lignes++; } else { strcat(ligne, " "); strcat(ligne, argv[i]); } } Ajoute_ligne(header_ptr, ligne); n_lignes++; return(n_lignes); } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Retire_lignes (void) */ /* */ /* description:Retire des lignes de commentaire a une structure Header */ /* */ /* parametres: header_ptr (Header *) pointeur a la structure */ /* de type Header */ /* n_lig_ret (int) le nombre de lignes a retirer */ /* */ /* revision: 25/03/88 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ void Retire_lignes(header_ptr, n_lig_ret) Header *header_ptr; int n_lig_ret; { register int i = 0, n_lignes = 0; while (header_ptr->comment[i++]!=NULL) n_lignes++; if (n_lignes 0) { free (header_ptr->comment[--n_lignes]); } header_ptr->comment[n_lignes] = NULL; } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Ajoute_com (int) */ /* */ /* description:Ajoute les commentaires d'une structure Header a ceux */ /* d'une autre structure Header */ /* */ /* parametres: header_ptr1 (Header *) pointeur a la structure */ /* cible de type Header */ /* header_ptr2 (Header *) pointeur a la structure */ /* source de type Header */ /* indent (int) le nombre d'espace dont */ /* on indente les commentaires */ /* de header_ptr2 */ /* */ /* retour: le nombre de lignes ajoutees */ /* */ /* revision: 07/02/89 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ int Ajoute_com(header_ptr1, header_ptr2, indent) Header *header_ptr1, *header_ptr2; int indent; { register int i = 0, j, n_lignes1 = 0, n_lignes2 = 0; while (header_ptr1->comment[i++]!=NULL) n_lignes1++; i = 0; while (header_ptr2->comment[i++]!=NULL) n_lignes2++; header_ptr1->comment = (char **)realloc(header_ptr1->comment, (n_lignes1+n_lignes2+1)*sizeof(char *)); i = -1; while (header_ptr2->comment[++i]!=NULL) { header_ptr1->comment[n_lignes1] = malloc(strlen(header_ptr2->comment[i]) + indent + 1); header_ptr1->comment[n_lignes1][0] = '\0'; for (j=0;jcomment[n_lignes1], " "); strcat(header_ptr1->comment[n_lignes1++], header_ptr2->comment[i]); } header_ptr1->comment[n_lignes1] = NULL; return(n_lignes2); } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Header_Cpy (void) */ /* */ /* description:Copie les membres d'une structure Header dans */ /* une autre structure Header a l'exception des commentaires */ /* */ /* parametres: header_ptr1 (Header *) pointeur a la structure */ /* cible de type Header */ /* header_ptr2 (Header *) pointeur a la structure */ /* source de type Header */ /* */ /* revision: 09/10/1997 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ void Header_Cpy(header_ptr1, header_ptr2) Header *header_ptr1, *header_ptr2; { if (header_ptr1==NULL || header_ptr2==NULL) return; header_ptr1->x = header_ptr2->x; header_ptr1->y = header_ptr2->y; header_ptr1->z = header_ptr2->z; header_ptr1->t = header_ptr2->t; header_ptr1->type = header_ptr2->type; header_ptr1->taille = header_ptr2->taille; header_ptr1->bin = header_ptr2->bin; header_ptr1->trame = header_ptr2->trame; header_ptr1->num = header_ptr2->num; header_ptr1->epais = header_ptr2->epais; header_ptr1->org_x = header_ptr2->org_x; header_ptr1->org_y = header_ptr2->org_y; header_ptr1->org_z = header_ptr2->org_z; header_ptr1->org_t = header_ptr2->org_t; header_ptr1->inc_x = header_ptr2->inc_x; header_ptr1->inc_y = header_ptr2->inc_y; header_ptr1->inc_z = header_ptr2->inc_z; header_ptr1->inc_t = header_ptr2->inc_t; header_ptr1->dim_x = header_ptr2->dim_x; header_ptr1->dim_y = header_ptr2->dim_y; header_ptr1->dim_z = header_ptr2->dim_z; header_ptr1->dim_t = header_ptr2->dim_t; header_ptr1->fac_x = header_ptr2->fac_x; header_ptr1->fac_y = header_ptr2->fac_y; header_ptr1->fac_z = header_ptr2->fac_z; header_ptr1->fac_t = header_ptr2->fac_t; header_ptr1->vect_z = header_ptr2->vect_z; strcpy(header_ptr1->unites_x,header_ptr2->unites_x); strcpy(header_ptr1->unites_y,header_ptr2->unites_y); strcpy(header_ptr1->unites_z,header_ptr2->unites_z); strcpy(header_ptr1->unites_t,header_ptr2->unites_t); header_ptr1->lut = header_ptr2->lut; header_ptr1->comp = header_ptr2->comp; strcpy(header_ptr1->unites,header_ptr2->unites); header_ptr1->facteur = header_ptr2->facteur; header_ptr1->zero = header_ptr2->zero; strcpy(header_ptr1->aut_name,header_ptr2->aut_name); } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Bool_Header_Cpy (void) */ /* */ /* description:Copie les membres d'une structure Bool_Header dans */ /* une autre structure Bool_Header, */ /* a l'exception du champs commentaires */ /* */ /* parametres: b_header_ptr1 (Bool_Header *) pointeur a la structure */ /* cible de type Bool_Header */ /* b_header_ptr2 (Bool_Header *) pointeur a la structure */ /* source de type Bool_Header */ /* */ /* revision: 09/10/1997 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ void Bool_Header_Cpy(b_header_ptr1, b_header_ptr2) Bool_Header *b_header_ptr1, *b_header_ptr2; { if (b_header_ptr1==NULL || b_header_ptr2==NULL) return; b_header_ptr1->x = b_header_ptr2->x; b_header_ptr1->y = b_header_ptr2->y; b_header_ptr1->z = b_header_ptr2->z; b_header_ptr1->t = b_header_ptr2->t; b_header_ptr1->type = b_header_ptr2->type; b_header_ptr1->taille = b_header_ptr2->taille; b_header_ptr1->bin = b_header_ptr2->bin; b_header_ptr1->trame = b_header_ptr2->trame; b_header_ptr1->num = b_header_ptr2->num; b_header_ptr1->epais = b_header_ptr2->epais; b_header_ptr1->org_x = b_header_ptr2->org_x; b_header_ptr1->org_y = b_header_ptr2->org_y; b_header_ptr1->org_z = b_header_ptr2->org_z; b_header_ptr1->org_t = b_header_ptr2->org_t; b_header_ptr1->inc_x = b_header_ptr2->inc_x; b_header_ptr1->inc_y = b_header_ptr2->inc_y; b_header_ptr1->inc_z = b_header_ptr2->inc_z; b_header_ptr1->inc_t = b_header_ptr2->inc_t; b_header_ptr1->dim_x = b_header_ptr2->dim_x; b_header_ptr1->dim_y = b_header_ptr2->dim_y; b_header_ptr1->dim_z = b_header_ptr2->dim_z; b_header_ptr1->dim_t = b_header_ptr2->dim_t; b_header_ptr1->fac_x = b_header_ptr2->fac_x; b_header_ptr1->fac_y = b_header_ptr2->fac_y; b_header_ptr1->fac_z = b_header_ptr2->fac_z; b_header_ptr1->fac_t = b_header_ptr2->fac_t; b_header_ptr1->vect_z = b_header_ptr2->vect_z; b_header_ptr1->unites_x = b_header_ptr2->unites_x; b_header_ptr1->unites_y = b_header_ptr2->unites_y; b_header_ptr1->unites_z = b_header_ptr2->unites_z; b_header_ptr1->unites_t = b_header_ptr2->unites_t; b_header_ptr1->lut = b_header_ptr2->lut; b_header_ptr1->comp = b_header_ptr2->comp; b_header_ptr1->unites = b_header_ptr2->unites; b_header_ptr1->facteur = b_header_ptr2->facteur; b_header_ptr1->zero = b_header_ptr2->zero; b_header_ptr1->aut_name = b_header_ptr2->aut_name; } /*--------------------------------------------------------------------------*/ /* */ /* fonction: Img_Ext() (char *) */ /* */ /* description:Donne l'extension a utiliser pour les fichiers d'images */ /* en fonction de la variable d'environnement IMG_EXT et de */ /* de la valeur par defaut definie dans header.h. */ /* */ /* parametres: aucun */ /* */ /* retour: (char *) Pointeur statique a la chaine de */ /* caracteres */ /* */ /* revision: 08/03/93 Andre Bleau, ing. */ /* */ /*--------------------------------------------------------------------------*/ char *Img_Ext() { static char *extension; /* Extension pour les fichiers d'images */ if (extension==NULL) { extension = getenv("IMG_EXT"); if (extension==NULL) { extension = malloc(strlen(IMG_EXT)+1); strcpy(extension, IMG_EXT); } } return(extension); } /*---------------------------------------------------------------------------*\ fonction: ImageInvalide() (int) description:Retourne 0 si le nom donne en argument est celui d'un fichier contenant une image valide (lisible); retourne 1 sinon. parametres: nom (char *) le nom du fichier a verifier retour: int 0 (c'est bien une image) ou 1 (ce n'est pas une image) revision: 23/03/94 Andre Bleau, ing. \*---------------------------------------------------------------------------*/ int ImageInvalide(nom) char *nom; { static char nom_complet[257]; static Header header; static Bool_Header bool_header; auto gzFile df_entree; auto int quiet, statut; strcpy(nom_complet, nom); strcat(nom_complet, Img_Ext()); df_entree = fopen(nom_complet, "r"); if (df_entree==NULL) { strcpy(nom_complet, nom); df_entree = gzopen(nom_complet, "r"); } if (df_entree==NULL) { return(1); } quiet = Header_Quiet; Header_Quiet = 1; statut = Header_Read(df_entree, &header, &bool_header); Header_Quiet = quiet; if (statut==0) { return(1); } else { return(0); } }