creaImageIOMultiThreadImageReader.h

Go to the documentation of this file.
00001 #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__
00002 #define __creaImageIOThreadedImageReader_h_INCLUDED__
00003 
00004 #include <creaImageIOSystem.h>
00005 #include <creaImageIOImageReader.h>
00006 #include <creaImageIOIndexedHeap.h>
00007 #include <map>
00008 #include <deque>
00009 #include <wx/thread.h>
00010 #include <queue>
00011 
00012 
00013 
00014 namespace creaImageIO
00015 {
00019   //=====================================================================
00020   class ThreadedImageReader;
00021   class MultiThreadImageReader;
00022   //=====================================================================
00023   
00024   //=====================================================================
00025   class CREAIMAGEIO_EXPORT MultiThreadImageReaderUser
00026   {
00027   public:
00028     friend class ThreadedImageReader;
00029     friend class MultiThreadImageReader;
00030 
00031     MultiThreadImageReaderUser() {}
00032     virtual ~MultiThreadImageReaderUser() {}
00033 
00034     typedef enum 
00035       {
00036         ThreadedReaderStarted,
00037         ThreadedReaderStopped,
00038         ImageLoaded,
00039         ImageUnloaded,
00040         Error
00041       }
00042       EventType;
00049     virtual void OnMultiThreadImageReaderEvent( const std::string& filename,
00050                                                 EventType type,
00051                                                 vtkImageData* image) 
00052     {}
00053     inline void MultiThreadImageReaderEventLock() 
00054     { mMultiThreadImageReaderUserMutex.Lock(); }
00055     inline void MultiThreadImageReaderEventUnlock() 
00056     { mMultiThreadImageReaderUserMutex.Unlock(); }
00057     inline wxMutex& GetMultiThreadImageReaderUserMutex() 
00058     { return mMultiThreadImageReaderUserMutex; }
00059   private:
00061     void MultiThreadImageReaderSendEvent( const std::string& filename,
00062                                           EventType type,
00063                                           vtkImageData* image);
00064     wxMutex mMultiThreadImageReaderUserMutex;
00065   };
00066   //=====================================================================
00067 
00068   //=====================================================================
00071 
00073   class MultiThreadImageReader : public MultiThreadImageReaderUser
00074   {
00075   public:
00076     friend class ThreadedImageReader;
00077 
00079     MultiThreadImageReader(int number_of_threads = 1);
00081     ~MultiThreadImageReader();
00082 
00085     bool Start();
00087     void Stop();
00088 
00092     void Request( MultiThreadImageReaderUser* user,
00093                   const std::string& filename, 
00094                   int priority );
00095     
00099     vtkImageData* GetImage(const std::string& filename);
00100 
00102     int GetMaximalPriority(); 
00103     
00105     void OnMultiThreadImageReaderEvent( const std::string& filename,
00106                                         EventType type,
00107                                         vtkImageData* image);
00108    
00110         void getAttributes(const std::string filename, std::map <std::string , std::string> &infos, std::vector<std::string> i_attr);
00111 
00112   protected:
00113           bool mDone;
00114     int GetMaximalPriorityWithoutLocking();
00116     class ImageToLoad
00117     {
00118     public:
00119       ImageToLoad( MultiThreadImageReaderUser* user,
00120                    const std::string& filename, 
00121                    int prio=0) 
00122         : mUser(user),
00123           mFilename(filename), 
00124           mPriority(prio), 
00125           mIndex(-1), 
00126           mUnloadIndex(-1), 
00127           mImage(0)
00128       {}
00129       ~ImageToLoad()
00130       {
00131         if (mImage>0) 
00132           {
00133             //      std::cout << "Refs = "<<mImage->GetReferenceCount()<<std::endl;
00134             mImage->Delete();
00135           }
00136       }
00137       MultiThreadImageReaderUser* GetUser() const { return mUser; }
00138       void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
00139       const std::string& GetFilename() const { return mFilename; }
00140       int GetPriority() const { return mPriority; }
00141       void SetPriority(int p) { mPriority=p; }
00142       int& Index() { return mIndex; }
00143       int& UnloadIndex() { return mUnloadIndex; }
00144       vtkImageData* GetImage() const { return mImage; }
00145       void SetImage( vtkImageData* i ) { mImage=i; }
00146 
00147           std::map<std::string, std::string> getAttributes(const std::vector<std::string> i_attr);
00148     private:
00149       MultiThreadImageReaderUser* mUser;
00150       std::string mFilename;
00151       int mPriority;
00152       int mIndex;
00153       int mUnloadIndex;
00154       vtkImageData* mImage;
00155     };
00156     // 
00157 
00159     typedef ImageToLoad* ImageToLoadPtr;
00160 
00162     struct ImageToLoadPtrPriorityComparator
00163     {
00164       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
00165         const 
00166       {
00167         return ( a->GetPriority() > b->GetPriority() );
00168       }
00169     };
00171     struct ImageToLoadPtrInversePriorityComparator
00172     {
00173       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
00174         const 
00175       {
00176         return ( a->GetPriority() < b->GetPriority() );
00177       }
00178     };
00179 
00180 
00182     struct ImageToLoadPtrFilenameComparator
00183     {
00184       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
00185         const 
00186       {
00187         return ( a->GetFilename() < b->GetFilename() );
00188       }
00189     };
00190 
00192     struct ImageToLoadPtrIndexer
00193     {
00194       int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
00195     };
00197     struct ImageToUnloadPtrIndexer
00198     {
00199       int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
00200     };
00201 
00203     void SignalImageRead(ImageToLoadPtr p, bool purge);
00204   
00206     typedef std::map<ImageToLoadPtr,vtkImageData*,
00207                      ImageToLoadPtrFilenameComparator> ImageMapType;
00209     ImageMapType mImages;
00211     ImageToLoadPtrPriorityComparator mComparator;
00213     ImageToLoadPtrIndexer mIndexer;
00215     IndexedHeap<ImageToLoadPtr,
00216                 ImageToLoadPtrPriorityComparator,
00217                 ImageToLoadPtrIndexer> mQueue;
00218 
00220         typedef std::vector<boost::shared_ptr<ThreadedImageReader> > ThreadedImageReaderListType;
00221         //typedef std::vector<ThreadedImageReader* > ThreadedImageReaderListType;
00222     ThreadedImageReaderListType mThreadedImageReaderList;
00224     int mNumberOfThreadedReadersRunning;
00228     //  wxMutex mMutex;
00229 
00231     std::string mRequestedFilename;
00233     vtkImageData* mRequestedImage;
00234 
00236     ImageReader* mReader;
00237 
00241     IndexedHeap<ImageToLoadPtr,
00242                 ImageToLoadPtrInversePriorityComparator,
00243                 ImageToUnloadPtrIndexer> mUnloadQueue;
00244 
00245     void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
00246     long mTotalMem;
00247     long mTotalMemMax;
00248 
00249 
00250   }; // class MultiThreadImageReader
00251   //=====================================================================
00252 
00253 
00254 
00255 } // namespace creaImageIO
00256 
00257 
00258 
00259 #endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__