1 | #include <string.h>
|
---|
2 | #include <stdlib.h>
|
---|
3 | #include <stdio.h>
|
---|
4 | #include <ctype.h>
|
---|
5 |
|
---|
6 | #include "strutil.h"
|
---|
7 | #include "nomfits2.h"
|
---|
8 | #include "datime.h"
|
---|
9 |
|
---|
10 | /*
|
---|
11 | ++
|
---|
12 | Module Aide au codage des noms Fits (C).
|
---|
13 | Lib LibsUtil
|
---|
14 | include nomfits2.h
|
---|
15 |
|
---|
16 | Pour aider a coder et decoder les noms de fichiers Fits Eros 1 et 2.
|
---|
17 | Pour verifier la bonne sante d'un fichier Fits.
|
---|
18 | --
|
---|
19 | */
|
---|
20 | /* ----------------------------------------------------------------- */
|
---|
21 | /* Reza+farhang, Avril 2007, copie depuis Peida/LibsUtil/datime.h .c */
|
---|
22 | /*
|
---|
23 | ++
|
---|
24 | int DecodeStrgtoJMAHMS(const char* strg, JMA* jma, HMS* hms)
|
---|
25 | Decodage d'une chaine sous forme "yyyy-mm-ddThh:mm:ss.s" ou "dd/mm/yy" ou
|
---|
26 | "yy/mm/dd" (si yy > 31) ou "yyyy-mm-dd" ou "dd/mm/yyThh:mm:ss.s" en
|
---|
27 | structure JMA et HMS. Si yy < 100 , 1900 est ajoute a l'annee.
|
---|
28 | Les argumets "jma" ou "hms" peuvenet etre nuls.
|
---|
29 | Code de retour :
|
---|
30 | | Bit 0 ( -> 1) : Decodage date OK
|
---|
31 | | Bit 1 ( -> 2) : DecodaGE Heure OK
|
---|
32 |
|
---|
33 | --
|
---|
34 | */
|
---|
35 | /* Nouvelle-Fonction */
|
---|
36 | int DecodeStrgtoJMAHMS(const char* strg, JMA* jma, HMS* hms)
|
---|
37 | {
|
---|
38 | JMA lj;
|
---|
39 | HMS lh;
|
---|
40 | int i,j,l,rc;
|
---|
41 | int tiret;
|
---|
42 | int T;
|
---|
43 | char buff[256];
|
---|
44 |
|
---|
45 | if (jma == NULL) jma = &lj;
|
---|
46 | if (hms == NULL) hms = &lh;
|
---|
47 |
|
---|
48 | /* Initialisation de la date et de l'heure */
|
---|
49 | rc = 0;
|
---|
50 | hms->Heures = 0;
|
---|
51 | hms->Minutes = 0;
|
---|
52 | hms->Secondes = 0.;
|
---|
53 | jma->Annee = 0;
|
---|
54 | jma->Mois = 0;
|
---|
55 | jma->Jour = 0;
|
---|
56 |
|
---|
57 |
|
---|
58 | l = strlen(strg);
|
---|
59 | tiret = T = -1;
|
---|
60 | for(i=0,j=0; i<l; i++) {
|
---|
61 | if (j > 254) break;
|
---|
62 | if (strg[i] == ' ') continue;
|
---|
63 | buff[j] = strg[i];
|
---|
64 | if (buff[j] == '-') { buff[j] = ' '; tiret = 1; } /* Date code avec un tiret */
|
---|
65 | if (buff[j] == 'T') T = j; /* Heure code dans la chaine */
|
---|
66 | j++;
|
---|
67 | }
|
---|
68 |
|
---|
69 | buff[j] ='\0';
|
---|
70 | if (T >= 0) {
|
---|
71 | buff[T] ='\0';
|
---|
72 | sscanf(buff+T+1,"%d:%d:%lf", &(hms->Heures),&(hms->Minutes),&(hms->Secondes));
|
---|
73 | if ( (hms->Heures>=0.) && (hms->Heures<24.) &&
|
---|
74 | (hms->Minutes>=0.) && (hms->Minutes<60.) &&
|
---|
75 | (hms->Secondes>=0.) && (hms->Secondes<60.) ) rc += 2;
|
---|
76 | }
|
---|
77 | if (tiret < 0) {
|
---|
78 | sscanf(buff,"%d/%d/%d", &(jma->Jour),&(jma->Mois),&(jma->Annee));
|
---|
79 | /* Jour > 31 -> On tente yy/mm/dd */
|
---|
80 | if (jma->Jour>31) sscanf(buff,"%d/%d/%d", &(jma->Annee),&(jma->Mois),&(jma->Jour));
|
---|
81 | }
|
---|
82 | else { /* Date code avec un tiret */
|
---|
83 | sscanf(buff,"%d %d %d", &(jma->Annee),&(jma->Mois),&(jma->Jour));
|
---|
84 | }
|
---|
85 | if (jma->Annee < 100) jma->Annee += 1900;
|
---|
86 | if ( (jma->Mois >= 1) && (jma->Mois <= 12) && (jma->Jour >= 1) && (jma->Jour <= 31) ) rc += 1;
|
---|
87 | return(rc);
|
---|
88 | }
|
---|
89 | /* --- fin ajout depuis Peida/LibsUtil/datime.h ----- */
|
---|
90 |
|
---|
91 |
|
---|
92 | /*====================================================*/
|
---|
93 | /*
|
---|
94 | ++
|
---|
95 | unsigned long int decode_zeza(char* s, int i1, int i2)
|
---|
96 | Pour coder (Rc) en entier decimal la chaine de caracteres
|
---|
97 | comprise entre `s[i1]' et `s[i2]' interpretee comme
|
---|
98 | une suite de Zezas (base 36 : 0 a z).
|
---|
99 | --
|
---|
100 | */
|
---|
101 | unsigned long int decode_zeza(char* s, int i1, int i2)
|
---|
102 | {
|
---|
103 | unsigned long int D, ibase = 1;
|
---|
104 | int i, i0, sic;
|
---|
105 |
|
---|
106 | if( i1 < 0 ) i1 = 0;
|
---|
107 | if( i2 > strlen(s) ) i2 = strlen(s);
|
---|
108 | if( i2 < i1 ) return(0);
|
---|
109 | for(i=i1; i<=i2; i++) if( ! isalnum((int) s[i]) ) break;
|
---|
110 | i2 = i-1;
|
---|
111 | /* printf("s=%s i1=%d i2=%d\n",s,i1,i2); */
|
---|
112 | if( i2 < i1 ) return(0);
|
---|
113 |
|
---|
114 | D = 0;
|
---|
115 | for(i=i2; i>=i1; i--) {
|
---|
116 | sic = (int) s[i];
|
---|
117 | if( islower(sic) ) i0 = (int) 'a' - 10;
|
---|
118 | else if( isupper(sic) ) i0 = (int) 'A' - 10;
|
---|
119 | else i0 = (int) '0';
|
---|
120 | D += (unsigned long int) ( sic - i0 ) * ibase;
|
---|
121 | /* printf("-- s[%d]=%c sic=%d i0=%d D=%ld\n",i,s[i],sic,i0,D); */
|
---|
122 | ibase *= 36;
|
---|
123 | }
|
---|
124 | return( D );
|
---|
125 | }
|
---|
126 |
|
---|
127 | /*====================================================*/
|
---|
128 | /*
|
---|
129 | ++
|
---|
130 | char * dec2zeza(unsigned long z, char *s, int n)
|
---|
131 | Pour coder en Zeza (base 36) dans la chaine de characteres
|
---|
132 | `s' de longeur maximum `n' le nombre entier decimal `z'.
|
---|
133 | --
|
---|
134 | */
|
---|
135 | char * dec2zeza(unsigned long z, char *s, int n)
|
---|
136 | {
|
---|
137 | int r,i,j;
|
---|
138 | char sz[16];
|
---|
139 | if(n<2) return NULL;
|
---|
140 | sz[0] = '0'; sz[1] = '\0';
|
---|
141 | i=0;
|
---|
142 | while (z) {
|
---|
143 | r = z%36;
|
---|
144 | if(r<10) sz[i] = '0'+r; else sz[i] = 'a'+r-10;
|
---|
145 | z /= 36;
|
---|
146 | i++;
|
---|
147 | }
|
---|
148 | for(j=0;j<i && j<n-1;j++) s[j] = sz[i-j-1];
|
---|
149 | s[j] = '\0';
|
---|
150 |
|
---|
151 | return( s );
|
---|
152 | }
|
---|
153 |
|
---|
154 | /*====================================================*/
|
---|
155 | /*
|
---|
156 | ++
|
---|
157 | int qSort_fits2(const void *x1,const void *x2)
|
---|
158 | Pour trier avec `qsort' un tableau de pointeurs sur
|
---|
159 | des chaines de caracteres de noms de fichiers fits Eros2.
|
---|
160 | Le tri s'effectue dans l'ordre canonique suivant,
|
---|
161 | apres convertion des chaines de caracteres
|
---|
162 | interpretees comme des Zezas en entier decimal:
|
---|
163 | | nom = oo ccc C c s f t dddd sss
|
---|
164 | | 1- sur la date dddd,
|
---|
165 | | 2- sur l'objet oo,
|
---|
166 | | 3- sur le champ ccc,
|
---|
167 | | 4- sur le numero de camera C
|
---|
168 | | 5- sur le nom du filtre f,
|
---|
169 | | 6- sur le type de traitement t,
|
---|
170 | | 7- sur le numero de sequence sss,
|
---|
171 | | 8- sur le numero de sous-image s,
|
---|
172 | | 9- sur le numero de ccd c.
|
---|
173 | --
|
---|
174 | */
|
---|
175 | int qSort_fits2(const void *x1,const void *x2)
|
---|
176 | /* oo ccc c c s f t dddd sss */
|
---|
177 | /* bb hhh a c s i r aaaa eee */
|
---|
178 | /* jj ppp m d i l a tttt qqq */
|
---|
179 | /* */
|
---|
180 | /* 01 234 5 6 7 8 9 1111 111 */
|
---|
181 | /* 0123 456 */
|
---|
182 | {
|
---|
183 | unsigned long int i,j;
|
---|
184 | char *s1, *s2;
|
---|
185 |
|
---|
186 | s1 = *((char **) x1);
|
---|
187 | s2 = *((char **) x2);
|
---|
188 |
|
---|
189 | /* tri par date */
|
---|
190 | i = decode_zeza(s1,10,13);
|
---|
191 | j = decode_zeza(s2,10,13);
|
---|
192 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
193 |
|
---|
194 | /* puis tri par objet*/
|
---|
195 | i = decode_zeza(s1,0,1);
|
---|
196 | j = decode_zeza(s2,0,1);
|
---|
197 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
198 |
|
---|
199 | /* puis tri par champ */
|
---|
200 | i = decode_zeza(s1,2,4);
|
---|
201 | j = decode_zeza(s2,2,4);
|
---|
202 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
203 |
|
---|
204 | /* puis tri par camera */
|
---|
205 | i = decode_zeza(s1,5,5);
|
---|
206 | j = decode_zeza(s2,5,5);
|
---|
207 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
208 |
|
---|
209 | /* puis tri par filtre */
|
---|
210 | i = decode_zeza(s1,8,8);
|
---|
211 | j = decode_zeza(s2,8,8);
|
---|
212 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
213 |
|
---|
214 | /* puis tri par traitement */
|
---|
215 | i = decode_zeza(s1,9,9);
|
---|
216 | j = decode_zeza(s2,9,9);
|
---|
217 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
218 |
|
---|
219 | /* puis tri par sequence */
|
---|
220 | i = decode_zeza(s1,14,999);
|
---|
221 | j = decode_zeza(s2,14,999);
|
---|
222 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
223 |
|
---|
224 | /* puis tri par sous-image */
|
---|
225 | i = decode_zeza(s1,7,7);
|
---|
226 | j = decode_zeza(s2,7,7);
|
---|
227 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
228 |
|
---|
229 | /* puis tri par ccd */
|
---|
230 | i = decode_zeza(s1,6,6);
|
---|
231 | j = decode_zeza(s2,6,6);
|
---|
232 | if(i<j) return(-1); else if(i>j) return(1);
|
---|
233 |
|
---|
234 | /* Ici les noms sont identiques. */
|
---|
235 | return(0);
|
---|
236 | }
|
---|
237 |
|
---|
238 |
|
---|
239 |
|
---|
240 | /* CMV: test des conneries du serveur MG ! */
|
---|
241 |
|
---|
242 | /* taille du block d'un fichier fits */
|
---|
243 | #define HEAD_SIZE_CMV 2880
|
---|
244 | /* nombre maximum permis de blocks pour le header */
|
---|
245 | #define N_BLK_HEAD_CMV 100
|
---|
246 |
|
---|
247 | /*
|
---|
248 | ++
|
---|
249 | int Test_NoCorrupt(char *flnm)
|
---|
250 | Test pour voir si le fichier Fits de nom `flnm' n'est
|
---|
251 | pas corrompu.
|
---|
252 | | Rc = 0 : fichier OK
|
---|
253 | | -1 : echec open
|
---|
254 | | -2 : le buffer lu ne fait pas 80 caracteres
|
---|
255 | | -3 : clef Fits sans signe =
|
---|
256 | | -4 : la longueur que l'on deduit de l'entete fits
|
---|
257 | | est incompatible avec celle du fichier.
|
---|
258 | | -5 : il manque une clef Fits (NAXIS1,NAXIS2,NAXIS, BITPIX)
|
---|
259 | | ou la clef BITPIX n'est pas correcte.
|
---|
260 | --
|
---|
261 | */
|
---|
262 | int Test_NoCorrupt(char *flnm)
|
---|
263 | {
|
---|
264 | int lp=0;
|
---|
265 | FILE *fip;
|
---|
266 | char buff[81],*c,*cval;
|
---|
267 | unsigned short naxis_set, naxis1_set, naxis2_set, bitpix_set, end_set;
|
---|
268 | int naxis1, naxis2, naxis, bitpix;
|
---|
269 | long int nbytes_head,nbytes_pix,nbytes_tot,nbytes_mes;
|
---|
270 | size_t i;
|
---|
271 |
|
---|
272 | fip = fopen(flnm,"rb");
|
---|
273 | if( fip == NULL ) {
|
---|
274 | if(lp) printf("fopen: impossible de lire %s\n",flnm);
|
---|
275 | return(-1);
|
---|
276 | }
|
---|
277 |
|
---|
278 | naxis_set = naxis1_set = naxis2_set = bitpix_set = end_set = 0;
|
---|
279 | naxis1 = naxis2 = naxis = bitpix = 0;
|
---|
280 | nbytes_head = nbytes_pix = nbytes_tot = nbytes_mes = 0;
|
---|
281 |
|
---|
282 | for(;;) {
|
---|
283 |
|
---|
284 | i = fread(buff,1,80,fip);
|
---|
285 | if(lp) printf("fread: rc=%d\n",(int) i);
|
---|
286 | if( i != 80 ) return(-2);
|
---|
287 | nbytes_head += (long int) i;
|
---|
288 |
|
---|
289 | if( nbytes_head / HEAD_SIZE_CMV > N_BLK_HEAD_CMV ) {
|
---|
290 | if(lp) printf("Trop de block dans le header %d > %d\n"
|
---|
291 | , (int) nbytes_head/HEAD_SIZE_CMV,N_BLK_HEAD_CMV);
|
---|
292 | break;
|
---|
293 | }
|
---|
294 |
|
---|
295 | buff[80] = '\0';
|
---|
296 | if(lp) printf("buff=(%s)\n",buff);
|
---|
297 |
|
---|
298 | c = buff;
|
---|
299 | strip(c,'B',' ');
|
---|
300 | if(lp) printf(" c=(%s)\n",c);
|
---|
301 |
|
---|
302 | if(strcmp(c,"END") == 0) {
|
---|
303 | if(lp) printf(" END trouve\n");
|
---|
304 | end_set = 1;
|
---|
305 | } else {
|
---|
306 | if( (i=posc(c,'=')) < 0 ) {
|
---|
307 | if(lp) printf(" pas de signe =\n");
|
---|
308 | return(-3);
|
---|
309 | }
|
---|
310 | *(c+i)='\0';
|
---|
311 | cval = c+i+1;
|
---|
312 | strip(c,'B',' ');
|
---|
313 | strip(cval,'B',' ');
|
---|
314 | if(lp) printf(" c=(%s) cval=(%s)\n",c,cval);
|
---|
315 |
|
---|
316 | if(strcmp(c,"NAXIS") == 0) {
|
---|
317 | sscanf(cval,"%d",&naxis);
|
---|
318 | if(lp) printf(" NAXIS trouve\n");
|
---|
319 | naxis_set = 1;
|
---|
320 | }
|
---|
321 | if(strcmp(c,"NAXIS1") == 0) {
|
---|
322 | sscanf(cval,"%d",&naxis1);
|
---|
323 | if(lp) printf(" NAXIS1 trouve= %d\n",naxis1);
|
---|
324 | naxis1_set = 1;
|
---|
325 | }
|
---|
326 | if(strcmp(c,"NAXIS2") == 0) {
|
---|
327 | sscanf(cval,"%d",&naxis2);
|
---|
328 | if(lp) printf(" NAXIS2 trouve= %d\n",naxis2);
|
---|
329 | naxis2_set = 1;
|
---|
330 | }
|
---|
331 | if(strcmp(c,"BITPIX") == 0) {
|
---|
332 | sscanf(cval,"%d",&bitpix);
|
---|
333 | if(lp) printf(" BITPIX trouve= %d\n",bitpix);
|
---|
334 | bitpix_set = 1;
|
---|
335 | }
|
---|
336 | }
|
---|
337 |
|
---|
338 | if(end_set) {
|
---|
339 | if( naxis1_set && naxis2_set && bitpix_set && bitpix%8==0 ) {
|
---|
340 |
|
---|
341 | if( nbytes_head % HEAD_SIZE_CMV == 0 ) nbytes_head = nbytes_head / HEAD_SIZE_CMV;
|
---|
342 | else nbytes_head = nbytes_head / HEAD_SIZE_CMV + 1;
|
---|
343 | nbytes_head = nbytes_head*HEAD_SIZE_CMV;
|
---|
344 |
|
---|
345 | if( bitpix < 0 ) bitpix *= -1;
|
---|
346 | bitpix /= 8;
|
---|
347 | nbytes_pix = bitpix * naxis1*naxis2;
|
---|
348 | if( nbytes_pix % HEAD_SIZE_CMV == 0 ) nbytes_pix = nbytes_pix / HEAD_SIZE_CMV;
|
---|
349 | else nbytes_pix = nbytes_pix / HEAD_SIZE_CMV + 1;
|
---|
350 | nbytes_pix = nbytes_pix*HEAD_SIZE_CMV;
|
---|
351 |
|
---|
352 | nbytes_tot = nbytes_head + nbytes_pix;
|
---|
353 |
|
---|
354 | if(lp)
|
---|
355 | printf("Taille predite: header=%ld core=%ld tot=%ld bytes\n"
|
---|
356 | ,nbytes_head,nbytes_pix,nbytes_tot);
|
---|
357 |
|
---|
358 | fseek(fip, 0L, SEEK_END);
|
---|
359 | nbytes_mes = ftell(fip);
|
---|
360 | if(lp) printf("Taille totale mesuree= %ld bytes\n",nbytes_mes);
|
---|
361 |
|
---|
362 | fclose(fip);
|
---|
363 | if( nbytes_tot == nbytes_mes ) return(0); else return(-4);
|
---|
364 | } else break;
|
---|
365 | }
|
---|
366 |
|
---|
367 | }
|
---|
368 |
|
---|
369 | fclose(fip);
|
---|
370 | return(-5);
|
---|
371 | }
|
---|
372 | #undef HEAD_SIZE_CMV
|
---|
373 | #undef N_BLK_HEAD_CMV
|
---|
374 |
|
---|
375 |
|
---|
376 | /*====================================================*/
|
---|
377 | /*
|
---|
378 | ++
|
---|
379 | uint_4 DateTstoInt(char *date,char *t)
|
---|
380 | Pour coder la date et l'heure
|
---|
381 | dans un entier (TimeInfo).
|
---|
382 | | 16 bits de poids forts : nombre de jours ecoules depuis de 1/1/90.
|
---|
383 | | faibles: temps en unites de 2sec.
|
---|
384 | --
|
---|
385 | */
|
---|
386 | uint_4 DateTstoInt(const char *date,const char *ts)
|
---|
387 | {
|
---|
388 | JMA D,D0;
|
---|
389 | HMS T;
|
---|
390 | uint_4 Dj,Ts;
|
---|
391 | int_4 dDj;
|
---|
392 |
|
---|
393 | /* init pout protection contre date,ts mal definis */
|
---|
394 | StrgtoJMA("01/01/1990",D);
|
---|
395 | StrgtoHMS("0:0:0",T);
|
---|
396 |
|
---|
397 | StrgtoJMA(date,D);
|
---|
398 | StrgtoJMA("01/01/1990",D0);
|
---|
399 | dDj = JMAtoJ(D) - JMAtoJ(D0);
|
---|
400 | if( dDj > 32767 ) dDj = 32767;
|
---|
401 | if( dDj < -32767 ) dDj = -32767;
|
---|
402 | if (dDj >= 0) Dj = dDj;
|
---|
403 | else Dj = 32768-dDj;
|
---|
404 |
|
---|
405 | StrgtoHMS(ts,T);
|
---|
406 | Ts = (uint_4)(HMStoSec(T)/2.);
|
---|
407 | if( Ts > 65535 ) Ts = 65535;
|
---|
408 |
|
---|
409 | return ((Dj<<16)+Ts);
|
---|
410 | }
|
---|
411 |
|
---|
412 | /*====================================================*/
|
---|
413 | /*
|
---|
414 | ++
|
---|
415 | uint_4 DateTimetoInt(const char *datetime)
|
---|
416 | Pour coder la date et l'heure
|
---|
417 | dans un entier (TimeInfo).
|
---|
418 | | 16 bits de poids forts : nombre de jours ecoules depuis de 1/1/90.
|
---|
419 | | faibles: temps en unites de 2sec.
|
---|
420 | --
|
---|
421 | */
|
---|
422 | uint_4 DateTimetoInt(const char *datetime)
|
---|
423 | {
|
---|
424 | JMA D,D0;
|
---|
425 | HMS T;
|
---|
426 | uint_4 Dj,Ts;
|
---|
427 | int_4 dDj;
|
---|
428 | int rc;
|
---|
429 |
|
---|
430 | /* init pout protection contre date,ts mal definis */
|
---|
431 | StrgtoJMA("01/01/1990",D);
|
---|
432 | StrgtoHMS("0:0:0",T);
|
---|
433 | rc = DecodeStrgtoJMAHMS(datetime, &D, &T);
|
---|
434 | if (rc != 3)
|
---|
435 | printf("DateTimetoInt(%s)/Warning - incomplete Date/Time specification (Rc=%d) \n",
|
---|
436 | datetime, rc);
|
---|
437 | StrgtoJMA("01/01/1990",D0);
|
---|
438 | dDj = JMAtoJ(D) - JMAtoJ(D0);
|
---|
439 | if( dDj > 32767 ) dDj = 32767;
|
---|
440 | if( dDj < -32767 ) dDj = -32767;
|
---|
441 | if (dDj >= 0) Dj = dDj;
|
---|
442 | else Dj = 32768-dDj;
|
---|
443 |
|
---|
444 | Ts = (uint_4)(HMStoSec(T)/2.);
|
---|
445 | if( Ts > 65535 ) Ts = 65535;
|
---|
446 |
|
---|
447 | return ((Dj<<16)+Ts);
|
---|
448 | }
|
---|
449 |
|
---|
450 | /*====================================================*/
|
---|
451 | /*
|
---|
452 | ++
|
---|
453 | void InttoDateTs(uint_4 n,int_4 *date,int_4 *t)
|
---|
454 | Pour decoder la date et l'heure
|
---|
455 | depuis un entier (TimeInfo).
|
---|
456 | | n : entier code.
|
---|
457 | | date: nombre de jours ecoules depuis de 1/1/90.
|
---|
458 | | t : heure en secondes (precision 2s).
|
---|
459 | --
|
---|
460 | */
|
---|
461 | void InttoDateTs(uint_4 n,int_4 *date,int_4 *ts)
|
---|
462 | {
|
---|
463 | uint_4 dj, dt;
|
---|
464 | dt = 2 * (n & 0xFFFF);
|
---|
465 | dj = (n>>16) & 0xFFFF;
|
---|
466 | if (dj > 32767) dj = 32768 - dj;
|
---|
467 | *ts = dt;
|
---|
468 | *date = dj;
|
---|
469 | }
|
---|