#include #include #include #include #include "strutil.h" #include "nomfits2.h" #include "datime.h" /* ++ Module Aide au codage des noms Fits (C). Lib LibsUtil include nomfits2.h Pour aider a coder et decoder les noms de fichiers Fits Eros 1 et 2. Pour verifier la bonne sante d'un fichier Fits. -- */ /* ----------------------------------------------------------------- */ /* Reza+farhang, Avril 2007, copie depuis Peida/LibsUtil/datime.h .c */ /* ++ int DecodeStrgtoJMAHMS(const char* strg, JMA* jma, HMS* hms) Decodage d'une chaine sous forme "yyyy-mm-ddThh:mm:ss.s" ou "dd/mm/yy" ou "yy/mm/dd" (si yy > 31) ou "yyyy-mm-dd" ou "dd/mm/yyThh:mm:ss.s" en structure JMA et HMS. Si yy < 100 , 1900 est ajoute a l'annee. Les argumets "jma" ou "hms" peuvenet etre nuls. Code de retour : | Bit 0 ( -> 1) : Decodage date OK | Bit 1 ( -> 2) : DecodaGE Heure OK -- */ /* Nouvelle-Fonction */ int DecodeStrgtoJMAHMS(const char* strg, JMA* jma, HMS* hms) { JMA lj; HMS lh; int i,j,l,rc; int tiret; int T; char buff[256]; if (jma == NULL) jma = &lj; if (hms == NULL) hms = &lh; /* Initialisation de la date et de l'heure */ rc = 0; hms->Heures = 0; hms->Minutes = 0; hms->Secondes = 0.; jma->Annee = 0; jma->Mois = 0; jma->Jour = 0; l = strlen(strg); tiret = T = -1; for(i=0,j=0; i 254) break; if (strg[i] == ' ') continue; buff[j] = strg[i]; if (buff[j] == '-') { buff[j] = ' '; tiret = 1; } /* Date code avec un tiret */ if (buff[j] == 'T') T = j; /* Heure code dans la chaine */ j++; } buff[j] ='\0'; if (T >= 0) { buff[T] ='\0'; sscanf(buff+T+1,"%d:%d:%lf", &(hms->Heures),&(hms->Minutes),&(hms->Secondes)); if ( (hms->Heures>=0.) && (hms->Heures<24.) && (hms->Minutes>=0.) && (hms->Minutes<60.) && (hms->Secondes>=0.) && (hms->Secondes<60.) ) rc += 2; } if (tiret < 0) { sscanf(buff,"%d/%d/%d", &(jma->Jour),&(jma->Mois),&(jma->Annee)); /* Jour > 31 -> On tente yy/mm/dd */ if (jma->Jour>31) sscanf(buff,"%d/%d/%d", &(jma->Annee),&(jma->Mois),&(jma->Jour)); } else { /* Date code avec un tiret */ sscanf(buff,"%d %d %d", &(jma->Annee),&(jma->Mois),&(jma->Jour)); } if (jma->Annee < 100) jma->Annee += 1900; if ( (jma->Mois >= 1) && (jma->Mois <= 12) && (jma->Jour >= 1) && (jma->Jour <= 31) ) rc += 1; return(rc); } /* --- fin ajout depuis Peida/LibsUtil/datime.h ----- */ /*====================================================*/ /* ++ unsigned long int decode_zeza(const char* s, int i1, int i2) Pour coder (Rc) en entier decimal la chaine de caracteres comprise entre `s[i1]' et `s[i2]' interpretee comme une suite de Zezas (base 36 : 0 a z). -- */ unsigned long int decode_zeza(const char* s, int i1, int i2) { unsigned long int D, ibase = 1; int i, i0, sic; if( i1 < 0 ) i1 = 0; if( i2 > strlen(s) ) i2 = strlen(s); if( i2 < i1 ) return(0); for(i=i1; i<=i2; i++) if( ! isalnum((int) s[i]) ) break; i2 = i-1; /* printf("s=%s i1=%d i2=%d\n",s,i1,i2); */ if( i2 < i1 ) return(0); D = 0; for(i=i2; i>=i1; i--) { sic = (int) s[i]; if( islower(sic) ) i0 = (int) 'a' - 10; else if( isupper(sic) ) i0 = (int) 'A' - 10; else i0 = (int) '0'; D += (unsigned long int) ( sic - i0 ) * ibase; /* printf("-- s[%d]=%c sic=%d i0=%d D=%ld\n",i,s[i],sic,i0,D); */ ibase *= 36; } return( D ); } /*====================================================*/ /* ++ char * dec2zeza(unsigned long z, char *s, int n) Pour coder en Zeza (base 36) dans la chaine de characteres `s' de longeur maximum `n' le nombre entier decimal `z'. -- */ char * dec2zeza(unsigned long z, char *s, int n) { int r,i,j; char sz[16]; if(n<2) return NULL; sz[0] = '0'; sz[1] = '\0'; i=0; while (z) { r = z%36; if(r<10) sz[i] = '0'+r; else sz[i] = 'a'+r-10; z /= 36; i++; } for(j=0;jj) return(1); /* puis tri par objet*/ i = decode_zeza(s1,0,1); j = decode_zeza(s2,0,1); if(ij) return(1); /* puis tri par champ */ i = decode_zeza(s1,2,4); j = decode_zeza(s2,2,4); if(ij) return(1); /* puis tri par camera */ i = decode_zeza(s1,5,5); j = decode_zeza(s2,5,5); if(ij) return(1); /* puis tri par filtre */ i = decode_zeza(s1,8,8); j = decode_zeza(s2,8,8); if(ij) return(1); /* puis tri par traitement */ i = decode_zeza(s1,9,9); j = decode_zeza(s2,9,9); if(ij) return(1); /* puis tri par sequence */ i = decode_zeza(s1,14,999); j = decode_zeza(s2,14,999); if(ij) return(1); /* puis tri par sous-image */ i = decode_zeza(s1,7,7); j = decode_zeza(s2,7,7); if(ij) return(1); /* puis tri par ccd */ i = decode_zeza(s1,6,6); j = decode_zeza(s2,6,6); if(ij) return(1); /* Ici les noms sont identiques. */ return(0); } /* CMV: test des conneries du serveur MG ! */ /* taille du block d'un fichier fits */ #define HEAD_SIZE_CMV 2880 /* nombre maximum permis de blocks pour le header */ #define N_BLK_HEAD_CMV 100 /* ++ int Test_NoCorrupt(const char *flnm) Test pour voir si le fichier Fits de nom `flnm' n'est pas corrompu. | Rc = 0 : fichier OK | -1 : echec open | -2 : le buffer lu ne fait pas 80 caracteres | -3 : clef Fits sans signe = | -4 : la longueur que l'on deduit de l'entete fits | est incompatible avec celle du fichier. | -5 : il manque une clef Fits (NAXIS1,NAXIS2,NAXIS, BITPIX) | ou la clef BITPIX n'est pas correcte. -- */ int Test_NoCorrupt(const char *flnm) { int lp=0; FILE *fip; char buff[81],*c,*cval; unsigned short naxis_set, naxis1_set, naxis2_set, bitpix_set, end_set; int naxis1, naxis2, naxis, bitpix; long int nbytes_head,nbytes_pix,nbytes_tot,nbytes_mes; size_t i; fip = fopen(flnm,"rb"); if( fip == NULL ) { if(lp) printf("fopen: impossible de lire %s\n",flnm); return(-1); } naxis_set = naxis1_set = naxis2_set = bitpix_set = end_set = 0; naxis1 = naxis2 = naxis = bitpix = 0; nbytes_head = nbytes_pix = nbytes_tot = nbytes_mes = 0; for(;;) { i = fread(buff,1,80,fip); if(lp) printf("fread: rc=%d\n",(int) i); if( i != 80 ) return(-2); nbytes_head += (long int) i; if( nbytes_head / HEAD_SIZE_CMV > N_BLK_HEAD_CMV ) { if(lp) printf("Trop de block dans le header %d > %d\n" , (int) nbytes_head/HEAD_SIZE_CMV,N_BLK_HEAD_CMV); break; } buff[80] = '\0'; if(lp) printf("buff=(%s)\n",buff); c = buff; strip(c,'B',' '); if(lp) printf(" c=(%s)\n",c); if(strcmp(c,"END") == 0) { if(lp) printf(" END trouve\n"); end_set = 1; } else { if( (i=posc(c,'=')) < 0 ) { if(lp) printf(" pas de signe =\n"); return(-3); } *(c+i)='\0'; cval = c+i+1; strip(c,'B',' '); strip(cval,'B',' '); if(lp) printf(" c=(%s) cval=(%s)\n",c,cval); if(strcmp(c,"NAXIS") == 0) { sscanf(cval,"%d",&naxis); if(lp) printf(" NAXIS trouve\n"); naxis_set = 1; } if(strcmp(c,"NAXIS1") == 0) { sscanf(cval,"%d",&naxis1); if(lp) printf(" NAXIS1 trouve= %d\n",naxis1); naxis1_set = 1; } if(strcmp(c,"NAXIS2") == 0) { sscanf(cval,"%d",&naxis2); if(lp) printf(" NAXIS2 trouve= %d\n",naxis2); naxis2_set = 1; } if(strcmp(c,"BITPIX") == 0) { sscanf(cval,"%d",&bitpix); if(lp) printf(" BITPIX trouve= %d\n",bitpix); bitpix_set = 1; } } if(end_set) { if( naxis1_set && naxis2_set && bitpix_set && bitpix%8==0 ) { if( nbytes_head % HEAD_SIZE_CMV == 0 ) nbytes_head = nbytes_head / HEAD_SIZE_CMV; else nbytes_head = nbytes_head / HEAD_SIZE_CMV + 1; nbytes_head = nbytes_head*HEAD_SIZE_CMV; if( bitpix < 0 ) bitpix *= -1; bitpix /= 8; nbytes_pix = bitpix * naxis1*naxis2; if( nbytes_pix % HEAD_SIZE_CMV == 0 ) nbytes_pix = nbytes_pix / HEAD_SIZE_CMV; else nbytes_pix = nbytes_pix / HEAD_SIZE_CMV + 1; nbytes_pix = nbytes_pix*HEAD_SIZE_CMV; nbytes_tot = nbytes_head + nbytes_pix; if(lp) printf("Taille predite: header=%ld core=%ld tot=%ld bytes\n" ,nbytes_head,nbytes_pix,nbytes_tot); fseek(fip, 0L, SEEK_END); nbytes_mes = ftell(fip); if(lp) printf("Taille totale mesuree= %ld bytes\n",nbytes_mes); fclose(fip); if( nbytes_tot == nbytes_mes ) return(0); else return(-4); } else break; } } fclose(fip); return(-5); } #undef HEAD_SIZE_CMV #undef N_BLK_HEAD_CMV /*====================================================*/ /* ++ uint_4 DateTstoInt(char *date,char *t) Pour coder la date et l'heure dans un entier (TimeInfo). | 16 bits de poids forts : nombre de jours ecoules depuis de 1/1/90. | faibles: temps en unites de 2sec. -- */ uint_4 DateTstoInt(const char *date,const char *ts) { JMA D,D0; HMS T; uint_4 Dj,Ts; int_4 dDj; /* init pout protection contre date,ts mal definis */ StrgtoJMA("01/01/1990",D); StrgtoHMS("0:0:0",T); StrgtoJMA(date,D); StrgtoJMA("01/01/1990",D0); dDj = JMAtoJ(D) - JMAtoJ(D0); if( dDj > 32767 ) dDj = 32767; if( dDj < -32767 ) dDj = -32767; if (dDj >= 0) Dj = dDj; else Dj = 32768-dDj; StrgtoHMS(ts,T); Ts = (uint_4)(HMStoSec(T)/2.); if( Ts > 65535 ) Ts = 65535; return ((Dj<<16)+Ts); } /*====================================================*/ /* ++ uint_4 DateTimetoInt(const char *datetime) Pour coder la date et l'heure dans un entier (TimeInfo). | 16 bits de poids forts : nombre de jours ecoules depuis de 1/1/90. | faibles: temps en unites de 2sec. -- */ uint_4 DateTimetoInt(const char *datetime) { JMA D,D0; HMS T; uint_4 Dj,Ts; int_4 dDj; int rc; /* init pout protection contre date,ts mal definis */ StrgtoJMA("01/01/1990",D); StrgtoHMS("0:0:0",T); rc = DecodeStrgtoJMAHMS(datetime, &D, &T); if (rc != 3) printf("DateTimetoInt(%s)/Warning - incomplete Date/Time specification (Rc=%d) \n", datetime, rc); StrgtoJMA("01/01/1990",D0); dDj = JMAtoJ(D) - JMAtoJ(D0); if( dDj > 32767 ) dDj = 32767; if( dDj < -32767 ) dDj = -32767; if (dDj >= 0) Dj = dDj; else Dj = 32768-dDj; Ts = (uint_4)(HMStoSec(T)/2.); if( Ts > 65535 ) Ts = 65535; return ((Dj<<16)+Ts); } /*====================================================*/ /* ++ void InttoDateTs(uint_4 n,int_4 *date,int_4 *t) Pour decoder la date et l'heure depuis un entier (TimeInfo). | n : entier code. | date: nombre de jours ecoules depuis de 1/1/90. | t : heure en secondes (precision 2s). -- */ void InttoDateTs(uint_4 n,int_4 *date,int_4 *ts) { uint_4 dj, dt; dt = 2 * (n & 0xFFFF); dj = (n>>16) & 0xFFFF; if (dj > 32767) dj = 32768 - dj; *ts = dt; *date = dj; }