/* @(#)getcur.c 17.1.1.1 (ESO-DMD) 01/25/02 17:39:35 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTIFICATION: routine GetCursor .AUTHOR K. Banse ESO - Garching .KEYWORDS: display, cursor .PURPOSE: high level interface to read the position of the two cursors on the Image display and get density of relevant pixel. .ALGORITHM: Use enabled cursor(s) and read screen pixels, get real pixels and world coordinates, when the ENTER button is pressed. Exit by pressing EXIT button. also the keyword ACTION/C/5/3 is used, to determine if we want to work with a zoom window .VERSIONS 1.00 940302: from getcur.for 001027 last modif ------------------------------------------------------------------- */ #include #include #include #include /* */ void GetCursor(action,frame,xyinfoa,stata,xyinfob,statb) char *action; /* IN: 4 action flags, [0] = Y, get intensities at cursor position(s) [1] = Y, draw a cross, circle or rectangle at cursor position(s) [2] = Y, show screen coords + value in alphanumerics plane [3] = Y, wait for ENTER button, else not = N, return cursor coords only = Z, return all info if changed */ char *frame; /* IN/OUT: has to be set to ' ' on first call of the routine to mark the beginning on return = name of frame in channel, where cursor(s) are pointing to */ float *xyinfoa; /* OUT: info about cursor 0 (7 values), [0,1] - screen pixels of cursor 0 [2,3] - frame pixel no's for pos. of cursor 0 [4,5] - world coordinates for above [6] - intensity at cursor position only filled, if action[0] = Y */ int *stata; /* OUT: status of cursor 0, 0 = off, 1 = on if action[3] != 'Y' then stata = -1 or -2 if ENTER-button or RETURN-key pushed stata = -9, if input from keyboard (statb indicates which key was pushed) */ float *xyinfob; /* OUT: info about cursor 1 (7 values), [0,1] - screen pixels of cursor 1 [2,3] - frame pixel no's for pos. of cursor 1 [4,5] - world coordinates for above [6] - intensity at cursor position only filled, if action[0] = Y */ int *statb; /* OUT: status of cursor 1, 0 = off, 1 = on if action[3] != 'Y' then statb = -1 or -2 if ENTER-button or RETURN-key pushed if stata = -9 (input from keyboard) then statb indicates which key was pushed */ { int xya[5], xyb[5]; int n, iav, stat; int curco[4], xfig[256], yfig[256]; int in[20], imnow, uni, nulo; int ec, ed, el; static int xcross[5] = {0,0,0,-3,3}, ycross[5] = {-3,3,0,0,0}; static int kpack = 4; static int oldmem, memo = -1; static int planoff = 0, croi = 0; static int xcont = -1, ycont = -1, xzont = -1, yzont = -1; static int ymapa, ymape, maxsiz, virtsz, nlines, nlin2, stapix; static int inopt, oldino, imno; static int tsty, tstz, zflag, aveflg; static int nocur, noc, trnoc; static int splmod, magnif, znoc, zstat; static int npix[2], naxis; char output[80]; static char oldfra[80], zact, *pntrw; static char *errmes = "no image loaded... "; static char *outma = " --- cursor #0 outside image --- "; static char *outmb = " --- cursor #1 outside image --- "; static char *magmes = "looking glass on - type `u' again to turn it off. "; static unsigned char *dpp; static double dd1[4], dd2[4], dd3[4]; /* synchronize with fp2wc */ float rdata; float Pixy(); void framdat(); /* test, if we are here for the first time */ if (*frame == ' ') { oldfra[0] = ' '; oldmem = -99; *frame = '_'; /* so we don't come here again... */ stat = SCKRDI("MONITPAR",20,1,&iav,&maxsiz,&uni,&nulo); maxsiz = maxsiz * maxsiz; /* get cursors involved + current split mode */ stat = SCKRDI("DAZHOLD",1,16,&iav,in,&uni,&nulo); nocur = in[0]; /* noc = 0,1,2 for cursor 0, 1 or both = roi */ if (nocur == 3) noc = 2; /* 3 = 0 and 1 independently */ else noc = nocur; if ((nocur == 2) && (in[1] == 2)) { croi = 1; nocur = 12 ; } else croi = 0; if ( (QRGBFL == 1) && (in[2] == 0) ) splmod = 0; /* in RGB + non-split mode */ else splmod = 1; zact = 'C'; /* default to get/cursor */ /* open zoom window, if required */ if ((action[4] == 'Z') && (IDINUM == 11)) { if (action[5] == 'V') zact = 'V'; /* view/image */ znoc = 0; if (action[6] == '2') znoc = 2; else if (action[6] == '3') znoc = 3; trnoc = znoc; /* true no. of cursors */ if (action[6] == '7') { znoc = 12; croi = 1; /* indicate circles */ } stat = SCKRDI("DAZIN",1,5,&iav,in,&uni,&nulo); /* get window size */ xya[0] = 1; /* display initial zoom factor */ stat = Cauxwnd(0,in,xya,xyb); zflag = 1; /* this implies single cursor... */ inopt = -1; } else { zflag = -1; inopt = 0; trnoc = noc; /* true no. of cursors */ } Ccursin(QDSPNO,inopt,nocur,xya,stata,xyb,statb); if (action[3] == 'N') inopt = 2; else if (action[3] == 'Z') { inopt = 3; xcont = -1; ycont = -1; xzont = -1; yzont = -1; } else inopt = 1; oldino = inopt; magnif = -1; /* magnifying glass off */ if (action[2] == 'Y') Alpcurs(trnoc,0); } for (n=0; n<5; n++) /* init xya + xyb arrays */ { xya[n] = xyb[n] = 0; } /* read the cursor positions in main window ---------------------------------------- */ Curs_loop: if (zflag != 2) { Ccursin(QDSPNO,inopt,nocur,xya,stata,xyb,statb); /* look for arrow keys + other keys from keyboard */ if (*stata == -9) { if (*statb < 18) /* arrow keys + special keys */ stat = Cauxwnd(4,statb,xya,xyb); else if ((*statb == 25) || (*statb == 26)) /* 'l','k' = modify LUT,ITT */ stat = Cauxwnd(9,statb,xya,xyb); else if (*statb == 22) /* 'u' = magnifying glass */ { magnif = -magnif; if (magnif == 1) { inopt = 2; SCTDIS(magmes,-9); SCTDIS(magmes,99); } else { inopt = oldino; (void) strcpy(output,"looking glass off..."); SCTDIS(output,-9); SCTDIS(output,99); } } else return; /* return for any other key */ goto Curs_loop; /* loop again */ } if (*stata == 0) goto sect_1100; /* if EXIT pushed get out of here */ /* get relevant memory board */ if (splmod == 0) /* in RGB + non-split mode */ memo = QIMCH; /* take last displayed channel as memory */ else { if (trnoc != 1) /* for cursor #0 or both cursors */ memo = xya[2]; else memo = xyb[2]; } } /* refresh drawings + check, if we work without a zoom window */ if (zact != 'V') /* NOT in continuous mode... */ (void) Cdazvis(QDSPNO,QOVCH,2,1); if (zflag == -1) goto sect_1060; /* yes - we do have a zoom window ------------------------------ */ if (magnif == 1) /* test, if we are in looking_glass_mode */ { in[0] = memo; in[1] = QOVCH; stat = Cauxwnd(5,in,xya,xyb); goto Curs_loop; } /* test, if we are reading continuously from main window */ if (zact == 'V') { zflag = 1; if (inopt == 3) { if ((xcont != xya[0]) || (ycont != xya[1])) { xcont = xya[0]; ycont = xya[1]; if (*stata >= 0) /* if no enter was pushed */ { zact = 'W'; /* indicate origin */ goto sect_1060; /* and return single cursor */ } } else if (*stata >= 0) /* if no enter was pushed */ goto Curs_loop; /* loop more */ } in[0] = memo; in[1] = QOVCH; stat = Cauxwnd(10,in,xya,xyb); } else { if (zflag == 1) { if (inopt == 3) { if ((xcont != xya[0]) || (ycont != xya[1])) { xcont = xya[0]; ycont = xya[1]; if (*stata >= 0) goto sect_1060; /* return single cursor */ } else if (*stata >= 0) /* if no enter was pushed */ goto Curs_loop; /* loop more */ } in[0] = memo; /* copy area into zoom window */ in[1] = QOVCH; in[2] = 0; in[3] = znoc; in[4] = inopt; stat = Cauxwnd(1,in,xya,xyb); } /* get coordinates from zoom window */ stat = Cauxwnd(2,&memo,xya,xyb); if (stat == 0) /* check for exit button */ { zflag = 1; stat = IIISTI_C(QDSPNO); Ccursin(QDSPNO,-1,nocur,xfig,stata,yfig,statb); goto Curs_loop; /* get out of this loop */ } zflag = 2; curco[0] = xya[0]; /* cursor coords from zoom window */ curco[1] = xya[1]; curco[2] = xyb[0]; curco[3] = xyb[1]; Sc2ch(-1,&curco[0],&curco[1]); /* ima_chan pixels -> screen pixels */ Sc2ch(-1,&curco[2],&curco[3]); /* ima_chan pixels -> screen pixels */ *stata = stat; *statb = stat; goto sect_1080; } /* get zoom + scroll values of image channel ----------------------------------------- */ sect_1060: curco[0] = xya[3]; /* raw curs_coords */ curco[1] = xya[4]; curco[2] = xyb[3]; curco[3] = xyb[4]; sect_1080: xyinfoa[0] = curco[0]; /* screen coords. of cursor 0 */ xyinfoa[1] = curco[1]; xyinfob[0] = curco[2]; /* screen coords. of cursor 1 */ xyinfob[1] = curco[3]; zstat = DCGICH( memo ); /* we need `zstat' later on */ if (zact == 'W') goto sect_2000; /* handle cursor input from main or zoom window -------------------------------------------- */ sect_1100: if (trnoc == 0) { if (*stata == 0) /* check status of cursor 0 */ { if (zflag != -1) { in[0] = QOVCH; stat = Cauxwnd(3,in,xya,xyb); } goto Exit_return; } else { if ((inopt == 2) && (*stata != -1)) goto Exit_return; /* only continue on enter */ if (inopt == 3) /* continuous readout */ { if (zact != 'V') /* in VIEW we use xcont, not xzont */ { if ((xzont != xya[0]) || (yzont != xya[1])) { xzont = xya[0]; yzont = xya[1]; } else if (*stata >= 0) /* no enter was pushed, */ goto Curs_loop; /* loop more */ } goto sect_2000; } if (action[1] == 'Y') /* mark cursor position... */ { for (n=0; n<5; n++) { xfig[n] = xcross[n] + curco[0]; yfig[n] = ycross[n] + curco[1]; } stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,5,255,1); } } } else if (trnoc == 1) { /* check status of cursor 1 */ if (*statb == 0) goto Exit_return; if ((inopt == 2) && (*statb != -1)) goto Exit_return; /* only continue on ENTER */ if (action[1] == 'Y') /* mark cursor position... */ { for (n=0; n<5; n++) { xfig[n] = xcross[n] + curco[2]; yfig[n] = ycross[n] + curco[3]; } stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,5,255,1); } } else { /* check status of cursor 0 and 1 */ if ( (*stata == 0) && (*statb == 0) ) { if (zflag != -1) { in[0] = QOVCH; stat = Cauxwnd(3,in,xya,xyb); } goto Exit_return; } else { float arcs[2]; if ((inopt == 2) && (*stata != -1)) goto Exit_return; /* only continue on enter */ arcs[0] = arcs[1] = -1.0; if (action[1] == 'Y') /* mark cursor position... */ { if (croi == 1) /* construct circle */ { curco[2] = xyb[0]; buildgra("CIR",curco,arcs,xfig,yfig,256,&n); stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,n,255,1); if (xyb[1] > 0) /* middle radius */ { curco[2] = xyb[1]; buildgra("CIR",curco,arcs,xfig,yfig,256,&n); stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,n,255,1); } if (xyb[2] > 0) /* outer radius */ { curco[2] = xyb[2]; buildgra("CIR",curco,arcs,xfig,yfig,256,&n); } } else buildgra("REC",curco,arcs,xfig,yfig,5,&n); /* build rectangle */ stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,n,255,1); } } } /* here we join again for all cursors */ sect_2000: if (oldmem != memo) { if (zstat != 0) { SCTPUT(errmes); /* no image loaded */ oldmem = -88; /* so we know later on... */ *frame = 'x'; goto sect_3000; } (void) strcpy(frame,dzmemc); /* copy name of loaded image */ oldmem = memo; } /* if necessary map new frame into memory -------------------------------------- */ if (strcmp(oldfra,frame) != 0) { stat = SCFOPN(frame,D_R4_FORMAT,0,F_IMA_TYPE,&imno); stat = SCDRDI(imno,"NPIX",1,2,&iav,npix,&uni,&nulo); if (ZPLANE == 0) planoff = 0; /* 2-dim frame loaded */ else planoff = (ZPLANE-1)*npix[0]*npix[1]; /* compute plane offset */ if (SOURCE == 3) aveflg = 1; else aveflg = 0; if (Pixconv("INIT",imno,dd1,dd2,dd3) > 0) /* init wc conversion */ SCETER(69,"initialization of world coord. conversion failed..."); stat = SCDRDI(imno,"NAXIS",1,1,&iav,&naxis,&uni,&nulo); if (naxis > 2) dd1[2] = ZPLANE; else dd1[2] = 0; if (action[0] == 'Y') { ymapa = 0; ymape = -1; /* enforce 1st time entry! */ if (*oldfra == ' ') { nlines = maxsiz / npix[0]; /* get multiple of lines */ virtsz = nlines * npix[0]; nlin2 = nlines / 2; stat = SCFINF("MIDXYZ",0,in); if (stat != 0) /* if not in FCT yet, create */ { stat = SCFCRE("MIDXYZ",D_R4_FORMAT,F_X_MODE,F_IMA_TYPE, virtsz,&imnow); stat = SCFMAP(imnow,F_X_MODE,1,virtsz,&iav,&pntrw); if (iav < virtsz) SCETER(91,"could not alloc virtual memory ..."); } } } framdat(frame); if (aveflg == 1) { SCTPUT("Caution: frame pixels were averaged when loaded."); SCTPUT("Displayed intensities are average values! "); } (void) strcpy(oldfra,frame); } /* now convert screen pixels to real pixels + world coordinates for ZACT = 'V' we need world coords. for corners of square ------------------------------------------------------------ */ sect_3000: if (zact == 'V') goto sect_3300; if (zact == 'W') { zact = 'V'; goto sect_3100; } else { if (croi == 1) /* here for circular roi */ { if (oldmem < 0) return; dd1[0] = (double)xya[0]; /* cursor 0 only */ dd1[1] = (double)xya[1]; stat = Pixconv("IRW",imno,dd1,dd2,dd3); if (stat != 0) { if (stat > 9) goto Exit_return; SCTDIS(outma,99); goto Curs_loop; } xyinfoa[2] = dd2[0]; xyinfoa[3] = dd2[1]; xyinfoa[4] = dd3[0]; xyinfoa[5] = dd3[1]; xyinfob[0] = -1; /* that indicates the modified retparms */ xyinfob[1] = -1; xyinfob[2] = xyb[0]; xyinfob[3] = xyb[1]; xyinfob[4] = xyb[2]; goto sect_3500; } } /* here for cursor 0 */ if (trnoc == 0) { sect_3100: if ((action[2] == 'Y') && (IDINUM != 11)) { stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp); in[0] = (int) *dpp; Alpcurs(0,1); } if (oldmem < 0) return; dd1[0] = (double)xya[0]; /* cursor 0 only */ dd1[1] = (double)xya[1]; stat = Pixconv("IRW",imno,dd1,dd2,dd3); if (stat != 0) { if (stat > 9) goto Exit_return; SCTDIS(outma,99); goto Curs_loop; } else /* save world coords... */ { xyinfoa[2] = dd2[0]; xyinfoa[3] = dd2[1]; xyinfoa[4] = dd3[0]; xyinfoa[5] = dd3[1]; } } /* here for cursor 1 */ else if (trnoc == 1) { if ((action[2] == 'Y') && (IDINUM != 11)) { stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp); in[1] = (int) *dpp; Alpcurs(1,1); } if (oldmem < 0) return; dd1[0] = (double)xyb[0]; /* cursor 1 only */ dd1[1] = (double)xyb[1]; stat = Pixconv("IRW",imno,dd1,dd2,dd3); if (stat != 0) { if (stat > 9) goto Exit_return; SCTDIS(outmb,99); goto Curs_loop; } else /* save world coords... */ { xyinfob[2] = dd2[0]; xyinfob[3] = dd2[1]; xyinfob[4] = dd3[0]; xyinfob[5] = dd3[1]; } } /* here for cursor 0 and 1 */ else { sect_3300: if ((action[2] == 'Y') && (IDINUM != 11)) { stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp); in[0] = (int) *dpp; Alpcurs(0,1); stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp); in[1] = (int) *dpp; Alpcurs(1,1); } if (oldmem < 0) return; /* make sure, we have lower-left and upper-right */ if (xya[0] > xyb[0]) { n = xya[0]; xya[0] = xyb[0]; xyb[0] = n; } if (xya[1] > xyb[1]) { n = xya[1]; xya[1] = xyb[1]; xyb[1] = n; } dd1[0] = (double)xya[0]; /* both cursors */ dd1[1] = (double)xya[1]; stat = Pixconv("IRW",imno,dd1,dd2,dd3); if (stat != 0) { if (stat > 9) goto Exit_return; SCTDIS(outma,99); goto Curs_loop; } else /* save world coords... */ { xyinfoa[2] = dd2[0]; xyinfoa[3] = dd2[1]; xyinfoa[4] = dd3[0]; xyinfoa[5] = dd3[1]; } dd1[0] = (double)xyb[0]; dd1[1] = (double)xyb[1]; stat = Pixconv("IRW",imno,dd1,dd2,dd3); if (stat != 0) { if (stat > 9) goto Exit_return; SCTDIS(outmb,99); goto Curs_loop; } else /* save world coords... */ { xyinfob[2] = dd2[0]; xyinfob[3] = dd2[1]; xyinfob[4] = dd3[0]; xyinfob[5] = dd3[1]; } } /* now get the intensities ----------------------- */ sect_3500: if (action[0] != 'Y') return; /* we don't want pixel values => go home */ tsty = CGN_NINT(xyinfoa[3]) - 1; /* frame pixels begin at 1 not 0 */ tstz = CGN_NINT(xyinfoa[2]) - 1; ec = 1; /* use `ec' as first-time flag */ sect_4000: if (aveflg != 1) iav = tsty; else iav = tsty + SCALY; if ((tsty < ymapa) || (iav > ymape)) { ymapa = tsty - nlin2; /* compute low, hi y-line */ if (ymapa < 0) ymapa = 0; /* for map_area */ ymape = ymapa + (nlines - 1); if (ymape >= npix[1]) ymape = npix[1]-1; stapix = (ymapa*npix[0]) + 1; /* first pixel in map_area */ stapix += planoff; /* add plane offset */ stat = SCFGET(imno,stapix,virtsz,&iav,pntrw); /* first index is 1 ... */ } tsty -= ymapa; rdata = Pixy( (float *) pntrw, npix[0], tstz, tsty, aveflg ); if (trnoc < 2) xyinfoa[6] = rdata; else if (ec > 1) xyinfob[6] = rdata; else /* for two cursors we loop */ { xyinfoa[6] = rdata; if (nocur != 12) { tsty = CGN_NINT(xyinfob[3]) - 1; tstz = CGN_NINT(xyinfob[2]) - 1; ec = 2; goto sect_4000; } } /* that's it folks - it was quite a job ... */ return; /* here we get out when EXIT button is pushed ------------------------------------------ */ Exit_return: return; } /* */ float Pixy(a,npix,kx,ky,avfla) int npix, kx, ky, avfla; float *a; { int m0, n, nn; float sum, retval, *w; m0 = (ky * npix) + kx; /* get to 1. pixel */ if (avfla == 0) return (*(a+m0)); /* here we get the average */ retval = 0.; for (n=0; n