From a3ee003efd32807cb313fa14a531fd4c2435396e Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Tue, 15 Nov 2011 10:15:56 +0100
Subject: [PATCH] ENH: One step toward parallel decoding (pre-sorting between
 tiles to decode and tiles from cache)

---
 Code/IO/otbJPEG2000ImageIO.cxx | 60 +++++++++++++++++++++++++---------
 Code/IO/otbJPEG2000ImageIO.h   | 11 +++++++
 2 files changed, 56 insertions(+), 15 deletions(-)

diff --git a/Code/IO/otbJPEG2000ImageIO.cxx b/Code/IO/otbJPEG2000ImageIO.cxx
index 6ec0cb7721..5d4c4ea1e4 100644
--- a/Code/IO/otbJPEG2000ImageIO.cxx
+++ b/Code/IO/otbJPEG2000ImageIO.cxx
@@ -629,7 +629,6 @@ void JPEG2000ImageIO::Read(void* buffer)
       }
     itkExceptionMacro(<< " IORegion is not correct in terme of tile!");
     }
-
   // Get nb. of lines and columns of the region to read
   int lNbLines     = this->GetIORegion().GetSize()[1];
   int lNbColumns   = this->GetIORegion().GetSize()[0];
@@ -645,24 +644,50 @@ void JPEG2000ImageIO::Read(void* buffer)
   otbMsgDevMacro(<< "Component type: " << this->GetComponentTypeAsString(this->GetComponentType()));
 
 
-  // Decode tile need
-  for (std::vector<unsigned int>::iterator itTile = tileList.begin(); itTile < tileList.end(); itTile++)
+  // Here we sort between tiles from cache and tiles to read
+  std::vector<JPEG2000TileCache::CachedTileType> cachedTiles;
+  std::vector<JPEG2000TileCache::CachedTileType> toReadTiles;
+  std::vector<JPEG2000TileCache::CachedTileType> allNeededTiles;
+
+  for (std::vector<unsigned int>::iterator itTile = tileList.begin(); itTile < tileList.end(); ++itTile)
+    {
+    opj_image_t * currentImage = m_TileCache->GetTile(*itTile);
+
+    JPEG2000TileCache::CachedTileType currentTile = std::make_pair((*itTile),currentImage);
+
+    if(!currentImage)
+      {
+      toReadTiles.push_back(currentTile);
+      }
+    else
+      {
+      cachedTiles.push_back(currentTile);
+      }
+    }
+
+  // Decode all tiles not in cache
+  for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = toReadTiles.begin(); itTile < toReadTiles.end(); ++itTile)
     {
-    opj_image_t * currentTile = m_TileCache->GetTile(*itTile);
+    // Call the reader
+    itTile->second = m_InternalReaders.front()->DecodeTile(itTile->first);
     
-    if(!currentTile)
+    // Check if tile is valid
+    if(!itTile->second)
       {
-      currentTile = m_InternalReaders.front()->DecodeTile(*itTile);
-      
-      if(!currentTile)
-        {
-        this->m_InternalReaders.front()->Clean();
-        itkExceptionMacro(<< " otbopenjpeg failed to decode the desired tile "<< *itTile << "!");
-        }
-      m_TileCache->AddTile((*itTile),currentTile);
+      this->m_InternalReaders.front()->Clean();
+      itkExceptionMacro(<< " otbopenjpeg failed to decode the desired tile "<< itTile->first << "!");
       }
+    otbMsgDevMacro(<< " Tile " << itTile->first << " is decoded.");
+    }
 
-    otbMsgDevMacro(<< " Tile " << *itTile << " is decoded.");
+  // Build the list of all tiles
+  allNeededTiles = cachedTiles;
+  allNeededTiles.insert(allNeededTiles.end(),toReadTiles.begin(),toReadTiles.end());
+
+  
+  for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = allNeededTiles.begin(); itTile < allNeededTiles.end(); ++itTile)
+    {
+    opj_image_t * currentTile = itTile->second;
 
     unsigned int lWidthSrc; // Width of the input pixel in nb of pixel
     unsigned int lHeightDest; // Height of the area where write in nb of pixel
@@ -753,9 +778,14 @@ void JPEG2000ImageIO::Read(void* buffer)
         itkGenericExceptionMacro(<< "This data type is not handled");
         break;
       }
-
     }
+  
 
+  // Now, do cache book-keeping
+  for (std::vector<JPEG2000TileCache::CachedTileType>::iterator itTile = toReadTiles.begin(); itTile < toReadTiles.end(); ++itTile)
+    {
+    m_TileCache->AddTile(itTile->first,itTile->second);
+    }
   chrono.Stop();
   otbMsgDevMacro( << "JPEG2000ImageIO::Read took " << chrono.GetTotal() << " sec");
 
diff --git a/Code/IO/otbJPEG2000ImageIO.h b/Code/IO/otbJPEG2000ImageIO.h
index ad2030d5d5..a81d999dcc 100644
--- a/Code/IO/otbJPEG2000ImageIO.h
+++ b/Code/IO/otbJPEG2000ImageIO.h
@@ -126,6 +126,17 @@ private:
    * (e.g., ImageSource). */
   itk::MultiThreader::Pointer m_Threader;
   int                    m_NumberOfThreads;
+
+  /** Static function used as a "callback" by the MultiThreader.  The threading
+   * library will call this routine for each thread, which will delegate the
+   * control to ThreadedGenerateData(). */
+  static ITK_THREAD_RETURN_TYPE ThreaderCallback( void *arg );
+
+  /** Internal structure used for passing image data into the threading library */
+  struct ThreadStruct
+    {
+    Pointer Filter;
+    };
 };
 
 } // end namespace otb
-- 
GitLab