diff --git a/Code/Visualization/otbImageLayer.txx b/Code/Visualization/otbImageLayer.txx
index f30c14843ced891af92cd46d9f88a41b1b172186..2e2da6b22fa9d92b0fa35d489f18d19ad7d4a2ff 100644
--- a/Code/Visualization/otbImageLayer.txx
+++ b/Code/Visualization/otbImageLayer.txx
@@ -253,11 +253,11 @@ ImageLayer<TImage,TOutputImage>
   m_RenderingFunction->Initialize();
   // The ouptut stringstream
   itk::OStringStream oss;
-  oss<<this->GetName();
+  oss<<"Layer: "<<this->GetName();
   // If we are inside the buffered region
   if(m_Image->GetBufferedRegion().IsInside(index))
     {
-    oss<<" "<<m_RenderingFunction->Describe(m_Image->GetPixel(index));
+    oss<<std::endl<<m_RenderingFunction->Describe(m_Image->GetPixel(index));
     }
   else if(m_Quicklook.IsNotNull())
     // Else we extrapolate the value from the quicklook
@@ -268,7 +268,7 @@ ImageLayer<TImage,TOutputImage>
 
     if(m_Quicklook->GetBufferedRegion().IsInside(ssindex))
       {
-      oss<<" (ql) "<<m_RenderingFunction->Describe(m_Quicklook->GetPixel(ssindex));
+      oss<<" (ql)"<<std::endl<<m_RenderingFunction->Describe(m_Quicklook->GetPixel(ssindex));
       }
     }
   return oss.str();
diff --git a/Code/Visualization/otbStandardImageViewer.h b/Code/Visualization/otbStandardImageViewer.h
index e8440d319a4a7f380650e0c1809a86e590541b9b..20f7ac4674c67dd75d9f7e4449d40ce06e568443 100644
--- a/Code/Visualization/otbStandardImageViewer.h
+++ b/Code/Visualization/otbStandardImageViewer.h
@@ -29,6 +29,14 @@
 #include "otbChangeScaledExtractRegionActionHandler.h"
 #include "otbChangeExtractRegionActionHandler.h"
 #include "otbChangeScaleActionHandler.h"
