/* @(#)xwimg.c 17.1.1.1 (ESO-DMD) 01/25/02 17:57:16 */ /*=========================================================================== 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 (c) 1994 European Southern Observatory .IDENTIFIER module XWIMG .LANGUAGE C .AUTHOR Klaus Banse, IPG-ESO Garching .KEYWORDS memory, ImageDisplay & Virtual Display .COMMENTS contains XWIMG Does not support device "Gould DeAnza IP8500" .ENVIRONment MIDAS #include Prototypes for MIDAS interfaces #include Global variables for DISPLAY interfaces .VERSIONS 1.00 940428 taken from wimg.c 011005 last modif ------------------------------------------------------------*/ /* Define _POSIX_SOURCE to indicate that this is a POSIX program */ #define _POSIX_SOURCE 1 #include #include #include #include #include #include #define FOREVER while(1) /* infinite loop */ /* */ /*++++++++++++++++++++++++++++++ .IDENTIFIER XWIMG .PURPOSE write a 2-D image into given memory board of Image Display .ALGORITHM set resolution to only low byte transfer if image is larger than the image memory size, a square around the given center pixels is loaded image is loaded into center of image memory .INPUT/OUTPUT call as XWIMG(ldspno,imch,frame,khelp,loaddir,npix,icen,cuts,scale) input: int ldspno : display no. int limch : channel no. char *frame : input image name int *khelp : [0] data type (as D_xx_FORMAT) [1,2] mapping sizes [3] subwindow flag (= 1, if so) [4] NFX, if SUBWDW > 0 [5,6] NSX,NSY, if SUBWDW > 0 [7,8] start pixels in frame, if SUBWDW > 0 [9] SOURCE, 2 or 1 - overwrite or not [10] cube_flag, 0 - 2-dim display 1 - 3-dim display in one channel 2 - 3-dim display in all channels [11,12,13] if cube_flag > 0: first plane, last plane, delay time int loaddir : load direction, 0 = bottom-up, 1 = top-down int npix[3] : no. of pixels in x- and y-dir. int icen[4] : fixpoint: screen pixels + frame pixels float cuts[2] : low + high cut in z-dir. int scale[3]: scaling factors for image in x,y [0,1] if > 1: make image smaller if < 1: make image larger [2] flag for using max (=3), using min (=2), averaging (=1) or not (=0) .RETURNS error code, 0 = o.k. ------------------------------*/ int XWIMG(ldspno,limch,frame,khelp,loaddir,npix,icen,cuts,scale) int ldspno, limch; char *frame; int *khelp, loaddir, *npix, *icen, *scale; float *cuts; { int status, bufind, incr, imx, imy, ilx, ily, insiz, intake, ifact; int ffelem, felem; int msizei, msizeo, ntx, nty, nfx, nfy, nlines, outmul, outsiz; int imno, qdepth, dattyp; int rmaind, scsave, insav, subwdw, trs, trsize, zin, zinsiz; int inaux[6], kcen[2], kcuts[2], outaux[2]; int nnsx, nnsy, nsspx, nsspy, nsfpx, nsfpy, origchan; int cube_flag, plane_off, plcount, plooff, delay; register int ii, jj, ix, iy, kk, mm; register int xdim, xscale; CONF_DATA *conf; MEM_DATA *mem; float factor, ranmax, sum, faux[3]; char cbuf[20]; char *pntrW; unsigned char *pntrD; /* allocate buffer space */ imx = khelp[2] * sizeof(unsigned char); pntrD = (unsigned char *) malloc((unsigned int) imx); dattyp = khelp[0]; origchan = limch; /* save local image channel */ xdim = *npix; xscale = *scale; conf = ididev[ldspno].confptr; if (conf->RGBmode == 1) mem = conf->memory[0]; else mem = conf->memory[limch]; qdepth = ididev[ldspno].depth; switch (dattyp) { case D_R4_FORMAT: imx = khelp[1] * sizeof(float); pntrW = malloc((unsigned int) imx); break; case D_I4_FORMAT: imx = khelp[1] * sizeof(int); pntrW = malloc((unsigned int) imx); break; case D_I2_FORMAT: imx = khelp[1] * sizeof(short int); pntrW = malloc((unsigned int) imx); break; case D_I1_FORMAT: imx = khelp[1] * sizeof(unsigned char); pntrW = malloc((unsigned int) imx); break; case D_UI2_FORMAT: imx = khelp[1] * sizeof(unsigned short int); pntrW = malloc((unsigned int) imx); break; default: return (ERR_INPINV); } /* open image on server side */ imno = 0; status = SCFOPN(frame,dattyp,0,F_IMA_TYPE,&imno ); if (status != ERR_NORMAL) return (40); inaux[0] = dattyp; /* get data type */ inaux[5] = ididev[ldspno].lutoff; /* LUT offset in X */ kk = ididev[ldspno].screen; ranmax = Xworkst[kk].lutlen - 1.0; msizei = khelp[1]; msizeo = khelp[2]; subwdw = khelp[3]; /* if = 1, it's a subwindow... */ *outaux = Xworkst[kk].lutlen - 1; trsize = xdim*npix[1]; cube_flag = khelp[10]; sum = cuts[1] - cuts[0]; /* scale image */ if (sum < 10.e-25) { *faux = 1.0; *cuts = 0.; } else *faux = ranmax / sum; faux[1] = cuts[0]; faux[2] = cuts[1]; if (xscale < 0) inaux[3] = - xscale; /* scaling factor in x */ else inaux[3] = xscale; inaux[4] = 1; if (*khelp == D_I1_FORMAT) { kcuts[0] = CGN_NINT(cuts[0]); kcuts[1] = CGN_NINT(cuts[1]); if ((kcuts[0] == 0) && (kcuts[1] == *outaux)) inaux[4] = 0; /* no packing for 1-byte `exact' data */ } plcount = 1; plooff = ididev[ldspno].ysize/8+4; if (!subwdw) { *kcen = *icen; *(kcen+1) = *(icen+2); SIZER_C(mem->xsize,xdim,xscale,scale[2],kcen,&nnsx,&nsspx,&nfx,&nsfpx); *kcen = *(icen+1); *(kcen+1) = *(icen+3); SIZER_C(mem->ysize,npix[1],scale[1],scale[2],kcen,&nnsy,&nsspy,&nfy,&nsfpy); /* set up values for image display size X-, Y-registers */ ntx = nnsx; nty = nnsy; ffelem = nsfpx + (xdim * (nsfpy-1)); plane_off = 0; } else /* subwindow */ { nfx = khelp[4]; ntx = khelp[5]; nty = khelp[6]; khelp[10] = 0; ffelem = khelp[7] + (xdim * (khelp[8]-1)); plane_off = (mem->plane_no-1)*trsize; } if (cube_flag > 0) /* check 3-dim stuff */ { plane_off = (khelp[11]-1) * trsize; plcount = khelp[12]-khelp[11]+1; if (khelp[13] > 0) delay = khelp[13] * 1000; /* move to seconds */ else delay = 0; } plane_loopA: if (!subwdw) { /* if complete window, save size of image loaded previously */ imx = mem->sspx; /* old SSPX */ imy = mem->sspy; ilx = imx + mem->nsx; ily = imy + mem->nsy; /* test if we have to clear channel first */ if ( ((ilx != 0) || (ily != 0)) && (mem->frame[0] != ' ') /* already an image loaded? */ && (khelp[9] != 2) ) { GLIST *gp; if (mem->gpntr != 0) { gp = mem->gpntr; jj = gp->geln; } else jj = 0; if ((jj != 0) || (imx < nsspx) || (imy < nsspy) || (ilx > (nsspx+ntx)) || (ily > (nsspy+nty)) ) (void) IIMCMY_C( ldspno, &limch, 1, 0 ); } /* set up transfer window (load size regs. + CMRs) */ (void) IIMSTW_C(ldspno,limch,loaddir,ntx,nty,qdepth,nsspx,nsspy); if (khelp[9] != 2) { mem->nsx = nnsx; mem->nsy = nnsy; mem->sspx = nsspx; mem->sspy = nsspy; mem->sfpx = nsfpx; mem->sfpy = nsfpy; mem->xscale = xscale; mem->yscale = scale[1]; mem->zoom = 1; mem->source = khelp[9]; mem->plane_no = 1; strcpy(mem->frame,frame); } } /* start in ima_memory */ plane_loopB: felem = ffelem + plane_off; imx = imy = 0; /* with respect to transfer window */ bufind = felem; if ((cube_flag > 0) && (khelp[9] != 2)) mem->plane_no = khelp[11]; /* compute internal buffer sizes depending on scaling */ if (scale[1] < 0) { outmul = 1; /* 1 input line => multiple output lines */ scsave = 1; incr = xdim; } else { outmul = msizeo / ntx; /* no. of lines in out buffer */ if (outmul < 1) return(41); /* should not happen... */ if (outmul > nty) outmul = nty; scsave = scale[1]; incr = xdim * scale[1]; } if (xscale < 0) inaux[2] = nfx; /* no. of input data to work on */ else inaux[2] = ntx; /* no. of input data to work on */ FOREVER /* we should fill at least once */ { intake = xdim * outmul * scsave; if (intake > trsize) intake = trsize; if (intake > msizei) { if (--outmul <= 0) { if ((scsave > 1) && (scale[2] == 0)) /* if we omit lines, */ { /* no problem... */ outmul = 1; intake = xdim * scsave; /* all lines together - this may be */ insiz = intake; /* too much, but truncated later on */ ifact = 1; outsiz = ntx; /* we'll process just 1 line */ nlines = nty ; rmaind = 0; break; } else return (41); /* if we really average, it's bad... */ } } else { ifact = msizei / intake; insiz = ifact * intake; /* size of in buffer */ outsiz = outmul * ntx; /* size of out buffer */ nlines = nty / outmul; rmaind = nty - (nlines * outmul); break; /* we have filled it! */ } } /* branch on scaling factor */ if ((xscale == 1) && (scale[1] == 1)) /* NO SCALING */ { if (xdim <= ntx) /* split depending on npix[0] */ { outaux[1] = 0; /* output offset */ inaux[2] = outsiz; for (ii=0; ii bufind) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); bufind += insiz; inaux[1] = 0; /* input offset */ } I1PACK_C(pntrW,inaux,faux,pntrD,outaux); inaux[1] += outsiz; (void) IIMWMY_C(ldspno,limch,pntrD,outsiz,qdepth,4,imx,imy); imy += outmul; felem += intake; } } else { for (ii=0; ii bufind) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); bufind += insiz; inaux[1] = 0; /* input offset */ } outaux[1] = 0; /* output offset */ for (jj=0; jj 0) { outsiz = rmaind * ntx; intake = rmaind * xdim; if ((felem + intake) > bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); inaux[1] = 0; } outaux[1] = 0; if (xdim <= ntx) { inaux[2] = outsiz; I1PACK_C(pntrW,inaux,faux,pntrD,outaux); inaux[1] += outsiz; } else { for (jj=0; jj 0) { zin = xdim * (1 + (outmul-1)*scsave); /* avoid last omitted lines */ zinsiz = xdim * (1 + (outmul*ifact - 1)*scsave); if (xscale < 0) { for (ii=0; ii bufind ) { (void) SCFGET(imno,felem,zinsiz,&trs,pntrW); bufind += insiz; inaux[1] = 0; } outaux[1] = 0; for (jj=0; jj 0 ) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; zin = intake - incr + xdim; zinsiz = insiz - incr + xdim; if ((felem + zin) > bufind ) { (void) SCFGET(imno,felem,zinsiz,&trs,pntrW); inaux[1] = 0; } outaux[1] = 0; for (jj=0; jj bufind ) { (void)SCFGET(imno,felem,zinsiz,&trs,pntrW); bufind += insiz; inaux[1] = 0; } outaux[1] = 0; for (jj=0; jj 0) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; zin = xdim + intake - incr; if ((felem + zin) > bufind ) { (void) SCFGET(imno,felem,zin,&trs,pntrW); inaux[1] = 0; } outaux[1] = 0; for (jj=0; jj 0 ) { inaux[3] = 1; /* we don't scale anymore... */ inaux[4] = 0; } factor = 1. / (xscale * scale[1]); /* scaling factor */ mm = xscale * ntx; if (dattyp == D_R4_FORMAT) { float *data, *tdata, *work; data = (float *) pntrW; /* create work space */ work = (float *) malloc((unsigned int)(ntx * sizeof(float))); for (ii=0; ii bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (float *) pntrW; bufind += insiz; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) sum = rr; } *work++ = sum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy 0) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; if ( felem + intake > bufind ) { /* intake instead of insiz...? */ (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (float *) pntrW; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) sum = rr; } *work++ = sum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (unsigned short int *) pntrW; bufind += insiz; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy 0) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; if ((felem + intake) > bufind ) { /* intake instead of insiz...? */ (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (unsigned short int *) pntrW; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (short int *) pntrW; bufind += insiz; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy 0) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; if ( felem + intake > bufind ) { /* intake instead of insiz...? */ (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (short int *) pntrW; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (unsigned char *) pntrW; bufind += insiz; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy 0) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; if ((felem + intake) > bufind ) { /* intake instead of insiz...? */ (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (unsigned char *) pntrW; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (int *) pntrW; bufind += insiz; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy 0) { outsiz = rmaind * ntx; intake = xdim * rmaind * scale[1]; if ((felem + intake) > bufind ) { /* intake instead of insiz...? */ (void) SCFGET(imno,felem,insiz,&trs,pntrW); data = (int *) pntrW; inaux[1] = 0; } outaux[1] = 0; if (scale[2] == 1) { for (jj=0; jj rr) isum = rr; } *work++ = isum; } work -= ntx; tdata += (xdim - mm); } } else /* Maximum */ { for (iy=0; iy bufind ) { (void) SCFGET(imno,felem,insiz,&trs,pntrW); bufind += trs; inaux[1] = 0; } if ( xscale < 0 ) K1PACK_C(pntrW,inaux,faux,pntrD,outaux); else I1PACK_C(pntrW,inaux,faux,pntrD,outaux); for (jj=0; jj<(- scale[1]) && imy 0) && (limch == origchan)) { (void) sprintf(cbuf,"PLANE:%d",khelp[11]); (void) IIGTXT_C(ldspno,99,cbuf,plooff,0,0,0,0,0); } else { (void) strcpy(cbuf," "); (void) IIGTXT_C(ldspno,99,cbuf,plooff,0,0,0,0,0); } if (plcount > 1) /* more than 1 plane? */ { plcount --; khelp[11] ++; plane_off += trsize; /* move to next plane */ if (limch == origchan) (void) IIMSMV_C(ldspno,&origchan,1,1); if (delay > 0) { sendX(ldspno); /* refresh display */ OSY_SLEEP(delay,0); /* and wait `delay' seconds */ } if (cube_flag == 1) goto plane_loopB; else { if (subwdw != 2) /* reset transfer window */ (void) IIMSTW_C(ldspno,limch,loaddir,mem->xsize,mem->ysize, qdepth,0,0); limch ++; /* move to next channel */ if (conf->RGBmode == 0) mem = conf->memory[limch]; /* update memory pointer */ goto plane_loopA; } } } (void) free(pntrW); (void) free((char *) pntrD); status = SCFCLO(imno); if (status != ERR_NORMAL) return (status); if (subwdw != 2) /* reset transfer window */ (void) IIMSTW_C(ldspno,limch,loaddir,mem->xsize,mem->ysize,qdepth,0,0); return (ERR_NORMAL); }