From 2f27bff3a4b34442c55c7c61405a64b6cd0eb96b Mon Sep 17 00:00:00 2001
From: Mickael Savinaud <mickael.savinaud@c-s.fr>
Date: Mon, 25 Feb 2013 16:14:21 +0100
Subject: [PATCH] ENH: support resolution navigation into the file : clean and
 small refactoring about best level of detatil refactoring + reduce the file
 acess

---
 Code/Common/mvdImageModelRenderer.cxx |  41 +++++-----
 Code/Common/mvdVectorImageModel.cxx   | 108 ++++++--------------------
 Code/Common/mvdVectorImageModel.h     |  12 ++-
 3 files changed, 46 insertions(+), 115 deletions(-)

diff --git a/Code/Common/mvdImageModelRenderer.cxx b/Code/Common/mvdImageModelRenderer.cxx
index 79d0f8ae7b..4815b23a34 100644
--- a/Code/Common/mvdImageModelRenderer.cxx
+++ b/Code/Common/mvdImageModelRenderer.cxx
@@ -77,31 +77,26 @@ void ImageModelRenderer::paintGL( const RenderingContext& context )
   // the region of the image to be rendered
   const ImageRegionType&  region = context.m_ImageRegion;
 
-  // If the image is a j2k image
-  int lod = 0;
-  CountType lodCount = 0;
   ImageRegionType  scaledRegion = region;
-  if ( viModel->GetBestLevelOfDetail(context.m_IsotropicZoom, lod, lodCount) )
+  CountType bestLod = viModel->ComputeBestLevelOfDetail(context.m_IsotropicZoom);
+
+  // If it is not the original level of detail recompute the region to request
+  if (bestLod != 0)
     {
-    // if the level of detail is an overview
-    // recompute the region to request
-    if (lod != 0)
-      {
-      ImageRegionType::SizeType  scaledSize;
-      ImageRegionType::IndexType scaledOrigin;
-      
-      scaledSize[0] = region.GetSize()[0]/(1<<lod);
-      scaledSize[1] = region.GetSize()[1]/(1<<lod);
-      
-      scaledOrigin[0] = region.GetIndex()[0]/(1<<lod);
-      scaledOrigin[1] = region.GetIndex()[1]/(1<<lod);
-      
-      scaledRegion.SetSize(scaledSize) ;
-      scaledRegion.SetIndex(scaledOrigin);
-      }
-    // TODO : remove verbosity 
-    std::cout <<"J2k resolution requested :" << lod<< std::endl;
+    ImageRegionType::SizeType  scaledSize;
+    ImageRegionType::IndexType scaledOrigin;
+
+    scaledSize[0] = region.GetSize()[0]/(1<<bestLod);
+    scaledSize[1] = region.GetSize()[1]/(1<<bestLod);
+
+    scaledOrigin[0] = region.GetIndex()[0]/(1<<bestLod);
+    scaledOrigin[1] = region.GetIndex()[1]/(1<<bestLod);
+
+    scaledRegion.SetSize(scaledSize) ;
+    scaledRegion.SetIndex(scaledOrigin);
     }
+  // TODO : remove verbosity
+  std::cout <<"Level of detail requested:" << bestLod << std::endl;
 
   if (!m_IsMoving)
     {
@@ -112,7 +107,7 @@ void ImageModelRenderer::paintGL( const RenderingContext& context )
     }
 
   // current resolution
-  double currentResolutionFactor = 1 << lod;
+  double currentResolutionFactor = 1 << bestLod;
 
   // final zoom factor : take into account the current resolution of
   // the file and the wheel zoom
diff --git a/Code/Common/mvdVectorImageModel.cxx b/Code/Common/mvdVectorImageModel.cxx
index 8b7094097a..2147d191af 100644
--- a/Code/Common/mvdVectorImageModel.cxx
+++ b/Code/Common/mvdVectorImageModel.cxx
@@ -72,8 +72,7 @@ VectorImageModel
   m_AlreadyLoadedRegion(),
   m_Region(),
   m_RegionsToLoadVector(),
-  m_Filename(),
-  m_NbLod( 0 )
+  m_Filename()
 {
 }
 
