home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / mcidas.c < prev    next >
C/C++ Source or Header  |  1993-10-21  |  5KB  |  227 lines

  1. /* mcidas.c:
  2.  *
  3.  * McIDAS areafile support.  contributed by Glenn P. Davis
  4.  * (davis@unidata.ucar.edu).
  5.  */
  6.  
  7. #include "xloadimage.h"
  8. #include "mcidas.h"
  9.  
  10. char *mc_sensor();
  11.  
  12. static struct {
  13.   int   days;
  14.   char *name;
  15. } month_info[13] = {
  16.   { 0,  "Pad" },
  17.   { 31, "Jan" },
  18.   { 29, "Feb" }, /* longest */
  19.   { 31, "Mar" },
  20.   { 30, "Apr" },
  21.   { 31, "May" },
  22.   { 30, "Jun" },
  23.   { 31, "Jul" },
  24.   { 31, "Aug" },
  25.   { 30, "Sep" },
  26.   { 31, "Oct" },
  27.   { 30, "Nov" },
  28.   { 31, "Dec" }
  29. };
  30.  
  31. /* convert numeric dates to human-readable
  32.  */
  33. static char *convert_date(time, date)
  34.      int time, date;
  35. { static char buf[30];
  36.   int hour;
  37.   int minute;
  38.   int second;
  39.   int year;
  40.   int month;
  41.   int day;
  42.  
  43.   year = date / 1000;
  44.   if (year > 50) /* gives us a range from 1950 - 2050, probably good enough */
  45.     year += 1900;
  46.   else
  47.     year += 2000;
  48.   day = date % 1000;
  49.  
  50.   /* adjust day for non-leap-years if necessary
  51.    */
  52.   if ((day > 31 + 28) && ((year % 4) || (year == 2000)))
  53.     day++;
  54.  
  55.   /* find month in year that this day falls in
  56.    */
  57.   for (month= 1; day > month_info[month].days; day -= month_info[month].days)
  58.     month++;
  59.  
  60.   /* break time-of-day up
  61.    */
  62.   hour = time / 10000;
  63.   minute = (time % 10000) / 100;
  64.   second = (time % 100);
  65.  
  66.   sprintf(buf, "%d:%2.2d:%2.2d %s %d, %d (day %d)",
  67.       hour, minute, second, month_info[month].name, day, year,
  68.       (date % 1000));
  69.   return(buf);
  70. }
  71.  
  72. /*
  73.  * convert from little endian to big endian four byte object
  74.  */
  75. static unsigned long
  76. vhtonl(lend)
  77. unsigned long lend ;
  78. {
  79.     unsigned long bend ;
  80.     unsigned char *lp, *bp ;
  81.  
  82.     lp = ((unsigned char *)&lend) + 3 ;
  83.     bp = (unsigned char *) &bend ;
  84.  
  85.     *bp++ = *lp-- ;
  86.     *bp++ = *lp-- ;
  87.     *bp++ = *lp-- ;
  88.     *bp = *lp ;
  89.  
  90.     return(bend) ;
  91. }
  92.  
  93. static void babble(name, dir)
  94.      char *name;
  95.      struct area_dir *dir;
  96. {
  97.   printf("%s is a %dx%d McIDAS areafile from %s at %s (%d, %d) (%d, %d)\n",
  98.      name,
  99.      dir->esiz, dir->lsiz,
  100.      mc_sensor(dir->satid),
  101.      convert_date(dir->itime, dir->idate),
  102.      dir->lcor,
  103.      dir->ecor,
  104.      dir->lres,
  105.      dir->eres) ;
  106. }
  107.  
  108. static void swap_bytes(dir)
  109.      struct area_dir *dir;
  110. {
  111.   unsigned long *begin ; 
  112.   unsigned long *ulp ;
  113.  
  114.   begin = (unsigned long *)dir ;
  115.   for(ulp = begin ; ulp < &begin[AREA_COMMENTS] ; ulp++)
  116.     *ulp = vhtonl(*ulp) ;
  117.   for(ulp = &begin[AREA_CALKEY] ; ulp < &begin[AREA_STYPE] ; ulp++)
  118.     *ulp = vhtonl(*ulp) ;
  119. }
  120.  
  121. /* ARGSUSED */
  122. int mcidasIdent(fullname, name)
  123.      char *fullname, *name;
  124. { ZFILE          *zf;
  125.   struct area_dir dir ;
  126.   int             r;
  127.  
  128.   if (! (zf= zopen(fullname))) {
  129.     perror("mcidasIdent");
  130.     return(0);
  131.   }
  132.   switch (zread(zf, (byte *)&dir, sizeof(struct area_dir))) {
  133.   case -1:
  134.     perror("mcidasIdent");
  135.     r= 0;
  136.     break;
  137.  
  138.   case sizeof(struct area_dir):
  139.     if (memToValLSB((char *)&dir.type, 4) != 4) {
  140.       r= 0;
  141.       break;
  142.     }
  143.     if (dir.type != 4)
  144.       swap_bytes(&dir);
  145.     babble(name, &dir);
  146.     r= 1;
  147.     break;
  148.  
  149.   default:
  150.     r= 0;
  151.     break;
  152.   }
  153.   zclose(zf);
  154.   return(r);
  155. }
  156.  
  157.  
  158. Image *mcidasLoad(fullname, name, verbose)
  159.      char         *fullname, *name;
  160.      unsigned int  verbose;
  161. { ZFILE          *zf;
  162.   struct area_dir  dir;
  163.   struct navigation  nav;
  164.   Image          *image;
  165.   unsigned int    y;
  166.   int doswap = 0 ;
  167.  
  168.   if (! (zf= zopen(fullname))) {
  169.     perror("mcidasLoad");
  170.     return(NULL);
  171.   }
  172.   switch (zread(zf, (byte *)&dir, sizeof(struct area_dir))) {
  173.   case -1:
  174.     perror("mcidasLoad");
  175.     zclose(zf);
  176.     exit(1);
  177.  
  178.   case sizeof(struct area_dir):
  179.     if (memToValLSB((char *)&dir.type, 4) != 4) {
  180.       zclose(zf);
  181.       return(NULL) ;
  182.     }
  183.     if (dir.type != 4)
  184.       swap_bytes(&dir);
  185.     break;
  186.  
  187.   default:
  188.     zclose(zf);
  189.     return(NULL);
  190.   }
  191.  
  192.   if (verbose)
  193.     babble(name, &dir);
  194.  
  195.   znocache(zf);
  196.   /* skip the nav */
  197.   if( zread(zf, (byte *)&nav, sizeof(struct navigation)) !=
  198.      sizeof(struct navigation)) {
  199.       zclose(zf);
  200.       return(NULL) ;
  201.   }
  202.  
  203.   /* get an image to put the data in
  204.    */
  205.   image= newRGBImage(dir.esiz, dir.lsiz, dir.zsiz * 8);
  206.  
  207.   /* set up the colormap, linear grey scale
  208.    */
  209.   for (y= 0; y < image->rgb.size; y++) {
  210.       *(image->rgb.red + y)= 
  211.       *(image->rgb.green + y)=
  212.           *(image->rgb.blue + y)= y * (65536 / image->rgb.size) ;
  213.   }
  214.   image->rgb.used= image->rgb.size ;
  215.  
  216.   /* read the first band from the image and warn if there are other bands
  217.    * we can't read.
  218.    */
  219.   zread(zf, image->data, dir.esiz * dir.lsiz * dir.zsiz) ;
  220.   if (dir.bands > 1)
  221.       printf("Warning: Only showing first of %d bands\n", dir.bands);
  222.  
  223.   zclose(zf);
  224.   image->title= dupString(name);
  225.   return(image);
  226. }
  227.