/*===========================================================================
  Copyright (C) 1994-2009 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
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENTIFIER  DRIMG_C
.LANGUAGE    C
.AUTHOR      K. Banse			IPG-ESO Garching
.KEYWORDS    memory, ImageDisplay
.PURPOSE     plot intensities of a 1-dim image as y-pixels into image channel
.ALGORITHM   use IDI_PL to do the job
.INPUT/OUTPUT:
    call as  DRIMG_C( dsplay, chan, over, iaux, data, npix, 
                                    icen, cuts, scale, angle )

  input:
         int   dsplay   :	device id
         int   chan     :	channel to draw image in
         int   over     :	I/0 for over_plot
         int   iaux[4]  :	yline, yscale + y-screen offset + intensity
         float *data    :	pointer to image data
         int   npix     :	number of pixels in x-direction
         int   icen[2]  :	frame,screen pixel of centeral x cood.
         float cuts[2]  :	low + high cut in z-dir.
         int   scale[2] :	scaling factors for image
				make image smaller, if > 1
				make image larger, if <  1
         float angle    :	angle with base line

.RETURNS     nothing
.COMMENTS    none
.ENVIRONment MIDAS
             #include <midas_def.h>   Prototypes for MIDAS interfaces

.VERSIONS    1.00       940517  F -> C, converted from RDIMG.FOR   RvH
.VERSIONS    1.10       941122  fix it, KB

 090706		last modif
------------------------------------------------------------*/


/* Define _POSIX_SOURCE to indicate that this is a POSIX program */

#define  _POSIX_SOURCE 1

/* definition of the used functions in this module */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include <midas_def.h>
#include <idinumd.h>
#include <proto_II.h>

#ifndef  PI
#define  PI             3.14159265358979325e0
#endif

#define DEG2RAD		(PI / 180)

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  D1PACK
.PURPOSE     pack a real array (from an image) into I*4 value
             for plotting in ImageDisplay
  input:
         int   hilim  :		hi limit for scaling
         float *data  :		image data
         int   ndim   :		dimension of array DATA
         int   iscale :		scaling factor
         float mfact  :		factor to map into [0,255]
         float cuts[2]:		artificial minimum and maximum of data
  output:
         int   *ldata :		scaled line with pixels
         
.RETURNS     nothing
.COMMENTS    static function
--------------------------------*/
#ifdef __STDC__
      static void D1PACK( int hilim, float *data, int ndim, int iscal, 
                                     double mfact, float *cuts, int *ldata )
#else
      static void D1PACK( hilim, data, ndim, iscal, mfact, cuts, ldata )
      int    hilim, ndim, iscal, *ldata;
      float  *data, *cuts;
      double mfact;
#endif

{
register float turbo, *pntr;


/*      loop + scale data */

turbo = 0.5 - ((*cuts) * mfact);
pntr = data;                              /* points to first element of data */
data += ndim;                       /* points after the last element of data */
if ( iscal >= 1 )
   {
   while (pntr < data) 
      {
      if (*pntr >= cuts[1])     
         *ldata++ = hilim;
      else if ( *pntr > *cuts )     
         *ldata++ = (int) (mfact * *pntr + turbo);
      else
         *ldata++ = 0;
      pntr += iscal;
      }
   }

else                                             /* "zoom" + scale data down */
   {
   register int kk, value;

   iscal *= -1;
   iscal -= 1;

   do {
      if (*pntr >= cuts[1])     
         value = hilim;
      else if (*pntr > *cuts)     
         value = (int) (mfact * *pntr + turbo);
      else
         value = 0;
      for (kk=0; kk<iscal; kk++) *ldata++ = value;
      } while ( ++pntr < data );
   }
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  ROTA
.PURPOSE     rotate coordinate pair IX,IY
.ALGORITHM   straight forward
.INPUT/OUTPUT
  input:
         double ca     :	cosine of rotation
         double sa     :	sine of rotation
         int    ix     :	x-coordinate to be rotated
         int    iy     :	y-coordinate to be rotated

  output:
         int    *ioutx :	rotated x-coordinate
         int    *iouty :	rotated y-coordinate
         
.RETURNS     nothing
.COMMENTS    static function
------------------------------*/
#ifdef __STDC__
      static void ROTA( double ca, double sa, int ix, int iy, 
                                              int *ioutx, int *iouty )
#else
      static void ROTA( ca, sa, ix, iy, ioutx, iouty )
      int    ix, iy, *ioutx, *iouty;
      double ca, sa;
#endif

{
*ioutx = CGN_NINT(ix * ca - iy * sa);
*iouty = CGN_NINT(iy * ca + ix * sa);
}

/*

*/


#ifdef __STDC__
void DRIMG_C( int dsplay, int chan, int over, int *iaux, float *data,
              int npix, int *icen, float *cuts, int *scale, float angle )
#else
void DRIMG_C( dsplay, chan, over, iaux, data, npix, icen, cuts, scale, angle )
int   dsplay, chan, over, npix, *iaux, *icen, *scale;
float angle, *data, *cuts; 
#endif

{
register int nn;

int    color, nfx, nsx, sfpx, sfpy, sspx, sspy, *xdata, *ydata;
double ca, sa, mfact;
      
static int ltype = 1;                                          /* solid line */


/*      calculate no. of x-pixels  (y-stuff is clear...) */

sfpy = iaux[0];
sspy = iaux[2];
color = iaux[3];

SIZER_C(QMSZX,npix,*scale,0,icen,&nsx,&sspx,&nfx,&sfpx);  /* no averaging */
xdata = (int *) malloc((size_t)(nsx*sizeof(int)));
ydata = (int *) malloc((size_t)(nsx*sizeof(int)));


/* if overlay flag = 0, clear channel first */

if (over != 1) (void) IIMCMY_C(dsplay,&chan,1,0);


/* scale image */

if ((cuts[1] - *cuts) < 10.e-25)            /* range interval too small... */
   { 
   mfact = 1.0;
   cuts[1] = 0.;
   }
else
   {
   mfact = iaux[1];
   mfact /= (cuts[1] - *cuts);
   }

data += (sfpx-1) + ((sfpy-1)*npix);			/* init pointer line */
D1PACK(iaux[1],data,nfx,*scale,mfact,cuts,ydata);


/* plot parallel to the base line */

if ((float) fabs((double) angle) <= 10.e-3)
   {
   for (nn=sspx; nn<sspx+nsx; nn++) *xdata++ = nn;

   xdata -= nsx;
   if ( sspy != 0 ) 
      {
      for (nn=sspx; nn<sspx+nsx; nn++) *ydata++ += sspy;
      ydata -= nsx;
      }
   }

else                                                  /* plot with an angle */
   {
   angle *= DEG2RAD;
   ca = cos(angle);
   sa = sin(angle);

   for (nn=0; nn<nsx; nn++)
      {
      ROTA(ca,sa,nn,*ydata,xdata,ydata);
      *xdata++ += sspx;
      *ydata++ += sspy;
      }
   xdata -= nsx;
   ydata -= nsx;
   }

/* now plot */

(void)IIGPLY_C(dsplay,chan,xdata,ydata,nsx,color,ltype);

(void) free((char *) xdata);
(void) free((char *) ydata);
}

