#ifndef Geom1_RGBAPalette_H
#define Geom1_RGBAPalette_H
#include <Glasses/ZGlass.h>
#include <Stones/ZColorMark.h>
class RGBAPalette : public ZGlass
{
MAC_RNR_FRIENDS(RGBAPalette);
public:
enum LimitAction_e { LA_Cut, LA_Mark, LA_Clip, LA_Wrap };
private:
void _init();
protected:
Int_t mMinInt;
Int_t mMaxInt;
Float_t mMinFlt;
Float_t mMaxFlt;
Bool_t bInterpolate;
Bool_t mShowDefValue;
LimitAction_e mUnderflowAction;
LimitAction_e mOverflowAction;
ZColor mDefaultColor;
ZColor mCutColor;
ZColor mUnderColor;
ZColor mOverColor;
UChar_t mDefaultRGBA[4];
UChar_t mCutRGBA[4];
UChar_t mUnderRGBA[4];
UChar_t mOverRGBA[4];
mutable UChar_t* mColorArray;
mutable Int_t mNBins;
vector<ZColorMark> mColorMarks;
public:
RGBAPalette(const Text_t* n="RGBAPalette", const Text_t* t=0);
virtual ~RGBAPalette();
void ClearColorArray();
void EmitClearCARay() { ClearColorArray(); }
void EmitRecolDCUORay();
void SetMinInt(Int_t min);
void SetMaxInt(Int_t max);
void SetupColorArray() const;
void SetMarksFromgStyle();
void SetMarksFromPOVFile(const Text_t* file_name);
void PrintMarks() const;
void PrintArray() const;
Bool_t WithinVisibleRange(Int_t val) const;
const UChar_t* ColorFromValue(Int_t val) const;
const UChar_t* ColorFromValue(Int_t val, Int_t def_val) const;
void ColorFromValue(Int_t val, UChar_t* pix, Bool_t alpha=true) const;
Bool_t ColorFromValue(Int_t val, Int_t def_val, UChar_t* pix, Bool_t alpha=true) const;
const UChar_t* ColorFromValue(Float_t val) const;
void ColorFromValue(Float_t val, UChar_t* pix, Bool_t alpha=true) const;
ZColor MarkToCol(Float_t mark);
static void ColorFromIdx(Short_t ci, UChar_t* col, Bool_t alpha=true);
static void ColorFromIdx(Float_t f1, Short_t c1, Float_t f2, Short_t c2,
UChar_t* col, Bool_t alpha=true);
#include "RGBAPalette.h7"
ClassDef(RGBAPalette, 1);
};
inline Bool_t RGBAPalette::WithinVisibleRange(Int_t val) const
{
if ((val < mMinInt && mUnderflowAction == LA_Cut) ||
(val > mMaxInt && mOverflowAction == LA_Cut))
return false;
else
return true;
}
inline const UChar_t* RGBAPalette::ColorFromValue(Int_t val) const
{
if (!mColorArray) SetupColorArray();
if (val < mMinInt)
{
if (mUnderflowAction == LA_Wrap)
val = (val+1-mMinInt)%mNBins + mMaxInt;
else if (mUnderflowAction == LA_Clip)
val = mMinInt;
else
return mUnderRGBA;
}
else if (val > mMaxInt)
{
if (mOverflowAction == LA_Wrap)
val = (val-1-mMaxInt)%mNBins + mMinInt;
else if (mOverflowAction == LA_Clip)
val = mMaxInt;
else
return mOverRGBA;
}
return mColorArray + 4 * (val - mMinInt);
}
inline const UChar_t* RGBAPalette::ColorFromValue(Int_t val, Int_t def_val) const
{
if (val == def_val && mShowDefValue)
return mDefaultRGBA;
else
return ColorFromValue(val);
}
inline void RGBAPalette::ColorFromValue(Int_t val, UChar_t* pix, Bool_t alpha) const
{
const UChar_t* c = ColorFromValue(val);
pix[0] = c[0]; pix[1] = c[1]; pix[2] = c[2];
if (alpha) pix[3] = c[3];
}
inline Bool_t RGBAPalette::ColorFromValue(Int_t val, Int_t def_val, UChar_t* pix, Bool_t alpha) const
{
if (val == def_val)
{
if (mShowDefValue) {
pix[0] = mDefaultRGBA[0];
pix[1] = mDefaultRGBA[1];
pix[2] = mDefaultRGBA[2];
if (alpha) pix[3] = mDefaultRGBA[3];
return true;
} else {
return false;
}
}
if (WithinVisibleRange(val))
{
ColorFromValue(val, pix, alpha);
return true;
}
else
{
return false;
}
}
inline const UChar_t* RGBAPalette::ColorFromValue(Float_t val) const
{
Int_t vint = mMinInt +
(Int_t) ((mMaxInt - mMinInt)*(val - mMinFlt)/(mMaxFlt - mMinFlt));
return ColorFromValue(vint);
}
inline void RGBAPalette::ColorFromValue(Float_t val, UChar_t* pix, Bool_t alpha) const
{
const UChar_t* c = ColorFromValue(val);
pix[0] = c[0]; pix[1] = c[1]; pix[2] = c[2];
if (alpha) pix[3] = c[3];
}
inline ZColor RGBAPalette::MarkToCol(Float_t mark)
{
if(mColorMarks.empty()) return ZColor();
vector<ZColorMark>::iterator i = mColorMarks.begin();
if (mark < i->m()) return ZColor(mColorMarks.front());
++i;
while (i != mColorMarks.end() && mark > i->m()) ++i;
if (i == mColorMarks.end()) return ZColor(mColorMarks.back());
vector<ZColorMark>::iterator j = i;
--j;
if (j == mColorMarks.end()) return ZColor(mColorMarks.back());
Float_t fi = (mark - j->m())/(i->m() - j->m());
return fi * ZColor(*i) + (1 - fi) * ZColor(*j);
}
#endif