diff --git a/Code/Visu/otbGLColorImageView.txx b/Code/Visu/otbGLColorImageView.txx
new file mode 100755
index 0000000000000000000000000000000000000000..28497316184f2a6f02dde7797528462b4dc240f9
--- /dev/null
+++ b/Code/Visu/otbGLColorImageView.txx
@@ -0,0 +1,886 @@
+#ifndef otbGLColorImageView_txx
+#define otbGLColorImageView_txx
+
+#include "otbGLColorImageView.h"
+
+#include <math.h>
+
+namespace otb
+{
+  
+  
+template <class ImagePixelType, class OverlayPixelType>
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+GLColorImageView():
+  GLImageView<ImagePixelType, OverlayPixelType>()
+  {
+  cClickSelectR = 0;
+  cClickSelectG = 0;
+  cClickSelectB = 0;
+  }
+
+template <class ImagePixelType, class OverlayPixelType>
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+~GLColorImageView()
+{
+
+}
+
+
+template <class ImagePixelType, class OverlayPixelType>
+void
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+Init(int x, int y, int w, int h, const char * l)
+{
+  cClickSelectR = 0;
+  cClickSelectG = 0;
+  cClickSelectB = 0;
+  this->Superclass::Init(x,y,w,h,l);
+}
+template <class ImagePixelType, class OverlayPixelType>
+void 
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+SetInput( const ImageType * image )
+{
+  // Process object is not const-correct so the const_cast is required here
+  this->itk::ProcessObject::SetNthInput(0, 
+                                   const_cast< ImageType *>( image ) );
+}
+
+/*
+template <class ImagePixelType, class OverlayPixelType>
+const typename GLColorImageView<ImagePixelType, OverlayPixelType>::ImageType *
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+GetInput(void) const
+{
+  if (this->GetNumberOfInputs() < 1)
+    {
+    return 0;
+    }
+
+  return ( (const_cast< ImageType * >
+     (this->itk::ProcessObject::GetInput(0) ) ) );
+}
+
+template <class ImagePixelType, class OverlayPixelType>
+typename GLColorImageView<ImagePixelType, OverlayPixelType>::ImageType * 
+//ImageType * 
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+GetInput(void)
+{
+  if (this->GetNumberOfInputs() < 1)
+    {
+    return 0;
+    }
+
+  return ( static_cast< ImageType * >
+     (this->itk::ProcessObject::GetInput(0) ) ) ;
+}
+*/
+
+  
+//
+//
+template <class ImagePixelType, class OverlayPixelType>
+void 
+GLColorImageView<ImagePixelType, OverlayPixelType>::
+SetInputImage(ImageType * newImData)
+  {
+  RegionType region = newImData->GetLargestPossibleRegion();
+  if( region.GetNumberOfPixels() == 0 ) 
+    {
+    return;
+    }
+
+  SizeType   size   = region.GetSize();
+
+
+  // If the overlay has been set and the size is different from the new image,
+  // it is removed.
+  if( this->cValidOverlayData)
+  {  
+    SizeType  overlay_size   = this->cOverlayData->GetLargestPossibleRegion().GetSize();
+      
+    if((overlay_size[0] != size[0])
+       ||  (overlay_size[1] != size[1])
+       ||  (overlay_size[2] != size[2])
+      )
+      {
+       if(this->cWinOverlayData != NULL)
+        {
+        delete [] this->cWinOverlayData;
+        }
+       this->cWinOverlayData       = NULL;
+       this->cValidOverlayData     = false;
+      }       
+  }
+    
+//  this->cImData = newImData;
+  this->SetInput( newImData );
+  ImageType * lImage = dynamic_cast<ImageType * >(this->GetInput());
+  
+  this->cDimSize[0] = size[0];
+  this->cDimSize[1] = size[1];
+  this->cDimSize[2] = size[2];
+  this->cSpacing[0] = lImage->GetSpacing()[0];
+  this->cSpacing[1] = lImage->GetSpacing()[1];
+  this->cSpacing[2] = lImage->GetSpacing()[2];
+
+  //calculating cDataMax and cDataMin
+  IndexType ind;
+  ind[0] = 0; 
+  ind[1] = 0; 
+  ind[2] = 0;
+  
+  
+  this->cDataMax = lImage->GetPixel(ind)[0];
+  this->cDataMin = this->cDataMax;
+  itk::RGBPixel<ImagePixelType> tfv;
+  double tf;
+    
+    
+  for( unsigned int i=0; i<this->cDimSize[0]; i++ )
+    {
+    ind[0] = i;
+    for(unsigned int j=0; j<this->cDimSize[1]; j++ )
+      {
+      ind[1] = j;
+      for( unsigned int k=0; k<this->cDimSize[2]; k++ )
+        {
+        ind[2] = k;
+        tfv = lImage->GetPixel(ind);
+        for( unsigned int l=0; l<3; l++)
+          {
+          tf = (double)(tfv[l]);
+          if(tf > this->cDataMax) 
+            {
+            this->cDataMax = tf;
+            }
+          else 
+            {
+            if(tf < this->cDataMin)
+              {
+              this->cDataMin = tf;
+              }
+            }
+          }
+        }
+      }
+    }
+  
+  this->cIWMin      = this->cDataMin;
+  this->cIWMax      = this->cDataMax;
+  this->cIWModeMin  = IW_MIN;
+  this->cIWModeMax  = IW_MAX;
+    
+  this->cImageMode = IMG_VAL;
+    
+  this->cWinZoom = 1;
+  this->cWinOrientation = 2;
+  this->cWinOrder[0] = 0;
+  this->cWinOrder[1] = 1;
+  this->cWinOrder[2] = 2;
+  
+  this->cWinCenter[0] = this->cDimSize[0]/2;
+  this->cWinCenter[1] = this->cDimSize[1]/2;
+  this->cWinCenter[2] = 0;
+  
+  this->cWinMinX  = 0;
+  this->cWinSizeX = this->cDimSize[0];
+  if(this->cWinSizeX<this->cDimSize[1])
+    {
+    this->cWinSizeX = this->cDimSize[1];
+    }
+  if(this->cWinSizeX<this->cDimSize[2])
+    {
+    this->cWinSizeX = this->cDimSize[2];
+    }
+  this->cWinMaxX  = this->cWinSizeX - 1;
+  
+  this->cWinMinY  = 0;
+  this->cWinSizeY = this->cWinSizeX;
+  this->cWinMaxY  = this->cWinSizeY - 1;
+  
+  this->cWinDataSizeX = this->cDimSize[0];
+  this->cWinDataSizeY = this->cDimSize[1];
+  
+  if(this->cWinImData != NULL)
+    {
+    delete [] this->cWinImData;
+    }
+  
+  this->cWinImData = new unsigned char[ this->cWinDataSizeX * this->cWinDataSizeY * 3 ];
+  
+  if(this->cWinZBuffer != NULL) 
+    {
+    delete [] this->cWinZBuffer;
+    }
+  
+  this->cWinZBuffer = new unsigned short[ this->cWinDataSizeX * this->cWinDataSizeY ];
+  
+  this->cViewImData  = true;
+  this->cValidImData = true;
+    
+  update();
+  }
+
+//
+//
+template <class ImagePixelType, class OverlayPixelType>
+void GLColorImageView<ImagePixelType, OverlayPixelType>::
+clickSelect(float newX, float newY, float newZ)
+  {    
+  this->cClickSelect[0] = newX;
+  if(this->cClickSelect[0]<0) 
+    {
+    this->cClickSelect[0] = 0;
+    }
+  if(this->cClickSelect[0] >= this->cDimSize[0])
+    {
+    this->cClickSelect[0] = this->cDimSize[0]-1;
+    }
+
+  this->cClickSelect[1] = newY;
+  if(this->cClickSelect[1]<0)
+    {
+    this->cClickSelect[1] = 0;
+    }
+  if(this->cClickSelect[1] >= this->cDimSize[1])
+    {
+    this->cClickSelect[1] = this->cDimSize[1]-1;
+    }
+
+  this->cClickSelect[2] = newZ;
+
+  if(this->cClickSelect[2]<0)
+    {
+    this->cClickSelect[2] = 0;
+    }
+  if(this->cClickSelect[2] >= this->cDimSize[2])
+    {
+    this->cClickSelect[2] = this->cDimSize[2]-1;
+    }
+
+  typename ImageType::IndexType ind;
+
+  ind[0] = (unsigned long)this->cClickSelect[0];
+  ind[1] = (unsigned long)this->cClickSelect[1];
+  ind[2] = (unsigned long)this->cClickSelect[2];
+  ImageType * lImage = dynamic_cast<ImageType * >(this->GetInput());
+  this->cClickSelectV = lImage->GetPixel(ind)[0];
+  cClickSelectR = lImage->GetPixel(ind)[0];
+  cClickSelectG = lImage->GetPixel(ind)[1];
+  cClickSelectB = lImage->GetPixel(ind)[2];
+      
+  /*if length of list is equal to max, remove the earliest point stored */
+  if((this->maxClickPoints>0)&&(this->cClickedPoints.size() == this->maxClickPoints))
+    {
+    this->cClickedPoints.pop_back();
+    }
+  
+  ClickPoint point( this->cClickSelect[0], 
+                    this->cClickSelect[1], 
+                    this->cClickSelect[2], 
+                    this->cClickSelectV     );
+
+  this->cClickedPoints.push_front( point );
+
+  if(this->cClickSelectCallBack != NULL)
+    {
+      this->cClickSelectCallBack(this->cClickSelect[0], this->cClickSelect[1], 
+                           this->cClickSelect[2], this->cClickSelectV);
+    }
+  if(this->cClickSelectArgCallBack != NULL)
+    {
+    this->cClickSelectArgCallBack(this->cClickSelect[0], this->cClickSelect[1], 
+                              this->cClickSelect[2], this->cClickSelectV,
+                              this->cClickSelectArg);
+    }
+
+  if(this->cViewValue || this->cViewCrosshairs)
+    {
+    this->redraw();
+    }
+  }
+
+
+template <class ImagePixelType, class OverlayPixelType>
+void GLColorImageView<ImagePixelType, OverlayPixelType>::
+size(int w, int h)
+  {
+  GLImageView<ImagePixelType, OverlayPixelType>::size(w, h);
+  }
+    
+template <class ImagePixelType, class OverlayPixelType>
+void GLColorImageView<ImagePixelType, OverlayPixelType>::
+resize(int x, int y, int w, int h)
+  {
+  GLImageView<ImagePixelType, OverlayPixelType>::resize(x, y, w, h);
+  }
+
+//
+template <class ImagePixelType, class OverlayPixelType>
+void GLColorImageView<ImagePixelType, OverlayPixelType>::
+update()
+  {
+  if( !this->cValidImData ) 
+    {
+    return;
+    }
+  
+  int winWidth = (int)( this->cDimSize[ this->cWinOrder[0] ] / this->cWinZoom );
+  this->cWinSizeX = ( (int) winWidth);
+  int ti = (int)( (int)this->cWinCenter[ this->cWinOrder[0] ] - winWidth/2);
+  if( ti <= - (int) this->cDimSize[ this->cWinOrder[0] ] ) 
+    {
+    ti = -(int)this->cDimSize[ this->cWinOrder[0] ] + 1;
+    }
+  else if( ti >= (int)this->cDimSize[ this->cWinOrder[0] ]) 
+    {
+    ti = this->cDimSize[ this->cWinOrder[0] ] - 1;
+    }
+  this->cWinMinX = ti;
+  this->cWinMaxX = this->cDimSize[ this->cWinOrder[0] ] - 1; // here
+  if( this->cWinMaxX >= static_cast<int>( this->cDimSize[ this->cWinOrder[0] ] ) )
+    {
+    this->cWinMaxX = this->cDimSize[ this->cWinOrder[0] ] - 1;
+    }
+  
+  winWidth = static_cast<int>( this->cDimSize[ this->cWinOrder[1] ] / this->cWinZoom );
+  this->cWinSizeY = ( static_cast<int>( winWidth) );
+  ti = static_cast<int>( static_cast<int>(this->cWinCenter[ this->cWinOrder[1] ]) 
+                         - winWidth/2);
+  if( ti <= - static_cast<int>( this->cDimSize[ this->cWinOrder[1] ] ) ) 
+    {
+    ti = -(int)this->cDimSize[ this->cWinOrder[1] ] + 1;
+    }
+  else if( ti >= static_cast<int>(this->cDimSize[ this->cWinOrder[1] ] ) ) 
+    {
+    ti = this->cDimSize[ this->cWinOrder[1] ] - 1;
+    } 
+  this->cWinMinY = ti;
+  this->cWinMaxY = this->cDimSize[ this->cWinOrder[1] ] - 1;
+  if( this->cWinMaxY >= static_cast<int>( this->cDimSize[ this->cWinOrder[1] ] ) ) 
+    {
+    this->cWinMaxY = this->cDimSize[ this->cWinOrder[1] ] - 1;
+    }
+  
+  memset( this->cWinImData, 0, this->cWinDataSizeX*this->cWinDataSizeY*3 );
+  if( this->cValidOverlayData ) 
+    {
+    memset(this->cWinOverlayData, 0, this->cWinDataSizeX*this->cWinDataSizeY*4);
+    }
+  
+  IndexType ind;
+  
+  int l, m;
+  
+  itk::RGBPixel<ImagePixelType> tfv;
+  float tf[3];
+
+  ImageType * lImage = dynamic_cast<ImageType * >(this->GetInput());
+  
+  ind[ this->cWinOrder[ 2 ] ] = this->cWinCenter[ this->cWinOrder[ 2 ] ];
+  int startK = this->cWinMinY;
+  if(startK<0)
+    startK = 0;
+  int startJ = this->cWinMinX;
+  if(startJ<0)
+    startJ = 0;
+  for(int k=startK; k <= this->cWinMaxY; k++)
+    {
+    ind[this->cWinOrder[1]] = k;
+    
+    if(k-this->cWinMinY >= (int)this->cWinDataSizeY)
+      continue;
+
+    for(int j=startJ; j <= this->cWinMaxX; j++) 
+      {
+      ind[this->cWinOrder[0]] = j;
+      
+      if(j-this->cWinMinX >= (int)this->cWinDataSizeX)
+         continue;
+
+      tfv = lImage->GetPixel(ind);
+      switch( this->cImageMode ) 
+        {
+        default:
+        case IMG_VAL:
+          tf[0] = (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          tf[1] = (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          tf[2] = (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          break;
+        case IMG_INV:
+          tf[0] = (float)((this->cIWMax-(float)tfv[0])/(this->cIWMax-this->cIWMin)*255);
+          tf[1] = (float)((this->cIWMax-(float)tfv[1])/(this->cIWMax-this->cIWMin)*255);
+          tf[2] = (float)((this->cIWMax-(float)tfv[2])/(this->cIWMax-this->cIWMin)*255);
+          break;
+        case IMG_LOG:
+          tf[0] = (float)(log((float)tfv[0]-this->cIWMin+0.00000001)
+                          /log(this->cIWMax-this->cIWMin+0.00000001)*255);
+          tf[1] = (float)(log((float)tfv[1]-this->cIWMin+0.00000001)
+                          /log(this->cIWMax-this->cIWMin+0.00000001)*255);
+          tf[2] = (float)(log((float)tfv[2]-this->cIWMin+0.00000001)
+                          /log(this->cIWMax-this->cIWMin+0.00000001)*255);
+          break;
+        case IMG_DX:
+          if(ind[0]>0) 
+            {
+            tf[0] = (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[1] = (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[2] = (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            ind[0]--;
+            tfv = lImage->GetPixel(ind);
+            tf[0] -= (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[1] -= (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[2] -= (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            ind[0]++;
+            tf[0] += 128;
+            tf[1] += 128;
+            tf[2] += 128;
+            } 
+          else
+            {
+            tf[0] = 128;
+            tf[1] = 128;
+            tf[2] = 128;
+            }
+          break;
+        case IMG_DY:
+          if(ind[1]>0) 
+            {
+            tf[0] = (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[1] = (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[2] = (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            ind[1]--;
+            tfv = lImage->GetPixel(ind);
+            tf[0] -= (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[1] -= (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[2] -= (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            ind[1]++;
+            tf[0] += 128;
+            tf[1] += 128;
+            tf[2] += 128;
+            }
+          else
+            {
+            tf[0] = 128;
+            tf[1] = 128;
+            tf[2] = 128;
+            }
+          break;
+        case IMG_DZ:
+          if(ind[2]>0) 
+            {
+            tf[0] = (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[1] = (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[2] = (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            ind[2]--;
+            tfv = lImage->GetPixel(ind);
+            tf[0] -= (float)(((float)tfv[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[1] -= (float)(((float)tfv[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            tf[2] -= (float)(((float)tfv[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+            ind[2]++;
+            tf[0] += 128;
+            tf[1] += 128;
+            tf[2] += 128;
+            }
+          else
+            {
+            tf[0] = 128;
+            tf[1] = 128;
+            tf[2] = 128;
+            }
+          break;
+        case IMG_BLEND:
+          {
+          const int tempval = (int)this->cWinCenter[this->cWinOrder[2]]-1;
+          int tmpI = ind[this->cWinOrder[2]];
+          ind[this->cWinOrder[2]] = (tempval < 0 ) ? 0 : tempval;
+          tfv = lImage->GetPixel(ind);
+          tf[0] = (float)(tfv[0]);
+          tf[1] = (float)(tfv[1]);
+          tf[2] = (float)(tfv[2]);
+          
+          ind[this->cWinOrder[2]] = this->cWinCenter[this->cWinOrder[2]];
+          tfv = lImage->GetPixel(ind);
+          tf[0] += (float)(tfv[0])*2;
+          tf[1] += (float)(tfv[1])*2;
+          tf[2] += (float)(tfv[2])*2;
+          
+          const int tempval1 = (int)this->cDimSize[this->cWinOrder[2]]-1;
+          const int tempval2 = (int)this->cWinCenter[this->cWinOrder[2]]+1;
+          ind[this->cWinOrder[2]] = (tempval1 < tempval2 ) ? tempval1 : tempval2;
+          tfv = lImage->GetPixel(ind);
+          tf[0] += (float)(tfv[0]);
+          tf[1] += (float)(tfv[1]);
+          tf[2] += (float)(tfv[2]);
+          
+          tf[0] = (float)((tf[0]/4-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          tf[1] = (float)((tf[1]/4-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          tf[2] = (float)((tf[2]/4-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          ind[this->cWinOrder[2]] = tmpI;
+          break;
+          }
+        case IMG_MIP:
+          tf[0] = this->cIWMin;
+          tf[1] = this->cIWMin;
+          tf[2] = this->cIWMin;
+          m = (j-this->cWinMinX) + (k-this->cWinMinY)*this->cWinDataSizeX;
+          this->cWinZBuffer[m] = 0;
+          int tmpI = ind[this->cWinOrder[2]];
+          float tfp = 0;
+          float tft = tf[0]+tf[1]+tf[2];
+          for(l=0; l<(int)this->cDimSize[this->cWinOrder[2]]; l++) 
+            {
+            ind[this->cWinOrder[2]] = l;        
+            tfv = lImage->GetPixel(ind);
+            tfp = (float)tfv[0] 
+                  + tfv[1] 
+                  + tfv[2];
+            if(tfp > tft) 
+              {
+              tf[0] = (float)(tfv[0]);
+              tf[1] = (float)(tfv[1]);
+              tf[2] = (float)(tfv[2]);
+              this->cWinZBuffer[m] = (unsigned short)l;
+              }
+            }
+          tf[0] = (float)((tf[0]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          tf[1] = (float)((tf[1]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          tf[2] = (float)((tf[2]-this->cIWMin)/(this->cIWMax-this->cIWMin)*255);
+          ind[this->cWinOrder[2]] = tmpI;
+          break;
+        }
+      
+      int c;
+      for(c=0; c<3; c++)
+        {
+        if( tf[c] > 255 )
+          {
+          switch(this->cIWModeMax) 
+            {
+            case IW_MIN:
+              tf[c] = 0;
+              break;
+            default:
+            case IW_MAX:
+              tf[c] = 255;
+              break;
+            case IW_FLIP:
+              tf[c] = 512-tf[c];
+              if(tf[c]<0) 
+                {
+                tf[c] = 0;
+                }
+              break;
+            }
+          }
+        else 
+          {
+          if( tf[c] < 0 )
+            {
+            switch(this->cIWModeMin) 
+              {
+              default:
+              case IW_MIN:
+                tf[c] = 0;
+                break;
+              case IW_MAX:
+                tf[c] = 255;
+                break;
+              case IW_FLIP:
+                tf[c] = -tf[c];
+                if(tf[c]>255)
+                  {
+                  tf[c] = 255;
+                  }
+                break;
+              }
+            }
+          }
+        }
+        
+      l = (j-this->cWinMinX)*3 + (k-this->cWinMinY)*this->cWinDataSizeX*3;
+      this->cWinImData[l+0] = (unsigned char)tf[0];
+      this->cWinImData[l+1] = (unsigned char)tf[1];
+      this->cWinImData[l+2] = (unsigned char)tf[2];
+      
+      if( this->cValidOverlayData ) 
+        {
+        l = (j-this->cWinMinX)*4 + (k-this->cWinMinY)*this->cWinDataSizeX*4;
+        if(this->cImageMode == IMG_MIP)
+          {
+          ind[this->cWinOrder[2]] = this->cWinZBuffer[(j-this->cWinMinX) + 
+                              (k-this->cWinMinY)*this->cWinDataSizeX];
+          }
+        
+        if( sizeof( OverlayPixelType ) == 1 )
+          {
+          m = (int)*((unsigned char *)&(this->cOverlayData->GetPixel(ind)));
+          if( m > 0 ) {
+            m = m - 1;
+            this->cWinOverlayData[l+0] = 
+              (unsigned char)(this->cColorTable->GetColorComponent(m, 'r')*255);
+            this->cWinOverlayData[l+1] = 
+              (unsigned char)(this->cColorTable->GetColorComponent(m, 'g')*255);
+            this->cWinOverlayData[l+2] = 
+              (unsigned char)(this->cColorTable->GetColorComponent(m, 'b')*255);
+            this->cWinOverlayData[l+3] = 
+              (unsigned char)(this->cOverlayOpacity*255);
+            }
+          }
+        else 
+          {
+          if(((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[0]
+            + ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[1]
+            + ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[2] > 0)
+            {
+            if( sizeof( OverlayPixelType ) == 3 )
+              {
+              this->cWinOverlayData[l+0] = 
+                ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[0];
+              this->cWinOverlayData[l+1] = 
+                ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[1];
+              this->cWinOverlayData[l+2] = 
+                ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[2];
+              this->cWinOverlayData[l+3] = 
+                (unsigned char)(this->cOverlayOpacity*255);
+              }
+            else 
+              {
+              if( sizeof( OverlayPixelType ) == 4 ) 
+                {
+                this->cWinOverlayData[l+0] = 
+                  ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[0];
+                this->cWinOverlayData[l+1] = 
+                  ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[1];
+                this->cWinOverlayData[l+2] = 
+                  ((unsigned char *)&(this->cOverlayData->GetPixel(ind)))[2];
+                this->cWinOverlayData[l+3] = 
+                  (unsigned char)(((unsigned char *)
+                  &(this->cOverlayData->GetPixel(ind)))[3]*this->cOverlayOpacity);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  
+  this->redraw();
+  
+  }
+
+//
+//
+template <class ImagePixelType, class OverlayPixelType>
+void GLColorImageView<ImagePixelType, OverlayPixelType>::
+draw()
+  {
+  ImageType * lImage = dynamic_cast<ImageType * >(this->GetInput());
+
+  if( !this->valid() )
+    {
+    glClearColor((float)0.0, (float)0.0, (float)0.0, (float)0.0);          
+    glShadeModel(GL_FLAT);
+    
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  //if you don't include this
+    //image size differences distort
+    //glPixelStorei(GL_PACK_ALIGNMENT, 1);
+    }
+  else
+    {
+    glClear(GL_COLOR_BUFFER_BIT);    //this clears and paints to black
+    
+    glMatrixMode(GL_MODELVIEW);    //clear previous 3D draw params
+    glLoadIdentity();
+    
+    glMatrixMode(GL_PROJECTION);
+    this->ortho();
+    
+    if( !lImage ) 
+      {
+      return;
+      }
+    
+    float scale0 = this->cW/(float)this->cDimSize[0] * this->cWinZoom
+      * fabs(this->cSpacing[this->cWinOrder[0]])/fabs(this->cSpacing[0]);
+    float scale1 = this->cW/(float)this->cDimSize[0] * this->cWinZoom
+      * fabs(this->cSpacing[this->cWinOrder[1]])/fabs(this->cSpacing[0]);
+    
+    
+    glRasterPos2i((this->cFlipX[this->cWinOrientation])?this->cW:0,
+      (this->cFlipY[this->cWinOrientation])?this->cH:0);  
+    glPixelZoom((this->cFlipX[this->cWinOrientation])?-scale0:scale0,
+      (this->cFlipY[this->cWinOrientation])?-scale1:scale1);
+    
+    if( this->cValidImData && this->cViewImData )
+      {
+      glDrawPixels( this->cWinDataSizeX, this->cWinDataSizeY, 
+                    GL_RGB, GL_UNSIGNED_BYTE, 
+                    this->cWinImData );
+      }
+    
+    if( this->cValidOverlayData && this->cViewOverlayData ) 
+      {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glDrawPixels(this->cWinDataSizeX, this->cWinDataSizeY, GL_RGBA, 
+        GL_UNSIGNED_BYTE, this->cWinOverlayData);
+      glDisable(GL_BLEND);
+      }
+    
+    if( this->cViewAxisLabel ) 
+      {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4f(0.2, 0.2, 0.78, (float)0.75);
+      gl_font(FL_TIMES_BOLD, 12);
+      
+      if( !this->cFlipX[this->cWinOrientation] )
+        {
+        const int y = static_cast<int>(  this->cH/2-gl_height()/2  );
+        gl_draw( this->cAxisLabelX[this->cWinOrientation],
+          this->cW-(gl_width(this->cAxisLabelX[this->cWinOrientation])+10), 
+          static_cast<float>( y ) );
+        }
+      else
+        {
+        const int y = static_cast<int>( this->cH/2-gl_height()/2  );
+        gl_draw( this->cAxisLabelX[this->cWinOrientation],
+          (gl_width(this->cAxisLabelX[this->cWinOrientation])+10),
+          static_cast<float>( y ));
+        }
+      
+      if(!this->cFlipY[this->cWinOrientation])
+        {
+        const int y = static_cast<int>( this->cH-gl_height()-10 ) ;
+        gl_draw( this->cAxisLabelY[this->cWinOrientation],
+          this->cW/2-(gl_width(this->cAxisLabelY[this->cWinOrientation])/2),
+          static_cast<float>(y) );
+        }
+      else
+        {
+        const int y = static_cast<int>( gl_height()+10 );
+        gl_draw( this->cAxisLabelY[this->cWinOrientation], 
+          this->cW/2-(gl_width(this->cAxisLabelY[this->cWinOrientation])/2),
+          static_cast<float>(y));
+        }
+      
+      glDisable(GL_BLEND);
+      }
+    if( this->cViewValue ) 
+      {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4f(0.1, 0.64, 0.2, (float)0.75);
+      gl_font(FL_TIMES_BOLD, 12);
+      char s[80];
+      if((ImagePixelType)1.1==1.1)
+        {
+        sprintf(s, "(%0.1f,  %0.1f,  %0.1f) = %0.3f,%03f,%0.3f", 
+          this->cClickSelect[0],
+          this->cClickSelect[1], 
+          this->cClickSelect[2], 
+          (float)cClickSelectR,
+          (float)cClickSelectG,
+          (float)cClickSelectB);
+        }
+      else
+        {
+        sprintf(s, "(%0.1f,  %0.1f,  %0.1f) = %d,%d,%d", 
+          this->cClickSelect[0],
+          this->cClickSelect[1], 
+          this->cClickSelect[2], 
+          (int)cClickSelectR,
+          (int)cClickSelectG,
+          (int)cClickSelectB);
+        }
+      gl_draw( s,
+        (int)(this->cW-(gl_width(s)+2)), 2);
+      glDisable(GL_BLEND);
+      
+      }
+    if( this->cViewDetails )
+      {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4f(0.9, 0.4, 0.1, (float)0.75);
+      gl_font(FL_TIMES_BOLD, 12);
+      char s[80];
+      if(this->cWinOrientation == 0)
+        sprintf(s, "X - Slice: %3d", this->cWinCenter[0]);
+      else if(this->cWinOrientation == 1)
+        sprintf(s, "Y - Slice: %3d", this->cWinCenter[1]);
+      else
+        sprintf(s, "Z - Slice: %3d", this->cWinCenter[2]);
+      gl_draw( s, 2, 2+5*(gl_height()+2) );
+      sprintf(s, "Dims: %3d x %3d x %3d", 
+        (int)this->cDimSize[0], (int)this->cDimSize[1], (int)this->cDimSize[2]);
+      gl_draw( s, 2, 2+4*(gl_height()+2) );
+      sprintf(s, "Voxel: %0.3f x %0.3f x %0.3f", 
+        this->cSpacing[0], this->cSpacing[1], this->cSpacing[2]);
+      gl_draw( s, 2, 2+3*(gl_height()+2) );
+      sprintf(s, "Int. Range: %0.3f - %0.3f", (float)this->cDataMin, 
+              (float)this->cDataMax);
+      gl_draw( s, 2, 2+2*(gl_height()+2) );
+      sprintf(s, "Int. Window: %0.3f(%s) - %0.3f(%s)", 
+        (float)this->cIWMin, IWModeTypeName[this->cIWModeMin], 
+        (float)this->cIWMax, IWModeTypeName[this->cIWModeMax]);
+      gl_draw( s, 2, 2+1*(gl_height()+2) );
+      sprintf(s, "View Mode: %s", ImageModeTypeName[this->cImageMode]);
+      gl_draw( s, 2, 2+0*(gl_height()+2) );
+      glDisable(GL_BLEND);
+      }
+    if( this->cViewCrosshairs 
+      && static_cast<int>(this->cClickSelect[this->cWinOrder[2]]) == 
+         static_cast<int>( this->sliceNum() ) )
+      {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4f(0.1, 0.64, 0.2, (float)0.75);
+      int x;
+      if(this->cFlipX[this->cWinOrientation])
+        {
+        x = (int)(this->cW - (this->cClickSelect[this->cWinOrder[0]] - this->cWinMinX) * scale0);
+        }
+      else
+        {
+        x = (int)((this->cClickSelect[this->cWinOrder[0]] - this->cWinMinX) * scale0);
+        }
+      int y;
+      if(this->cFlipY[this->cWinOrientation])
+        {
+        y = (int)(this->cH - (this->cClickSelect[this->cWinOrder[1]] - this->cWinMinY) * scale1);
+        }
+      else
+        {
+        y = (int)((this->cClickSelect[this->cWinOrder[1]] - this->cWinMinY) * scale1);
+        }
+      glBegin(GL_LINES);
+      glVertex2d(0, y);
+      glVertex2d(x-2, y);
+      glVertex2d(x+2, y);
+      glVertex2d(this->cW-1, y);
+      glVertex2d(x, 0);
+      glVertex2d(x, y-2);
+      glVertex2d(x, y+2);
+      glVertex2d(x, this->cH-1);
+      glEnd();
+      glDisable(GL_BLEND);
+      }
+    
+    }
+  }
+
+template <class ImagePixelType, class OverlayPixelType>
+int GLColorImageView<ImagePixelType, OverlayPixelType>::
+handle(int event)
+  {
+  return GLImageView<ImagePixelType, OverlayPixelType>::handle(event);
+  }
+
+}; //namespace
+#endif
+