/* @(#)scaux.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:25 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++ Module SCAUX +++++++++++++++++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION Module SCAUX.C .AUTHOR Klaus Banse .KEYWORDS Midas utility routines. .ENVIRONMENT VMS and UNIX .COMMENTS holds conv_dat, conv_pix, get_byte, rddisk, wrdisk .VERSION 010914 last modif ------------------------------------------------------------------------*/ #include #include #include #define AUX_READ 1 #define AUX_WRITE 2 #define AUX_GET 3 #define NO_LINES 512 #define DISK_REC 512 static int wrkspace = -1; static char *wrkptr; int get_byte(); static struct FCT_STRUCT *fctpntr; /* */ int conv_dat(flg,imno,felem,size,actsize,newptr) int flg /* IN: 1 or 2 for read or write */; int imno /* IN: FCT entry number */; int felem /* IN: first data pixel in input frame */; int size /* IN: no. of data pixels to convert */; int *actsize /* OUT: actual size (only for flg = AUX_GET */; char **newptr /* IN/OUT: holds addresses of disk buffer/virtual memory */; { int status, ktimes, kpix, newbyte, oldbyte; int newfmt, oldfmt, actsz, total; register int nr, mm; char *newbuf, *oldbuf; fctpntr = FCT.ENTRIES + imno; oldbyte = get_byte(fctpntr->FORMAT); newbyte = get_byte(fctpntr->DATTYP); /* allocate virtual memory for working buffer */ if (wrkspace == -1) { wrkspace = NO_LINES * DISK_REC; /* this may be updated ... */ wrkptr = malloc((unsigned int)wrkspace); if (wrkptr == (char *) 0) return ERR_MEMOUT; } kpix = wrkspace / oldbyte; /* no. of pixels in wrkspace */ ktimes = ((size - 1) / kpix) + 1; if (ktimes == 1 ) kpix = size; if (flg == AUX_WRITE) goto write_section; total = 0; /* if here for mapping, allocate virtual memory for data in new format */ if (flg == AUX_READ) { mm = (size * newbyte); newptr[0] = malloc((unsigned int)mm); if (newptr[0] == (char *) 0) return ERR_MEMOUT; newptr[1] = newptr[0] + mm - 1; } /* here for reading in stuff */ /*******************************/ newbuf = newptr[0]; oldbuf = wrkptr; newfmt = fctpntr->DATTYP; oldfmt = fctpntr->FORMAT; /* now read in from file and convert */ for (nr=0; nrDATTYP; newfmt = fctpntr->FORMAT; /* now convert back and write to file */ for (nr=0; nrIOCHAN; /* I/O channel of frame */ nbytes = fctpntr->NOBYTE; /* no. of bytes per pixel */ pixblock = fctpntr->PIXPBL; /* no. of pixels per block */ fsize = fctpntr->SIZE; if (size <= 0) /* if no size given, get all pixels */ nopix = fsize; else nopix = size; if ( (felem+nopix-1) > fsize) { nopix = fsize - felem + 1; if (nopix <= 0) { if (nopix == 0) return ERR_NODATA; /* we're at the end */ else return ERR_INPINV; } } /* get first virtual block + real start pixel */ fvbn = ((felem*nbytes) - 1) / DISK_REC; /* to be added to 1. data block */ firstpix = fvbn*pixblock + 1; /* first pixel accessible */ difpix = felem - firstpix; /* difference to 1. required pixel */ /* calculate starting block */ lovbn = fctpntr->STBLOK + fvbn; /* 1. data block + offset = 1. block to map */ bytesize = nopix * nbytes; /* total no. of bytes we have to provide */ /* either we have to read two blocks */ if (difpix > 0) { char temp[DISK_REC]; difbytes = difpix * nbytes; status = OSY_RVB(chanl,temp,DISK_REC,lovbn); if (status != ERR_NORMAL) return status; mm = DISK_REC - difbytes; if (mm > bytesize) mm = bytesize; (void) memcpy(bufadr,&temp[difbytes],(size_t)mm); if (bytesize > mm) status = OSY_RVB(chanl,bufadr+mm,bytesize-mm,lovbn+1); } /* or we get it all in one go */ else status = OSY_RVB(chanl,bufadr,bytesize,lovbn); *actsize = nopix; return status; } /* */ int wrdisk(imno,felem,size,bufadr) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE write data from memory into disk frame .ALGORITHM synchronous disk I/O .RETURNS return status ( 0 = o.k ) --------------------------------------------------------*/ int imno /* IN : file no. of data frame */; int felem /* IN : 1st pixel to be accessed in data space */; int size /* IN : no. of data values (pixels) to be written */; char *bufadr; /* IN: address of data buffer */ { int difpix, firstpix, nbytes, pixblock; int fvbn, lovbn, difbytes, bytesize; int status, fsize, nopix, chanl, nvb; register int mm; fctpntr = FCT.ENTRIES + imno; chanl = fctpntr->IOCHAN; /* I/O channel of frame */ nbytes = fctpntr->NOBYTE; /* no. of bytes per pixel */ pixblock = fctpntr->PIXPBL; /* no. of pixels per block */ fsize = fctpntr->SIZE; if (size <= 0) /* if no size given, get all pixels */ nopix = fsize; else nopix = size; if ( (felem+nopix-1) > fsize ) { nopix = fsize - felem + 1; if (nopix <= 0) return ERR_INPINV; } /* get first virtual block + real start pixel */ fvbn = ((felem*nbytes) - 1) / DISK_REC; /* to be added to 1. data block */ firstpix = (fvbn * pixblock) + 1; /* first pixel accessible */ difpix = felem - firstpix; /* difference to 1. required pixel */ /* calculate starting block */ lovbn = fctpntr->STBLOK + fvbn; /* 1. data block + offset = 1. block to map */ bytesize = nopix * nbytes; /* total no. of bytes we have to write */ /* either we have to read + write first block */ if (difpix > 0) { char temp[DISK_REC]; difbytes = difpix * nbytes; status = OSY_RVB(chanl,temp,DISK_REC,lovbn); if (status != ERR_NORMAL) return status; mm = DISK_REC - difbytes; if (mm > bytesize) mm = bytesize; (void) memcpy(&temp[difbytes],bufadr,(size_t)mm); status = OSY_WVB(chanl,temp,DISK_REC,lovbn); if (status != ERR_NORMAL) return status; if (bytesize > mm) { lovbn ++; bufadr += mm; bytesize -= mm; nvb = bytesize / DISK_REC; /* get no. of full blocks */ if (nvb > 0) { mm = nvb * DISK_REC; status = OSY_WVB(chanl,bufadr,mm,lovbn); if (status != ERR_NORMAL) return status; lovbn += nvb; bufadr += mm; bytesize -= mm; } if (bytesize > 0) /* we must be in [0,DISK_REC-1] ... */ { status = OSY_RVB(chanl,temp,DISK_REC,lovbn); if (status != ERR_NORMAL) return status; (void) memcpy(temp,bufadr,(size_t)bytesize); status = OSY_WVB(chanl,temp,DISK_REC,lovbn); } } } /* or we send it all in one go */ else status = OSY_WVB(chanl,bufadr,bytesize,lovbn); return status; }