@@ -232,16 +231,13 @@ VectorImageModel
 {
   m_Region = region;
 
-  // Set the best level of detail
-  int best_lod = 0;
-  CountType nbLod = 0;
+  // Compute the best level of detail
+  int bestLod = this->ComputeBestLevelOfDetail(zoomFactor);
 
-  if ( this->GetBestLevelOfDetail(zoomFactor, best_lod, nbLod) )
+  // Set the corresponding Level of Detail
+  if( GetCurrentLod()!=bestLod )
     {
-    if( GetCurrentLod()!=best_lod )
-      {
-      this->SetCurrentLod(best_lod);
-      }
+    this->SetCurrentLod(bestLod);
     }
 
   // Don't do anything if the region did not changed
@@ -489,46 +485,12 @@ size[0] = vcl_abs(static_cast<int>(region.GetSize()[0] + region.GetIndex()[0]
 }
 
 /*******************************************************************************/
-bool
-VectorImageModel::GetBestLevelOfDetail(const double zoomFactor,
-				       int& lod,
-				       CountType& nbLod)
+CountType
+VectorImageModel::ComputeBestLevelOfDetail(const double zoomFactor)
 {
-  //TODO: Optimize method (minimize JPEG2000 readers; preprocess LOD).
-
-  // Note : index 0 is the full resolution image
-
   int inverseZoomFactor =  static_cast<int>((1/zoomFactor + 0.5));
-
-  // By default, there is only one LOD level: the native image (level zero).
-  nbLod = 1;
-
-  typedef otb::VectorImage<unsigned int , 2> ImageType;
-  typedef otb::ImageFileReader<ImageType> ReaderType;
-  ReaderType::Pointer reader = ReaderType::New();
-  reader->SetFileName(m_Filename.toLatin1().constData());
-  reader->UpdateOutputInformation();
-
-
-
-  std::vector<unsigned int> res;
-  if (reader->GetAvailableResolutions(res) )
-    {
-    // Compute the best lod from inverseZoomFactor and resolution of the file
-    lod = this->Closest(inverseZoomFactor, res);
-    std::cout << "LOD = " << lod <<std::endl;
-
-    // Return the number of LOD levels
-    nbLod = res.size();
-    std::cout << "nbLOD = " << nbLod <<std::endl;
-
-    return true;
-    }
-  else
-    {
-    return false;
-    }
-
+  CountType bestLod = this->Closest(inverseZoomFactor, m_AvailableLod);
+  return bestLod;
 }
 
 /*******************************************************************************/
@@ -559,22 +521,19 @@ VectorImageModel
 ::SetupCurrentLodImage( int width, int height )
 {
   // Get the largest possible region of the image
-  DefaultImageFileReaderType::Pointer tmpReader(
-    DefaultImageFileReaderType::New() );
+  m_ImageFileReader = DefaultImageFileReaderType::New() ;
 
-  tmpReader->SetFileName( static_cast<const char*>(m_Filename.toAscii()) );
-  tmpReader->UpdateOutputInformation();
+  m_ImageFileReader->SetFileName( static_cast<const char*>(m_Filename.toAscii()) );
+  m_ImageFileReader->UpdateOutputInformation();
+  // Retrieve the list of Lod from file
+  m_ImageFileReader->GetAvailableResolutions(m_AvailableLod);
 
   // Get native image largest region, which is LOD level zero.
   ImageRegionType nativeLargestRegion =
-    tmpReader->GetOutput()->GetLargestPossibleRegion();
+      m_ImageFileReader->GetOutput()->GetLargestPossibleRegion();
 
-  // Initialize lod count.
-  CountType nbLod = 1;
-  bool hasBestLod = false;
-  int bestLod = 0;
-
-  // Try to compute best LOD.
+  CountType bestInitialLod = 0;
+  // Compute the initial zoom factor and the best LOD.
   if( width>0 && height>0 )
     {
     double factorX =
@@ -583,36 +542,16 @@ VectorImageModel
     double factorY =
       double( height ) / double( nativeLargestRegion.GetSize()[ 1 ] );
 
-  double initialZoomFactor = std::min(factorX, factorY);
+    double initialZoomFactor = std::min(factorX, factorY);
 
-  // if mutli-resolution file
-  hasBestLod = GetBestLevelOfDetail(initialZoomFactor, bestLod, nbLod);
+    // Compute the best lod from the initialZoomFactor
+    bestInitialLod = ComputeBestLevelOfDetail(initialZoomFactor);
     }
 
-  // If best-lod is available for multi-resolution image.
-  if( hasBestLod )
-    {
-    // Change current-lod: update m_ImageFileReader, m_Image and
-    // current LOD index.
-    this->SetCurrentLod( bestLod );
-    }
-
-  else // Otherwise
-    {
-    // Leave current LOD index to 0.
-
-    // Update m_ImageFileReader
-    m_ImageFileReader = tmpReader;
-    
-    // Update m_Image
-    m_Image = m_ImageFileReader->GetOutput();
-    }
+    this->SetCurrentLod( bestInitialLod );
 
   // Remember native largest region.
   m_NativeLargestRegion = nativeLargestRegion;
-
-  // Remember number of LOD levels.
-  m_NbLod = nbLod;
 }
 
 /*******************************************************************************/
@@ -620,8 +559,7 @@ CountType
 VectorImageModel
 ::GetNbLod() const
 {
-  // TODO: Implement method.
-  return m_NbLod;
+  return m_AvailableLod.size();
 }
 
 /*******************************************************************************/
diff --git a/Code/Common/mvdVectorImageModel.h b/Code/Common/mvdVectorImageModel.h
index dfe4d9c619..00ab257460 100644
--- a/Code/Common/mvdVectorImageModel.h
+++ b/Code/Common/mvdVectorImageModel.h
@@ -286,12 +286,9 @@ public:
                                   bool refresh);
 
   /**
-   * Following the zoom factor, get the best level of detail knowing
-   * the overviews size
+   * Following the zoom factor, get the best level of detail
    */
-  bool GetBestLevelOfDetail(const double ZoomFactor,
-			    int& lod,
-			    CountType& lodCount );
+  CountType ComputeBestLevelOfDetail(const double ZoomFactor);
 
   //
   // AbstractImageModel overrides.
@@ -491,8 +488,9 @@ private:
   // store the input image filename
   QString m_Filename;
 
-  /** */
-  CountType m_NbLod;
+  /** List of all Level of detail (Resolution) available from the file */
+  UIntVector m_AvailableLod;
+
 
   /*-[ PRIVATE SLOTS SECTION ]-----------------------------------------------*/
 
-- 
GitLab