/* @(#)pixcnv.c 17.1.1.1 (ESO-DMD) 01/25/02 17:39:36 */ /*=========================================================================== 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 .IDENTIFICATION: Pixconv .LANGUAGE: C and ANSI C .AUTHOR: K.Banse ESO - Garching .KEYWORDS: screen pixels, real pixels, world coordinates .PURPOSE: convert screen pixel values to real pixels and world coordinates and vice versa .ALGORITHM: formulae for converting screen pixels to real (image memory) pixels are: -------------------------------------------------------- | xreal = xscreen/zoom + scrolx | | | | yreal = scroly - (SCROLMAX - yscreen)/zoom | | | | SCROLMAX = (QDSZY - 1) | -------------------------------------------------------- ==> <== ==> frame (real) pixels in [1,NPIX(i)] <== ==> screen pixels in [0,(screensize-1)] <== ==> <== .RETURNS return status: 0 o.k. 0 for INIT, if non-linear worldcoord_sys -1 for INIT, if linear worldcoord_sys 1 x-pixel outside image 2 y-pixel outside image 3 x and y pixel outside .VERSION 1.00 940303: convert from pixcnv.for 001213 last modif ------------------------------------------------------------------- */ /* Define _POSIX_SOURCE to indicate that this is a POSIX program */ #define _POSIX_SOURCE 1 #include #include #include /* */ int Pixconv(cflag,imno,dd1,dd2,dd3) char *cflag; /* IN: conversion to perform; "INIT" initialize internal structures "SRW" screen-pix -> real-pix -> world-coord "WRS" world-coord -> real-pix -> screen-pix "_RW" real-pix -> world-coord "_RS" real-pix -> screen-pix "IRW" image-chan-pix -> real-pix -> world-coord */ int imno; /* IN: imno of frame only needed for cflag = "INIT" */ double *dd1; /* IN: array of NAXIS (of imno) elements; for "SRW" it contains screen pixels for "WRS" it contains world coordinates for "_RW" it contains real pixel numbers for "_RS" it contains real pixel numbers for "IRW" it contains image channel pixels */ double *dd2; /* OUT: array of NAXIS (of imno) elements; always receives real pixel numbers */ double *dd3; /* OUT: array of NAXIS (of imno) elements; for "SRW" it receives world coordinates for "WRS" it receives screen pixels for "_RW" it receives world coordinates for "_RS" it receives screen pixels for "IRW" it receives world coordinates */ /* Note: real_pix means the same as frame_pix used elsewhere in Midas */ { int istat, iy, kxpix, kypix; double dindx, dindy, dx, dy, z; /* -------------- initialization -------------- */ if ( strncmp(cflag,"IN",2) == 0 ) { istat = fp2wc(0,imno,dd1,dd2); if (istat > 0) return (istat+10); /* initialization gave problems */ else return (istat); } /* ------------------------------------- conversion s.p. -> r.p. -> w.c. (SRW) or i.p. -> r.p. -> w.c. (IRW) or r.p. -> w.c. (_RW) ------------------------------------- */ else if ( strncmp(cflag+1,"RW",2) == 0 ) { if ( *cflag == '_' ) /* only r.p. -> w.c. */ { *dd2 = *dd1; /* real pixel no.s */ *(dd2+1) = *(dd1+1); } else { kxpix = NINT(*dd1); kypix = NINT(*(dd1+1)); /* im.p. -> r.p. -> w.c. o.k. */ if ( *cflag == 'S' ) /* s.p. -> r.p. -> w.c. */ Sc2ch(1,&kxpix,&kypix); kxpix -= SSPX; kypix -= SSPY; if (LOADDR > 0) kypix = NSY - kypix; istat = 0; if ((kxpix < 0) || (kxpix >= NSX)) istat ++; if ((kypix < 0) || (kypix >= NSY)) istat += 2; if (istat != 0) return (istat); if (SCALX < 0) /* take care of scaling */ dx = (double) (kxpix / (-SCALX)); else dx = (double) (kxpix * SCALX); /* dx, dy start from 0,... */ if (SCALY < 0) dy = (double) (kypix / (-SCALY)); else dy = (double) (kypix * SCALY); *dd2 = (double)(SFPX) + dx; /* real pixel no. (1, ...) */ *(dd2+1) = (double)(SFPY) + dy; } *(dd2+2) = *(dd1+2); istat = fp2wc(1,0,dd2,dd3); /* world coordinates */ if (istat != 0) return (istat+10); /* conversion gave problems */ } /* ------------------------------------- conversion w.c. -> r.p. -> s.p. (WRS) or r.p. -> s.p. (_RS) ------------------------------------- */ else { register int nr, mr; double zz; if (*cflag == '_') /* first pixel is pixel no. 1 ... */ { *dd2 = *dd1; *(dd2+1) = *(dd1+1); } else { istat = fp2wc(-1,0,dd1,dd2); /* world co. -> real pixels */ if (istat != 0) return (istat+10); /* conversion gave problems */ } if (SCALX < 0) /* take care of 1. real pixel + scaling */ { nr = -SCALX; mr = (nr-1)/2; /* (n-1)/2 = (n+1)/2 -1 */ zz = *dd2; z = zz - (int) zz; /* get fraction */ dx = ((int)zz - SFPX)*nr + mr; /* => center pixel */ /* printf("worldx = %f, framxpix = %f, dx offset = %f, fraction = %f\n", *dd1,zz,dx,z); printf("dx = %f, z = %f\n",dx,z); move down 1 line... */ dx += (z * nr); /* add fraction*scale */ } else dx = (*dd2 - SFPX) / SCALX; if (SCALY < 0) { nr = -SCALY; mr = (nr-1)/2; /* (n-1)/2 = (n+1)/2 -1 */ zz = *(dd2 + 1); z = zz - (int) zz; /* get fraction */ dy = ((int)zz - SFPY)*nr + mr; /* => center pixel */ /* printf("worldy = %f, framypix = %f, dy offset = %f, fraction = %f\n", *(dd1+1),zz,dy,z); printf("dy = %f, z = %f\n",dy,z); move down 1 line... */ dy += (z * nr); /* add fraction*scale */ } else dy = (*(dd2+1) - SFPY) / SCALY; kxpix = NINT(dx) + SSPX; kypix = NINT(dy) + SSPY; Sc2ch(-1,&kxpix,&kypix); /* move to screen pixels */ *dd3 = (double) kxpix; *(dd3+1) = (double) kypix; } return (0); }