ROOT logo
// @(#)root/graf:$Id$
// Author: Reiner Rohlfs   24/03/02

/*************************************************************************
 * Copyright (C) 2001-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  TAttImage                                                           //
//                                                                      //
//  Image attributes are:                                               //
//    Image Quality (see EImageQuality for the list of qualities)       //
//    Compression defines the compression rate of the color data in the //
//                internal image structure. Speed and memory depends    //
//                on this rate, but not the image display itself        //
//                0: no compression;  100: max compression              //
//    Radio Flag: kTRUE  the x/y radio of the displayed image is always //
//                       identical to the original image                //
//                kFALSE the x and y size of the displayed image depends//
//                       on the size of the pad                         //
//    Palette:    Defines the conversion from a pixel value to the      //
//                screen color                                          //
//                                                                      //
//  This class is used (in general by secondary inheritance)            //
//  by some other classes (image display).                              //
//                                                                      //
//                                                                      //
//  TImagePalette                                                       //
//                                                                      //
//  A class to define a conversion from pixel values to pixel color.    //
//  A Palette is defined by some anchor points. Each anchor point has   //
//  a value between 0 and 1 and a color. An image has to be normalized  //
//  and the values between the anchor points are interpolated.          //
//  All member variables are public and can be directly manipulated.    //
//  In most cases the default operator will be used to create a         //
//  TImagePalette. In this case the member arrays have to be allocated  //
//  by an application and will be deleted in the destructor of this     //
//  class.                                                              //
//                                                                      //
//  We provide few predifined palettes:                                 //
//                                                                      //
//    o gHistImagePalette - palette used in TH2::Draw("col")            //
//                                                                      //
//    o gWebImagePalette                                                //
//       The web palette is a set of 216 colors that will not dither or //
//       shift on PCs or Macs. Browsers use this built-in palette when  //
//       they need to render colors on monitors with only 256 colors    //
//       (also called 8-bit color monitors).                            //
//       The 6x6x6 web palette provides very quick color index lookup   //
//       and can be used for good quality convertion of images into     //
//       2-D histograms.                                                //
//                                                                      //
//    o  TImagePalette(Int_t ncolors, Int_t *colors)                    //
//        if ncolors <= 0 a default palette (see below) of 50 colors    //
//        is defined.                                                   //
//                                                                      //   
//        if ncolors == 1 && colors == 0, then                          //
//        a Pretty Palette with a Spectrum Violet->Red is created.      //
//                                                                      //
//        if ncolors > 50 and colors=0, the DeepSea palette is used.    //
//         (see TStyle::CreateGradientColorTable for more details)      //
//                                                                      //
//        if ncolors > 0 and colors = 0, the default palette is used    //
//        with a maximum of ncolors.                                    //
//                                                                      //
// The default palette defines:                                         //
//   index 0->9   : grey colors from light to dark grey                 //
//   index 10->19 : "brown" colors                                      //
//   index 20->29 : "blueish" colors                                    //
//   index 30->39 : "redish" colors                                     //
//   index 40->49 : basic colors                                        //
//                                                                      //
//                                                                      //
//  TPaletteEditor                                                      //
//                                                                      //
//  This class provides a way to edit the palette via a GUI.            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TAttImage.h"
#include "TROOT.h"
#include "TPluginManager.h"
#include "Riostream.h"
#include "TColor.h"
#include "TMath.h"


ClassImp(TPaletteEditor)
ClassImp(TAttImage)
ClassImp(TImagePalette)


// definition of a default palette
const Int_t kNUM_DEFAULT_COLORS = 12;
static UShort_t gAlphaDefault[kNUM_DEFAULT_COLORS] = {
   0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
   0xffff, 0xffff, 0xffff, 0xffff
};

static UShort_t gRedDefault[kNUM_DEFAULT_COLORS] = {
   0x0000, 0x0000, 0x7000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff,
   0x7000, 0x8000, 0xffff, 0xffff
};

static UShort_t gGreenDefault[kNUM_DEFAULT_COLORS] = {
   0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0000,
   0x0000, 0x8000, 0xffff, 0xffff
};

static UShort_t gBlueDefault[kNUM_DEFAULT_COLORS] = {
   0x0000, 0x0000, 0x7000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000,
   0x0000, 0xa000, 0xffff, 0xffff
};


//////////////////////////// Web Palette ////////////////////////////////////
static UShort_t gWebBase[6] = { 0, 51, 102, 153, 204, 255 };

class TWebPalette : public TImagePalette {

private:
   Int_t fCLUT[6][6][6];   // Color LookUp Table

public:
   TWebPalette() : TImagePalette() {
      int i = 0;
      fNumPoints = 216;
      fPoints = new Double_t[216];
      fColorRed = new UShort_t[216];
      fColorBlue = new UShort_t[216];
      fColorGreen = new UShort_t[216];
      fColorAlpha = new UShort_t[216];

      for (i = 0; i < 214; i++) {
         fPoints[i + 1]  =  (double)i/213;
      }
      fPoints[0] = 0;
      fPoints[215] = 1;

      i = 0;
      for (int r = 0; r < 6; r++) {
         for (int g = 0; g < 6; g++) {
            for (int b = 0; b < 6; b++) {
               fColorRed[i] = gWebBase[r] << 8;
               fColorGreen[i] = gWebBase[g] << 8;
               fColorBlue[i] = gWebBase[b] << 8;
               fColorAlpha[i] = 0xffff;
               fCLUT[r][g][b] = i;
               i++;
            }
         }
      }
   }

   Int_t FindColor(UShort_t r, UShort_t g, UShort_t b) {
      Int_t ri = TMath:: BinarySearch(6, (const Short_t*)gWebBase, (Short_t)r);
      Int_t gi = TMath:: BinarySearch(6, (const Short_t*)gWebBase, (Short_t)g);
      Int_t bi = TMath:: BinarySearch(6, (const Short_t*)gWebBase, (Short_t)b);
      return fCLUT[ri][gi][bi];
   }

   Int_t *GetRootColors() {
      static Int_t *gRootColors = 0;
      if (gRootColors) return gRootColors;

      gRootColors = new Int_t[216];

      int i = 0;
      for (int r = 0; r < 6; r++) {
         for (int g = 0; g < 6; g++) {
            for (int b = 0; b < 6; b++) {
               gRootColors[i] = TColor::GetColor(gWebBase[r], gWebBase[g], gWebBase[b]);
               i++;
            }
         }
      }
      return gRootColors;
   }
};

TImagePalette *gWebImagePalette = new TWebPalette();


////////////////////////////// Hist Palette ////////////////////////////////////
static Double_t gDefHistP[50] =  {
      0.00,0.02,0.04,0.06,0.08,0.10,0.12,0.14,0.16,0.18,0.20,0.22,0.24,0.26,
      0.28,0.30,0.32,0.34,0.36,0.38,0.40,0.42,0.44,0.46,0.48,0.50,0.52,0.54,
      0.56,0.58,0.60,0.62,0.64,0.66,0.68,0.70,0.72,0.74,0.76,0.78,0.80,0.82,
      0.84,0.86,0.88,0.90,0.92,0.94,0.96,0.98 };

static UShort_t gDefHistR[50] = {
      242,229,204,178,153,127,102,76,192,204,204,193,186,178,183,173,155,135,
      175,132,89,137,130,173,122, 117,104,109,124,127,170,89,211,221,188,198,
      191,170,165,147,206,211,255,0,255,255,0,0,53,0 };

static UShort_t gDefHistG[50] = {
      242,229,204,178,153,127,102,76,182,198,198,191,181,165,163,153,142,102,
      206,193,211,168,158,188,142,137,130,122,153,127,165,84,206,186,158,153,
      130,142,119,104,94,89,0,255,0,255,0,255,53,0 };

static UShort_t gDefHistB[50] = {
      242,229,204,178,153,127,102,76,172,170,170,168,163,150,155,140,130,86,
      198,163,84,160,140,198,153,145,150,132,209,155,191,216,135,135,130,124,
      119,147,122,112,96,84,0,255,255,0,255,0,53,0 };

static UShort_t gDefHistA[50] = {
      255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
      255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
      255,255,255,255,255,255,255,255,255,255,255,255,255,255 };

static Int_t gDefHistRoot[50] = {
      19,18,17,16,15,14,13,12,11,20,21,22,23,24,25,26,27,28,29,30, 8,
      31,32,33,34,35,36,37,38,39,40, 9, 41,42,43,44,45,47,48,49,46,50, 2,
      7, 6, 5, 4, 3, 112,1};


class TDefHistImagePalette : public TImagePalette {

public:
   TDefHistImagePalette() : TImagePalette() {
      fNumPoints = 50;
      fPoints = gDefHistP;
      fColorRed = gDefHistR;
      fColorGreen = gDefHistG;
      fColorBlue = gDefHistB;
      fColorAlpha = gDefHistA;

      for (int i = 0; i<50; i++) {
         fColorRed[i] = fColorRed[i] << 8;
         fColorGreen[i] = fColorGreen[i] << 8;
         fColorBlue[i] = fColorBlue[i] << 8;
         fColorAlpha[i] = fColorAlpha[i] << 8;
      }
   }

   Int_t *GetRootColors() { return gDefHistRoot; }
};

TImagePalette *gHistImagePalette = new TDefHistImagePalette();


///////////////////////////////////////////////////////////////////////////////
//______________________________________________________________________________
TPaletteEditor::TPaletteEditor(TAttImage *attImage, UInt_t, UInt_t)
{
   // Constructor.

   fAttImage = attImage;
}

//______________________________________________________________________________
void TPaletteEditor::CloseWindow()
{
   // Closes the window and deletes itself.

   fAttImage->EditorClosed();
}


//______________________________________________________________________________
TImagePalette::TImagePalette()
{
   // Default constructor, sets all pointers to 0.

   fNumPoints     = 0;
   fPoints        = 0;
   fColorRed      = 0;
   fColorGreen    = 0;
   fColorBlue     = 0;
   fColorAlpha    = 0;
}

//______________________________________________________________________________
TImagePalette::TImagePalette(UInt_t numPoints)
{
   // Constructor for a palette with numPoints anchor points.
   // It allocates the memory but does not set any colors.

   fNumPoints  = numPoints;
   fPoints     = new Double_t[fNumPoints];
   fColorRed   = new UShort_t[fNumPoints];
   fColorGreen = new UShort_t[fNumPoints];
   fColorBlue  = new UShort_t[fNumPoints];
   fColorAlpha = new UShort_t[fNumPoints];
}

//______________________________________________________________________________
TImagePalette::TImagePalette(const TImagePalette &palette) : TObject(palette)
{
   // Copy constructor.

   fNumPoints = palette.fNumPoints;

   fPoints = new Double_t[fNumPoints];
   memcpy(fPoints, palette.fPoints, fNumPoints * sizeof(Double_t));

   fColorRed   = new UShort_t[fNumPoints];
   fColorGreen = new UShort_t[fNumPoints];
   fColorBlue  = new UShort_t[fNumPoints];
   fColorAlpha = new UShort_t[fNumPoints];
   memcpy(fColorRed,   palette.fColorRed,   fNumPoints * sizeof(UShort_t));
   memcpy(fColorGreen, palette.fColorGreen, fNumPoints * sizeof(UShort_t));
   memcpy(fColorBlue,  palette.fColorBlue,  fNumPoints * sizeof(UShort_t));
   memcpy(fColorAlpha, palette.fColorAlpha, fNumPoints * sizeof(UShort_t));
}

//______________________________________________________________________________
TImagePalette::TImagePalette(Int_t ncolors, Int_t *colors)
{
   // Creates palette in the same way as TStyle::SetPalette

   fNumPoints  = 0;
   fPoints     = 0;
   fColorRed   = 0;
   fColorGreen = 0;
   fColorBlue  = 0;
   fColorAlpha = 0;

   Int_t i;
   static Int_t palette[50] = {19,18,17,16,15,14,13,12,11,20,
                        21,22,23,24,25,26,27,28,29,30, 8,
                        31,32,33,34,35,36,37,38,39,40, 9,
                        41,42,43,44,45,47,48,49,46,50, 2,
                         7, 6, 5, 4, 3, 112,1};
   TColor *col = 0;
   Float_t step = 0;
   // set default palette (pad type)
   if (ncolors <= 0) {
      ncolors = 50;
      fNumPoints  = ncolors;
      step = 1./fNumPoints;
      fPoints     = new Double_t[fNumPoints];
      fColorRed   = new UShort_t[fNumPoints];
      fColorGreen = new UShort_t[fNumPoints];
      fColorBlue  = new UShort_t[fNumPoints];
      fColorAlpha = new UShort_t[fNumPoints];
      for (i=0;i<ncolors;i++) {
         col = gROOT->GetColor(palette[i]);
         fPoints[i] = i*step;
         if (col) {
            fColorRed[i]   = UShort_t(col->GetRed()*255)  << 8;
            fColorGreen[i] = UShort_t(col->GetGreen()*255) << 8;
            fColorBlue[i]  = UShort_t(col->GetBlue()*255) << 8;
         }
         fColorAlpha[i] = 65280;
      }
      return;
   }

   // set Pretty Palette Spectrum Violet->Red
   if (ncolors == 1 && colors == 0) {
      ncolors = 50;
      fNumPoints  = ncolors;
      step = 1./fNumPoints;
      fPoints     = new Double_t[fNumPoints];
      fColorRed   = new UShort_t[fNumPoints];
      fColorGreen = new UShort_t[fNumPoints];
      fColorBlue  = new UShort_t[fNumPoints];
      fColorAlpha = new UShort_t[fNumPoints];

      // 0 point is white
      fPoints[0] = 0;
      fColorRed[0] = 255 << 8;
      fColorGreen[0] = 255 << 8;
      fColorBlue[0] = 255 << 8;
      fColorAlpha[0] = 0;

      for (i=1;i<ncolors;i++) {
         col = gROOT->GetColor(51+i);
         fPoints[i] = i*step;
         if (col) {
            fColorRed[i]   = UShort_t(col->GetRed()*255) << 8;
            fColorGreen[i] = UShort_t(col->GetGreen()*255) << 8;
            fColorBlue[i]  = UShort_t(col->GetBlue()*255) << 8;
         }
         fColorAlpha[i] = 65280;
      }
      return;
   }

   // set DeepSea palette
   if (colors == 0 && ncolors > 50) {
      static const Int_t nRGBs = 5;
      static Float_t stops[nRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
      static Float_t red[nRGBs] = { 0.00, 0.09, 0.18, 0.09, 0.00 };
      static Float_t green[nRGBs] = { 0.01, 0.02, 0.39, 0.68, 0.97 };
      static Float_t blue[nRGBs] = { 0.17, 0.39, 0.62, 0.79, 0.97 };
      fNumPoints = nRGBs;
      fPoints     = new Double_t[fNumPoints];
      fColorRed   = new UShort_t[fNumPoints];
      fColorGreen = new UShort_t[fNumPoints];
      fColorBlue  = new UShort_t[fNumPoints];
      fColorAlpha = new UShort_t[fNumPoints];
      for (i=0;i<(int)fNumPoints;i++) {
         fPoints[i] = stops[i];
         fColorRed[i] = UShort_t(red[i]*255) << 8;
         fColorGreen[i] = UShort_t(green[i]*255) << 8;
         fColorBlue[i] = UShort_t(blue[i]*255) << 8;
         fColorAlpha[i] = 65280;   
      }
      return;
   }

   // set user defined palette
   if (colors)  {
      fNumPoints  = ncolors;
      step = 1./fNumPoints;
      fPoints     = new Double_t[fNumPoints];
      fColorRed   = new UShort_t[fNumPoints];
      fColorGreen = new UShort_t[fNumPoints];
      fColorBlue  = new UShort_t[fNumPoints];
      fColorAlpha = new UShort_t[fNumPoints];
      for (i=0;i<ncolors;i++) {
         fPoints[i] = i*step;
         col = gROOT->GetColor(colors[i]);
         if (col) {
            fColorRed[i] = UShort_t(col->GetRed()*255) << 8;
            fColorGreen[i] = UShort_t(col->GetGreen()*255) << 8;
            fColorBlue[i] = UShort_t(col->GetBlue()*255) << 8;
            fColorAlpha[i] = 65280;
         } else {
            fColorRed[i] = 0;
            fColorGreen[i] = 0;
            fColorBlue[i] = 0;
            fColorAlpha[i] = 0;
         }
      }
   }
}

//______________________________________________________________________________
TImagePalette::~TImagePalette()
{
   // Destructor.

   delete [] fPoints;
   delete [] fColorRed;
   delete [] fColorGreen;
   delete [] fColorBlue;
   delete [] fColorAlpha;
}

//______________________________________________________________________________
TImagePalette &TImagePalette::operator=(const TImagePalette &palette)
{
   // Assignment operator.

   if (this != &palette) {
      fNumPoints = palette.fNumPoints;

      delete [] fPoints;
      fPoints = new Double_t[fNumPoints];
      memcpy(fPoints, palette.fPoints, fNumPoints * sizeof(Double_t));

      delete [] fColorRed;
      fColorRed = new UShort_t[fNumPoints];
      memcpy(fColorRed, palette.fColorRed, fNumPoints * sizeof(UShort_t));

      delete [] fColorGreen;
      fColorGreen = new UShort_t[fNumPoints];
      memcpy(fColorGreen, palette.fColorGreen, fNumPoints * sizeof(UShort_t));

      delete [] fColorBlue;
      fColorBlue = new UShort_t[fNumPoints];
      memcpy(fColorBlue, palette.fColorBlue, fNumPoints * sizeof(UShort_t));

      delete [] fColorAlpha;
      fColorAlpha = new UShort_t[fNumPoints];
      memcpy(fColorAlpha, palette.fColorAlpha, fNumPoints * sizeof(UShort_t));
   }

   return *this;
}

//______________________________________________________________________________
Int_t TImagePalette::FindColor(UShort_t r, UShort_t g, UShort_t b)
{
   // returns an index of the closest color

   Int_t ret = 0;
   UInt_t d = 10000;
   UInt_t min = 10000;

   for (UInt_t i = 0; i < fNumPoints; i++) {
      d = TMath::Abs(r - ((fColorRed[i] & 0xff00) >> 8)) +
          TMath::Abs(g - ((fColorGreen[i] & 0xff00) >> 8)) +
          TMath::Abs(b - ((fColorBlue[i] & 0xff00) >> 8));
      if (d < min) {
         min = d;
         ret = i;
      }
   }
   return ret;
}

//______________________________________________________________________________
Int_t *TImagePalette::GetRootColors()
{
   // Returns a list of ROOT colors. Could be used to set histogram palette.
   // See also http://root.cern.ch/root/htmldoc/TStyle.html#TStyle:SetPalette

   static Int_t *gRootColors = 0;
   if (gRootColors) return gRootColors;

   gRootColors = new Int_t[fNumPoints];

   for (UInt_t i = 0; i < fNumPoints; i++) {
      gRootColors[i] = TColor::GetColor(fColorRed[i], fColorGreen[i], fColorBlue[i]);
   }
   return gRootColors;
}


//______________________________________________________________________________
TAttImage::TAttImage()
{
   // TAttImage default constructor.
   // Calls ResetAttImage to set the attributes to a default state.

   ResetAttImage();
   fPaletteEditor = 0;
   fPaletteEnabled = kTRUE;
}

//______________________________________________________________________________
TAttImage::TAttImage(EImageQuality lquality, UInt_t lcompression,
                     Bool_t constRatio)
{
   // TAttImage normal constructor.
   // Image attributes are taken from the argument list
   //    qualtity     : must be one of EImageQuality (kImgDefault is same as
   //                   kImgGood in the current implementation)
   //    lcompression : defines the compression rate of the color data in the
   //                   image. Speed and memory depends on this rate, but not
   //                   the image display itself
   //                   0: no compression;  100: max compression
   //    constRatio   : keeps the aspect ratio of the image constant on the
   //                   screen (in pixel units)

   ResetAttImage();

   fImageQuality = lquality;
   fImageCompression = (lcompression > 100) ? 100 : lcompression;
   fConstRatio = constRatio;
   fPaletteEditor = 0;
   fPaletteEnabled = kTRUE;
}

//______________________________________________________________________________
TAttImage::~TAttImage()
{
   // TAttImage destructor.

   delete fPaletteEditor;
}

//______________________________________________________________________________
void TAttImage::Copy(TAttImage &attimage) const
{
   // Copy this image attributes to a new attimage.

   attimage.fImageQuality     = fImageQuality;
   attimage.fImageCompression = fImageCompression;
   attimage.fConstRatio       = fConstRatio;
   attimage.fPalette          = fPalette;
}

//______________________________________________________________________________
void TAttImage::ResetAttImage(Option_t *)
{
   // Reset this image attributes to default values.
   // Default values are:
   //    quality:     kImgPoor, (no smoothing while the image is zoomed)
   //    compression: 0 (no compression)
   //    constRatio:  kTRUE
   //    palette:     a default rainbow palette

   fImageQuality      = kImgPoor;
   fImageCompression  = 0;
   fConstRatio        = kTRUE;

   // set the default palette
   delete [] fPalette.fPoints;
   delete [] fPalette.fColorRed;
   delete [] fPalette.fColorGreen;
   delete [] fPalette.fColorBlue;
   delete [] fPalette.fColorAlpha;

   fPalette.fNumPoints = kNUM_DEFAULT_COLORS;

   fPalette.fColorRed    = new UShort_t [kNUM_DEFAULT_COLORS];
   fPalette.fColorGreen  = new UShort_t [kNUM_DEFAULT_COLORS];
   fPalette.fColorBlue   = new UShort_t [kNUM_DEFAULT_COLORS];
   fPalette.fColorAlpha  = new UShort_t [kNUM_DEFAULT_COLORS];
   fPalette.fPoints      = new Double_t [kNUM_DEFAULT_COLORS];

   memcpy(fPalette.fColorRed,   gRedDefault,   kNUM_DEFAULT_COLORS * sizeof(UShort_t));
   memcpy(fPalette.fColorGreen, gGreenDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
   memcpy(fPalette.fColorBlue,  gBlueDefault,  kNUM_DEFAULT_COLORS * sizeof(UShort_t));
   memcpy(fPalette.fColorAlpha, gAlphaDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));

   for (Int_t point = 0; point < kNUM_DEFAULT_COLORS - 2; point++)
      fPalette.fPoints[point + 1]  =  (double)point / (kNUM_DEFAULT_COLORS - 3);
   fPalette.fPoints[0] = 0;
   fPalette.fPoints[kNUM_DEFAULT_COLORS - 1] = 1;
}

//______________________________________________________________________________
void TAttImage::SaveImageAttributes(ostream &out, const char *name,
                                    EImageQuality qualdef,
                                    UInt_t comprdef, Bool_t constRatiodef)
{
   // Save image attributes as C++ statement(s) on output stream, but
   // not the palette.

   if (fImageQuality != qualdef) {
      out<<"   "<<name<<"->SetImageQuality("<<fImageQuality<<");"<<endl;
   }
   if (fImageCompression != comprdef) {
      out<<"   "<<name<<"->SetImageCompression("<<fImageCompression<<");"<<endl;
   }
   if (fConstRatio != constRatiodef) {
      out<<"   "<<name<<"->SetConstRatio("<<fConstRatio<<");"<<endl;
   }
}

//______________________________________________________________________________
void TAttImage::SetConstRatio(Bool_t constRatio)
{
   // Set (constRatio = kTRUE) or unset (constRadio = kFALSE) the ratio flag.
   // The aspect ratio of the image on the screen is constant if the ratio
   // flag is set. That means one image pixel is allways a square on the screen
   // independent of the pad size and of the size of the zoomed area.

   fConstRatio = constRatio;
}

//______________________________________________________________________________
void TAttImage::SetPalette(const TImagePalette *palette)
{
   // Set a new palette for the image. If palette == 0 a default
   // rainbow color palette is used.

   if (palette)
      fPalette = *palette;
   else {
      // set default palette

      delete [] fPalette.fPoints;
      delete [] fPalette.fColorRed;
      delete [] fPalette.fColorGreen;
      delete [] fPalette.fColorBlue;
      delete [] fPalette.fColorAlpha;

      fPalette.fNumPoints = kNUM_DEFAULT_COLORS;

      fPalette.fColorRed    = new UShort_t [kNUM_DEFAULT_COLORS];
      fPalette.fColorGreen  = new UShort_t [kNUM_DEFAULT_COLORS];
      fPalette.fColorBlue   = new UShort_t [kNUM_DEFAULT_COLORS];
      fPalette.fColorAlpha  = new UShort_t [kNUM_DEFAULT_COLORS];
      fPalette.fPoints      = new Double_t [kNUM_DEFAULT_COLORS];

      memcpy(fPalette.fColorRed,   gRedDefault,   kNUM_DEFAULT_COLORS * sizeof(UShort_t));
      memcpy(fPalette.fColorGreen, gGreenDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
      memcpy(fPalette.fColorBlue,  gBlueDefault,  kNUM_DEFAULT_COLORS * sizeof(UShort_t));
      memcpy(fPalette.fColorAlpha, gAlphaDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));

      for (Int_t point = 0; point < kNUM_DEFAULT_COLORS - 2; point++)
         fPalette.fPoints[point + 1]  =  (double)point / (kNUM_DEFAULT_COLORS - 3);
      fPalette.fPoints[0] = 0;
      fPalette.fPoints[kNUM_DEFAULT_COLORS - 1] = 1;
   }
}

//______________________________________________________________________________
void TAttImage::StartPaletteEditor()
{
   // Opens a GUI to edit the color palette.

   if (fPaletteEditor == 0) {
      TPluginHandler *h;

      if ((h = gROOT->GetPluginManager()->FindHandler("TPaletteEditor"))) {
         if (h->LoadPlugin() == -1)
            return;
         fPaletteEditor = (TPaletteEditor *) h->ExecPlugin(3, this, 80, 25);
      }
   }
}
 TAttImage.cxx:1
 TAttImage.cxx:2
 TAttImage.cxx:3
 TAttImage.cxx:4
 TAttImage.cxx:5
 TAttImage.cxx:6
 TAttImage.cxx:7
 TAttImage.cxx:8
 TAttImage.cxx:9
 TAttImage.cxx:10
 TAttImage.cxx:11
 TAttImage.cxx:12
 TAttImage.cxx:13
 TAttImage.cxx:14
 TAttImage.cxx:15
 TAttImage.cxx:16
 TAttImage.cxx:17
 TAttImage.cxx:18
 TAttImage.cxx:19
 TAttImage.cxx:20
 TAttImage.cxx:21
 TAttImage.cxx:22
 TAttImage.cxx:23
 TAttImage.cxx:24
 TAttImage.cxx:25
 TAttImage.cxx:26
 TAttImage.cxx:27
 TAttImage.cxx:28
 TAttImage.cxx:29
 TAttImage.cxx:30
 TAttImage.cxx:31
 TAttImage.cxx:32
 TAttImage.cxx:33
 TAttImage.cxx:34
 TAttImage.cxx:35
 TAttImage.cxx:36
 TAttImage.cxx:37
 TAttImage.cxx:38
 TAttImage.cxx:39
 TAttImage.cxx:40
 TAttImage.cxx:41
 TAttImage.cxx:42
 TAttImage.cxx:43
 TAttImage.cxx:44
 TAttImage.cxx:45
 TAttImage.cxx:46
 TAttImage.cxx:47
 TAttImage.cxx:48
 TAttImage.cxx:49
 TAttImage.cxx:50
 TAttImage.cxx:51
 TAttImage.cxx:52
 TAttImage.cxx:53
 TAttImage.cxx:54
 TAttImage.cxx:55
 TAttImage.cxx:56
 TAttImage.cxx:57
 TAttImage.cxx:58
 TAttImage.cxx:59
 TAttImage.cxx:60
 TAttImage.cxx:61
 TAttImage.cxx:62
 TAttImage.cxx:63
 TAttImage.cxx:64
 TAttImage.cxx:65
 TAttImage.cxx:66
 TAttImage.cxx:67
 TAttImage.cxx:68
 TAttImage.cxx:69
 TAttImage.cxx:70
 TAttImage.cxx:71
 TAttImage.cxx:72
 TAttImage.cxx:73
 TAttImage.cxx:74
 TAttImage.cxx:75
 TAttImage.cxx:76
 TAttImage.cxx:77
 TAttImage.cxx:78
 TAttImage.cxx:79
 TAttImage.cxx:80
 TAttImage.cxx:81
 TAttImage.cxx:82
 TAttImage.cxx:83
 TAttImage.cxx:84
 TAttImage.cxx:85
 TAttImage.cxx:86
 TAttImage.cxx:87
 TAttImage.cxx:88
 TAttImage.cxx:89
 TAttImage.cxx:90
 TAttImage.cxx:91
 TAttImage.cxx:92
 TAttImage.cxx:93
 TAttImage.cxx:94
 TAttImage.cxx:95
 TAttImage.cxx:96
 TAttImage.cxx:97
 TAttImage.cxx:98
 TAttImage.cxx:99
 TAttImage.cxx:100
 TAttImage.cxx:101
 TAttImage.cxx:102
 TAttImage.cxx:103
 TAttImage.cxx:104
 TAttImage.cxx:105
 TAttImage.cxx:106
 TAttImage.cxx:107
 TAttImage.cxx:108
 TAttImage.cxx:109
 TAttImage.cxx:110
 TAttImage.cxx:111
 TAttImage.cxx:112
 TAttImage.cxx:113
 TAttImage.cxx:114
 TAttImage.cxx:115
 TAttImage.cxx:116
 TAttImage.cxx:117
 TAttImage.cxx:118
 TAttImage.cxx:119
 TAttImage.cxx:120
 TAttImage.cxx:121
 TAttImage.cxx:122
 TAttImage.cxx:123
 TAttImage.cxx:124
 TAttImage.cxx:125
 TAttImage.cxx:126
 TAttImage.cxx:127
 TAttImage.cxx:128
 TAttImage.cxx:129
 TAttImage.cxx:130
 TAttImage.cxx:131
 TAttImage.cxx:132
 TAttImage.cxx:133
 TAttImage.cxx:134
 TAttImage.cxx:135
 TAttImage.cxx:136
 TAttImage.cxx:137
 TAttImage.cxx:138
 TAttImage.cxx:139
 TAttImage.cxx:140
 TAttImage.cxx:141
 TAttImage.cxx:142
 TAttImage.cxx:143
 TAttImage.cxx:144
 TAttImage.cxx:145
 TAttImage.cxx:146
 TAttImage.cxx:147
 TAttImage.cxx:148
 TAttImage.cxx:149
 TAttImage.cxx:150
 TAttImage.cxx:151
 TAttImage.cxx:152
 TAttImage.cxx:153
 TAttImage.cxx:154
 TAttImage.cxx:155
 TAttImage.cxx:156
 TAttImage.cxx:157
 TAttImage.cxx:158
 TAttImage.cxx:159
 TAttImage.cxx:160
 TAttImage.cxx:161
 TAttImage.cxx:162
 TAttImage.cxx:163
 TAttImage.cxx:164
 TAttImage.cxx:165
 TAttImage.cxx:166
 TAttImage.cxx:167
 TAttImage.cxx:168
 TAttImage.cxx:169
 TAttImage.cxx:170
 TAttImage.cxx:171
 TAttImage.cxx:172
 TAttImage.cxx:173
 TAttImage.cxx:174
 TAttImage.cxx:175
 TAttImage.cxx:176
 TAttImage.cxx:177
 TAttImage.cxx:178
 TAttImage.cxx:179
 TAttImage.cxx:180
 TAttImage.cxx:181
 TAttImage.cxx:182
 TAttImage.cxx:183
 TAttImage.cxx:184
 TAttImage.cxx:185
 TAttImage.cxx:186
 TAttImage.cxx:187
 TAttImage.cxx:188
 TAttImage.cxx:189
 TAttImage.cxx:190
 TAttImage.cxx:191
 TAttImage.cxx:192
 TAttImage.cxx:193
 TAttImage.cxx:194
 TAttImage.cxx:195
 TAttImage.cxx:196
 TAttImage.cxx:197
 TAttImage.cxx:198
 TAttImage.cxx:199
 TAttImage.cxx:200
 TAttImage.cxx:201
 TAttImage.cxx:202
 TAttImage.cxx:203
 TAttImage.cxx:204
 TAttImage.cxx:205
 TAttImage.cxx:206
 TAttImage.cxx:207
 TAttImage.cxx:208
 TAttImage.cxx:209
 TAttImage.cxx:210
 TAttImage.cxx:211
 TAttImage.cxx:212
 TAttImage.cxx:213
 TAttImage.cxx:214
 TAttImage.cxx:215
 TAttImage.cxx:216
 TAttImage.cxx:217
 TAttImage.cxx:218
 TAttImage.cxx:219
 TAttImage.cxx:220
 TAttImage.cxx:221
 TAttImage.cxx:222
 TAttImage.cxx:223
 TAttImage.cxx:224
 TAttImage.cxx:225
 TAttImage.cxx:226
 TAttImage.cxx:227
 TAttImage.cxx:228
 TAttImage.cxx:229
 TAttImage.cxx:230
 TAttImage.cxx:231
 TAttImage.cxx:232
 TAttImage.cxx:233
 TAttImage.cxx:234
 TAttImage.cxx:235
 TAttImage.cxx:236
 TAttImage.cxx:237
 TAttImage.cxx:238
 TAttImage.cxx:239
 TAttImage.cxx:240
 TAttImage.cxx:241
 TAttImage.cxx:242
 TAttImage.cxx:243
 TAttImage.cxx:244
 TAttImage.cxx:245
 TAttImage.cxx:246
 TAttImage.cxx:247
 TAttImage.cxx:248
 TAttImage.cxx:249
 TAttImage.cxx:250
 TAttImage.cxx:251
 TAttImage.cxx:252
 TAttImage.cxx:253
 TAttImage.cxx:254
 TAttImage.cxx:255
 TAttImage.cxx:256
 TAttImage.cxx:257
 TAttImage.cxx:258
 TAttImage.cxx:259
 TAttImage.cxx:260
 TAttImage.cxx:261
 TAttImage.cxx:262
 TAttImage.cxx:263
 TAttImage.cxx:264
 TAttImage.cxx:265
 TAttImage.cxx:266
 TAttImage.cxx:267
 TAttImage.cxx:268
 TAttImage.cxx:269
 TAttImage.cxx:270
 TAttImage.cxx:271
 TAttImage.cxx:272
 TAttImage.cxx:273
 TAttImage.cxx:274
 TAttImage.cxx:275
 TAttImage.cxx:276
 TAttImage.cxx:277
 TAttImage.cxx:278
 TAttImage.cxx:279
 TAttImage.cxx:280
 TAttImage.cxx:281
 TAttImage.cxx:282
 TAttImage.cxx:283
 TAttImage.cxx:284
 TAttImage.cxx:285
 TAttImage.cxx:286
 TAttImage.cxx:287
 TAttImage.cxx:288
 TAttImage.cxx:289
 TAttImage.cxx:290
 TAttImage.cxx:291
 TAttImage.cxx:292
 TAttImage.cxx:293
 TAttImage.cxx:294
 TAttImage.cxx:295
 TAttImage.cxx:296
 TAttImage.cxx:297
 TAttImage.cxx:298
 TAttImage.cxx:299
 TAttImage.cxx:300
 TAttImage.cxx:301
 TAttImage.cxx:302
 TAttImage.cxx:303
 TAttImage.cxx:304
 TAttImage.cxx:305
 TAttImage.cxx:306
 TAttImage.cxx:307
 TAttImage.cxx:308
 TAttImage.cxx:309
 TAttImage.cxx:310
 TAttImage.cxx:311
 TAttImage.cxx:312
 TAttImage.cxx:313
 TAttImage.cxx:314
 TAttImage.cxx:315
 TAttImage.cxx:316
 TAttImage.cxx:317
 TAttImage.cxx:318
 TAttImage.cxx:319
 TAttImage.cxx:320
 TAttImage.cxx:321
 TAttImage.cxx:322
 TAttImage.cxx:323
 TAttImage.cxx:324
 TAttImage.cxx:325
 TAttImage.cxx:326
 TAttImage.cxx:327
 TAttImage.cxx:328
 TAttImage.cxx:329
 TAttImage.cxx:330
 TAttImage.cxx:331
 TAttImage.cxx:332
 TAttImage.cxx:333
 TAttImage.cxx:334
 TAttImage.cxx:335
 TAttImage.cxx:336
 TAttImage.cxx:337
 TAttImage.cxx:338
 TAttImage.cxx:339
 TAttImage.cxx:340
 TAttImage.cxx:341
 TAttImage.cxx:342
 TAttImage.cxx:343
 TAttImage.cxx:344
 TAttImage.cxx:345
 TAttImage.cxx:346
 TAttImage.cxx:347
 TAttImage.cxx:348
 TAttImage.cxx:349
 TAttImage.cxx:350
 TAttImage.cxx:351
 TAttImage.cxx:352
 TAttImage.cxx:353
 TAttImage.cxx:354
 TAttImage.cxx:355
 TAttImage.cxx:356
 TAttImage.cxx:357
 TAttImage.cxx:358
 TAttImage.cxx:359
 TAttImage.cxx:360
 TAttImage.cxx:361
 TAttImage.cxx:362
 TAttImage.cxx:363
 TAttImage.cxx:364
 TAttImage.cxx:365
 TAttImage.cxx:366
 TAttImage.cxx:367
 TAttImage.cxx:368
 TAttImage.cxx:369
 TAttImage.cxx:370
 TAttImage.cxx:371
 TAttImage.cxx:372
 TAttImage.cxx:373
 TAttImage.cxx:374
 TAttImage.cxx:375
 TAttImage.cxx:376
 TAttImage.cxx:377
 TAttImage.cxx:378
 TAttImage.cxx:379
 TAttImage.cxx:380
 TAttImage.cxx:381
 TAttImage.cxx:382
 TAttImage.cxx:383
 TAttImage.cxx:384
 TAttImage.cxx:385
 TAttImage.cxx:386
 TAttImage.cxx:387
 TAttImage.cxx:388
 TAttImage.cxx:389
 TAttImage.cxx:390
 TAttImage.cxx:391
 TAttImage.cxx:392
 TAttImage.cxx:393
 TAttImage.cxx:394
 TAttImage.cxx:395
 TAttImage.cxx:396
 TAttImage.cxx:397
 TAttImage.cxx:398
 TAttImage.cxx:399
 TAttImage.cxx:400
 TAttImage.cxx:401
 TAttImage.cxx:402
 TAttImage.cxx:403
 TAttImage.cxx:404
 TAttImage.cxx:405
 TAttImage.cxx:406
 TAttImage.cxx:407
 TAttImage.cxx:408
 TAttImage.cxx:409
 TAttImage.cxx:410
 TAttImage.cxx:411
 TAttImage.cxx:412
 TAttImage.cxx:413
 TAttImage.cxx:414
 TAttImage.cxx:415
 TAttImage.cxx:416
 TAttImage.cxx:417
 TAttImage.cxx:418
 TAttImage.cxx:419
 TAttImage.cxx:420
 TAttImage.cxx:421
 TAttImage.cxx:422
 TAttImage.cxx:423
 TAttImage.cxx:424
 TAttImage.cxx:425
 TAttImage.cxx:426
 TAttImage.cxx:427
 TAttImage.cxx:428
 TAttImage.cxx:429
 TAttImage.cxx:430
 TAttImage.cxx:431
 TAttImage.cxx:432
 TAttImage.cxx:433
 TAttImage.cxx:434
 TAttImage.cxx:435
 TAttImage.cxx:436
 TAttImage.cxx:437
 TAttImage.cxx:438
 TAttImage.cxx:439
 TAttImage.cxx:440
 TAttImage.cxx:441
 TAttImage.cxx:442
 TAttImage.cxx:443
 TAttImage.cxx:444
 TAttImage.cxx:445
 TAttImage.cxx:446
 TAttImage.cxx:447
 TAttImage.cxx:448
 TAttImage.cxx:449
 TAttImage.cxx:450
 TAttImage.cxx:451
 TAttImage.cxx:452
 TAttImage.cxx:453
 TAttImage.cxx:454
 TAttImage.cxx:455
 TAttImage.cxx:456
 TAttImage.cxx:457
 TAttImage.cxx:458
 TAttImage.cxx:459
 TAttImage.cxx:460
 TAttImage.cxx:461
 TAttImage.cxx:462
 TAttImage.cxx:463
 TAttImage.cxx:464
 TAttImage.cxx:465
 TAttImage.cxx:466
 TAttImage.cxx:467
 TAttImage.cxx:468
 TAttImage.cxx:469
 TAttImage.cxx:470
 TAttImage.cxx:471
 TAttImage.cxx:472
 TAttImage.cxx:473
 TAttImage.cxx:474
 TAttImage.cxx:475
 TAttImage.cxx:476
 TAttImage.cxx:477
 TAttImage.cxx:478
 TAttImage.cxx:479
 TAttImage.cxx:480
 TAttImage.cxx:481
 TAttImage.cxx:482
 TAttImage.cxx:483
 TAttImage.cxx:484
 TAttImage.cxx:485
 TAttImage.cxx:486
 TAttImage.cxx:487
 TAttImage.cxx:488
 TAttImage.cxx:489
 TAttImage.cxx:490
 TAttImage.cxx:491
 TAttImage.cxx:492
 TAttImage.cxx:493
 TAttImage.cxx:494
 TAttImage.cxx:495
 TAttImage.cxx:496
 TAttImage.cxx:497
 TAttImage.cxx:498
 TAttImage.cxx:499
 TAttImage.cxx:500
 TAttImage.cxx:501
 TAttImage.cxx:502
 TAttImage.cxx:503
 TAttImage.cxx:504
 TAttImage.cxx:505
 TAttImage.cxx:506
 TAttImage.cxx:507
 TAttImage.cxx:508
 TAttImage.cxx:509
 TAttImage.cxx:510
 TAttImage.cxx:511
 TAttImage.cxx:512
 TAttImage.cxx:513
 TAttImage.cxx:514
 TAttImage.cxx:515
 TAttImage.cxx:516
 TAttImage.cxx:517
 TAttImage.cxx:518
 TAttImage.cxx:519
 TAttImage.cxx:520
 TAttImage.cxx:521
 TAttImage.cxx:522
 TAttImage.cxx:523
 TAttImage.cxx:524
 TAttImage.cxx:525
 TAttImage.cxx:526
 TAttImage.cxx:527
 TAttImage.cxx:528
 TAttImage.cxx:529
 TAttImage.cxx:530
 TAttImage.cxx:531
 TAttImage.cxx:532
 TAttImage.cxx:533
 TAttImage.cxx:534
 TAttImage.cxx:535
 TAttImage.cxx:536
 TAttImage.cxx:537
 TAttImage.cxx:538
 TAttImage.cxx:539
 TAttImage.cxx:540
 TAttImage.cxx:541
 TAttImage.cxx:542
 TAttImage.cxx:543
 TAttImage.cxx:544
 TAttImage.cxx:545
 TAttImage.cxx:546
 TAttImage.cxx:547
 TAttImage.cxx:548
 TAttImage.cxx:549
 TAttImage.cxx:550
 TAttImage.cxx:551
 TAttImage.cxx:552
 TAttImage.cxx:553
 TAttImage.cxx:554
 TAttImage.cxx:555
 TAttImage.cxx:556
 TAttImage.cxx:557
 TAttImage.cxx:558
 TAttImage.cxx:559
 TAttImage.cxx:560
 TAttImage.cxx:561
 TAttImage.cxx:562
 TAttImage.cxx:563
 TAttImage.cxx:564
 TAttImage.cxx:565
 TAttImage.cxx:566
 TAttImage.cxx:567
 TAttImage.cxx:568
 TAttImage.cxx:569
 TAttImage.cxx:570
 TAttImage.cxx:571
 TAttImage.cxx:572
 TAttImage.cxx:573
 TAttImage.cxx:574
 TAttImage.cxx:575
 TAttImage.cxx:576
 TAttImage.cxx:577
 TAttImage.cxx:578
 TAttImage.cxx:579
 TAttImage.cxx:580
 TAttImage.cxx:581
 TAttImage.cxx:582
 TAttImage.cxx:583
 TAttImage.cxx:584
 TAttImage.cxx:585
 TAttImage.cxx:586
 TAttImage.cxx:587
 TAttImage.cxx:588
 TAttImage.cxx:589
 TAttImage.cxx:590
 TAttImage.cxx:591
 TAttImage.cxx:592
 TAttImage.cxx:593
 TAttImage.cxx:594
 TAttImage.cxx:595
 TAttImage.cxx:596
 TAttImage.cxx:597
 TAttImage.cxx:598
 TAttImage.cxx:599
 TAttImage.cxx:600
 TAttImage.cxx:601
 TAttImage.cxx:602
 TAttImage.cxx:603
 TAttImage.cxx:604
 TAttImage.cxx:605
 TAttImage.cxx:606
 TAttImage.cxx:607
 TAttImage.cxx:608
 TAttImage.cxx:609
 TAttImage.cxx:610
 TAttImage.cxx:611
 TAttImage.cxx:612
 TAttImage.cxx:613
 TAttImage.cxx:614
 TAttImage.cxx:615
 TAttImage.cxx:616
 TAttImage.cxx:617
 TAttImage.cxx:618
 TAttImage.cxx:619
 TAttImage.cxx:620
 TAttImage.cxx:621
 TAttImage.cxx:622
 TAttImage.cxx:623
 TAttImage.cxx:624
 TAttImage.cxx:625
 TAttImage.cxx:626
 TAttImage.cxx:627
 TAttImage.cxx:628
 TAttImage.cxx:629
 TAttImage.cxx:630
 TAttImage.cxx:631
 TAttImage.cxx:632
 TAttImage.cxx:633
 TAttImage.cxx:634
 TAttImage.cxx:635
 TAttImage.cxx:636
 TAttImage.cxx:637
 TAttImage.cxx:638
 TAttImage.cxx:639
 TAttImage.cxx:640
 TAttImage.cxx:641
 TAttImage.cxx:642
 TAttImage.cxx:643
 TAttImage.cxx:644
 TAttImage.cxx:645
 TAttImage.cxx:646
 TAttImage.cxx:647
 TAttImage.cxx:648
 TAttImage.cxx:649
 TAttImage.cxx:650
 TAttImage.cxx:651
 TAttImage.cxx:652
 TAttImage.cxx:653
 TAttImage.cxx:654
 TAttImage.cxx:655
 TAttImage.cxx:656
 TAttImage.cxx:657
 TAttImage.cxx:658
 TAttImage.cxx:659
 TAttImage.cxx:660
 TAttImage.cxx:661
 TAttImage.cxx:662
 TAttImage.cxx:663
 TAttImage.cxx:664
 TAttImage.cxx:665
 TAttImage.cxx:666
 TAttImage.cxx:667
 TAttImage.cxx:668
 TAttImage.cxx:669
 TAttImage.cxx:670
 TAttImage.cxx:671
 TAttImage.cxx:672
 TAttImage.cxx:673
 TAttImage.cxx:674
 TAttImage.cxx:675
 TAttImage.cxx:676
 TAttImage.cxx:677
 TAttImage.cxx:678
 TAttImage.cxx:679
 TAttImage.cxx:680
 TAttImage.cxx:681
 TAttImage.cxx:682
 TAttImage.cxx:683
 TAttImage.cxx:684
 TAttImage.cxx:685
 TAttImage.cxx:686
 TAttImage.cxx:687
 TAttImage.cxx:688
 TAttImage.cxx:689
 TAttImage.cxx:690
 TAttImage.cxx:691
 TAttImage.cxx:692
 TAttImage.cxx:693
 TAttImage.cxx:694