Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TAttImage.cxx
Go to the documentation of this file.
1 // @(#)root/graf:$Id$
2 // Author: Reiner Rohlfs 24/03/02
3 
4 /*************************************************************************
5  * Copyright (C) 2001-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TAttImage
13 \ingroup BasicGraphics
14 \ingroup GraphicsAtt
15 
16 TImage attributes.
17 
18 Image attributes are:
19 
20 - Image Quality (see EImageQuality for the list of qualities)
21 - Compression defines the compression rate of the color data in the
22  internal image structure. Speed and memory depends
23  on this rate, but not the image display itself
24  0: no compression; 100: max compression
25 - Radio Flag: kTRUE the x/y radio of the displayed image is always
26  identical to the original image kFALSE the x and y size of the displayed
27  image depends on the size of the pad
28 - Palette: Defines the conversion from a pixel value to the
29  screen color
30 
31 This class is used (in general by secondary inheritance)
32 by some other classes (image display).
33 */
34 
35 /** \class TImagePalette
36 \ingroup BasicGraphics
37 
38 A class to define a conversion from pixel values to pixel color.
39 
40 A Palette is defined by some anchor points. Each anchor point has
41 a value between 0 and 1 and a color. An image has to be normalized
42 and the values between the anchor points are interpolated.
43 All member variables are public and can be directly manipulated.
44 In most cases the default operator will be used to create a
45 TImagePalette. In this case the member arrays have to be allocated
46 by an application and will be deleted in the destructor of this
47 class.
48 
49 We provide few predefined palettes:
50 
51 - gHistImagePalette - palette used in TH2::Draw("col")
52 - gWebImagePalette
53  The web palette is a set of 216 colors that will not dither or
54  shift on PCs or Macs. Browsers use this built-in palette when
55  they need to render colors on monitors with only 256 colors
56  (also called 8-bit color monitors).
57  The 6x6x6 web palette provides very quick color index lookup
58  and can be used for good quality conversion of images into
59  2-D histograms.
60 - TImagePalette(Int_t ncolors, Int_t *colors)
61  if ncolors <= 0 a default palette (see below) of 50 colors
62  is defined.
63 
64 if ncolors == 1 && colors == 0, then a Rainbow Palette is created.
65 
66 if ncolors > 50 and colors=0, the DeepSea palette is used.
67 (see TStyle::CreateGradientColorTable for more details)
68 
69 if ncolors > 0 and colors = 0, the default palette is used with a maximum of ncolors.
70 
71 The default palette defines:
72 - index 0->9 : grey colors from light to dark grey
73 - index 10->19 : "brown" colors
74 - index 20->29 : "blueish" colors
75 - index 30->39 : "redish" colors
76 - index 40->49 : basic colors
77 */
78 
79 /** \class TPaletteEditor
80 \ingroup BasicGraphics
81 
82 Edit the palette via a GUI.
83 
84 This class provides a way to edit the palette via a GUI.
85 */
86 
87 
88 #include "TAttImage.h"
89 #include "TROOT.h"
90 #include "TPluginManager.h"
91 #include "Riostream.h"
92 #include "TColor.h"
93 #include "TMath.h"
94 #include "TStyle.h"
95 
96 
97 ClassImp(TPaletteEditor);
98 ClassImp(TAttImage);
99 ClassImp(TImagePalette);
100 
101 
102 // definition of a default palette
103 const Int_t kNUM_DEFAULT_COLORS = 12;
104 static UShort_t gAlphaDefault[kNUM_DEFAULT_COLORS] = {
105  0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
106  0xffff, 0xffff, 0xffff, 0xffff
107 };
108 
109 static UShort_t gRedDefault[kNUM_DEFAULT_COLORS] = {
110  0x0000, 0x0000, 0x7000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff,
111  0x7000, 0x8000, 0xffff, 0xffff
112 };
113 
114 static UShort_t gGreenDefault[kNUM_DEFAULT_COLORS] = {
115  0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0000,
116  0x0000, 0x8000, 0xffff, 0xffff
117 };
118 
119 static UShort_t gBlueDefault[kNUM_DEFAULT_COLORS] = {
120  0x0000, 0x0000, 0x7000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000,
121  0x0000, 0xa000, 0xffff, 0xffff
122 };
123 
124 
125 //////////////////////////// Web Palette ///////////////////////////////////////
126 static UShort_t gWebBase[6] = { 0, 51, 102, 153, 204, 255 };
127 
128 class TWebPalette : public TImagePalette {
129 
130 private:
131  Int_t fCLUT[6][6][6]; // Color LookUp Table
132 
133 public:
134  TWebPalette() : TImagePalette() {
135  int i = 0;
136  fNumPoints = 216;
137  fPoints = new Double_t[216];
138  fColorRed = new UShort_t[216];
139  fColorBlue = new UShort_t[216];
140  fColorGreen = new UShort_t[216];
141  fColorAlpha = new UShort_t[216];
142 
143  for (i = 0; i < 214; i++) {
144  fPoints[i + 1] = (double)i/213;
145  }
146  fPoints[0] = 0;
147  fPoints[215] = 1;
148 
149  i = 0;
150  for (int r = 0; r < 6; r++) {
151  for (int g = 0; g < 6; g++) {
152  for (int b = 0; b < 6; b++) {
153  fColorRed[i] = gWebBase[r] << 8;
154  fColorGreen[i] = gWebBase[g] << 8;
155  fColorBlue[i] = gWebBase[b] << 8;
156  fColorAlpha[i] = 0xffff;
157  fCLUT[r][g][b] = i;
158  i++;
159  }
160  }
161  }
162  }
163 
164  Int_t FindColor(UShort_t r, UShort_t g, UShort_t b) {
165  Int_t ri = TMath:: BinarySearch(6, (const Short_t*)gWebBase, (Short_t)r);
166  Int_t gi = TMath:: BinarySearch(6, (const Short_t*)gWebBase, (Short_t)g);
167  Int_t bi = TMath:: BinarySearch(6, (const Short_t*)gWebBase, (Short_t)b);
168  return fCLUT[ri][gi][bi];
169  }
170 
171  Int_t *GetRootColors() {
172  static Int_t *gRootColors = 0;
173  if (gRootColors) return gRootColors;
174 
175  gRootColors = new Int_t[216];
176 
177  int i = 0;
178  for (int r = 0; r < 6; r++) {
179  for (int g = 0; g < 6; g++) {
180  for (int b = 0; b < 6; b++) {
181  gRootColors[i] = TColor::GetColor(gWebBase[r], gWebBase[g], gWebBase[b]);
182  i++;
183  }
184  }
185  }
186  return gRootColors;
187  }
188 };
189 
190 TImagePalette *gWebImagePalette = new TWebPalette();
191 
192 
193 ////////////////////////////// Hist Palette ////////////////////////////////////
194 static Double_t gDefHistP[50] = {
195  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,
196  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,
197  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,
198  0.84,0.86,0.88,0.90,0.92,0.94,0.96,0.98 };
199 
200 static UShort_t gDefHistR[50] = {
201  242,229,204,178,153,127,102,76,192,204,204,193,186,178,183,173,155,135,
202  175,132,89,137,130,173,122, 117,104,109,124,127,170,89,211,221,188,198,
203  191,170,165,147,206,211,255,0,255,255,0,0,53,0 };
204 
205 static UShort_t gDefHistG[50] = {
206  242,229,204,178,153,127,102,76,182,198,198,191,181,165,163,153,142,102,
207  206,193,211,168,158,188,142,137,130,122,153,127,165,84,206,186,158,153,
208  130,142,119,104,94,89,0,255,0,255,0,255,53,0 };
209 
210 static UShort_t gDefHistB[50] = {
211  242,229,204,178,153,127,102,76,172,170,170,168,163,150,155,140,130,86,
212  198,163,84,160,140,198,153,145,150,132,209,155,191,216,135,135,130,124,
213  119,147,122,112,96,84,0,255,255,0,255,0,53,0 };
214 
215 static UShort_t gDefHistA[50] = {
216  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
217  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
218  255,255,255,255,255,255,255,255,255,255,255,255,255,255 };
219 
220 static Int_t gDefHistRoot[50] = {
221  19,18,17,16,15,14,13,12,11,20,21,22,23,24,25,26,27,28,29,30, 8,
222  31,32,33,34,35,36,37,38,39,40, 9, 41,42,43,44,45,47,48,49,46,50, 2,
223  7, 6, 5, 4, 3, 112,1};
224 
225 
226 class TDefHistImagePalette : public TImagePalette {
227 
228 public:
229  TDefHistImagePalette() : TImagePalette() {
230  fNumPoints = 50;
231  fPoints = gDefHistP;
232  fColorRed = gDefHistR;
233  fColorGreen = gDefHistG;
234  fColorBlue = gDefHistB;
235  fColorAlpha = gDefHistA;
236 
237  for (int i = 0; i<50; i++) {
238  fColorRed[i] = fColorRed[i] << 8;
239  fColorGreen[i] = fColorGreen[i] << 8;
240  fColorBlue[i] = fColorBlue[i] << 8;
241  fColorAlpha[i] = fColorAlpha[i] << 8;
242  }
243  }
244 
245  Int_t *GetRootColors() { return gDefHistRoot; }
246 };
247 
248 TImagePalette *gHistImagePalette = new TDefHistImagePalette();
249 
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 /// Constructor.
253 
254 TPaletteEditor::TPaletteEditor(TAttImage *attImage, UInt_t, UInt_t)
255 {
256  fAttImage = attImage;
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// Closes the window and deletes itself.
261 
262 void TPaletteEditor::CloseWindow()
263 {
264  fAttImage->EditorClosed();
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// Default constructor, sets all pointers to 0.
269 
270 TImagePalette::TImagePalette()
271 {
272  fNumPoints = 0;
273  fPoints = 0;
274  fColorRed = 0;
275  fColorGreen = 0;
276  fColorBlue = 0;
277  fColorAlpha = 0;
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Constructor for a palette with numPoints anchor points.
282 /// It allocates the memory but does not set any colors.
283 
284 TImagePalette::TImagePalette(UInt_t numPoints)
285 {
286  fNumPoints = numPoints;
287  fPoints = new Double_t[fNumPoints];
288  fColorRed = new UShort_t[fNumPoints];
289  fColorGreen = new UShort_t[fNumPoints];
290  fColorBlue = new UShort_t[fNumPoints];
291  fColorAlpha = new UShort_t[fNumPoints];
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// Copy constructor.
296 
297 TImagePalette::TImagePalette(const TImagePalette &palette) : TObject(palette)
298 {
299  fNumPoints = palette.fNumPoints;
300 
301  fPoints = new Double_t[fNumPoints];
302  memcpy(fPoints, palette.fPoints, fNumPoints * sizeof(Double_t));
303 
304  fColorRed = new UShort_t[fNumPoints];
305  fColorGreen = new UShort_t[fNumPoints];
306  fColorBlue = new UShort_t[fNumPoints];
307  fColorAlpha = new UShort_t[fNumPoints];
308  memcpy(fColorRed, palette.fColorRed, fNumPoints * sizeof(UShort_t));
309  memcpy(fColorGreen, palette.fColorGreen, fNumPoints * sizeof(UShort_t));
310  memcpy(fColorBlue, palette.fColorBlue, fNumPoints * sizeof(UShort_t));
311  memcpy(fColorAlpha, palette.fColorAlpha, fNumPoints * sizeof(UShort_t));
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Creates palette in the same way as TStyle::SetPalette
316 
317 TImagePalette::TImagePalette(Int_t ncolors, Int_t *colors)
318 {
319  fNumPoints = 0;
320  fPoints = 0;
321  fColorRed = 0;
322  fColorGreen = 0;
323  fColorBlue = 0;
324  fColorAlpha = 0;
325 
326  Int_t i;
327  static Int_t palette[50] = {19,18,17,16,15,14,13,12,11,20,
328  21,22,23,24,25,26,27,28,29,30, 8,
329  31,32,33,34,35,36,37,38,39,40, 9,
330  41,42,43,44,45,47,48,49,46,50, 2,
331  7, 6, 5, 4, 3, 112,1};
332  TColor *col = 0;
333  Float_t step = 0;
334  // set default palette (pad type)
335  if (ncolors <= 0) {
336  ncolors = 50;
337  fNumPoints = ncolors;
338  step = 1./fNumPoints;
339  fPoints = new Double_t[fNumPoints];
340  fColorRed = new UShort_t[fNumPoints];
341  fColorGreen = new UShort_t[fNumPoints];
342  fColorBlue = new UShort_t[fNumPoints];
343  fColorAlpha = new UShort_t[fNumPoints];
344  for (i=0;i<ncolors;i++) {
345  col = gROOT->GetColor(palette[i]);
346  fPoints[i] = i*step;
347  if (col) {
348  fColorRed[i] = UShort_t(col->GetRed()*255) << 8;
349  fColorGreen[i] = UShort_t(col->GetGreen()*255) << 8;
350  fColorBlue[i] = UShort_t(col->GetBlue()*255) << 8;
351  }
352  fColorAlpha[i] = 65280;
353  }
354  return;
355  }
356 
357  // set Pretty Palette Spectrum Violet->Red
358  if (ncolors == 1 && colors == 0) {
359  ncolors = 50;
360  fNumPoints = ncolors;
361  step = 1./fNumPoints;
362  fPoints = new Double_t[fNumPoints];
363  fColorRed = new UShort_t[fNumPoints];
364  fColorGreen = new UShort_t[fNumPoints];
365  fColorBlue = new UShort_t[fNumPoints];
366  fColorAlpha = new UShort_t[fNumPoints];
367 
368  // 0 point is white
369  fPoints[0] = 0;
370  fColorRed[0] = 255 << 8;
371  fColorGreen[0] = 255 << 8;
372  fColorBlue[0] = 255 << 8;
373  fColorAlpha[0] = 0;
374 
375  for (i=1;i<ncolors;i++) {
376  col = gROOT->GetColor(51+i);
377  fPoints[i] = i*step;
378  if (col) {
379  fColorRed[i] = UShort_t(col->GetRed()*255) << 8;
380  fColorGreen[i] = UShort_t(col->GetGreen()*255) << 8;
381  fColorBlue[i] = UShort_t(col->GetBlue()*255) << 8;
382  }
383  fColorAlpha[i] = 65280;
384  }
385  return;
386  }
387 
388  // set DeepSea palette
389  if (colors == 0 && ncolors > 50) {
390  static const Int_t nRGBs = 5;
391  static Float_t stops[nRGBs] = { 0.00, 0.34, 0.61, 0.84, 1.00 };
392  static Float_t red[nRGBs] = { 0.00, 0.09, 0.18, 0.09, 0.00 };
393  static Float_t green[nRGBs] = { 0.01, 0.02, 0.39, 0.68, 0.97 };
394  static Float_t blue[nRGBs] = { 0.17, 0.39, 0.62, 0.79, 0.97 };
395  fNumPoints = nRGBs;
396  fPoints = new Double_t[fNumPoints];
397  fColorRed = new UShort_t[fNumPoints];
398  fColorGreen = new UShort_t[fNumPoints];
399  fColorBlue = new UShort_t[fNumPoints];
400  fColorAlpha = new UShort_t[fNumPoints];
401  for (i=0;i<(int)fNumPoints;i++) {
402  fPoints[i] = stops[i];
403  fColorRed[i] = UShort_t(red[i]*255) << 8;
404  fColorGreen[i] = UShort_t(green[i]*255) << 8;
405  fColorBlue[i] = UShort_t(blue[i]*255) << 8;
406  fColorAlpha[i] = 65280;
407  }
408  return;
409  }
410 
411  // set user defined palette
412  if (colors) {
413  fNumPoints = ncolors;
414  step = 1./fNumPoints;
415  fPoints = new Double_t[fNumPoints];
416  fColorRed = new UShort_t[fNumPoints];
417  fColorGreen = new UShort_t[fNumPoints];
418  fColorBlue = new UShort_t[fNumPoints];
419  fColorAlpha = new UShort_t[fNumPoints];
420  for (i=0;i<ncolors;i++) {
421  fPoints[i] = i*step;
422  col = gROOT->GetColor(colors[i]);
423  if (col) {
424  fColorRed[i] = UShort_t(col->GetRed()*255) << 8;
425  fColorGreen[i] = UShort_t(col->GetGreen()*255) << 8;
426  fColorBlue[i] = UShort_t(col->GetBlue()*255) << 8;
427  fColorAlpha[i] = 65280;
428  } else {
429  fColorRed[i] = 0;
430  fColorGreen[i] = 0;
431  fColorBlue[i] = 0;
432  fColorAlpha[i] = 0;
433  }
434  }
435  }
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 /// Destructor.
440 
441 TImagePalette::~TImagePalette()
442 {
443  delete [] fPoints;
444  delete [] fColorRed;
445  delete [] fColorGreen;
446  delete [] fColorBlue;
447  delete [] fColorAlpha;
448 }
449 
450 ////////////////////////////////////////////////////////////////////////////////
451 /// Assignment operator.
452 
453 TImagePalette &TImagePalette::operator=(const TImagePalette &palette)
454 {
455  if (this != &palette) {
456  fNumPoints = palette.fNumPoints;
457 
458  delete [] fPoints;
459  fPoints = new Double_t[fNumPoints];
460  memcpy(fPoints, palette.fPoints, fNumPoints * sizeof(Double_t));
461 
462  delete [] fColorRed;
463  fColorRed = new UShort_t[fNumPoints];
464  memcpy(fColorRed, palette.fColorRed, fNumPoints * sizeof(UShort_t));
465 
466  delete [] fColorGreen;
467  fColorGreen = new UShort_t[fNumPoints];
468  memcpy(fColorGreen, palette.fColorGreen, fNumPoints * sizeof(UShort_t));
469 
470  delete [] fColorBlue;
471  fColorBlue = new UShort_t[fNumPoints];
472  memcpy(fColorBlue, palette.fColorBlue, fNumPoints * sizeof(UShort_t));
473 
474  delete [] fColorAlpha;
475  fColorAlpha = new UShort_t[fNumPoints];
476  memcpy(fColorAlpha, palette.fColorAlpha, fNumPoints * sizeof(UShort_t));
477  }
478 
479  return *this;
480 }
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// Returns an index of the closest color
484 
485 Int_t TImagePalette::FindColor(UShort_t r, UShort_t g, UShort_t b)
486 {
487  Int_t ret = 0;
488  UInt_t d = 10000;
489  UInt_t min = 10000;
490 
491  for (UInt_t i = 0; i < fNumPoints; i++) {
492  d = TMath::Abs(r - ((fColorRed[i] & 0xff00) >> 8)) +
493  TMath::Abs(g - ((fColorGreen[i] & 0xff00) >> 8)) +
494  TMath::Abs(b - ((fColorBlue[i] & 0xff00) >> 8));
495  if (d < min) {
496  min = d;
497  ret = i;
498  }
499  }
500  return ret;
501 }
502 
503 ////////////////////////////////////////////////////////////////////////////////
504 /// Returns a list of ROOT colors. Could be used to set histogram palette.
505 /// See also TStyle::SetPalette
506 
507 Int_t *TImagePalette::GetRootColors()
508 {
509  static Int_t *gRootColors = 0;
510  if (gRootColors) return gRootColors;
511 
512  gRootColors = new Int_t[fNumPoints];
513 
514  for (UInt_t i = 0; i < fNumPoints; i++) {
515  gRootColors[i] = TColor::GetColor(fColorRed[i], fColorGreen[i], fColorBlue[i]);
516  }
517  return gRootColors;
518 }
519 
520 ////////////////////////////////////////////////////////////////////////////////
521 /// TAttImage default constructor.
522 /// Calls ResetAttImage to set the attributes to a default state.
523 
524 TAttImage::TAttImage()
525 {
526  ResetAttImage();
527  fPaletteEditor = 0;
528  fPaletteEnabled = kTRUE;
529 }
530 
531 ////////////////////////////////////////////////////////////////////////////////
532 /// TAttImage normal constructor.
533 /// Image attributes are taken from the argument list
534 ///
535 /// \param[in] lquality must be one of EImageQuality (kImgDefault is same as
536 /// kImgGood in the current implementation)
537 /// \param[in] lcompression defines the compression rate of the color data in the
538 /// image. Speed and memory depends on this rate, but not
539 /// the image display itself
540 /// 0: no compression; 100: max compression
541 /// \param[in] constRatio keeps the aspect ratio of the image constant on the
542 /// screen (in pixel units)
543 
544 TAttImage::TAttImage(EImageQuality lquality, UInt_t lcompression,
545  Bool_t constRatio)
546 {
547  ResetAttImage();
548 
549  fImageQuality = lquality;
550  fImageCompression = (lcompression > 100) ? 100 : lcompression;
551  fConstRatio = constRatio;
552  fPaletteEditor = 0;
553  fPaletteEnabled = kTRUE;
554 }
555 
556 ////////////////////////////////////////////////////////////////////////////////
557 /// TAttImage destructor.
558 
559 TAttImage::~TAttImage()
560 {
561  delete fPaletteEditor;
562 }
563 
564 ////////////////////////////////////////////////////////////////////////////////
565 /// Copy this image attributes to a new attimage.
566 
567 void TAttImage::Copy(TAttImage &attimage) const
568 {
569  attimage.fImageQuality = fImageQuality;
570  attimage.fImageCompression = fImageCompression;
571  attimage.fConstRatio = fConstRatio;
572  attimage.fPalette = fPalette;
573 }
574 
575 ////////////////////////////////////////////////////////////////////////////////
576 /// Reset this image attributes to default values.
577 /// Default values are:
578 ///
579 /// - quality: kImgPoor, (no smoothing while the image is zoomed)
580 /// - compression: 0 (no compression)
581 /// - constRatio: kTRUE
582 /// - palette: a default rainbow palette
583 
584 void TAttImage::ResetAttImage(Option_t *)
585 {
586  fImageQuality = kImgPoor;
587  fImageCompression = 0;
588  fConstRatio = kTRUE;
589 
590  // set the default palette
591  delete [] fPalette.fPoints;
592  delete [] fPalette.fColorRed;
593  delete [] fPalette.fColorGreen;
594  delete [] fPalette.fColorBlue;
595  delete [] fPalette.fColorAlpha;
596 
597  fPalette.fNumPoints = kNUM_DEFAULT_COLORS;
598 
599  fPalette.fColorRed = new UShort_t [kNUM_DEFAULT_COLORS];
600  fPalette.fColorGreen = new UShort_t [kNUM_DEFAULT_COLORS];
601  fPalette.fColorBlue = new UShort_t [kNUM_DEFAULT_COLORS];
602  fPalette.fColorAlpha = new UShort_t [kNUM_DEFAULT_COLORS];
603  fPalette.fPoints = new Double_t [kNUM_DEFAULT_COLORS];
604 
605  memcpy(fPalette.fColorRed, gRedDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
606  memcpy(fPalette.fColorGreen, gGreenDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
607  memcpy(fPalette.fColorBlue, gBlueDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
608  memcpy(fPalette.fColorAlpha, gAlphaDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
609 
610  for (Int_t point = 0; point < kNUM_DEFAULT_COLORS - 2; point++)
611  fPalette.fPoints[point + 1] = (double)point / (kNUM_DEFAULT_COLORS - 3);
612  fPalette.fPoints[0] = 0;
613  fPalette.fPoints[kNUM_DEFAULT_COLORS - 1] = 1;
614 }
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// Save image attributes as C++ statement(s) on output stream, but
618 /// not the palette.
619 
620 void TAttImage::SaveImageAttributes(std::ostream &out, const char *name,
621  EImageQuality qualdef,
622  UInt_t comprdef, Bool_t constRatiodef)
623 {
624  if (fImageQuality != qualdef) {
625  out<<" "<<name<<"->SetImageQuality("<<fImageQuality<<");"<<std::endl;
626  }
627  if (fImageCompression != comprdef) {
628  out<<" "<<name<<"->SetImageCompression("<<fImageCompression<<");"<<std::endl;
629  }
630  if (fConstRatio != constRatiodef) {
631  out<<" "<<name<<"->SetConstRatio("<<fConstRatio<<");"<<std::endl;
632  }
633 }
634 
635 ////////////////////////////////////////////////////////////////////////////////
636 /// Set (constRatio = kTRUE) or unset (constRadio = kFALSE) the ratio flag.
637 /// The aspect ratio of the image on the screen is constant if the ratio
638 /// flag is set. That means one image pixel is always a square on the screen
639 /// independent of the pad size and of the size of the zoomed area.
640 
641 void TAttImage::SetConstRatio(Bool_t constRatio)
642 {
643  fConstRatio = constRatio;
644 }
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 /// Set a new palette for the image. If palette == 0 a default
648 /// rainbow color palette is used.
649 
650 void TAttImage::SetPalette(const TImagePalette *palette)
651 {
652  if (palette)
653  fPalette = *palette;
654  else {
655  // set default palette
656 
657  delete [] fPalette.fPoints;
658  delete [] fPalette.fColorRed;
659  delete [] fPalette.fColorGreen;
660  delete [] fPalette.fColorBlue;
661  delete [] fPalette.fColorAlpha;
662 
663  fPalette.fNumPoints = kNUM_DEFAULT_COLORS;
664 
665  fPalette.fColorRed = new UShort_t [kNUM_DEFAULT_COLORS];
666  fPalette.fColorGreen = new UShort_t [kNUM_DEFAULT_COLORS];
667  fPalette.fColorBlue = new UShort_t [kNUM_DEFAULT_COLORS];
668  fPalette.fColorAlpha = new UShort_t [kNUM_DEFAULT_COLORS];
669  fPalette.fPoints = new Double_t [kNUM_DEFAULT_COLORS];
670 
671  memcpy(fPalette.fColorRed, gRedDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
672  memcpy(fPalette.fColorGreen, gGreenDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
673  memcpy(fPalette.fColorBlue, gBlueDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
674  memcpy(fPalette.fColorAlpha, gAlphaDefault, kNUM_DEFAULT_COLORS * sizeof(UShort_t));
675 
676  for (Int_t point = 0; point < kNUM_DEFAULT_COLORS - 2; point++)
677  fPalette.fPoints[point + 1] = (double)point / (kNUM_DEFAULT_COLORS - 3);
678  fPalette.fPoints[0] = 0;
679  fPalette.fPoints[kNUM_DEFAULT_COLORS - 1] = 1;
680  }
681 }
682 
683 ////////////////////////////////////////////////////////////////////////////////
684 /// Factory method to creates an image palette of a specific typ
685 ///
686 /// Create a new palette
687 ///
688 /// This creates a new TImagePalette based on the
689 /// option specified in the parameter. The supported options are:
690 ///
691 /// - "col" - color palette similar in TStyle (i.e. use for "col" option)
692 /// - "web" - color palette similar to gWebImagePalette
693 /// - "hist" - color palette similar to gHistImagePalette
694 ///
695 /// \param opts the type of palette to create
696 ///
697 /// Ownership of the returned object transfers to the caller.
698 ///
699 /// \retval new palette
700 /// \retval nullptr - option does not exist
701 
702 TImagePalette* TImagePalette::Create(Option_t* opts)
703 {
704  TImagePalette* pPalette = nullptr;
705 
706  TString option(opts);
707  if (option.Contains("col", TString::kIgnoreCase)) {
708  // Define the new palette using the current palette in TStyle
709  pPalette = new TImagePalette(gStyle->GetNumberOfColors());
710  Double_t step = 1./(pPalette->fNumPoints-1);
711 
712  for (UInt_t i=0; i<pPalette->fNumPoints; ++i) {
713  TColor* pColor = gROOT->GetColor(gStyle->GetColorPalette(i));
714  pPalette->fPoints[i] = i*step;
715  if (pColor) {
716  pPalette->fColorRed[i] = UShort_t(pColor->GetRed()*255) << 8;
717  pPalette->fColorGreen[i] = UShort_t(pColor->GetGreen()*255) << 8;
718  pPalette->fColorBlue[i] = UShort_t(pColor->GetBlue()*255) << 8;
719  }
720  pPalette->fColorAlpha[i] = 0xff00;
721  }
722  } else if (option.Contains("web", TString::kIgnoreCase)) {
723  pPalette = new TDefHistImagePalette();
724  } else if (option.Contains("hist", TString::kIgnoreCase)) {
725  pPalette = new TWebPalette();
726  }
727 
728  return pPalette;
729 }
730 
731 ////////////////////////////////////////////////////////////////////////////////
732 /// Factory method to creates an image palette for histogram plotting.
733 ///
734 /// Creates a "col" palette with correct number of contours
735 ///
736 /// The behavior is similar to the TImagePalette::Create() method with
737 /// the "col" option. The difference here is that the palette will only
738 /// contain a specific number of colors. This method is used to create
739 /// the palette used in the "col2" and "colz2" options. It handles the
740 /// color selection for contours.
741 ///
742 /// \param ncontours number of contours
743 ///
744 /// Ownership of the returned object transfers to the caller.
745 ///
746 /// \return new palette
747 
748 TImagePalette* TImagePalette::CreateCOLPalette(Int_t ncontours)
749 {
750  Int_t ncolors = gStyle->GetNumberOfColors();
751  Int_t minColor = 0;
752  Double_t scale = 1;
753  if (ncontours != 0 ) {
754  minColor = (0.99*ncolors)/ncontours;
755  scale = static_cast<Double_t>(ncolors)/ncontours;
756  ncolors = ncontours;
757  }
758 
759  // Define the new palette using the current palette in TStyle
760  auto pPalette = new TImagePalette(ncolors);
761  Double_t step = 1./(pPalette->fNumPoints-1);
762 
763  for (UInt_t i=0; i<pPalette->fNumPoints; ++i) {
764  TColor* pColor = gROOT->GetColor(gStyle->GetColorPalette(minColor + i*scale));
765  pPalette->fPoints[i] = i*step;
766  if (pColor) {
767  pPalette->fColorRed[i] = UShort_t(pColor->GetRed()*255) << 8;
768  pPalette->fColorGreen[i] = UShort_t(pColor->GetGreen()*255) << 8;
769  pPalette->fColorBlue[i] = UShort_t(pColor->GetBlue()*255) << 8;
770  pPalette->fColorAlpha[i] = UShort_t(pColor->GetAlpha()*255) << 8;
771  }
772  }
773 
774  return pPalette;
775 }
776 
777 ////////////////////////////////////////////////////////////////////////////////
778 /// Opens a GUI to edit the color palette.
779 
780 void TAttImage::StartPaletteEditor()
781 {
782  if (fPaletteEditor == 0) {
783  TPluginHandler *h;
784 
785  if ((h = gROOT->GetPluginManager()->FindHandler("TPaletteEditor"))) {
786  if (h->LoadPlugin() == -1)
787  return;
788  fPaletteEditor = (TPaletteEditor *) h->ExecPlugin(3, this, 80, 25);
789  }
790  }
791 }