/* @(#)subext.c 17.1.1.1 (ESO-DMD) 01/25/02 17:39:37 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT: Copyright (c) 1994 European Southern Observatory, all rights reserved .IDENTIFIER SUBEXT_C .LANGUAGE C .AUTHOR K. Banse IPG-ESO Garching .KEYWORDS image display, cursor, subframe .PURPOSE read the position of one or two cursors on the DeAnza display extract a subframe from the displayed frame, the limits of which are given either by the two cursors or by one cursor and parameters XSIZE + Y, if limits are defined by the two cursors, always a minimal square is extracte .ALGORITHM read once the cursor(s), only if outside limits loop more .INPUT/OUTPUT call as SUBEXT_C( ncurs, loopfl, splmod, frame ) input int ncurs : number of cursors int loopfl : int splmod : split mode char *frame : name of frame to be created .RETURNS nothing .ENVIRONment MIDAS #include Prototypes for MIDAS interfaces #include Global variables for DISPLAY interfaces .VERSIONS 1.00 940630 from IDAUXZ.FOR R.M.van Hees 010423 last modif ------------------------------------------------------------*/ /* Define _POSIX_SOURCE to indicate that this is a POSIX program */ #define _POSIX_SOURCE 1 #include #include #include #include #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif static int ffelem = 1; /* */ /*++++++++++++++++++++++++++++++ .IDENTIFIER CONV_PIX .PURPOSE convert screen pixels to real pixels + world coordinates .INPUT/OUTPUT call as CONV_PIX(ncurs,xysize,xyA,xyB,pixelA,pixelB) input: int ncurs : int *xysize : in/output: int *xyA : int *xyB : output: float *pixelA : float *pixelB : .RETURNS status ------------------------------*/ #ifdef __STDC__ static int CONV_PIX(int ncurs,int *xysize, int *xyA,int *xyB,float *pixelA,float *pixelB) #else static int CONV_PIX(ncurs,xysize,xyA,xyB,pixelA,pixelB) int ncurs, *xysize, *xyA, *xyB; float *pixelA, *pixelB; #endif { float xm, ym; double dd1[4], dd2[4], dd3[4]; /* synchronize with fp2wc */ pixelA[0] = xyA[0]; pixelA[1] = xyA[1]; dd1[0] = (double)xyA[0]; dd1[1] = (double)xyA[1]; dd1[2] = ZPLANE; if ( Pixconv("IRW",0,dd1,dd2,dd3) != 0 ) { SCTPUT( "Cursor(s) outside image... (in x)" ); return (1); } else { pixelA[2] = (float) dd2[0]; pixelA[3] = (float) dd2[1]; pixelA[4] = (float) dd3[0]; pixelA[5] = (float) dd3[1]; } if ( ncurs > 1 ) /* both cursors */ { pixelB[0] = xyB[0]; pixelB[1] = xyB[1]; dd1[0] = (double)xyB[0]; dd1[1] = (double)xyB[1]; if ( Pixconv("IRW",0,dd1,dd2,dd3) != 0 ) { SCTPUT( "Cursor(s) outside image... (in y)" ); return (1); } else { pixelB[2] = (float) dd2[0]; pixelB[3] = (float) dd2[1]; pixelB[4] = (float) dd3[0]; pixelB[5] = (float) dd3[1]; } } else /* if only one cursor involved, we have to build a rectangle */ { pixelB[0] = SSPX + NSX - 1; /* last screen pixel */ pixelB[1] = SSPY + NSY - 1; dd1[0] = (double)pixelB[0]; dd1[1] = (double)pixelB[1]; if ( Pixconv("IRW",0,dd1,dd2,dd3) != 0 ) { SCTPUT( "Cursor(s) outside image... (in y)" ); return (1); } else { pixelB[2] = (float) dd2[0]; pixelB[3] = (float) dd2[1]; pixelB[4] = (float) dd3[0]; pixelB[5] = (float) dd3[1]; } xm = pixelB[2]; /* last frame pixel visible */ ym = pixelB[3]; *xyA = pixelA[2] - (xysize[0]/2); if ( *xyA < SFPX ) *xyA = SFPX; /* make sure, it stays inside... */ *xyB = *xyA + xysize[0] - 1; if ( *xyB > xm ) { *xyB = xm; *xyA = *xyB - xysize[0] + 1; if ( *xyA < SFPX ) *xyA = SFPX; } xyA[1] = pixelA[3] - (xysize[1]/2); if ( xyA[1] < SFPY ) xyA[1] = SFPY; /* make sure, it stays inside... */ xyB[1] = xyA[1] + xysize[1] - 1; if ( xyB[1] > ym ) { xyB[1] = ym; xyA[1] = xyB[1] - xysize[1] + 1; if ( xyA[1] < SFPY ) xyA[1] = SFPY ; } pixelA[0] = xyA[0]; /* frame pixels -> screen pixels */ pixelA[1] = xyA[1]; dd1[0] = (double)pixelA[0]; dd1[1] = (double)pixelA[1]; if ( Pixconv("_RS",0,dd1,dd2,dd3) != 0 ) { SCTPUT( "Cursor(s) outside image... (in x)" ); return (1); } else { pixelA[2] = (float) dd2[0]; pixelA[3] = (float) dd2[1]; pixelA[4] = (float) dd3[0]; pixelA[5] = (float) dd3[1]; } xyA[0] = pixelA[4]; xyA[1] = pixelA[5]; pixelB[0] = xyB[0]; pixelB[1] = xyB[1]; dd1[0] = (double)pixelB[0]; dd1[1] = (double)pixelB[1]; if ( Pixconv("_RS",0,dd1,dd2,dd3) != 0 ) { SCTPUT( "Cursor(s) outside image... (in y)" ); return (1); } else { pixelB[2] = (float) dd2[0]; pixelB[3] = (float) dd2[1]; pixelB[4] = (float) dd3[0]; pixelB[5] = (float) dd3[1]; } xyB[0] = pixelB[4]; xyB[1] = pixelB[5]; } return (0); } /* */ /*++++++++++++++++++++++++++++++ .IDENTIFIER SHOW_REC .PURPOSE show rectangle with extracted frame .INPUT/OUTPUT call as SHOW_REC( xyA, xyB) input: int *xyA : int *xyB : .RETURNS status ------------------------------*/ #ifdef __STDC__ static void SHOW_REC( int *xyA, int *xyB ) #else static void SHOW_REC( xyA, xyB ) int *xyA, *xyB; #endif { int offs, npnts, coos[4], xfig[5], yfig[5]; float arcs[2]; if ( SCALX < -1) offs = -SCALX / 2; else offs = 0; coos[0] = xyA[0] + offs; coos[2] = xyB[0] + offs; if (SCALY < -1) offs = -SCALY / 2; else offs = 0; coos[1] = xyA[1] + offs; coos[3] = xyB[1] + offs; arcs[0] = arcs[1] = -1.0; /* not used... */ (void) buildgra("REC",coos,arcs,xfig,yfig,5,&npnts); (void) IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,npnts,255,1); } /* */ void SUBEXT_C( ncurs, loopfl, splmod, frame ) int ncurs, loopfl, splmod; char *frame; { int mm, actvals, go_on, ioff, knul, naxis, memo, size, unit, subhi[2]; int imnoA, imnoR, imnoX, statA, statB, xyA[5], xyB[5], xysize[2]; int npix[2], npixR[2], bgnA[2], dimA[2], bgnR[2], respix[2]; float *pntrX, *pntrR, cuts[4], pixelA[6], pixelB[6]; double step[2], startR[2], dd1[4], dd2[4], dd3[4]; char *cpntr, newfra[61], ident[33], cunit[49], output[81]; int sizeX = -99, /* size of scratch memory */ oldmem = -99, first = TRUE; static int coord[4] = { -1, -1, -1, -1 }, sublo[2] = { 0, 0 }; static float cutvls[2] = { 0.0, 0.0 }; static char *usr_info = "switch cursor(s) on - next time we exit...", *mes_start = "start coordinates of subframe %s: %#12.6g%#12.6g", *mes_pixel = "no. of pixels of subframe: %5d%5d"; /* initialize */ CGN_FILL( ident, ' ', 32 ); ident[32] = '\0'; CGN_FILL( cunit, ' ', 48 ); cunit[48] = '\0'; if (ncurs == 2) { mm = 1; /* rectangle shape */ xysize[0] = xysize[1] = 0; } else { mm = 3; /* open cross */ (void) SCKRDI("INPUTI",10,2,&actvals,xysize,&unit,&knul); } SETCUR_C(QDSPNO,ncurs,mm,2,coord); Ccursin(QDSPNO,0,ncurs,xyA,&statA,xyB,&statB); /* bind interaction */ /* get cursor position */ go_on = TRUE; while ( go_on ) { Ccursin( QDSPNO, 1, ncurs, xyA, &statA, xyB, &statB ); if ( statA == 0 && statB == 0 ) { (void) IIISTI_C( QDSPNO ); /* terminate interaction */ if ( ! first ) go_on = FALSE; else { first = FALSE; SCTPUT( usr_info ); Ccursin( QDSPNO, 0, ncurs, xyA, &statA, xyB, &statB ); } } else /* get relevant memory board */ { if ( QRGBFL == 1 && splmod == 0 ) /* RGB + non-split mode */ memo = QIMCH; else memo = xyA[2]; if (oldmem != memo) /* if necessary open new frame */ { if (DCGICH(memo) != 0) /* get channel info */ SCETER(1,"SUBEXT: no image loaded!"); if (oldmem != -99) (void) SCFCLO(imnoA); oldmem = memo; (void) SCFOPN(dzmemc,D_R4_FORMAT,0,F_IMA_TYPE,&imnoA); (void) SCDRDI(imnoA,"NAXIS",1,1,&actvals,&naxis,&unit,&knul); if ( naxis > 2 ) naxis = 2; (void) SCDRDI(imnoA,"NPIX",1,naxis,&actvals,npix,&unit,&knul); (void) SCDRDD(imnoA,"STEP",1,naxis,&actvals,step,&unit,&knul); (void) SCDRDR(imnoA,"LHCUTS",1,4,&actvals,cuts,&unit,&knul); (void) SCDGETC(imnoA,"IDENT",1,32,&actvals,ident); (void) SCDGETC(imnoA,"CUNIT",1,48,&actvals,cunit); if (Pixconv("INIT",imnoA,dd1,dd2,dd3) > 0) SCETER(69,"initialization of world coord. conversion failed ..."); if (ZPLANE != 0) { ffelem = ((ZPLANE-1)*npix[0]*npix[1]) + 1; dd1[2] = ZPLANE; } else ffelem = 1; (void) sprintf(output, "Extracting from frame: %s", dzmemc ); SCTPUT(output); } /* now convert screen pixels to real pixels + world coordinates */ if (CONV_PIX(ncurs,xysize,xyA,xyB,pixelA,pixelB) == 0) { SHOW_REC(xyA,xyB); bgnA[0] = CGN_NINT(pixelA[2]); /* prepare pixno.s for subframe */ bgnA[1] = 1; npixR[0] = dimA[0] = CGN_NINT(pixelB[2]-pixelA[2]) + 1; npixR[1] = dimA[1] = CGN_NINT(pixelB[3]-pixelA[3]) + 1; bgnR[0] = bgnR[1] = 1; ioff = *npix * CGN_NINT(pixelA[3]-1) + ffelem; if ((size = *npix * dimA[1]) > sizeX) /* new size */ { if (sizeX != -99) (void) SCFCLO(imnoX); sizeX = size; (void) SCFCRE("dumextra",D_R4_FORMAT,F_X_MODE, F_IMA_TYPE,sizeX,&imnoX); (void) SCFMAP(imnoX,F_X_MODE,1,sizeX,&actvals,&cpntr); (void) SCFGET(imnoA,ioff,sizeX,&actvals,cpntr); pntrX = (float *) cpntr; } else { cpntr = (char *) pntrX; /* already allocated! */ (void) SCFGET(imnoA,ioff,size,&actvals,cpntr); } dd1[0] = (double)pixelA[2]; dd1[1] = (double)pixelA[3]; (void) Pixconv("_RW",0,dd1,dd2,dd3); startR[0] = dd3[0]; startR[1] = dd3[1]; /* show world coordinates of subframe */ if ( loopfl == -1 ) (void) strcpy(newfra,frame); else { mm = CGN_INDEXC(frame,' '); if (mm > 0) frame[mm] = '\0'; (void) sprintf(newfra,"%s%04d",frame,++loopfl); } mm = CGN_INDEXC(newfra,' '); if (mm > 0) newfra[mm] = '\0'; (void) sprintf(output,mes_start,newfra,*startR,startR[1]); SCTPUT(output); (void) sprintf(output,mes_pixel,*npixR,npixR[1]); SCTPUT(output); /* map subframe */ (void) SCIPUT(newfra,D_R4_FORMAT,F_O_MODE,F_IMA_TYPE,naxis, npixR,startR,step,ident,cunit,&cpntr,&imnoR); pntrR = (float *) cpntr; /* and fill it... */ Ccopyf1(pntrX,npix,bgnA,dimA,pntrR,npixR,bgnR); /* get new min + max value */ subhi[0] = npixR[0] - 1; subhi[1] = npixR[1] - 1; (void) Cstvals("MIN",pntrR,naxis,npixR,sublo,subhi, cutvls,cuts+2,respix,&actvals); /* copy non-standard descriptors, update LHCUTS + append HISTORY */ CGN_DSCUPD(imnoA,imnoR," "); (void) SCDWRR( imnoR, "LHCUTS", cuts, 1, 4, &unit ); (void) SCFCLO( imnoR ); if ( loopfl == -1 ) go_on = FALSE; first = FALSE; } } } /* End of WHILE-loop */ }