/* @(#)hsirbg.c	19.1 (ESO-DMD) 02/25/03 13:59:59 */
/*===========================================================================
  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  HSIRBG_C
.LANGUAGE    C
.AUTHOR      K. Banse, IPG-ESO Garching
.KEYWORDS    ImageDisplay, LUT table convertion
.PURPOSE     convert HSI table to RGB table
.ALGORITHM   algorithm from "Interactive Graphics" by Foley, page 615,...
.INPUT/OUTPUT
    call as  HSIRGB_C(flag, hsi, rgb)

  input:
         int  flag         :	= 1 convert RGB -> HSI
                                = 2 convert HSI -> RGB

  in/output:
         float *hsi :		Hue        in [0,360.]
                                Saturation in [0,1]
                                Intensity  in [0,1]
         float *rgb :		Red        in [0,1]
                                Green      in [0,1]
                                Blue       in [0,1]

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

.VERSIONS    1.00       940517  converted to C from JOYSTICK.FOR   RvHees

000627
------------------------------------------------------------*/

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

#define  _POSIX_SOURCE 1

#include <midas_def.h>


#ifdef __STDC__
      static float VALUE( float a, float b, float hue )
#else
      static float VALUE( a, b, hue )
      float a, b, hue;
#endif

{

if (hue > 360.0) hue -= 360.0;
if (hue < 0.0) hue += 360.0;

if (hue < 60.0) return (a + (b-a)*hue/60.0);

if (hue < 180.0) return b;

if (hue < 240.0) return (a + (b-a)*(240.0 - hue)/60.0);

return a;
}



void HSIRGB_C(flag,hsi,rgb)
int flag;
float *hsi, *rgb;

{
register int nn, indx, jndx;
int   imax;

float hue, satu, intens, red, green, blue, rmin, rmax, rdif, rsum, r1, r2;




/* FLAG = 1: go from RGB -> HSI */

indx = jndx= 0;

if (flag == 1)     
   {
   for (nn=0; nn<256; nn++)
      {
      red = rgb[indx++];
      green = rgb[indx++];
      blue = rgb[indx++];

      imax = 1;
      rmin = rmax = red;
      if (green > rmax)     
         { 
         imax = 2;
         rmax = green;
         }
      else if (green < rmin) 
         rmin = green;

      if (blue > rmax)     
         {
         imax = 3;
         rmax = blue;
         }
      else if (blue  < rmin)
         rmin = blue;

      intens = (rmax + rmin) * 0.5;

      rdif = rmax - rmin;
      rsum = rmax + rmin;
      if (rdif < 10.e-30)     
         { 
         satu = 0.;
         hue  = 0.;
         }
      else
         { 
         if (intens <= 0.5)     
            satu = rdif / rsum;
         else
            satu = rdif / (2. - rsum);
         }

      if ( imax == 1 )
         hue = (green - blue) / rdif;
      else if ( imax == 2 )
         hue = 2. + (blue - red) / rdif;
      else
         hue = 4. + (red - green) / rdif;

      hue *= 60.0;                                /* convert to degrees */
      if (hue < 0.0) hue += 360.0;
      }

   hsi[jndx++] = hue;
   hsi[jndx++] = satu;
   hsi[jndx++] = intens;
   }

else if (flag == 2)     
   {
   for (nn=0; nn<256; nn++)
      {
      hue = hsi[indx++];
      satu = hsi[indx++];
      intens = hsi[indx++];

      if ( intens <= 0.5 )     
         r2 = intens * (satu + 1.0);
      else
         r2 = intens + satu - (intens * satu);
      r1 = intens + intens - r2;

      if (satu <= 0.0)
         {
         red = green = blue = intens;
         }
      else
         {
         rsum = hue + 120.0;
         red   = VALUE(r1,r2,rsum);
         green = VALUE(r1,r2,hue);
         rsum = hue - 120.0;
         blue  = VALUE(r1,r2,rsum);
         }

      rgb[jndx++] = red;
      rgb[jndx++] = green;
      rgb[jndx++] = blue;
      }
   }

else
   SCETER(1,"FATAL error in HSIRGB_C: unknown convertion flag...");
}
