From 99e544e741fd8992fb8c590714a729d6a39f79f1 Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Fri, 26 Oct 2007 10:59:06 +0000
Subject: [PATCH] From valeriy: o TASImage.h, TASImage.cxx, TImage.h   new
 method was introduced GetVecArray   Returns a pointer to internal array[width
 x height] of double values [0, 1]   This array is directly accessible. That
 allows to manipulate/change the image.

o TASImage::GetArray
  Fix to return correct array (previously it was truncated when
  x, y shift position were not zeros).

o TASImage::GetPolygonSpans
  Fix segv when producing images from some Rene's macro.

o fix segv. when image is drawn in canvas and canvas resized.

o TAttImage.cxx
  For "Pretty Palette with a Spectrum Violet->Red" set
  white color to zeros.


git-svn-id: http://root.cern.ch/svn/root/trunk@20500 27541ba8-7e3a-0410-8455-c3a389f83636
---
 asimage/inc/TASImage.h   |  1 +
 asimage/src/TASImage.cxx | 86 ++++++++++++++++++++++++----------------
 graf/inc/TImage.h        |  1 +
 graf/src/TAttImage.cxx   | 30 +++++++++++++-
 4 files changed, 82 insertions(+), 36 deletions(-)

diff --git a/asimage/inc/TASImage.h b/asimage/inc/TASImage.h
index 30c8eadbb72..f25f890ef74 100644
--- a/asimage/inc/TASImage.h
+++ b/asimage/inc/TASImage.h
@@ -206,6 +206,7 @@ public:
    TArrayD   *GetArray(UInt_t w = 0, UInt_t h = 0, TImagePalette *pal = gWebImagePalette);
    UInt_t    *GetArgbArray();
    UInt_t    *GetRgbaArray();
+   Double_t  *GetVecArray();
    UInt_t    *GetScanline(UInt_t y);
    void       GetImageBuffer(char **buffer, int *size, EImageFileTypes type = TImage::kPng);
    Bool_t     SetImageBuffer(char **buffer, EImageFileTypes type = TImage::kPng);