+#include "otbCurves2DWidget.h"
+#include "otbHistogramCurve.h"
+#include "otbPixelDescriptionModel.h"
+#include "otbPixelDescriptionActionHandler.h"
+#include "otbPixelDescriptionView.h"
+
+#include <Fl/Fl_Tile.H>
+#include <Fl/Fl_Group.H>
 
 namespace otb
 {
@@ -61,11 +69,12 @@ public:
 
   /** Output image type */
   typedef itk::RGBPixel<unsigned char>              RGBPixelType;
-  typedef otb::Image<RGBPixelType,2>                OutputImageType;
+  typedef Image<RGBPixelType,2>                     OutputImageType;
   
   /** Image layer type */
   typedef ImageLayer<ImageType>                     ImageLayerType;
   typedef typename ImageLayerType::Pointer          ImageLayerPointerType;
+  typedef typename ImageLayerType::HistogramType    HistogramType;
   
   /** Image layer generator type */
   typedef ImageLayerGenerator<ImageLayerType>       ImageLayerGeneratorType;
@@ -76,13 +85,19 @@ public:
   typedef typename RenderingModelType::Pointer      RenderingModelPointerType;
   
   /** View type */
-  typedef otb::ImageView<RenderingModelType>        ViewType;
+  typedef ImageView<RenderingModelType>             ViewType;
   typedef typename ViewType::Pointer                ViewPointerType;
 
   /** Widget controller */
-  typedef otb::ImageWidgetController                WidgetControllerType;
+  typedef ImageWidgetController                     WidgetControllerType;
   typedef typename WidgetControllerType::Pointer    WidgetControllerPointerType;
   
+  /** Curves 2D widget */
+  typedef Curves2DWidget                            CurvesWidgetType;
+  typedef typename CurvesWidgetType::Pointer        CurvesWidgetPointerType;
+  typedef HistogramCurve<HistogramType>             HistogramCurveType;
+  typedef typename HistogramCurveType::Pointer      HistogramCurvePointerType;
+
   /** Standard action handlers */
   typedef otb::WidgetResizingActionHandler
   <RenderingModelType,ViewType>                     ResizingHandlerType;
@@ -93,6 +108,15 @@ public:
   typedef otb::ChangeScaleActionHandler
   <RenderingModelType,ViewType>                     ChangeScaleHandlerType;
 
+  /** Pixel description */
+  typedef PixelDescriptionModel<OutputImageType>    PixelDescriptionModelType;
+  typedef typename PixelDescriptionModelType::Pointer PixelDescriptionModelPointerType;
+  typedef PixelDescriptionActionHandler
+    < PixelDescriptionModelType, ViewType>          PixelDescriptionActionHandlerType;
+  typedef otb::PixelDescriptionView
+    < PixelDescriptionModelType >                   PixelDescriptionViewType;
+  typedef typename PixelDescriptionViewType::Pointer PixelDescriptionViewPointerType;
+
   /** Set/Get the image to render */
   itkSetObjectMacro(Image,ImageType);
   itkGetObjectMacro(Image,ImageType);
@@ -121,16 +145,31 @@ private:
 
   /** The rendering model */
   RenderingModelPointerType   m_RenderingModel;
+
+  /** The pixel description model */
+  PixelDescriptionModelPointerType m_PixelDescriptionModel;
   
   /** The view */
   ViewPointerType             m_View;
 
+  /** The pixel description view */
+  PixelDescriptionViewPointerType m_PixelDescriptionView;
+
+  /** Curve widget */
+  CurvesWidgetPointerType     m_CurveWidget;
+
   /** The widget controller */
   WidgetControllerPointerType m_Controller;
 
   /** The window */
   Fl_Window * m_Window;
 
+  Fl_Group *  m_FullGroup;
+
+   Fl_Group *  m_SideGroup;
+
+  Fl_Tile  *  m_Tile;
+
   /** Intial sizes */
   int m_Width;
   
diff --git a/Code/Visualization/otbStandardImageViewer.txx b/Code/Visualization/otbStandardImageViewer.txx
index e32eaaa9fe86b940083a4593969b6d72a38aea0b..b260cb68a874f37342b5dd9765c94a0ce432435d 100644
--- a/Code/Visualization/otbStandardImageViewer.txx
+++ b/Code/Visualization/otbStandardImageViewer.txx
@@ -25,19 +25,28 @@ namespace otb
 
 template <class TImage>  
 StandardImageViewer<TImage>
-::StandardImageViewer() : m_Image(), m_ImageLayer(), m_RenderingModel(), m_View(), m_Controller(), m_Window(),
-			  m_Width(800),m_Height(600), m_SideBarWidth(100)
+::StandardImageViewer() : m_Image(), m_ImageLayer(), m_RenderingModel(),m_PixelDescriptionModel(), m_View(), m_PixelDescriptionView(), m_CurveWidget(), m_Controller(), m_Window(),
+			  m_FullGroup(),m_SideGroup(),m_Tile(),m_Width(800),m_Height(600), m_SideBarWidth(200)
 {
   // Build a new rendering model
   m_RenderingModel = RenderingModelType::New();
+  m_PixelDescriptionModel = PixelDescriptionModelType::New();
+  m_PixelDescriptionModel->SetLayers(m_RenderingModel->GetLayers());
+
   // Build a view
-  m_View           = ViewType::New();
+  m_View                 = ViewType::New();
+  m_PixelDescriptionView = PixelDescriptionViewType::New();
+
   // Build a controller
   m_Controller     = WidgetControllerType::New();
+
+  // Build the curve widget
+  m_CurveWidget    = CurvesWidgetType::New();
   
   // Wire the MBC
   m_View->SetModel(m_RenderingModel);
   m_View->SetController(m_Controller);
+  m_PixelDescriptionView->SetModel(m_PixelDescriptionModel);
 
    // Add the resizing handler
   ResizingHandlerType::Pointer resizingHandler = ResizingHandlerType::New();
@@ -63,25 +72,43 @@ StandardImageViewer<TImage>
   changeScaleHandler->SetView(m_View);
   m_Controller->AddActionHandler(changeScaleHandler);
 
+// Add the pixel description action handler
+  PixelDescriptionActionHandlerType::Pointer pixelActionHandler = PixelDescriptionActionHandlerType::New();
+  pixelActionHandler->SetView(m_View);
+  pixelActionHandler->SetModel(m_PixelDescriptionModel);
+  m_Controller->AddActionHandler(pixelActionHandler);
+
+
   // Build the window
   m_Window = new Fl_Window(0,0,m_Width,m_Height);
-  
-  m_Window->add(m_View->GetFullWidget());
-  m_Window->resizable(m_View->GetFullWidget());
+  m_Tile = new Fl_Tile(0,0,m_Width,m_Height);
+  m_Window->add(m_Tile);
+  m_Window->resizable(m_Tile);
+    
+  m_Tile->add(m_View->GetFullWidget());
+  //   m_Tile->resizable(m_View->GetFullWidget());
+
+  m_Tile->add(m_View->GetScrollWidget());
+  m_Tile->add(m_View->GetZoomWidget());
+  m_Tile->add(m_CurveWidget);
+  m_Tile->add(m_PixelDescriptionView->GetPixelDescriptionWidget());
+
+  m_View->GetZoomWidget()->resize(m_Width-m_SideBarWidth,m_Height/4,m_SideBarWidth,m_Height/4);
   m_View->GetFullWidget()->resize(0,0,m_Width-m_SideBarWidth,m_Height);
-
-  m_Window->add(m_View->GetScrollWidget());
   m_View->GetScrollWidget()->resize(m_Width-m_SideBarWidth,0,m_SideBarWidth,m_Height/4);
-  
-  m_Window->add(m_View->GetZoomWidget());
-  m_View->GetZoomWidget()->resize(m_Width-m_SideBarWidth,m_Height/4,m_SideBarWidth,m_Height/2);
-  
+  m_CurveWidget->resize(m_Width-m_SideBarWidth,m_Height/2,m_SideBarWidth,m_Height/4);
+  m_PixelDescriptionView->GetPixelDescriptionWidget()->resize(m_Width-m_SideBarWidth,3*m_Height/4,m_SideBarWidth,m_Height/4);
 }
 
 template <class TImage>  
 StandardImageViewer<TImage>
 ::~StandardImageViewer()
 {
+  m_Tile->remove(m_View->GetScrollWidget());
+  m_Tile->remove(m_View->GetFullWidget());
+  m_Tile->remove(m_View->GetZoomWidget());
+  m_Tile->remove(m_CurveWidget);
+  m_Tile->remove(m_PixelDescriptionView->GetPixelDescriptionWidget());
   delete m_Window;
 }
 
@@ -90,16 +117,68 @@ void
 StandardImageViewer<TImage>
 ::Update()
 {
+  if(m_Image.IsNull())
+    {
+    itkExceptionMacro(<<"The image pointer is null, there is nothing to display. You probably forget to set the image.");
+    }
+
+  // TODO: Add a real label here
+  m_Window->label("The label");
+
+  // Generate the layer
+ ImageLayerGeneratorPointerType generator = ImageLayerGeneratorType::New();
+  generator->SetImage(m_Image);
+  generator->GenerateLayer();
   
+  m_ImageLayer = generator->GetLayer();
 
+  m_RenderingModel->AddLayer(generator->GetLayer());
 
+  m_Window->show();
 
+  m_View->GetScrollWidget()->show();
+  m_View->GetFullWidget()->show();
+  m_View->GetZoomWidget()->show();
+  m_CurveWidget->show();
+  
+  m_RenderingModel->Update();
 
+  // adding histograms
+  typename HistogramCurveType::ColorType red,green,blue, gray;
+  red.Fill(0);
+  red[0]=1.;
+  red[3]=0.5;
 
+  green.Fill(0);
+  green[1]=1.;
+  green[3]=0.5;
 
+  blue.Fill(0);
+  blue[2]=1.;
+  blue[3]=0.5;
 
+  gray.Fill(0.5);
+
+  typename HistogramCurveType::Pointer rhistogram = HistogramCurveType::New();
+  rhistogram->SetHistogram(m_ImageLayer->GetHistogramList()->GetNthElement(0));
+  rhistogram->SetHistogramColor(red);
+  rhistogram->SetLabelColor(red);
+  
+  typename HistogramCurveType::Pointer ghistogram = HistogramCurveType::New();
+  ghistogram->SetHistogram(m_ImageLayer->GetHistogramList()->GetNthElement(1));
+  ghistogram->SetHistogramColor(green);
+  ghistogram->SetLabelColor(green);
+
+  typename HistogramCurveType::Pointer bhistogram = HistogramCurveType::New();
+  bhistogram->SetHistogram(m_ImageLayer->GetHistogramList()->GetNthElement(2));
+  bhistogram->SetHistogramColor(blue);
+  bhistogram->SetLabelColor(blue);
+  m_CurveWidget->AddCurve(rhistogram);
+  m_CurveWidget->AddCurve(ghistogram);
+  m_CurveWidget->AddCurve(bhistogram);
+  m_CurveWidget->SetXAxisLabel("Pixels");
+  m_CurveWidget->SetYAxisLabel("Amount");
 
-  m_Window->show();
 
 }
 }
