home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / fblnk224.zip / blink.c < prev    next >
C/C++ Source or Header  |  1999-01-28  |  31KB  |  994 lines

  1. /*  blink.c  for fitsblink */
  2. #ifdef HPUX
  3. #define _INCLUDE_HPUX_SOURCE
  4. #define _INCLUDE_XOPEN_SOURCE
  5. #define _INCLUDE_POSIX_SOURCE
  6. #endif
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <math.h>
  10. #include <string.h>
  11. #include <sys/types.h> 
  12. #include <sys/time.h>
  13. #include <unistd.h>
  14. #include <getopt.h>
  15. #include <time.h>
  16.  
  17. #include "functs.h"
  18. #include "consts.h"
  19.  
  20. STATE state;
  21. BLINK_FRAME *frame;
  22. CATALOG catalog[NUMBER_OF_CATALOGS];
  23. OBSERVATORY observatory;
  24. MAIL mail;
  25. FITS_IMAGE count_options;
  26. MATCH_OPTIONS match_options;
  27. TELESCOPE telescope;
  28. GAUSSF gaussf;
  29. /*****************/
  30. /*  MYALLOC      */
  31. /*****************/
  32. void *
  33. myalloc(unsigned int size, char *function, char *variable)
  34.      
  35. {
  36.   void *p;
  37.   if (size == 0) {
  38.     fprintf(stderr, "Zero size, function %s, variable %s.\n",
  39.            function, variable);
  40.   }
  41.   p = malloc(size);
  42.   if (p == NULL) {
  43.     fprintf(stderr, "Out of memory, function %s, variable %s.\n",
  44.            function, variable);
  45.     exit(1);
  46.   }
  47.   return(p);
  48. }
  49.  
  50.  
  51. /*      DELAY                            */
  52. /*      Wait for  t hundreths of second */
  53. void
  54. delay(int t)
  55.      
  56. {
  57.   fd_set set;
  58.   struct timeval timeout;
  59.   
  60.   FD_ZERO (&set);
  61.   /* Initialize the timeout data structure.  */
  62.   timeout.tv_sec = t / 100;
  63.   timeout.tv_usec = (t % 100) * 10000;
  64.   select(FD_SETSIZE, &set, NULL, NULL, &timeout);
  65. }
  66.  
  67. /*  Transform pixel value according to values in arrays gamx and gamy  */
  68. int
  69. correct(BLINK_FRAME *frame, int n, PIXEL x)
  70.  
  71. {
  72.   int i;
  73.   float *gamx = frame[n].gamx;
  74.   float *gamy = frame[n].gamy;
  75.   for (i = 1; i < frame[n].ngam; i++) {
  76.     if (x <= gamx[i] && x >= gamx[i - 1]) {
  77.       return (int) (gamy[i - 1] + (x - gamx[i - 1]) * frame[n].kg[i]);
  78.     }
  79.   }
  80.   return 0;
  81. }
  82.  
  83. /*  Draw objects which belong to the image */
  84. void
  85. draw_objects(BLINK_FRAME *frame, int n)
  86.  
  87. {
  88.   int j;
  89.   Pixmap pixmap = frame[n].pixmap;
  90.   Display *disp = state.disp;
  91.   GC gc = fl_state[fl_get_form_vclass(state.blinker->blinker)].gc[0];
  92.   OBJECT *obj = frame[n].obj;
  93.   float dx = frame[n].dx, dy = frame[n].dy;
  94.   int x0, y0, w0, h0;
  95.   int xmax, ymax;
  96.   float kx, ky;
  97.   float ta, tb, tc;
  98.   XPoint xpoints[10];
  99.  
  100.   if (!frame[n].objshow) return;
  101.   xmax = frame[n].fits.width;
  102.   ymax = frame[n].fits.height;
  103.   kx = (float) (xmax - 1) / (state.blinker->blinkW->w - 1);
  104.   ky = (float) (ymax - 1) / (state.blinker->blinkW->h - 1);
  105.   if (kx < ky) kx = ky;
  106.   w0 = (xmax - 1) / kx + 0.5;
  107.   h0 = (ymax - 1) / kx + 0.5;
  108.   x0 = (state.blinker->blinkW->w - w0) / 2 + 0.5;
  109.   y0 = (state.blinker->blinkW->h - h0) / 2 + 0.5;
  110.   /*  Draw additonal objects  */
  111.   for (j = 0; j < frame[n].objnum; j++) {
  112.     XSetState(disp, gc, fl_get_pixel(obj[j].color), 0, GXcopy, AllPlanes);
  113.     switch (obj[j].shape) {
  114.     case OBJ_CIRCLE:
  115.       XDrawArc(disp, pixmap, gc, 
  116.            x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 0.5), 
  117.            y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 0.5), 
  118.            (int) (2 * obj[j].r), (int) (2 * obj[j].r), 0, 23040);
  119.       XDrawArc(disp, pixmap, gc, 
  120.            x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 1.5), 
  121.            y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 1.5), 
  122.            (int) (2 * obj[j].r + 2), (int) (2 * obj[j].r + 2), 0, 23040);
  123.       break;
  124.     case OBJ_BOX:
  125.       XDrawRectangle(disp, pixmap, gc, 
  126.              x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 0.5), 
  127.              y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 0.5), 
  128.              (int) (2 * obj[j].r), (int) (2 * obj[j].r));
  129.       XDrawRectangle(disp, pixmap, gc, 
  130.              x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 1.5), 
  131.              y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 1.5), 
  132.              (int) (2 * obj[j].r + 2), (int) (2 * obj[j].r + 2));
  133.       break;
  134.     case OBJ_DIAMOND:
  135.       xpoints[0].x = x0 + (int) ((obj[j].x - dx) / kx + 0.5);
  136.       xpoints[0].y = y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 0.5);
  137.       xpoints[1].x = x0 + (int) ((obj[j].x - dx) / kx + obj[j].r + 0.5);
  138.       xpoints[1].y = y0 + (int) ((obj[j].y - dy) / kx + 0.5);
  139.       xpoints[2].x = xpoints[0].x;
  140.       xpoints[2].y = y0 + (int) ((obj[j].y - dy) / kx + obj[j].r + 0.5);
  141.       xpoints[3].x = x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 0.5);
  142.       xpoints[3].y = xpoints[1].y;
  143.       xpoints[4].x = xpoints[0].x;
  144.       xpoints[4].y = xpoints[0].y;
  145.       xpoints[5].x = xpoints[0].x;
  146.       xpoints[5].y = xpoints[0].y - 1;
  147.       xpoints[6].x = xpoints[1].x + 1;
  148.       xpoints[6].y = xpoints[1].y;
  149.       xpoints[7].x = xpoints[2].x;
  150.       xpoints[7].y = xpoints[2].y + 1;
  151.       xpoints[8].x = xpoints[3].x - 1;
  152.       xpoints[8].y = xpoints[3].y;
  153.       xpoints[9].x = xpoints[5].x;
  154.       xpoints[9].y = xpoints[5].y;
  155.       XDrawLines(disp, pixmap, gc, xpoints, 10, CoordModeOrigin);
  156.       break;
  157.       case OBJ_UPTRIANGLE:
  158.     tb = 0.5773502 * obj[j].r;
  159.     tc = 0.5 * tb;
  160.     ta = 0.5 * obj[j].r;
  161.     xpoints[0].x = x0 + (int) ((obj[j].x - dx) / kx + 0.5);
  162.     xpoints[0].y = y0 + (int) ((obj[j].y - dy) / kx - tb - 0.5);
  163.     xpoints[1].x = x0 + (int) ((obj[j].x - dx) / kx + ta + 0.5);
  164.     xpoints[1].y = y0 + (int) ((obj[j].y - dy) / kx + tc + 0.5);
  165.     xpoints[2].x = x0 + (int) ((obj[j].x - dx) / kx - ta - 0.5);
  166.     xpoints[2].y = xpoints[1].y;
  167.     xpoints[3].x = xpoints[0].x;
  168.     xpoints[3].y = xpoints[0].y;
  169.     xpoints[4].x = xpoints[0].x;
  170.     xpoints[4].y = xpoints[0].y - 1;
  171.     xpoints[5].x = xpoints[1].x + 1;
  172.     xpoints[5].y = xpoints[1].y + 1;
  173.     xpoints[6].x = xpoints[2].x - 1;
  174.     xpoints[6].y = xpoints[5].y;
  175.     xpoints[7].x = xpoints[4].x;
  176.     xpoints[7].y = xpoints[4].y;
  177.     XDrawLines(disp, pixmap, gc, xpoints, 8, CoordModeOrigin);
  178.     break;
  179.       case OBJ_DOWNTRIANGLE:
  180.     tb = 0.5773502 * obj[j].r;
  181.     tc = 0.5 * tb;
  182.     ta = 0.5 * obj[j].r;
  183.     xpoints[0].x = x0 + (int) ((obj[j].x - dx) / kx + 0.5);
  184.     xpoints[0].y = y0 + (int) ((obj[j].y - dy) / kx + tb - 0.5);
  185.     xpoints[1].x = x0 + (int) ((obj[j].x - dx) / kx + ta + 0.5);
  186.     xpoints[1].y = y0 + (int) ((obj[j].y - dy) / kx - tb + 0.5);
  187.     xpoints[2].x = x0 + (int) ((obj[j].x - dx) / kx - ta - 0.5);
  188.     xpoints[2].y = xpoints[1].y;
  189.     xpoints[3].x = xpoints[0].x;
  190.     xpoints[3].y = xpoints[0].y;
  191.     xpoints[4].x = xpoints[0].x;
  192.     xpoints[4].y = xpoints[0].y + 1;
  193.     xpoints[5].x = xpoints[1].x + 1;
  194.     xpoints[5].y = xpoints[1].y + 1;
  195.     xpoints[6].x = xpoints[2].x - 1;
  196.     xpoints[6].y = xpoints[2].y - 1;
  197.     xpoints[7].x = xpoints[4].x;
  198.     xpoints[7].y = xpoints[4].y;
  199.     XDrawLines(disp, pixmap, gc, xpoints, 8, CoordModeOrigin);
  200.     break;
  201.     }
  202.   }
  203.   XSetState(disp, gc, state.pixel[0], 0, GXcopy, AllPlanes);
  204. }
  205.  
  206. /*  Determine the size of pixmap  */
  207. int
  208. pixmap_size(int width, int height, int depth)
  209.  
  210. {
  211.   int count;
  212.   int bits;
  213.   XPixmapFormatValues *pfv;
  214.  
  215.   pfv = XListPixmapFormats(state.disp,  &count);
  216.   for (count--; count > 0; count--) {
  217.     if (pfv[count].depth != depth) continue;
  218.     bits = width * pfv[count].bits_per_pixel;
  219.     if (bits % pfv[count].scanline_pad) {
  220.       bits -= bits % pfv[count].scanline_pad;
  221.       bits += pfv[count].scanline_pad;
  222.     }
  223.     XFree(pfv);
  224.     return (bits / 8) * height;
  225.   }
  226.   return 0;
  227. }
  228.  
  229.  
  230. /*  Draw the image with current "gamma" settings to the memory  */
  231. void
  232. set_image(BLINK_FRAME *frame, int n)
  233.  
  234. {
  235.   float kx, ky;
  236.   int w, h;
  237.   int x, y, x0, y0, w0, h0, xp, yp;
  238.   int ys, xi, yi;
  239.   float dx, dy;
  240.   GC gc;
  241.   int xmax, ymax;
  242.  
  243.   Window win = FL_ObjWin(state.blinker->blinkW);
  244.   XImage *xim;
  245.   XWindowAttributes xwa;
  246.   unsigned char *data = NULL;
  247.  
  248.  
  249.   Pixmap pixmap = frame[n].pixmap;
  250.   Display *disp = state.disp;
  251.   PIXEL *image = frame[n].fits.image;
  252.  
  253.   fl_set_oneliner_font(0, 20); 
  254.   fl_show_oneliner("Setting the image", 100, 100);
  255.   XFlush(state.disp);
  256.   xmax = frame[n].fits.width;
  257.   ymax = frame[n].fits.height;
  258.   if (xmax == 0 || ymax == 0) return;
  259.   dx = frame[n].dx;
  260.   dy = frame[n].dy;
  261.   gc = fl_state[fl_get_form_vclass(state.blinker->blinker)].gc[0];
  262.   w = state.blinker->blinkW->w;
  263.   h = state.blinker->blinkW->h;
  264.  
  265.   kx = (float) (xmax - 1) / (w - 1);
  266.   ky = (float) (ymax - 1) / (h - 1);
  267.   if (kx < ky) kx = ky;
  268.   w0 = (xmax - 1) / kx + 0.5;
  269.   h0 = (ymax - 1) / kx + 0.5;
  270.   x0 = (w - w0) / 2 + 0.5;
  271.   y0 = (h - h0) / 2 + 0.5;
  272.   XSetState(disp, gc, state.pixel[0], 0, GXcopy, AllPlanes);
  273.   XFillRectangle(disp, pixmap, gc, 0, 0, w, h); 
  274.  
  275.  
  276.   XGetWindowAttributes(state.disp, win, &xwa);
  277.   data = myalloc(pixmap_size(w0, h0, xwa.depth), "set_image", "data");
  278.   xim = XCreateImage(state.disp, xwa.visual, xwa.depth, ZPixmap, 0, data, w0, h0, 8, 0);
  279.  
  280.   /*  Draw the image  */
  281.   yp = y0;
  282.   for (y = 0; y < h0; y++, yp++) {
  283.     yi = (int) (kx * y + dy + 0.5);
  284.     if (yi >=0 && yi < ymax) {
  285.       ys = yi * xmax;
  286.       xp = x0;
  287.       for (x = 0; x < w0; x++, xp++) {
  288.     xi = (int) (kx * x + dx + 0.5);
  289.     if (xi >= 0 && xi < xmax) {
  290.       XPutPixel(xim, x, y, state.pixel[correct(frame, n, image[xi + ys])]); 
  291.     }
  292.       }
  293.     }
  294.   }
  295.   XPutImage(state.disp, pixmap, gc, xim, 0, 0, x0, y0, w0, h0);
  296.   XDestroyImage(xim);
  297.   draw_objects(frame, n);
  298.   fl_hide_oneliner();
  299.   fl_winset(FL_ObjWin(state.blinker->blinkW));
  300. }
  301.  
  302.  
  303. /*  Calculate values for linear grey level correction  */
  304. void
  305. set_lin(BLINK_FRAME *frame, int n)
  306.  
  307. {
  308.   float dg, dx;
  309.   int i;
  310.  
  311.   dx = frame[n].high - frame[n].low;
  312.   dg = dx / (frame[n].ngam - 1.0);
  313.   /*  Set tables for brightness correction  */
  314.   for (i = 0; i < frame[n].ngam; i++) {
  315.     frame[n].gamx[i] = frame[n].low + i * dg;
  316.     frame[n].gamy[i] = (state.grey_max * i) / (frame[n].ngam - 1.0);
  317.     if (i > 0) {
  318.       frame[n].kg[i] = (frame[n].gamy[i] - frame[n].gamy[i - 1]) / 
  319.     (frame[n].gamx[i] - frame[n].gamx[i - 1]);
  320.     }
  321.   }
  322. }
  323.  
  324.  
  325. int
  326. load_frame(BLINK_FRAME *frame, int n)
  327.  
  328. {
  329.   int xmax, ymax;
  330.   PIXEL *image;
  331.   int i, j, low, high, g;
  332.   float dg;
  333.   int wh;
  334.   char *errors[ERROR_MAX];
  335.   int errnum;
  336.  
  337.   if ((errnum = read_fits(frame[n].name, &image, &xmax, &ymax, 
  338.               &(frame[n].fitsfile), errors)) > 0) {
  339.     if (state.interactive) {
  340.       show_errors(errnum, errors);
  341.       return 1;
  342.     }
  343.     else {
  344.       for (i = 0; i < errnum; i++) {
  345.     fprintf(stderr, errors[i]);
  346.       }
  347.       exit(1);
  348.     }
  349.   }
  350.   frame[n].fits.name = frame[n].name;
  351.   frame[n].imagelist.s = NULL;
  352.   frame[n].imagelist.n = 0;
  353.   frame[n].cataloglist.s = NULL;
  354.   frame[n].cataloglist.n = 0;
  355.   frame[n].detect = 0;
  356.   frame[n].matched = 0;
  357.   frame[n].map.minmag = DEFAULT_MINMAG;
  358.   frame[n].map.maxmag = DEFAULT_MAXMAG;
  359.   /*  If WCS coordinates are present, calculate coordinates of the image center */
  360.   /*  Enable the Set parameters option in the astrometry menu  */
  361.   if (state.interactive) {
  362.     fl_set_menu_item_mode(state.blinker->astrometryW, EDIT_PARAMETERS, FL_PUP_NONE);
  363.     fl_set_menu_item_mode(state.blinker->astrometryW, LOAD_STAR_LIST, FL_PUP_NONE);
  364.   }
  365.   if (frame[n].fitsfile.wcs) {
  366.     int status = 0;
  367.     fits_pix_to_world(0.5 * xmax, 0.5 * ymax,
  368.          frame[n].fitsfile.crval1, frame[n].fitsfile.crval2,
  369.          frame[n].fitsfile.crpix1, frame[n].fitsfile.crpix2,
  370.          frame[n].fitsfile.cdelt1, frame[n].fitsfile.cdelt2,
  371.          frame[n].fitsfile.crot,
  372.          frame[n].fitsfile.ctype,
  373.          &(frame[n].ra), &(frame[n].dec), &status);
  374.     frame[n].fi = frame[n].fitsfile.crot;
  375.     frame[n].xsize = fabs(frame[n].fitsfile.cdelt1 * 3600.0);
  376.     frame[n].ysize = fabs(frame[n].fitsfile.cdelt2 * 3600.0);
  377.   }
  378.   else {
  379.     frame[n].ra = 0.0;
  380.     frame[n].dec = 0.0;
  381.     frame[n].fi = 0.0;
  382.     frame[n].xsize = 1.92;
  383.     frame[n].ysize = 1.92;
  384.   }
  385.   if (state.interactive) 
  386.     fl_set_menu_item_mode(state.blinker->astrometryW, DETECT_STARS, FL_PUP_NONE);
  387.   /*  If possible, calculate time and date of mid-exposure  */
  388.   calculate_midexposure(&frame[n].fitsfile, &frame[n].year, &frame[n].month,
  389.             &frame[n].day, &frame[n].hour, 
  390.             &frame[n].minute, &frame[n].second);
  391.   /*  Set default options for star matching  */
  392.   set_match_defaults(frame, n);
  393.   set_image_parameters(&frame[n].fits, xmax, ymax, image);
  394.   /* awx = state.blinker->zoom1W.x / state.zoom_width;
  395.   awy = state.blinker->zoom1W.y / state.zoom_width;
  396.   frame[n].astrwin.image = (PIXEL *) myalloc(sizeof(PIXEL) * awx * awy, 
  397.                          "load_frame", "astrwin");
  398.   set_image_parameters(&frame[n].astrwin, awx, awy,
  399.   state.blinker->zoom1W.y / state.zoom_width, );  */
  400.   /*  Translation and rotation of the image  */
  401.   frame[n].dx = frame[n].dy = frame[n].alfa = 0.0;
  402.   if (state.interactive) {
  403.     /*  Create Pixmap for image  */
  404.     frame[n].pixmap = 
  405.       XCreatePixmap(state.disp, 
  406.             FL_ObjWin(state.blinker->blinkW), 
  407.             state.bw, state.bh, 
  408.             fl_state[fl_get_form_vclass(state.blinker->blinker)].depth);
  409.  
  410.     /*  Find the lowest and the highest grey level  */
  411.     low = 65536;
  412.     high = -65536;
  413.     for (i = 0; i < xmax * ymax; i++) {
  414.       g = image[i];
  415.       if (low > g) low = g;
  416.       if (high < g) high = g;
  417.     }
  418.     frame[n].xmin = frame[n].low = low;
  419.     frame[n].xmax = frame[n].high = high;
  420.     /*  Set number of points for grey level correction  */
  421.     frame[n].ngam = NGAMMA;
  422.     frame[n].gamx = myalloc(frame[n].ngam * sizeof(float), 
  423.                 "load_frame", "frame[n].gamx");
  424.     frame[n].gamy = myalloc(frame[n].ngam * sizeof(float), 
  425.                 "load_frame", "frame[n].gamy");
  426.     frame[n].kg = myalloc(frame[n].ngam * sizeof(float), 
  427.               "load_frame", "frame[n].kg");
  428.     /*  Width of the histogram box  */
  429.     frame[n].nhisto = wh = HISTOGRAM_WIDTH;
  430.     /* reserve space for histogram  */
  431.     frame[n].histx = myalloc(wh * sizeof(float), 
  432.                  "load_frame", "frame[n].histx");
  433.     frame[n].histy = myalloc(wh * sizeof(float), 
  434.                  "load_frame", "frame[n].histy");
  435.     for (i = 0; i < wh; i++) {
  436.       frame[n].histx[i] = i / (double) (wh - 1) * (high - low);
  437.       frame[n].histy[i] = 0;
  438.     }
  439.     /*  Calculate histogram  */
  440.     dg = (high - low) / (wh - 1.0);
  441.     for (i = 0; i < xmax * ymax; i++) {
  442.       j = (image[i] - low) / dg;
  443.       frame[n].histy[j]++;
  444.     }
  445.     for (i = 0; i < wh; i++) {
  446.       frame[n].histy[i] = log(frame[n].histy[i] + 1);
  447.     }
  448.     /*  Number of markers  */
  449.     frame[n].objnum = 0;
  450.     frame[n].objshow = 1;
  451.     /*  Make automatic grey level correction  */
  452.     autolevels(n);
  453.   }
  454.   return 0;
  455. }
  456.  
  457. /*  Remove all the data belonging to frame n from the memory  */
  458. int
  459. remove_frame(BLINK_FRAME *frame, int n)
  460.  
  461. {
  462.   int i;
  463.  
  464.   if (state.interactive) {
  465.     free(frame[n].histy);
  466.     free(frame[n].histx);
  467.     free(frame[n].kg);
  468.     free(frame[n].gamy);
  469.     free(frame[n].gamx);
  470.     /*  Free the Pixmap  */
  471.     XFreePixmap(state.disp, frame[n].pixmap);
  472.   }
  473.   /*  Free space for the image  */
  474.   free(frame[n].fits.image);
  475.   if (frame[n].imagelist.s) free(frame[n].imagelist.s);
  476.   if (frame[n].cataloglist.s) free(frame[n].cataloglist.s);
  477.   if (frame[n].obj) free(frame[n].obj);
  478.   /* Move data about other images so that they fill the hole which appeared */
  479.   (state.frame_used)--;
  480.   for (i = n; i < state.frame_used; i++) frame[i] = frame[i + 1];
  481.   /*  Set pointers to NULL */
  482.   frame[i].gamx = NULL;
  483.   frame[i].gamy = NULL;
  484.   frame[i].kg = NULL;
  485.   frame[i].histx = NULL;
  486.   frame[i].histy = NULL;
  487.   frame[i].name = NULL;
  488.   frame[i].fits.image = NULL;
  489.   frame[i].cataloglist.s = NULL;
  490.   frame[i].imagelist.s = NULL;
  491.   return 0;
  492. }
  493.  
  494.  
  495. /*  Find color index from the string  */
  496. int
  497. find_object_color(char *color)
  498.  
  499. {
  500.   char *c[] = {"red", "yellow", "blue", "green", "magenta", "cyan"};
  501.   int cl[] = {FL_RED, FL_YELLOW, FL_BLUE, FL_GREEN, FL_MAGENTA, FL_CYAN, FL_RED};
  502.   int i;
  503.  
  504.   if (strlen(color) == 0) return FL_RED;
  505.   strlwr(color);
  506.   for (i = 0; i < sizeof(c); i++) {
  507.     if (strcmp(color, c[i]) == 0) break;
  508.   }
  509.   return cl[i];
  510. }
  511.  
  512.  
  513. /*  Find shape index from the string  */
  514. int
  515. find_object_shape(char *shape)
  516.  
  517. {
  518.   char *c[] = {"circle", "box", "diamond", "uptriangle", "downtriangle"};
  519.   int cl[] = {OBJ_CIRCLE, OBJ_BOX, OBJ_DIAMOND, OBJ_UPTRIANGLE, OBJ_DOWNTRIANGLE,
  520.           OBJ_CIRCLE};
  521.   int i;
  522.  
  523.   if (strlen(shape) == 0) return OBJ_CIRCLE;
  524.   strlwr(shape);
  525.   for (i = 0; i < sizeof(c); i++) {
  526.     if (strcmp(shape, c[i]) == 0) break;
  527.   }
  528.   return cl[i];
  529. }
  530.  
  531.  
  532.  
  533. int
  534. load_file(char *pname)
  535.  
  536. {
  537.   char line[80], *line1, *p, name[80], *fname;
  538.   FILE *fp;
  539.   int i, i1, j, n;
  540.   float dx, dy;
  541.   GC gc;
  542.   int xmax, ymax;
  543.   int w, h, x0, y0, w0, h0;
  544.   float kx, ky;
  545.   float ta, tb, tc;
  546.   Pixmap pixmap;
  547.   OBJECT *obj = NULL;
  548.   char color[80], shape[80];
  549.   XPoint xpoints[10];
  550.  
  551.   Display *disp = state.disp;
  552.   gc = fl_state[fl_get_form_vclass(state.blinker->blinker)].gc[0];
  553.   w = state.blinker->blinkW->w;
  554.   h = state.blinker->blinkW->h;
  555.   
  556.   if ((fp = fopen(pname, "r")) == NULL) {
  557.     fprintf(stderr, "Can not open file %s\n", pname);
  558.     exit(1);
  559.   }
  560.   i = 0; /*  Number of currently loaded images  */
  561.   while(!feof(fp)) {
  562.     n = 0;
  563.     /*  Read a line from file  */
  564.     fgets(line, 80, fp);
  565.     if (feof(fp)) break;
  566.     line1 = (char *) strdup(line);
  567.     do {
  568.       p = strtok(line1, " \t");
  569.       if (p != NULL) n++;
  570.       line1 = NULL;
  571.     } while (p != NULL);
  572.     /*  n contains a number of items in the current line  */
  573.     switch (n) {
  574.     case 3:
  575.       /*    case 7: */
  576.       if (n == 3) {
  577.       /*  Three items: get file name and offsets in x and y direction */
  578.       /****************************************************************/
  579.       sscanf(line, "%s %f %f", name, &dx, &dy);
  580.       frame[i].a = 0.0;
  581.       frame[i].b = 0.0;
  582.       frame[i].d = 0.0;
  583.       frame[i].e = 0.0;
  584.       }
  585.       else {
  586.     /*  Seven items: */
  587.       /****************************************************************/
  588.     /*      sscanf(line, "%s %f %f %f %f %f %f %f", name, &dx, &dy,
  589.          &frame[i].a, &frame[i].b, &frame[i].d, &frame[i].e);  */
  590.       }
  591.       frame[i].name = (char *)strdup(name);
  592.       (state.frame_used)++;
  593.       if (state.frame_used == state.frame_max) {
  594.     int i;
  595.     state.frame_max += FRAME_MAX;
  596.     if ((frame = (BLINK_FRAME *) 
  597.          realloc(frame, sizeof(BLINK_FRAME) * state.frame_max)) == NULL) {
  598.       fprintf(stderr, "Out of memory, function loadC, variable frame\n");
  599.       exit(1);
  600.     }
  601.     for (i = state.frame_used; i < state.frame_max; i++) {
  602.       frame[i].gamx = NULL;
  603.       frame[i].gamy = NULL;
  604.       frame[i].kg = NULL;
  605.       frame[i].histx = NULL;
  606.       frame[i].histy = NULL;
  607.       frame[i].name = NULL;
  608.       frame[i].fits.image = NULL;
  609.     }
  610.       }
  611.       /*  Load the image into the structure */
  612.       if (load_frame(frame, i)) {
  613.     (state.frame_used)--;
  614.     break;
  615.       }
  616.       frame[i].dx = dx;
  617.       frame[i].dy = dy;
  618.       frame[i].objmax = OBJECT_NUM;
  619.       obj = frame[i].obj = (OBJECT *) myalloc(sizeof(OBJECT) * frame[i].objmax, 
  620.                           "load_file", "obj");
  621.       frame[i].imagelist.s = (STAR *) myalloc(sizeof(OBJECT) * frame[i].objmax, 
  622.                           "load_file", "imagelist.s");
  623.       set_image(frame, i);
  624.       /*  Add image name to choices  */
  625.       fname = strrchr(name, '/');
  626.       if (!fname) fname = name;
  627.       else fname++;
  628.       fl_addto_choice(state.gui->firstnameW, fname);
  629.       fl_addto_choice(state.gui->secondnameW, fname);
  630.       if (i == 0 || i == 1) {
  631.     state.control[state.control_num] = i;
  632.     /*  Write the file name into the input field,  */
  633.     /*  draw histogram, grey level correction curve, translation and rotation  */
  634.     show_frame_info(frame, i, 0);
  635.     if (state.frame_used == 1) {
  636.       state.control[1] = 0;
  637.       show_frame_info(frame, i, 1);
  638.     }
  639.       }
  640.       i++;
  641.       break;
  642.     case 4:
  643.     case 5:
  644.     case 6:
  645.       /*  Info about an additional object  */
  646.       if (state.frame_used == 0) {
  647.     fprintf(stderr, "No image loaded yet: ignoring line %s", line);
  648.     break;
  649.       }
  650.       i1 = i - 1;
  651.       j = frame[i1].objnum;
  652.       obj[j].s = (char *) myalloc(sizeof(char) * 81, "load_image", "obj[j].s");
  653.       color[0] = '\0';
  654.       shape[0] = '\0';
  655.       if (n == 4) {
  656.     if (sscanf(line, "%f %f %f %s", &(obj[j].x), &(obj[j].y),
  657.            &(obj[j].r), obj[j].s) != 4) break;
  658.     frame[i1].imagelist.s[j].x = obj[j].x;
  659.     frame[i1].imagelist.s[j].y = obj[j].y;
  660.     frame[i1].imagelist.s[j].mag = obj[j].r;
  661.     frame[i1].imagelist.n = j + 1;
  662.       }
  663.       else if (n == 5) {
  664.     if (sscanf(line, "%f %f %f %s %s", &(obj[j].x), &(obj[j].y),
  665.            &(obj[j].r), obj[j].s, color) != 5) break;
  666.     frame[i1].imagelist.s[j].x = obj[j].x;
  667.     frame[i1].imagelist.s[j].y = obj[j].y;
  668.     frame[i1].imagelist.s[j].mag = obj[j].r;
  669.     frame[i1].imagelist.n = j + 1;
  670.       }
  671.       else if (n == 6) {
  672.     if (sscanf(line, "%f %f %f %s %s %s", &(obj[j].x), &(obj[j].y),
  673.            &(obj[j].r), obj[j].s, color, shape) != 6) break;
  674.     frame[i1].imagelist.s[j].x = obj[j].x;
  675.     frame[i1].imagelist.s[j].y = obj[j].y;
  676.     frame[i1].imagelist.s[j].mag = obj[j].r;
  677.     frame[i1].imagelist.n = j + 1;
  678.       }
  679.       obj[j].color = find_object_color(color);
  680.       obj[j].shape = find_object_shape(shape);
  681.       frame[i1].objnum++;
  682.       if (frame[i1].objnum == frame[i1].objmax) {
  683.     frame[i1].objmax += OBJECT_NUM;
  684.     if ((obj = frame[i1].obj = (OBJECT *)
  685.          realloc(obj, sizeof(OBJECT) * frame[i1].objmax)) == NULL) {
  686.       fprintf(stderr, "Out of memory, function load_image, variable obj\n");
  687.       exit(1);
  688.     }
  689.     if ((frame[i1].imagelist.s = (STAR *)
  690.          realloc(frame[i1].imagelist.s, sizeof(OBJECT) * frame[i1].objmax)) == NULL) {
  691.       fprintf(stderr, "Out of memory, function load_image, variable obj\n");
  692.       exit(1);
  693.     }
  694.       }
  695.       pixmap = frame[i1].pixmap;
  696.       xmax = frame[i1].fits.width;
  697.       ymax = frame[i1].fits.height;
  698.       dx = frame[i1].dx;
  699.       dy = frame[i1].dy;
  700.       kx = (float) (xmax - 1) / (w - 1);
  701.       ky = (float) (ymax - 1) / (h - 1);
  702.       if (kx < ky) kx = ky;
  703.       w0 = (xmax - 1) / kx + 0.5;
  704.       h0 = (ymax - 1) / kx + 0.5;
  705.       x0 = (w - w0) / 2 + 0.5;
  706.       y0 = (h - h0) / 2 + 0.5;
  707.       XSetState(disp, gc, fl_get_pixel(obj[j].color), 0, GXcopy, AllPlanes);
  708.       switch (obj[j].shape) {
  709.       case OBJ_CIRCLE:
  710.     XDrawArc(disp, pixmap, gc, 
  711.          x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 0.5), 
  712.          y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 0.5), 
  713.        (int) (2 * obj[j].r), (int) (2 * obj[j].r), 0, 23040);
  714.     XDrawArc(disp, pixmap, gc, 
  715.            x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 1.5), 
  716.          y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 1.5), 
  717.            (int) (2 * obj[j].r + 2), (int) (2 * obj[j].r + 2), 0, 23040);
  718.     break;
  719.       case OBJ_BOX:
  720.     XDrawRectangle(disp, pixmap, gc, 
  721.          x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 0.5), 
  722.                y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 0.5), 
  723.        (int) (2 * obj[j].r), (int) (2 * obj[j].r));
  724.     XDrawRectangle(disp, pixmap, gc, 
  725.          x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 1.5), 
  726.                y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 1.5), 
  727.        (int) (2 * obj[j].r + 2), (int) (2 * obj[j].r + 2));
  728.     break;
  729.       case OBJ_DIAMOND:
  730.     xpoints[0].x = x0 + (int) ((obj[j].x - dx) / kx + 0.5);
  731.     xpoints[0].y = y0 + (int) ((obj[j].y - dy) / kx - obj[j].r - 0.5);
  732.     xpoints[1].x = x0 + (int) ((obj[j].x - dx) / kx + obj[j].r + 0.5);
  733.     xpoints[1].y = y0 + (int) ((obj[j].y - dy) / kx + 0.5);
  734.     xpoints[2].x = xpoints[0].x;
  735.     xpoints[2].y = y0 + (int) ((obj[j].y - dy) / kx + obj[j].r + 0.5);
  736.     xpoints[3].x = x0 + (int) ((obj[j].x - dx) / kx - obj[j].r - 0.5);
  737.     xpoints[3].y = xpoints[1].y;
  738.     xpoints[4].x = xpoints[0].x;
  739.     xpoints[4].y = xpoints[0].y;
  740.     xpoints[5].x = xpoints[0].x;
  741.     xpoints[5].y = xpoints[0].y - 1;
  742.     xpoints[6].x = xpoints[1].x + 1;
  743.     xpoints[6].y = xpoints[1].y;
  744.     xpoints[7].x = xpoints[2].x;
  745.     xpoints[7].y = xpoints[2].y + 1;
  746.     xpoints[8].x = xpoints[3].x - 1;
  747.     xpoints[8].y = xpoints[3].y;
  748.     xpoints[9].x = xpoints[5].x;
  749.     xpoints[9].y = xpoints[5].y;
  750.     XDrawLines(disp, pixmap, gc, xpoints, 10, CoordModeOrigin);
  751.     break;
  752.       case OBJ_UPTRIANGLE:
  753.     tb = 0.5773502 * obj[j].r;
  754.     tc = 0.5 * tb;
  755.     ta = 0.5 * obj[j].r;
  756.     xpoints[0].x = x0 + (int) ((obj[j].x - dx) / kx + 0.5);
  757.     xpoints[0].y = y0 + (int) ((obj[j].y - dy) / kx - tb - 0.5);
  758.     xpoints[1].x = x0 + (int) ((obj[j].x - dx) / kx + ta + 0.5);
  759.     xpoints[1].y = y0 + (int) ((obj[j].y - dy) / kx + tc + 0.5);
  760.     xpoints[2].x = x0 + (int) ((obj[j].x - dx) / kx - ta - 0.5);
  761.     xpoints[2].y = xpoints[1].y;
  762.     xpoints[3].x = xpoints[0].x;
  763.     xpoints[3].y = xpoints[0].y;
  764.     xpoints[4].x = xpoints[0].x;
  765.     xpoints[4].y = xpoints[0].y - 1;
  766.     xpoints[5].x = xpoints[1].x + 1;
  767.     xpoints[5].y = xpoints[1].y + 1;
  768.     xpoints[6].x = xpoints[2].x - 1;
  769.     xpoints[6].y = xpoints[5].y;
  770.     xpoints[7].x = xpoints[4].x;
  771.     xpoints[7].y = xpoints[4].y;
  772.     XDrawLines(disp, pixmap, gc, xpoints, 8, CoordModeOrigin);
  773.     break;
  774.       case OBJ_DOWNTRIANGLE:
  775.     tb = 0.5773502 * obj[j].r;
  776.     tc = 0.5 * tb;
  777.     ta = 0.5 * obj[j].r;
  778.     xpoints[0].x = x0 + (int) ((obj[j].x - dx) / kx + 0.5);
  779.     xpoints[0].y = y0 + (int) ((obj[j].y - dy) / kx + tb - 0.5);
  780.     xpoints[1].x = x0 + (int) ((obj[j].x - dx) / kx + ta + 0.5);
  781.     xpoints[1].y = y0 + (int) ((obj[j].y - dy) / kx - tb + 0.5);
  782.     xpoints[2].x = x0 + (int) ((obj[j].x - dx) / kx - ta - 0.5);
  783.     xpoints[2].y = xpoints[1].y;
  784.     xpoints[3].x = xpoints[0].x;
  785.     xpoints[3].y = xpoints[0].y;
  786.     xpoints[4].x = xpoints[0].x;
  787.     xpoints[4].y = xpoints[0].y + 1;
  788.     xpoints[5].x = xpoints[1].x + 1;
  789.     xpoints[5].y = xpoints[1].y + 1;
  790.     xpoints[6].x = xpoints[2].x - 1;
  791.     xpoints[6].y = xpoints[2].y - 1;
  792.     xpoints[7].x = xpoints[4].x;
  793.     xpoints[7].y = xpoints[4].y;
  794.     XDrawLines(disp, pixmap, gc, xpoints, 8, CoordModeOrigin);
  795.     break;
  796.       }
  797.       break;
  798.     }
  799.   }
  800.   fclose(fp);
  801.   XSetState(disp, gc, state.pixel[0], 0, GXcopy, AllPlanes);
  802.   if (state.frame_used > 0) {
  803.     show_frame_info(frame, state.control[state.control_num], state.control_num);
  804.   }
  805.   return 0;
  806. }
  807.  
  808.  
  809. int
  810. main(int argc, char *argv[])
  811.  
  812. {
  813.   int i;
  814.   char *np;
  815.  
  816.   /*  reserve space for FRAME_MAX descriptions of images  */
  817.   frame = (BLINK_FRAME *) myalloc(sizeof(BLINK_FRAME) * FRAME_MAX,
  818.                   "main", "frame");
  819.   state.frame_max = FRAME_MAX;
  820.   for (i = 0; i < state.frame_max; i++) {
  821.     frame[i].gamx = NULL;
  822.     frame[i].gamy = NULL;
  823.     frame[i].kg = NULL;
  824.     frame[i].histx = NULL;
  825.     frame[i].histy = NULL;
  826.     frame[i].name = NULL;
  827.     frame[i].fits.image = NULL;
  828.   }
  829.   /*===============================================*/
  830.   /*  Set defaults for the program state variable  */
  831.   /*===============================================*/
  832.   state.browser[0] = NULL;
  833.   state.browser[1] = NULL;
  834.   state.b[0] = 0;
  835.   state.b[1] = 0; 
  836.   state.error = NULL; 
  837.   state.readme = NULL;
  838.   state.parameters = NULL;
  839.   state.report = NULL;
  840.   state.options = NULL;
  841.   state.catalogs = NULL;
  842.   state.mail = NULL;
  843.   state.newwcs = NULL;
  844.   state.settings = NULL;
  845.   state.set_catalogs = NULL;
  846.   state.set_observatory = NULL;
  847.   state.set_display = NULL;
  848.   state.set_mail = NULL;
  849.   state.set_commands = NULL;
  850.   state.set_ccd = NULL;
  851.   state.set_count = NULL;
  852.   state.set_match = NULL;
  853.   state.showstar = NULL;
  854.   state.showcomet = NULL;
  855.   state.telescope = NULL;
  856.   state.message = NULL;
  857.   state.blinkwidth = 1000;
  858.   state.blinkheight = 910;
  859.   state.frame_used = 0;
  860.   state.control_num = 0;
  861.   state.zoom_width = 4;
  862.   state.freeze = 0;
  863.   state.blink = 0;
  864.   state.blinknum = 0;
  865.   state.delay = DEFAULT_DELAY;
  866.   state.autolevel_high = DEFAULT_AUTOLEVEL_HIGH;
  867.   state.logfile = NULL;
  868.   state.logfp = stdout;
  869.   state.interactive = 1;
  870.   state.verbose = 0;
  871.   state.doastr = 0;
  872.   state.color = 0;
  873.   state.inverse = 0;
  874.   state.wwwbrowser = NULL;
  875.   state.helpfile = NULL;
  876.   /*======================================================*/
  877.   /*  Set default values for star counting and matching   */
  878.   /*======================================================*/
  879.   set_defvals();
  880.   /*====================================*/
  881.   /*  Mark count_options variables      */
  882.   /*====================================*/
  883.   count_options.maxsize = -999;
  884.   count_options.sg_num = -999;
  885.   count_options.fitmeasure = -999;
  886.   count_options.border = -999;
  887.   count_options.minbright = -999;
  888.   count_options.minstar = -999;
  889.   count_options.inner = -999;
  890.   count_options.outer = -999;
  891.   count_options.aperture = -999;
  892.   /*  Define supported catalogs  */
  893.   /*====================================*/
  894.   /*  Mark match_options variables      */
  895.   /*====================================*/
  896.   match_options.firstbright = -999;
  897.   match_options.nstar = -999;
  898.   match_options.min = -999;
  899.   match_options.poserrmax = -999;
  900.   match_options.magerrmax = -999;
  901.   match_options.maxres = -999;
  902.   /*=============================*/
  903.   catalog[CAT_USNO].use = 0;
  904.   catalog[CAT_USNO].name = "USNO-SA 1.0";
  905.   catalog[CAT_USNO].lpath = PATHLENGTH;
  906.   if ((catalog[CAT_USNO].path = (char *) malloc(catalog[CAT_USNO].lpath)) == NULL) {
  907.     fprintf(stderr, "Out of memory, path for USNO catalog.\n");
  908.     exit(1);
  909.   }
  910.   catalog[CAT_USNO].path[0] = '\0';
  911.   catalog[CAT_PPM].use = 0;
  912.   catalog[CAT_PPM].name = "PPM";
  913.   catalog[CAT_PPM].lpath = PATHLENGTH;
  914.   if ((catalog[CAT_PPM].path = (char *) malloc(catalog[CAT_PPM].lpath)) == NULL) {
  915.     fprintf(stderr, "Out of memory, path for PPM catalog.\n");
  916.     exit(1);
  917.   }
  918.   catalog[CAT_PPM].path[0] = '\0';
  919.   catalog[CAT_GUIDE].use = 0;
  920.   catalog[CAT_GUIDE].name = "GSC 1.1";
  921.   catalog[CAT_GUIDE].lpath = PATHLENGTH;
  922.   if ((catalog[CAT_GUIDE].path = (char *) malloc(catalog[CAT_GUIDE].lpath)) == NULL) {
  923.     fprintf(stderr, "Out of memory, path for GUIDE NORTH catalog.\n");
  924.     exit(1);
  925.   }
  926.   catalog[CAT_GUIDE].path[0] = '\0';
  927.  
  928.   catalog[CAT_GUIDE_SOUTH].use = 0;
  929.   catalog[CAT_GUIDE_SOUTH].name = "GSC 1.1";
  930.   catalog[CAT_GUIDE_SOUTH].lpath = PATHLENGTH;
  931.   if ((catalog[CAT_GUIDE_SOUTH].path = (char *) malloc(catalog[CAT_GUIDE_SOUTH].lpath)) == NULL) {
  932.     fprintf(stderr, "Out of memory, path for GUIDE SOUTH catalog.\n");
  933.     exit(1);
  934.   }
  935.   catalog[CAT_GUIDE_SOUTH].path[0] = '\0';
  936.  
  937.   /*=================================*/
  938.   /*  Define observatory parameters  */
  939.   /*=================================*/
  940.   observatory.code = 0;
  941.   observatory.observer[0] = '\0';
  942.   observatory.telescope[0] = '\0';
  943.   observatory.instrument[0] = '\0';
  944.  
  945.   /*=================================*/
  946.   /*  Telescope control defaults     */
  947.   /*=================================*/
  948.   telescope.ra = 0;
  949.   telescope.dec = 0;
  950.   telescope.exptime = 1;
  951.   telescope.dark = 0;
  952.   telescope.temp = 0;
  953.   telescope.filename = NULL;
  954.  
  955.   /*  Mail structure  */
  956.   if ((mail.to = (char *) malloc(1)) == NULL) {
  957.     fprintf(stderr, "Out of memory, mail.to string.\n");
  958.     exit(1);
  959.   }
  960.   mail.to[0] = '\0';
  961.   if ((mail.cc = (char *) malloc(1)) == NULL) {
  962.     fprintf(stderr, "Out of memory, mail.cc string.\n");
  963.     exit(1);
  964.   }
  965.   mail.cc[0] = '\0';
  966.   if ((mail.title = (char *) malloc(1)) == NULL) {
  967.     fprintf(stderr, "Out of memory, mail.title string.\n");
  968.     exit(1);
  969.   }
  970.   mail.title[0] = '\0';
  971.   if ((mail.file = (char *) malloc(1)) == NULL) {
  972.     fprintf(stderr, "Out of memory, mail.file string.\n");
  973.     exit(1);
  974.   }
  975.   mail.file[0] = '\0';
  976.  
  977.   /*  Find out name of the program  */
  978.   /*================================*/
  979.   np = strrchr(argv[0], '/');  /* check first if there is any path  */
  980.   if (np == NULL) np = argv[0];  /*  No path, just name  */
  981.   else np++;
  982.   if (strcmp(np, "starcount") == 0) {
  983.     state.interactive = 0;
  984.     starcount(argc, argv);
  985.   } 
  986.   else if (strcmp(np, "catalog") == 0) {
  987.     state.interactive = 0;
  988.     make_catalog(argc, argv);
  989.   } else {
  990.     tgui(argc, argv);
  991.   }
  992.   return 0;
  993. }
  994.