diff --git a/asimage/src/TASImage.cxx b/asimage/src/TASImage.cxx
index 7baaebb1242..adb95d3f6aa 100644
--- a/asimage/src/TASImage.cxx
+++ b/asimage/src/TASImage.cxx
@@ -1348,18 +1348,22 @@ void TASImage::Paint(Option_t *option)
          if (!fScaledImage) {
             fScaledImage = (TASImage*)TImage::Create();
 
-            if ((fImage->width != fZoomWidth) || (fImage->height != fZoomHeight)) {
+            if (fZoomWidth && fZoomHeight && 
+                ((fImage->width != fZoomWidth) || (fImage->height != fZoomHeight))) {
                // zoom and scale image
                ASImage *tmpImage = 0;
+
                tmpImage = tile_asimage(fgVisual, fImage, fZoomOffX,
-                                       fImage->height - fZoomHeight - fZoomOffY,
-                                       fZoomWidth, fZoomHeight, 0, ASA_ASImage,
-                                       GetImageCompression(), GetImageQuality());
+                                          fImage->height - fZoomHeight - fZoomOffY,
+                                          fZoomWidth, fZoomHeight, 0, ASA_ASImage,
+                                          GetImageCompression(), GetImageQuality());
 
-               fScaledImage->fImage = scale_asimage(fgVisual, tmpImage, to_w, to_h,
-                                                   ASA_ASImage, GetImageCompression(),
-                                                   GetImageQuality());
-               destroy_asimage(&tmpImage);
+               if (tmpImage) {
+                  fScaledImage->fImage = scale_asimage(fgVisual, tmpImage, to_w, to_h,
+                                                       ASA_ASImage, GetImageCompression(),
+                                                      GetImageQuality());
+                  destroy_asimage(&tmpImage);
+               }
             } else {
                // scale image, no zooming
                fScaledImage->fImage = scale_asimage(fgVisual, fImage, to_w, to_h,
@@ -2255,18 +2259,44 @@ TArrayL *TASImage::GetPixels(Int_t x, Int_t y, UInt_t width, UInt_t height)
    return ret;
 }
 
+//______________________________________________________________________________
+Double_t *TASImage::GetVecArray()
+{
+   // Returns a pointer to internal array[width x height] of double values [0, 1]
+   // This array is directly accessible. That allows to manipulate/change the image
+
+   if (!fImage) {
+      Warning("GetVecArray", "Bad Image");
+      return 0;
+   }
+   if (fImage->alt.vector) {
+      return fImage->alt.vector;
+   }
+   // vectorize
+   return 0;
+}
+
 //______________________________________________________________________________
 TArrayD *TASImage::GetArray(UInt_t w, UInt_t h, TImagePalette *palette)
 {
-   // Converts an image into 2D array of doubles according to palette.
+   // In case of vectorized image return an associated array of doubles 
+   // otherwise this method creates and returns a 2D array of doubles corresponding to palette.
    // If palette is ZERO a color converted to double value [0, 1] according to formula
    //   Double_t((r << 16) + (g << 8) + b)/0xFFFFFF
+   // The returned array must be deleted after usage.
 
    if (!fImage) {
-      Warning("GetArray", "Wrong Image");
+      Warning("GetArray", "Bad Image");
       return 0;
    }
 
+   TArrayD *ret;
+
+   if (fImage->alt.vector) {
+      ret = new TArrayD(fImage->width*fImage->height, fImage->alt.vector);
+      return ret;
+   }
+
    ASImageDecoder *imdec;
 
    w = w ? w : fImage->width;
@@ -2284,7 +2314,7 @@ TArrayD *TASImage::GetArray(UInt_t w, UInt_t h, TImagePalette *palette)
       return 0;
    }
 
-   TArrayD *ret = new TArrayD(w * h);
+   ret = new TArrayD(w * h);
    CARD32 r = 0;
    CARD32 g = 0;
    CARD32 b = 0;
@@ -2480,8 +2510,8 @@ void TASImage::Merge(const TImage *im, const char *op, Int_t x, Int_t y)
    layers[1].im = ((TASImage*)im)->fImage;
    layers[1].dst_x = x;
    layers[1].dst_y = y;
-   layers[1].clip_width = im->GetWidth();
-   layers[1].clip_height = im->GetHeight();
+   layers[1].clip_width = x + im->GetWidth();
+   layers[1].clip_height = y + im->GetHeight();
    layers[1].merge_scanlines = blend_scanlines_name2func(op ? op : "add");
 
    rendered_im = merge_layers(fgVisual, &(layers[0]), 2, fImage->width, fImage->height,
@@ -4891,7 +4921,7 @@ static int GetPolyYBounds(TPoint *pts, int n, int *by, int *ty)
 Bool_t TASImage::GetPolygonSpans(UInt_t npt, TPoint *ppt, UInt_t *nspans,
                                  TPoint **outPoint, UInt_t **outWidth)
 {
-   // The code is taken on Xserver/mi/mipolycon.c
+   // The code is based on Xserver/mi/mipolycon.c
    //    "Copyright 1987, 1998  The Open Group"
 
    int xl = 0;                   // x vals of leftedges
@@ -4910,8 +4940,8 @@ Bool_t TASImage::GetPolygonSpans(UInt_t npt, TPoint *ppt, UInt_t *nspans,
    int nextleft, nextright;      // indices to second endpoints
    TPoint *ptsOut;               // output buffer
    UInt_t *width;                // output buffer
-   TPoint *firstPoint;
-   UInt_t *firstWidth;
+   TPoint *firstPoint=0;
+   UInt_t *firstWidth=0;
    int imin;                     // index of smallest vertex (in y)
    int ymin;                     // y-extents of polygon
    int ymax;
@@ -4950,19 +4980,9 @@ Bool_t TASImage::GetPolygonSpans(UInt_t npt, TPoint *ppt, UInt_t *nspans,
    dy = ymax - ymin + 1;
    if ((npt < 3) || (dy < 0)) return kFALSE;
 
-   static const Int_t gCachePwSize = 512;
-   static TPoint gPointCache[gCachePwSize];
-   static UInt_t gWidthCache[gCachePwSize];
-
-   if (dy < gCachePwSize) {
-      ptsOut = firstPoint = (TPoint*)&gPointCache;
-      width = firstWidth = (UInt_t*)&gWidthCache;
-      ret = kFALSE;
-   } else {
-      ptsOut = firstPoint = new TPoint[dy];
-      width = firstWidth = new UInt_t[dy];
-      ret = kTRUE;
-   }
+   ptsOut = firstPoint = new TPoint[dy];
+   width = firstWidth = new UInt_t[dy];
+   ret = kTRUE;
 
    nextleft = nextright = imin;
    y = ppt[nextleft].fY;
@@ -5009,13 +5029,9 @@ Bool_t TASImage::GetPolygonSpans(UInt_t npt, TPoint *ppt, UInt_t *nspans,
       //  a right edge as well as a left edge.
       i = min(ppt[nextleft].fY, ppt[nextright].fY) - y;
 
-      // in case we're called with non-convex polygon
+      // in case of non-convex polygon
       if (i < 0) {
-         delete [] firstWidth;
-         delete [] firstPoint;
-         firstPoint = 0;
-         firstWidth = 0;
-         return kFALSE;
+         return kTRUE;
       }
 
       while (i-- > 0)  {
diff --git a/graf/inc/TImage.h b/graf/inc/TImage.h
index 56e9cb456ac..5df4496de20 100644
--- a/graf/inc/TImage.h
+++ b/graf/inc/TImage.h
@@ -225,6 +225,7 @@ public:
    virtual Pixmap_t  GetMask() { return 0; }
    virtual UInt_t   *GetArgbArray() { return 0; }
    virtual UInt_t   *GetRgbaArray() { return 0; }
+   virtual Double_t *GetVecArray() { return 0; }
    virtual UInt_t   *GetScanline(UInt_t /*y*/) { return 0; }
    virtual void      GetImageBuffer(char ** /*buffer*/, int* /*size*/, EImageFileTypes /*type*/ = TImage::kPng) {}
    virtual Bool_t    SetImageBuffer(char ** /*buffer*/, EImageFileTypes /*type*/ = TImage::kPng) { return kFALSE; }
diff --git a/graf/src/TAttImage.cxx b/graf/src/TAttImage.cxx
index 6dda4db5ce7..b959b45e73b 100644
--- a/graf/src/TAttImage.cxx
+++ b/graf/src/TAttImage.cxx
@@ -55,6 +55,26 @@
 //       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                                                      //
 //                                                                      //
@@ -333,7 +353,15 @@ TImagePalette::TImagePalette(Int_t ncolors, Int_t *colors)
       fColorGreen = new UShort_t[fNumPoints];
       fColorBlue  = new UShort_t[fNumPoints];
       fColorAlpha = new UShort_t[fNumPoints];
-      for (i=0;i<ncolors;i++) {
+
+      // 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;
          fColorRed[i] = UShort_t(col->GetRed()*255) << 8;
-- 
GitLab