// This may look like C code, but it is really -*- C++ -*-
// Classe Look-Up-Table  pour convertir image en entree ds
// une table de couleur.
//       Classe LUT              R. Ansari  05/95
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef LUT_SEEN
#define LUT_SEEN

// LUT : Look-Up-Table avec nLevel bins entre min et max
// Apply retourne * 0 < min   * nLevel+1 > max 
// et de 1 a nLevel pour min<=x<max

// Type de lut possibles 
enum {kLutType_Lin=1, kLutType_Log=2, kLutType_Exp=3, kLutType_Sqrt=4, kLutType_Square=5, kLutType_RGB=11 };

class LUT 
{
public:
  
  LUT(double min, double max, unsigned short ncol=16, int typ=kLutType_Lin);
  ~LUT();
  void SetNCol(unsigned short ncol);
  void SetLut(double min, double max, int typ=kLutType_Lin);
  void Print();

  inline unsigned short Apply(double x)
    { 
    if (type == kLutType_RGB) return ApplyRGB(x); 
    else return ApplyI(x);	
    } 

  inline unsigned short ApplyFast(double x)
    { 
    if (type == kLutType_RGB) return ApplyRGB(x); 
    else return AppFast(x);	
    } 


  inline double Min() { return(bornes[0]); };
  inline double Max() { return(bornes[nLevel]); };
  inline double Borne(int k) { return(bornes[k]); };
  inline int Type() { return(type); };
  inline int NCol() { return(nLevel+2); };


protected:
  void ComputeTable(int nt);
  unsigned short ApplyI(double x);
  unsigned short ApplyRGB(double x);
  inline unsigned short AppFast(double x)
    {
    if (x < Min())  return(0);
    if (x >= Max() )  return(nLevel+1);  
    int k = (int)((x-Min())/tablebinwidth);
    return(table[k]); 
    } 
  inline int  Contraste(int ii)   /* for ApplyRGB */
    {
    if (ii >= mMaxI) return quantum-1;
    if (ii <= mMinI) return 0;
    else return ((ii-mMinI)*(quantum-1)/mMaxI);
    }	  
  int type;
  int nLevel;
  int quantum;
  double * bornes;
  double mMin, mMax;
  int mMinI, mMaxI;
  int tablenbin;
  unsigned short * table;
  double tablebinwidth;

};

#endif



  