diff --git a/Code/Visualization/otbStandardRenderingFunction.h b/Code/Visualization/otbStandardRenderingFunction.h
index df3a35288a970f5b1db3255ab22df6aa280be980..0cafd81aca245730fccbac704cff273875c5ec52 100644
--- a/Code/Visualization/otbStandardRenderingFunction.h
+++ b/Code/Visualization/otbStandardRenderingFunction.h
@@ -113,8 +113,8 @@ public:
   {
     itk::OStringStream oss;
     OutputPixelType output = this->Evaluate(vpixel);
-    oss<<"R[chan="  <<m_RedChannelIndex   <<" val="<< vpixel[m_RedChannelIndex]   <<" disp="<<static_cast<unsigned int>(output[0])<<"], ";
-    oss<<"G[chan="<<m_GreenChannelIndex   <<" val="<< vpixel[m_GreenChannelIndex] <<" disp="<<static_cast<unsigned int>(output[1])<<"], ";
+    oss<<"R[chan="  <<m_RedChannelIndex   <<" val="<< vpixel[m_RedChannelIndex]   <<" disp="<<static_cast<unsigned int>(output[0])<<"]\n";
+    oss<<"G[chan="<<m_GreenChannelIndex   <<" val="<< vpixel[m_GreenChannelIndex] <<" disp="<<static_cast<unsigned int>(output[1])<<"]\n";
     oss<<"B[chan=" <<m_BlueChannelIndex   <<" val="<< vpixel[m_BlueChannelIndex]  <<" disp="<<static_cast<unsigned int>(output[2])<<"]";
     return oss.str();
 
diff --git a/Testing/Code/Visualization/CMakeLists.txt b/Testing/Code/Visualization/CMakeLists.txt
index 59db4889ae64c180bf88d8a60dabbcaad11bea34..619a893e96cb6d5a934a03ba626ebd66b5095c21 100644
--- a/Testing/Code/Visualization/CMakeLists.txt
+++ b/Testing/Code/Visualization/CMakeLists.txt
@@ -57,6 +57,10 @@ ADD_TEST(vrTuImageLayerNew ${VISUREFAC_TESTS1}
 otbImageLayerNew
 )
 
+ADD_TEST(vrTvImageLayer ${VISUREFAC_TESTS1}
+otbImageLayer
+)
+
 ADD_TEST(vrTvImageLayerScalar ${VISUREFAC_TESTS1}
 --compare-n-images ${TOL} 3
 ${BASELINE}/vrTvImageLayerScalarQuicklookOutput.png
@@ -277,6 +281,11 @@ ADD_TEST(vrTuStandardImageViewerNew ${VISUREFAC_TESTS1}
 otbStandardImageViewerNew
 )
 
+ADD_TEST(vrTvStandardImageViewer ${VISUREFAC_TESTS1}
+otbStandardImageViewer
+${INPUTDATA}/couleurs.tif 0
+)
+
 # Testing srcs
 SET(Visualization_SRCS1
 otbImageWidgetNew.cxx
@@ -315,6 +324,7 @@ otbVectorDataGlComponentNew.cxx
 otbImageWidgetWithVectorDataGlComponent.cxx
 otbImageViewerEndToEndWithVectorData.cxx
 otbStandardImageViewerNew.cxx
+otbStandardImageViewer.cxx
 )
 
 # Building testing executables
diff --git a/Testing/Code/Visualization/otbStandardImageViewer.cxx b/Testing/Code/Visualization/otbStandardImageViewer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..62b29154c748153471ed6b182d33003b3625a3ce
--- /dev/null
+++ b/Testing/Code/Visualization/otbStandardImageViewer.cxx
@@ -0,0 +1,48 @@
+/*=========================================================================
+
+Program:   ORFEO Toolbox
+Language:  C++
+Date:      $Date$
+Version:   $Revision$
+
+
+Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
+See OTBCopyright.txt for details.
+
+
+This software is distributed WITHOUT ANY WARRANTY; without even
+the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "otbStandardImageViewer.h"
+#include "otbVectorImage.h"
+#include "otbImageFileReader.h"
+
+int otbStandardImageViewer( int argc, char * argv[] )
+{
+  bool run = atoi(argv[2]);
+
+  typedef otb::VectorImage<double,2> ImageType;
+  typedef otb::ImageFileReader<ImageType> ReaderType;
+  typedef otb::StandardImageViewer<ImageType> ViewerType;
+
+  ReaderType::Pointer reader = ReaderType::New();
+  ViewerType::Pointer viewer = ViewerType::New();
+
+  reader->SetFileName(argv[1]);
+
+  viewer->SetImage(reader->GetOutput());
+  viewer->Update();
+  
+  if(run)
+    {
+    Fl::run();
+    }
+  else
+    {
+    Fl::check();
+    }
+
+  return EXIT_SUCCESS;
+}
diff --git a/Testing/Code/Visualization/otbVisualizationTests1.cxx b/Testing/Code/Visualization/otbVisualizationTests1.cxx
index 8d388d23d3921a3152664eb039819d9ae7d0a312..b4e51d26abe3f1a86dd167de682a07c13d564f5f 100644
--- a/Testing/Code/Visualization/otbVisualizationTests1.cxx
+++ b/Testing/Code/Visualization/otbVisualizationTests1.cxx
@@ -62,4 +62,5 @@ void RegisterTests()
   REGISTER_TEST(otbImageWidgetWithVectorDataGlComponent);
   REGISTER_TEST(otbImageViewerEndToEndWithVectorData);
   REGISTER_TEST(otbStandardImageViewerNew);
+  REGISTER_TEST(otbStandardImageViewer);
 }