File: irafpipe.c

package info (click to toggle)
saoimage 1.35.1-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 4,188 kB
  • ctags: 4,403
  • sloc: ansic: 52,848; makefile: 243; sh: 31
file content (180 lines) | stat: -rw-r--r-- 5,900 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#ifndef lint
static char SccsId[] = "%W%  %G%";
#endif

/* Module:	irafpipe.c (IRAF Pipe Connection)
 * Purpose:	Read an image in from the IRAF pipe
 * Subroutine:	read_imtool_packet()		returns: void
 * Copyright:	1990-1998 Smithsonian Astrophysical Observatory
 *		You may do anything you like with this file except remove
 *		this copyright.  The Smithsonian Astrophysical Observatory
 *		makes no representations about the suitability of this
 *		software for any purpose.  It is provided "as is" without
 *		express or implied warranty.
 * Modified:	{0} based on code from Doug Tody's IRAF Imtool (NOAO)
 *		{1} Michael VanHilst	adapted			 9 Jul 1989
 *		{2} MVH rearranged structure			29 Mar 1990
 *		{3} Doug Mink (SAO) Changed WCS flag to IWCS	25 Feb 1998
 *		{n} <who> -- <does what> -- <when>
 * "For the moment we take an IIS model 70 command/data stream as input; this
 * is used to load images into the image display.  This is a kludge interface
 * for the prototype, convenient since the high level software is written for
 * the IIS." - explanation by Doug Tody
 */

#ifdef IMTOOL

#include <stdio.h>		/* stderr, FILE, NULL, etc. */
#include <X11/Xlib.h>		/* get X types and constants */
#include "hfiles/control.h"	/* struct connectRec */
#include "hfiles/imtool.h"	/* struct imtoolRec, codes */

/*
 * Subroutine:	read_imtool_packet()
 * Purpose:	event handler for packet input from iraf
 */
void read_imtool_packet( port )
     struct connectRec *port;
{
  int ndatabytes;
  int bytes;
  int last_packet;
  struct imtoolRec imhead;
  static int byteswap = 0;	/* l: flag to byteswap packets */
  static int errcnt=0;		/* l: count packet errors (before giving up) */
  static int noblock=0;		/* l: check if in non-blocking loop */
#ifdef DEBUG
  int pkt;			/* l: make packet code discrete variable */
#endif
  int read_connection();
  void imtool_response(), swap_bytes();
  static int check_packet_sum();

  /* read the header */
  bytes = read_connection(port, (char *)&imhead, sizeof(struct imtoolRec));
  /* check size of read */
  if( bytes < sizeof(struct imtoolRec) ) {
    /* if EOF, must be problem with this end of pipe, call plumber */
    /* read 0 may happen once on EOF, happens forever if non-blocking */
    if( bytes == 0 ) {
      /* pipe mustn't be blocking, count the bad passes through here */
      /* noblock is set to zero everywhere but here */
      ++noblock;
      return;
    } else {
      noblock = 0;
#ifdef DEBUG
      (void)fprintf(stderr, "Pipe read error\n");
#endif
      return;
    }
  }

#if DEBUG
  if( getenv("DEBUG_IMTOOL") ) {
	char  *s;
	short su;

	(void)fprintf(stderr, "\n=== Imtool header ===\n");
	(void)fprintf(stderr, "  tid:     %d  -- ", imhead.tid);
	if(imhead.tid & PACKED)		(void)fprintf(stderr, "PACKED ");
	if( imhead.tid & COMMAND )	(void)fprintf(stderr, "COMMAND ");
	if( imhead.tid & IIS_READ )	(void)fprintf(stderr, "IIS_READ ");
	if( imhead.tid & IMC_SAMPLE )	(void)fprintf(stderr, "IMC_SAMPLE ");
	(void)fprintf(stderr, "\n");
	(void)fprintf (stderr, "  count:   %d\n", -imhead.thingct);
	su = imhead.subunit & 077;
	if( su == MEMORY )		s = "MEMORY";
	else if( su == LUT )		s = "LUT";
	else if( su == FEEDBACK )	s = "FEEDBACK";
	else if( su == IWCS )		s = "WCS";
	else if( su == IMCURSOR )	s = "IMCURSOR";
	else if( su == 12 )		s = "ZOOM/PAN (ignored)";
	else				s = "???";
	(void)fprintf(stderr, "  subunit: %d -- %s\n", su, s);
	/* (void)fprintf(stderr, "  chksum:  %x\n", imhead.checksum); */
	(void)fprintf(stderr, "  x: %d  y: %d  z: %d  t: %d\n",
		      imhead.x & 077777, imhead.y & 077777,
		      imhead.z & 07777, imhead.t & 077);
  }
#endif

  noblock = 0;
  if( byteswap )
    swap_bytes((char *)&imhead, sizeof(struct imtoolRec));
  /* check the packet checksum (debug it after 2nd try), don't die */
  if( !check_packet_sum((char *)&imhead, sizeof(struct imtoolRec),
			 &byteswap, (errcnt > 2), 0) ) {
    /* no hope of syncing on next read, better flush out pipe */
    flush_connection(port);
    errcnt++;
    return;
  }
  /* read the count field */
  if( (ndatabytes = -(int)imhead.thingct) < 0 ) {
    (void)fprintf(stderr,"bad packet\n");
    return;
  }
  /* check for packed short's (we wish) */
  if( !(imhead.tid & PACKED) )
    ndatabytes *= 2;
  imtool_response(port, &imhead, ndatabytes);
}


/*
 * Subroutine:	check_packet_sum
 * Purpose:	Check packet sum against checksum (and verify byteswap)
 * Returns:	1
 */
static int check_packet_sum ( packet, size, byteswap, errmsg, die )
     char *packet;
     int size;
     int *byteswap, errmsg, die;
{
  int i, sum, second_try=0;
  register short *p;
  void swap_bytes(), exit_errmsg();

  while( 1 ) {
    /* add up the sum */
    for( i=0, sum=0, p=(short *)packet;  i < 8;  i++ )
      sum += *p++;
    /* sum (including checksum) should roll at 0177777 */
    if( (sum & 0177777) == 0177777 )
      return( 1 );
    /* if not, bswap and try again (note danger of swab in place) */
    swap_bytes(packet, size);
    *byteswap = !(*byteswap);
    if( second_try++ ) {
      /* after retry, report the error */
      if( errmsg ) {
	(void)fprintf(stderr, "imtool: bad data header checksum\n");
#ifdef DEBUG
	/* display first few bytes both swapped and unswapped */
	if( *byteswap )
	  /* if was byteswapped, start unswapped */
	  swap_bytes(packet, size);
	/* what it looks like unswapped */
	(void)fprintf(stderr, "noswap:");
	for( i=0, p=(short *)packet;  i < 8;  i++ )
	  (void)fprintf(stderr, " %6o", p[i]);
	(void)fprintf(stderr, "\n");
	/* what it looks like swapped */
	swap_bytes(packet, size);
	(void)fprintf(stderr, "  swap:");
	for( i=0, p=(short *)packet;  i < 8;  i++ )
	  (void)fprintf(stderr, " %6o", p[i]);
	(void)fprintf(stderr, "\n");
#endif
      }
      /* imtool dies at this point */
      if( die )
        exit_errmsg("FATAL ERROR: imtool pipe datastream synch lost\n");
      else
	return( 0 );
    }
  }
}

#endif