OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
pdsmerge.c
Go to the documentation of this file.
1 /********************************************************************
2  * *
3  * Copyright (C) 2007, 2008 *
4  * Charles Darwin University, Darwin, Australia *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be *
12  * useful, but WITHOUT ANY WARRANTY; without even the implied *
13  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *
14  * PURPOSE. See the GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public *
17  * License along with this program; if not, write to the Free *
18  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
19  * MA 02111-1307 USA *
20  * *
21  ********************************************************************
22  * *
23  * merge multiple PDS files into one file *
24  * *
25  * 12/12/2007 S. W. Maier start of work *
26  * 12/12/2007 S. W. Maier initial version *
27  * 25/12/2007 S. W. Maier added start and end date parameters *
28  * 10/06/2008 S. W. Maier increased data buffer and test for *
29  * packet size before reading *
30  * 10/10/2008 S. W. Maier increased data buffer *
31  * *
32  ********************************************************************
33  * *
34  * usage: pdsmerge start_date end_date APID <input 1> [<input 2> *
35  * [...]] output *
36  * *
37  ********************************************************************
38  * *
39  * to do: *
40  * - support other sensors *
41  * *
42  * known issues: *
43  * - doesn't take into account leap seconds *
44  * *
45  ********************************************************************
46  * *
47  * build: cc pdsmerge.c -lm -o pdsmerge *
48  * *
49  ********************************************************************/
50 
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <math.h>
54 #include <string.h>
55 
56 
57 /********************************************************************
58  * *
59  * defines *
60  * *
61  ********************************************************************/
62 /* name */
63 #define NAME "pdsmerge"
64 /* version */
65 #define VERSION 1
66 /* revision */
67 #define REVISION 3
68 /* usage */
69 #define USAGE "start_date end_date APID <input 1> [<input 2> [...]] output\nstart_date/end_date: YYYY/MM/DD,hh:mm:ss or -"
70 /* primary header size */
71 #define PRI_HDR_SIZE 6
72 /* MODIS secondary header size */
73 #define MODIS_HDR_SIZE 12
74 /* data buffer size */
75 #define DATA_SIZE 100000
76 /* Julian Day of MODIS reference date (01/01/1958)*/
77 #define MODIS_REF_DATE 2436205.0
78 
79 
80 /********************************************************************
81  * *
82  * structure definitions *
83  * *
84  ********************************************************************/
85 
86 /* primary header */
87 struct pri_hdr {
88  int flag;
89  int version;
90  int type;
91  int sec_hdr_flag;
92  int apid;
93  int seq_flags;
94  int pkt_count;
95  int pkt_length;
96 };
97 
98 /* MODIS header */
99 struct modis_hdr {
100  int days;
101  unsigned long int millisec;
102  int microsec;
103  int ql;
104  int pkt_type;
105  int scan_count;
106  int mirror_side;
107  int src1;
108  int src2;
109  int conf;
110  int sci_state;
111  int sci_abnorm;
112  int checksum;
113 };
114 
115 
116 /********************************************************************
117  * *
118  * function declarations *
119  * *
120  ********************************************************************/
121 int ReadPriHdr(FILE *f, unsigned char *buf);
122 int WritePriHdr(FILE *f, unsigned char *buf);
123 int DecodePriHdr(unsigned char *buf, struct pri_hdr *hdr);
124 int DecodeMODISHdr(unsigned char *buf, int len,
125  struct modis_hdr *hdr);
126 void julday(int minute, int hour, int day, int month, int year,
127  double *jul);
128 void caldat(int *minute, int *hour, int *day, int *month, int *year,
129  double jul);
130 int CalcChecksum12(unsigned char *buf, int n);
131 
132 /********************************************************************
133  * *
134  * main function *
135  * *
136  ********************************************************************/
137 int main(int argc, char *argv[]) {
138  /* pointer to input file pointer array */
139  FILE **fin;
140  /* output file pointer */
141  FILE *fout;
142  /* pointer to primary header structure pointer array */
143  struct pri_hdr **hdr;
144  /* pointer to MODIS header structure pointer array */
145  struct modis_hdr **mhdr;
146  /* pointer to header buffer pointer array */
147  unsigned char **buf_hdr;
148  /* pointer to data buffer pointer array */
149  unsigned char **buf_data;
150  /* number of input files */
151  int n;
152  /* APID */
153  int apid;
154  /* checksum */
155  int chksum;
156  /* input stream with oldest packet */
157  int oldest;
158  /* flag for valid packet available */
159  int valpkt;
160  /* counter */
161  int i;
162  /* error code */
163  int error;
164  /* date/time */
165  int year, month, day, hour, min, sec;
166  /* start date/time */
167  int startday;
168  unsigned long startmillisec;
169  /* end date/time */
170  int endday;
171  unsigned long endmillisec;
172  /* buffer */
173  double x;
174  /* last packet date/time/pktcount */
175  int lastdays = 0, lastmicrosec = 0, lastpktcount = 0;
176  unsigned long int lastmillisec = 0;
177  /* packet difference */
178  int pktdiff;
179 
180 
181  /* print version information */
182  fprintf(stderr, "%s V%d.%d ("__DATE__")\n",
183  NAME, VERSION, REVISION);
184 
185  /* check number of arguments */
186  if (argc < 6) {
187  fprintf(stderr, "USAGE: %s %s\n", NAME, USAGE);
188  return (20);
189  }
190 
191  /* determine number of input files */
192  n = argc - 5;
193 
194  /* get start date */
195  if (strcmp(argv[1], "-") == 0) {
196  startday = 0;
197  startmillisec = 0;
198  } else {
199  if (sscanf(argv[1], " %d/%d/%d,%d:%d:%d",
200  &year, &month, &day, &hour, &min, &sec) != 6) {
201  fprintf(stderr, "USAGE: %s %s\n", NAME, USAGE);
202  return (20);
203  }
204  if ((year < 1958) ||
205  (month < 1) || (month > 12) ||
206  (day < 1) || (day > 31) ||
207  (hour < 0) || (hour > 23) ||
208  (min < 0) || (min > 59) ||
209  (sec < 0) || (sec > 59)) {
210  fprintf(stderr, "USAGE: %s %s\n", NAME, USAGE);
211  return (10);
212  }
213  julday(0, 0, day, month, year, &x);
214  startday = (int) (x - MODIS_REF_DATE);
215  startmillisec =
216  (unsigned long) hour * 60L * 60L * 1000L +
217  (unsigned long) min * 60L * 1000L +
218  (unsigned long) sec * 1000L;
219  }
220 
221  /* get end date */
222  if (strcmp(argv[2], "-") == 0) {
223  endday = 4000000;
224  endmillisec = 90000000L;
225  } else {
226  if (sscanf(argv[2], " %d/%d/%d,%d:%d:%d",
227  &year, &month, &day, &hour, &min, &sec) != 6) {
228  fprintf(stderr, "USAGE: %s %s\n", NAME, USAGE);
229  return (20);
230  }
231  if ((year < 1958) ||
232  (month < 1) || (month > 12) ||
233  (day < 1) || (day > 31) ||
234  (hour < 0) || (hour > 23) ||
235  (min < 0) || (min > 59) ||
236  (sec < 0) || (sec > 59)) {
237  fprintf(stderr, "USAGE: %s %s\n", NAME, USAGE);
238  return (10);
239  }
240  julday(0, 0, day, month, year, &x);
241  endday = (int) (x - MODIS_REF_DATE);
242  endmillisec =
243  (unsigned long) hour * 60L * 60L * 1000L +
244  (unsigned long) min * 60L * 1000L +
245  (unsigned long) sec * 1000L;
246  }
247 
248  /* check if end date/time is after start date/time */
249  if ((endday < startday) ||
250  ((endday == startday) && (endmillisec <= startmillisec))) {
251  fprintf(stderr, "USAGE: %s %s\n", NAME, USAGE);
252  return (10);
253  }
254 
255  /* get APID */
256  apid = atoi(argv[3]);
257  if ((apid < 64) || (apid > 127)) {
258  fprintf(stderr, "only APID 64 to 127 supported\n");
259  return (10);
260  }
261 
262  /* allocate pointer memory */
263  if (!(fin = malloc(sizeof (FILE *) * n))) {
264  fprintf(stderr, "not enough memory\n");
265  return (10);
266  }
267  if (!(hdr = malloc(sizeof (struct pri_hdr *) * n))) {
268  fprintf(stderr, "not enough memory\n");
269  return (10);
270  }
271  if (!(mhdr = malloc(sizeof (struct modis_hdr *) * n))) {
272  fprintf(stderr, "not enough memory\n");
273  return (10);
274  }
275  if (!(buf_hdr = malloc(sizeof (unsigned char *) * n))) {
276  fprintf(stderr, "not enough memory\n");
277  return (10);
278  }
279  if (!(buf_data = malloc(sizeof (unsigned char *) * n))) {
280  fprintf(stderr, "not enough memory\n");
281  return (10);
282  }
283 
284  /* allocate data memory */
285  for (i = 0; i < n; i++) {
286  if (!(hdr[i] = malloc(sizeof (struct pri_hdr)))) {
287  fprintf(stderr, "not enough memory\n");
288  return (10);
289  }
290  hdr[i]->flag = 0;
291  if (!(mhdr[i] = malloc(sizeof (struct modis_hdr)))) {
292  fprintf(stderr, "not enough memory\n");
293  return (10);
294  }
295  if (!(buf_hdr[i] = malloc(sizeof (unsigned char) * PRI_HDR_SIZE))) {
296  fprintf(stderr, "not enough memory\n");
297  return (10);
298  }
299  if (!(buf_data[i] = malloc(sizeof (unsigned char) * DATA_SIZE))) {
300  fprintf(stderr, "not enough memory\n");
301  return (10);
302  }
303  }
304 
305  /* open input files */
306  for (i = 0; i < n; i++) {
307  if (!(fin[i] = fopen(argv[i + 4], "rb"))) {
308  fprintf(stderr, "can't open input file (%s)\n", argv[i + 4]);
309  return (10);
310  }
311  }
312 
313  /* open output file */
314  if (!(fout = fopen(argv[n + 4], "wb"))) {
315  fprintf(stderr, "can't create output file (%s)\n", argv[n + 4]);
316  return (10);
317  }
318 
319  /* main loop */
320  for (;;) {
321  /* for each input file */
322  for (i = 0; i < n; i++) {
323  /* do until we have a valid packet or we have reached EOF */
324  for (; hdr[i]->flag == 0;) {
325  /* read primary header */
326  if (ReadPriHdr(fin[i], buf_hdr[i])) {
327  /* end of file? */
328  if (feof(fin[i])) {
329  hdr[i]->flag = -1;
330  break;
331  } else {
332  fprintf(stderr,
333  "error reading input file (%s)\n",
334  argv[i + 4]);
335  return (5);
336  }
337  }
338 
339  /* decode primary header */
340  switch (error = DecodePriHdr(buf_hdr[i], hdr[i])) {
341  case 0:
342  break;
343  case -1:
344  fprintf(stderr,
345  "unsupported packet version (%d) in input file "
346  "(%s): "
347  "file might be corrupted, trying to resyncronise\n",
348  hdr[i]->version,
349  argv[i + 4]);
350 
351  /* read data block */
352  if (hdr[i]->pkt_length + 1 > DATA_SIZE) {
353  fprintf(stderr,
354  "buffer overflow (%d), "
355  "please contact developer\n",
356  hdr[i]->pkt_length);
357  return (20);
358  }
359  if (fread(buf_data[i], hdr[i]->pkt_length + 1, 1, fin[i]) !=
360  1) {
361  fprintf(stderr,
362  "error reading input file (%s)\n",
363  argv[i + 4]);
364  return (5);
365  }
366  continue;
367  default:
368  fprintf(stderr,
369  "unknown error (%d) while decoding primary "
370  "header\n",
371  error);
372  return (5);
373  }
374 
375  /* read data block */
376  if (hdr[i]->pkt_length + 1 > DATA_SIZE) {
377  fprintf(stderr,
378  "buffer overflow (%d), "
379  "please contact developer\n",
380  hdr[i]->pkt_length);
381  return (20);
382  }
383  if (fread(buf_data[i], hdr[i]->pkt_length + 1, 1, fin[i]) !=
384  1) {
385  fprintf(stderr,
386  "error reading input file (%s)\n",
387  argv[i + 4]);
388  return (5);
389  }
390 
391  /* is it a packet we need? */
392  if (hdr[i]->apid != apid)
393  continue;
394 
395  /* decode MODIS header */
396  DecodeMODISHdr(buf_data[i],
397  hdr[i]->pkt_length + 1,
398  mhdr[i]);
399 
400  /* calculate checksum */
401  chksum =
402  CalcChecksum12(&(buf_data[i][MODIS_HDR_SIZE]),
403  (hdr[i]->pkt_length + 1 - MODIS_HDR_SIZE) /
404  1.5 - 1);
405 
406  /* invalid packet? */
407  if (chksum != mhdr[i]->checksum)
408  continue;
409 
410  /* before startdate? */
411  if ((mhdr[i]->days < startday) ||
412  ((mhdr[i]->days == startday) &&
413  (mhdr[i]->millisec < startmillisec)))
414  continue;
415 
416  /* after enddate? */
417  if ((mhdr[i]->days > endday) ||
418  ((mhdr[i]->days == endday) &&
419  (mhdr[i]->millisec >= endmillisec)))
420  continue;
421 
422  /* set valid packet flag */
423  hdr[i]->flag = 1;
424  }
425  }
426 
427  /* find the oldest packet */
428  for (i = 0, valpkt = 0; i < n; i++) {
429  /* invalid packet? */
430  if (hdr[i]->flag != 1)
431  continue;
432 
433  /* first valid packet? */
434  if (valpkt == 0) {
435  /* set oldest to this this packet */
436  oldest = i;
437 
438  /* set flag for valid packet available */
439  valpkt = 1;
440 
441  /* next stream */
442  continue;
443  }
444 
445  /* test days */
446  if (mhdr[i]->days < mhdr[oldest]->days) {
447  oldest = i;
448  continue;
449  }
450  if (mhdr[i]->days > mhdr[oldest]->days) {
451  continue;
452  }
453 
454  /* test milliseconds */
455  if (mhdr[i]->millisec < mhdr[oldest]->millisec) {
456  oldest = i;
457  continue;
458  }
459  if (mhdr[i]->millisec > mhdr[oldest]->millisec) {
460  continue;
461  }
462 
463  /* test microseconds */
464  if (mhdr[i]->microsec < mhdr[oldest]->microsec) {
465  oldest = i;
466  continue;
467  }
468  if (mhdr[i]->microsec > mhdr[oldest]->microsec) {
469  continue;
470  }
471 
472  /* test packet count */
473  pktdiff = hdr[i]->pkt_count - hdr[oldest]->pkt_count;
474  if (pktdiff < -8191) pktdiff += 16384;
475  if (pktdiff > 8191) pktdiff -= 16384;
476  if (pktdiff < 0) {
477  oldest = i;
478  continue;
479  }
480  if (pktdiff > 0) {
481  continue;
482  }
483 
484  /* identical packets, flag packet from stream i invalid */
485  hdr[i]->flag = 0;
486  }
487 
488  /* no valid packet available? */
489  if (valpkt == 0)
490  break;
491 
492  /* avoid duplicated and old packets */
493  if (mhdr[oldest]->days < lastdays) {
494  hdr[oldest]->flag = 0;
495  lastdays = mhdr[oldest]->days;
496  lastmillisec = mhdr[oldest]->millisec;
497  lastmicrosec = mhdr[oldest]->microsec;
498  lastpktcount = hdr[oldest]->pkt_count;
499  continue;
500  }
501  if (mhdr[oldest]->days == lastdays) {
502  if (mhdr[oldest]->millisec < lastmillisec) {
503  hdr[oldest]->flag = 0;
504  lastdays = mhdr[oldest]->days;
505  lastmillisec = mhdr[oldest]->millisec;
506  lastmicrosec = mhdr[oldest]->microsec;
507  lastpktcount = hdr[oldest]->pkt_count;
508  continue;
509  }
510  if (mhdr[oldest]->millisec == lastmillisec) {
511  if (mhdr[oldest]->microsec < lastmicrosec) {
512  hdr[oldest]->flag = 0;
513  lastdays = mhdr[oldest]->days;
514  lastmillisec = mhdr[oldest]->millisec;
515  lastmicrosec = mhdr[oldest]->microsec;
516  lastpktcount = hdr[oldest]->pkt_count;
517  continue;
518  }
519  if (mhdr[oldest]->microsec == lastmicrosec) {
520  pktdiff = hdr[oldest]->pkt_count - lastpktcount;
521  if (pktdiff < -8191) pktdiff += 16384;
522  if (pktdiff > 8191) pktdiff -= 16384;
523  if (pktdiff <= 0) {
524  hdr[oldest]->flag = 0;
525  lastdays = mhdr[oldest]->days;
526  lastmillisec = mhdr[oldest]->millisec;
527  lastmicrosec = mhdr[oldest]->microsec;
528  lastpktcount = hdr[oldest]->pkt_count;
529  continue;
530  /* }*/
531  }
532  }
533  }
534  }
535 
536  /* store packet date/time/sample/pktcount */
537  lastdays = mhdr[oldest]->days;
538  lastmillisec = mhdr[oldest]->millisec;
539  lastmicrosec = mhdr[oldest]->microsec;
540  lastpktcount = hdr[oldest]->pkt_count;
541 
542  /* write packet to output file */
543  if (WritePriHdr(fout, buf_hdr[oldest])) {
544  fprintf(stderr,
545  "error writing to output file (%s)\n",
546  argv[n + 4]);
547  return (5);
548  }
549  if (fwrite(buf_data[oldest],
550  hdr[oldest]->pkt_length + 1,
551  1, fout) != 1) {
552  fprintf(stderr,
553  "error writing to output file (%s)\n",
554  argv[n + 4]);
555  return (5);
556  }
557 
558  /* flag packet from stream oldest invalid */
559  hdr[oldest]->flag = 0;
560  }
561 
562  /* close output file */
563  fclose(fout);
564 
565  /* close input files */
566  for (i = 0; i < n; i++) {
567  fclose(fin[i]);
568  }
569 
570  /* free memory */
571  for (i = 0; i < n; i++) {
572  free(buf_data[i]);
573  free(buf_hdr[i]);
574  free(mhdr[i]);
575  free(hdr[i]);
576  }
577  free(buf_data);
578  free(buf_hdr);
579  free(mhdr);
580  free(hdr);
581  free(fin);
582 
583  /* Ja das war's. Der Pop-Shop ist zu Ende */
584  return (0);
585 }
586 
587 /********************************************************************
588  * *
589  * read primary header from file *
590  * *
591  * f: file pointer *
592  * buf: pointer to buffer *
593  * *
594  * result: 0 - ok *
595  * -1 - read error *
596  * *
597  ********************************************************************/
598 int ReadPriHdr(FILE *f, unsigned char *buf) {
599  /* read header */
600  if (fread(buf, PRI_HDR_SIZE, 1, f) != 1)
601  return (-1);
602 
603  /* ois rodger */
604  return (0);
605 }
606 
607 /********************************************************************
608  * *
609  * write primary header to file *
610  * *
611  * f: file pointer *
612  * buf: pointer to buffer *
613  * *
614  * result: 0 - ok *
615  * -1 - write error *
616  * *
617  ********************************************************************/
618 int WritePriHdr(FILE *f, unsigned char *buf) {
619  /* read header */
620  if (fwrite(buf, PRI_HDR_SIZE, 1, f) != 1)
621  return (-1);
622 
623  /* ois rodger */
624  return (0);
625 }
626 
627 /********************************************************************
628  * *
629  * decode primary header *
630  * *
631  * buf: pointer to buffer *
632  * hdr: pointer to header structure *
633  * *
634  * result: 0 - ok *
635  * -1 - decode error (version not supported) *
636  * *
637  ********************************************************************/
638 int DecodePriHdr(unsigned char *buf, struct pri_hdr *hdr) {
639  /* version */
640  hdr->version = (buf[0] & 0xE0) >> 5;
641 
642  /* version supported? */
643  if (hdr->version != 0)
644  return (-1);
645 
646  /* type */
647  hdr->type = (buf[0] & 0x10) >> 4;
648 
649  /* secondary header flag */
650  hdr->sec_hdr_flag = (buf[0] & 0x08) >> 3;
651 
652  /* APID */
653  hdr->apid = (((int) (buf[0] & 0x07)) << 8) + buf[1];
654 
655  /* sequence flags */
656  hdr->seq_flags = (buf[2] & 0xC0) >> 6;
657 
658  /* packet count per APID */
659  hdr->pkt_count = (((int) (buf[2] & 0x3F)) << 8) + buf[3];
660 
661  /* packet length (length - 1) */
662  hdr->pkt_length = (((int) buf[4]) << 8) + buf[5];
663 
664  /* okeydokey */
665  return (0);
666 }
667 
668 /********************************************************************
669  * *
670  * decode MODIS header *
671  * *
672  * buf: pointer to buffer *
673  * len: data lengh *
674  * hdr: pointer to header structure *
675  * *
676  * result: 0 - ok *
677  * -1 - decode error *
678  * -2 - decode error *
679  * *
680  ********************************************************************/
681 int DecodeMODISHdr(unsigned char *buf, int len,
682  struct modis_hdr *hdr) {
683  /* days since 01/01/1958 */
684  hdr->days =
685  (((int) buf[0]) << 8) +
686  (((int) buf[1]));
687 
688  /* milliseconds of day */
689  hdr->millisec =
690  (((unsigned long int) buf[2]) << 24) +
691  (((unsigned long int) buf[3]) << 16) +
692  (((unsigned long int) buf[4]) << 8) +
693  (((unsigned long int) buf[5]));
694 
695  /* microseconds of milliseconds */
696  hdr->microsec =
697  (((int) buf[6]) << 8) +
698  (((int) buf[7]));
699 
700  /* quicklook flag */
701  hdr->ql = (buf[8] & 0x80) >> 7;
702 
703  /* packet type */
704  hdr->pkt_type = (buf[8] & 0x70) >> 4;
705 
706  /* scan count */
707  hdr->scan_count = (buf[8] & 0x0E) >> 1;
708 
709  /* mirror side */
710  hdr->mirror_side = (buf[8] & 1);
711 
712  /* source identification (0 = earth, 1 = calibration) */
713  hdr->src1 = (buf[9] & 0x80) >> 7;
714 
715  /* source identification (0 = eng., 1 to 1354 = sample count) */
716  hdr->src2 =
717  (((int) buf[9] & 0x7F) << 4) +
718  (((int) buf[10] & 0xF0) >> 4);
719 
720  /* FPA/AEM config */
721  hdr->conf =
722  (((int) buf[10] & 0x0F) << 6) +
723  (((int) buf[11] & 0xFC) >> 2);
724 
725  /* sci state */
726  hdr->sci_state = (((int) buf[11] & 0x02) >> 1);
727 
728  /* sci abnorm */
729  hdr->sci_abnorm = (((int) buf[11] & 0x01));
730 
731  /* check sum */
732  hdr->checksum =
733  (((int) buf[len - 2] & 0x0F) << 8) +
734  (((int) buf[len - 1]));
735 
736  return 0;
737 }
738 
739 /********************************************************************
740  * *
741  * convert calendar date to julian day *
742  * *
743  * minute: minute of time to convert *
744  * hour: hour of time to convert *
745  * day: day of date to convert *
746  * month: month of date to convert *
747  * year: year of date to convert *
748  * jul: pointer to store julian day *
749  * *
750  * result: none *
751  * *
752  ********************************************************************/
753 void julday(int minute, int hour, int day, int month, int year,
754  double *jul) {
755  /* julian day as long */
756  long ljul;
757  /* helping variables */
758  int ja, jy, jm;
759 
760 
761  jy = year;
762 
763  if (jy < 0)
764  ++jy;
765  if (month > 2) {
766  jm = month + 1;
767  } else {
768  --jy;
769  jm = month + 13;
770  }
771  ljul = (long) (floor(365.25 * jy) + floor(30.6001 * jm) + day +
772  1720995);
773  if (day + 31L * (month + 12L * year) >= (15 + 31L * (10 + 12L * 1582))) {
774  ja = (int) (0.01 * jy);
775  ljul += 2 - ja + (int) (0.25 * ja);
776  }
777 
778  *jul =
779  (double) ljul +
780  (double) hour / 24.0 +
781  (double) minute / 1440.0 +
782  0.000001; /* add about 0.1s to avoid precision problems */
783 }
784 
785 /********************************************************************
786  * *
787  * convert julian day to calendar date *
788  * *
789  * minute: pointer to store minute *
790  * hour: pointer to store hour *
791  * day: pointer to store day *
792  * month: pointer to store month *
793  * year: pointer to store year *
794  * jul: julian day *
795  * *
796  * result: none *
797  * *
798  ********************************************************************/
799 void caldat(int *minute, int *hour, int *day, int *month, int *year,
800  double jul) {
801  /* julian day as long */
802  long ljul;
803  /* helping variables */
804  long ja, jalpha, jb, jc, jd, je;
805 
806 
807  ljul = (long) floor(jul);
808  jul -= (double) ljul;
809  *hour = (int) (floor(jul * 24.0));
810  jul -= (double) *hour / 24.0;
811  *minute = (int) (floor(jul * 1440.0));
812 
813  if (ljul >= 2299161) {
814  jalpha = (long) (((float) (ljul - 1867216) - 0.25) / 36524.25);
815  ja = ljul + 1 + jalpha - (long) (0.25 * jalpha);
816  } else
817  ja = ljul;
818  jb = ja + 1524;
819  jc = (long) (6680.0 + ((float) (jb - 2439870) - 122.1) / 365.25);
820  jd = (long) (365 * jc + (0.25 * jc));
821  je = (long) ((jb - jd) / 30.6001);
822  *day = jb - jd - (long) (30.6001 * je);
823  *month = je - 1;
824  if (*month > 12)
825  *month -= 12;
826  *year = jc - 4715;
827  if (*month > 2)
828  --(*year);
829  if (*year <= 0)
830  --(*year);
831 }
832 
833 /********************************************************************
834  * *
835  * calculate 12bit checksum *
836  * *
837  * buf: pointer to data buffer *
838  * n: number of bytes in buffer *
839  * *
840  * result: checksum *
841  * *
842  ********************************************************************/
843 int CalcChecksum12(unsigned char *buf, int n) {
844  /* counter */
845  int i;
846  /* data value */
847  unsigned long x;
848  /* checksum */
849  unsigned long s = 0;
850 
851 
852  /* main loop */
853  for (i = 0; i < n; i++) {
854  /* get 1. value */
855  x =
856  (((unsigned long) buf[(int) (1.5 * i)]) << 4) +
857  (((unsigned long) buf[(int) (1.5 * i) + 1] & 0xF0) >> 4);
858 
859  /* add to checksum */
860  s = s + x;
861 
862  /* increase counter */
863  i++;
864 
865  /* do we have a second value */
866  if (i >= n)
867  break;
868 
869  /* get 2. value */
870  x =
871  (((unsigned long) buf[(int) (1.5 * (i - 1)) + 1] & 0x0F) << 8) +
872  (((unsigned long) buf[(int) (1.5 * (i - 1)) + 2]));
873 
874  /* add to checksum */
875  s = s + x;
876  }
877 
878 
879  s = s >> 4;
880  s = s & 0xFFF;
881 
882  /* return checksum */
883  return (s);
884 }
unsigned long int millisec
Definition: pdsinfo.c:109
int apid
Definition: pdsinfo.c:94
int version
Definition: pdsinfo.c:91
int src2
Definition: pdsinfo.c:116
int flag
Definition: pdsmerge.c:92
int32_t day
#define L(lambda, T)
Definition: PreprocessP.h:185
#define NAME
Definition: pdsmerge.c:63
int sci_abnorm
Definition: pdsinfo.c:119
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
int sci_state
Definition: pdsinfo.c:118
function jd(i, j, k)
Definition: jd.f:2
int microsec
Definition: pdsinfo.c:110
int CalcChecksum12(unsigned char *buf, int n)
Definition: pdsmerge.c:843
int ql
Definition: pdsinfo.c:111
int sec_hdr_flag
Definition: pdsinfo.c:93
int type
Definition: pdsinfo.c:92
#define MODIS_REF_DATE
Definition: pdsmerge.c:77
int ReadPriHdr(FILE *f, unsigned char *buf)
Definition: pdsmerge.c:598
int main(int argc, char *argv[])
Definition: pdsmerge.c:137
#define MODIS_HDR_SIZE
Definition: pdsmerge.c:73
int jb
Definition: atrem_corl1.h:227
#define PRI_HDR_SIZE
Definition: pdsmerge.c:71
int pkt_count
Definition: pdsinfo.c:96
a context in which it is NOT documented to do so subscript error
Definition: HISTORY.txt:53
#define DATA_SIZE
Definition: pdsmerge.c:75
double precision function f(R1)
Definition: tmd.lp.f:1454
int DecodePriHdr(unsigned char *buf, struct pri_hdr *hdr)
Definition: pdsmerge.c:638
#define VERSION
Definition: pdsmerge.c:65
int conf
Definition: pdsinfo.c:117
Definition: jd.py:1
int checksum
Definition: pdsinfo.c:120
float ja
Definition: atrem_cor.h:114
integer, parameter double
int days
Definition: pdsinfo.c:108
int DecodeMODISHdr(unsigned char *buf, int len, struct modis_hdr *hdr)
Definition: pdsmerge.c:681
#define USAGE
Definition: pdsmerge.c:69
void caldat(int *minute, int *hour, int *day, int *month, int *year, double jul)
Definition: pdsmerge.c:799
int src1
Definition: pdsinfo.c:115
int pkt_length
Definition: pdsinfo.c:97
data_t s[NROOTS]
Definition: decode_rs.h:75
int seq_flags
Definition: pdsinfo.c:95
int i
Definition: decode_rs.h:71
int WritePriHdr(FILE *f, unsigned char *buf)
Definition: pdsmerge.c:618
#define REVISION
Definition: pdsmerge.c:67
int mirror_side
Definition: pdsinfo.c:114
int scan_count
Definition: pdsinfo.c:113
version
Definition: setup.py:15
void julday(int minute, int hour, int day, int month, int year, double *jul)
Definition: pdsmerge.c:753
int pkt_type
Definition: pdsinfo.c:112