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
|