/*************************************************************** pdliisdisplay.c ****************************************************************/ /* Redefine iis_error to use Perl's croak() */ void iis_error( char* error1, char*error2 ) { croak (error1,error2); } /*****************************************************/ /* Rest of the subroutines are identical to libiis.c v1.0 */ /******************* iis_cur ************************/ /* Return cursor position and character typed */ void iis_cur(float*x, float*y, char* ch) { unsigned short hdr[8]; short buf[SZ_WCSTEXT]; int nbytes,wcs; /* Send read request */ hdr[TRANSFER_ID] = PDL_IIS_IREAD; hdr[THING_COUNT] = 0; hdr[SUB_UNIT] = IMCURSOR; hdr[CHECK_SUM] = 0; hdr[X_REGISTER] = 0; hdr[Y_REGISTER] = 0; hdr[Z_REGISTER] = 0; hdr[T_REGISTER] = 0; iis_checksum(hdr); iis_write((char*)hdr, 8*sizeof(short)); /* Read however many bytes it send in this case */ if ((nbytes = read (iispipe_i, buf, SZ_WCSTEXT)) <= 0) iis_error ("iis_cur: cannot read IIS pipe\n",""); if (sscanf ((char*)buf, "%f %f %d %c", x, y, &wcs, ch) != 4) iis_error ("iis_cur: can't parse '%s'\n", (char*)buf); } /******************* iis_drawcirc *******************/ /* Draw a circle on the image display at a given position */ void iis_drawcirc(float xcen, float ycen, float radius, int colour, int frame) { unsigned short hdr[8]; unsigned char *data; int i,j,y; int ymin,ymax,ntrans,nlines,nbytes; float xcen2,ycen2,dd; char wcsbuf[SZ_WCSTEXT]; float xx, yx, xy, yy, xo, yo; /* wcs matrix values */ float xx2, yx2, xy2, yy2, xo2, yo2; /* wcs inverse matrix values */ char label[1024]; /* wcs file title */ int w_type; /* wcs scaling code */ float low, high; /* wcs scaling limits */ int chan; float rr; chan = iis_chan(frame); /* Send WCS read request */ hdr[TRANSFER_ID] = -PDL_IIS_IREAD; hdr[THING_COUNT] = 0; hdr[SUB_UNIT] = WCS; hdr[CHECK_SUM] = 0; hdr[X_REGISTER] = 0; hdr[Y_REGISTER] = 0; hdr[Z_REGISTER] = chan; hdr[T_REGISTER] = 0; iis_checksum(hdr); iis_write((char*)hdr, 8*sizeof(short)); iis_read ((char*)wcsbuf, SZ_WCSTEXT); /* Get WCS data */ sscanf(wcsbuf, "%[^\n]\n%f%f%f%f%f%f%f%f%d", label, &xx, &yx, &xy, &yy, &xo, &yo, &low, &high, &w_type); /* Invert transform (I don't care about non-square coord systems! */ xcen2 = (xcen-xo)/xx; ycen2 = frameY - (ycen-yo)/yy - 1; /* Correct scale factor - OK for square images don't want to draw ellipses for non-square ones so take geometric mean */ rr = radius / sqrt(iis_abs(xx*yy)); /* Transfer limits (with buffer to allow for edge effects) */ ymin = ycen2-rr-2; if (ymin<0) ymin=0; ymax = ycen2+rr+2; if (ymax>=frameY) ymax=frameY-1; /* Work out how many lines to transfer at a go */ ntrans = RBUFFSZ/frameX; if (ntrans<1) ntrans = 1; /* Allocate buffer for data transfers */ data = (unsigned char*) calloc(ntrans*frameX, sizeof(unsigned char)); if (data==NULL) iis_error("iis_drawcirc: out of memory for buffer",""); /* Loop over blocks */ for (y = ymin; y < ymax; y+=ntrans) { nlines = ntrans; /* Number of lines to transfer */ if (y+ntrans>ymax) nlines = ymax - y; /* Read data */ hdr[TRANSFER_ID] = -PDL_IIS_IREAD | PACKED | BLOCKXFER; hdr[THING_COUNT] = -nlines*frameX; hdr[SUB_UNIT] = REFRESH; hdr[CHECK_SUM] = 0; hdr[X_REGISTER] = ADVXONTC; hdr[Y_REGISTER] = ADVYONXOV+frameY-y-nlines; hdr[Z_REGISTER] = chan; hdr[T_REGISTER] = ALLBITPL; iis_checksum(hdr); iis_write((char*)hdr, 8*sizeof(short)); iis_read((char*)data, nlines*frameX*sizeof(char)); /* Write data */ hdr[TRANSFER_ID] = PDL_IIS_IWRITE | PACKED | BLOCKXFER; hdr[THING_COUNT] = -nlines*frameX; hdr[SUB_UNIT] = REFRESH; hdr[CHECK_SUM] = 0; hdr[X_REGISTER] = ADVXONTC; hdr[Y_REGISTER] = ADVYONXOV+frameY-y-nlines; hdr[Z_REGISTER] = chan; hdr[T_REGISTER] = ALLBITPL; iis_checksum(hdr); iis_write((char*)hdr, 8*sizeof(short)); /* Change Data - draw in i and j to fill circle gaps via symmetry */ for (j=0; j=0) { dd = sqrt(dd); i = iis_round( (float)xcen2 - dd ); if (i>=0 && i=0 && i=0) { dd = sqrt(dd); j = iis_round( (float)ycen2 - (float)y - dd ); if (j>=0 && j=0 && j0 && frame<5) return chan[frame]; else iis_error("iis_display: invalid frame number, must be 1-4\n",""); } /* Round to nearest int symmetrically about zero */ int iis_round ( float i ) { if (i>=0) return (int) (i+0.5); else return -( (int)(0.5-i) ); } float iis_abs(float x) { if (x<0) return (-x); else return x; }