]> Creatis software - creaImageIO.git/blob - src/creaImageIOMultiThreadImageReader.h
461d2c31397c2a83d6865ed1c24a134bc0214607
[creaImageIO.git] / src / creaImageIOMultiThreadImageReader.h
1 #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__
2 #define __creaImageIOThreadedImageReader_h_INCLUDED__
3
4 #include <creaImageIOSystem.h>
5 #include <creaImageIOImageReader.h>
6 #include <creaImageIOIndexedHeap.h>
7 #include <map>
8 #include <deque>
9 #include <wx/thread.h>
10 #include <queue>
11
12
13
14 namespace creaImageIO
15 {
16         /**
17         * \ingroup IO
18         */
19   //=====================================================================
20   class ThreadedImageReader;
21   class MultiThreadImageReader;
22   //=====================================================================
23   
24   //=====================================================================
25   class CREAIMAGEIO_EXPORT MultiThreadImageReaderUser
26   {
27   public:
28     friend class ThreadedImageReader;
29     friend class MultiThreadImageReader;
30
31     MultiThreadImageReaderUser() {}
32     virtual ~MultiThreadImageReaderUser() {}
33
34     typedef enum 
35       {
36         ThreadedReaderStarted,
37         ThreadedReaderStopped,
38         ImageLoaded,
39         ImageUnloaded,
40         Error
41       }
42       EventType;
43     /// The virtual method to overload by MultiThreadImageReader users
44       /// It is called when an image has been loaded or unloaded 
45       /// Provides :
46       /// * The image file name which was requested 
47       /// * The type of event 
48       /// * If type==ImageLoaded the image pointer, else NULL pointer 
49     virtual void OnMultiThreadImageReaderEvent( const std::string& filename,
50                                                 EventType type,
51                                                 vtkImageData* image) 
52     {}
53     inline void MultiThreadImageReaderEventLock() 
54     { mMultiThreadImageReaderUserMutex.Lock(); }
55     inline void MultiThreadImageReaderEventUnlock() 
56     { mMultiThreadImageReaderUserMutex.Unlock(); }
57     inline wxMutex& GetMultiThreadImageReaderUserMutex() 
58     { return mMultiThreadImageReaderUserMutex; }
59   private:
60     /// 
61     void MultiThreadImageReaderSendEvent( const std::string& filename,
62                                           EventType type,
63                                           vtkImageData* image);
64     wxMutex mMultiThreadImageReaderUserMutex;
65   };
66   //=====================================================================
67
68   //=====================================================================
69   /// 
70   /// TAKE CARE : For the moment it only supports a **SINGLE USER** 
71
72    ///Class that allows parallel lectures of several images
73   class MultiThreadImageReader : public MultiThreadImageReaderUser
74   {
75   public:
76     friend class ThreadedImageReader;
77
78     /// Ctor with the number of threads to use
79     MultiThreadImageReader(int number_of_threads = 1);
80     /// Dtor 
81     ~MultiThreadImageReader();
82
83     /// Starts the reader = create the threads which start to check 
84     /// periodically the queue of requested images to read
85     bool Start();
86     /// Stops the reader = stops the threads and delete the images loaded
87     void Stop();
88
89     /// Request the image "filename" with a given priority 
90     /// When the image is ready (or an error occurred) 
91     /// The observer's callback is invoked 
92     void Request( MultiThreadImageReaderUser* user,
93                   const std::string& filename, 
94                   int priority );
95     
96     /// Request the image "filename" immediately 
97         /// Blocks until image loaded
98     /// (no user callback but image returned)
99     vtkImageData* GetImage(const std::string& filename);
100
101     /// 
102     int GetMaximalPriority(); 
103     
104     ///
105     void OnMultiThreadImageReaderEvent( const std::string& filename,
106                                         EventType type,
107                                         vtkImageData* image);
108    
109     /// Function to read attributes for a file 
110         void getAttributes(const std::string filename, std::map <std::string , std::string> &infos, std::vector<std::string> i_attr);
111
112   protected:
113           bool mDone;
114     int GetMaximalPriorityWithoutLocking();
115     ///Class that represents an image to be loaded
116     class ImageToLoad
117     {
118     public:
119       ImageToLoad( MultiThreadImageReaderUser* user,
120                    const std::string& filename, 
121                    int prio=0) 
122         : mUser(user),
123           mFilename(filename), 
124           mPriority(prio), 
125           mIndex(-1), 
126           mUnloadIndex(-1), 
127           mImage(0)
128       {}
129       ~ImageToLoad()
130       {
131         if (mImage>0) 
132           {
133             //      std::cout << "Refs = "<<mImage->GetReferenceCount()<<std::endl;
134             mImage->Delete();
135           }
136       }
137       MultiThreadImageReaderUser* GetUser() const { return mUser; }
138       void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
139       const std::string& GetFilename() const { return mFilename; }
140       int GetPriority() const { return mPriority; }
141       void SetPriority(int p) { mPriority=p; }
142       int& Index() { return mIndex; }
143       int& UnloadIndex() { return mUnloadIndex; }
144       vtkImageData* GetImage() const { return mImage; }
145       void SetImage( vtkImageData* i ) { mImage=i; }
146
147           std::map<std::string, std::string> getAttributes(const std::vector<std::string> i_attr);
148     private:
149       MultiThreadImageReaderUser* mUser;
150       std::string mFilename;
151       int mPriority;
152       int mIndex;
153       int mUnloadIndex;
154       vtkImageData* mImage;
155     };
156     // 
157
158     /// Type of pointer on an ImageToLoad struct
159     typedef ImageToLoad* ImageToLoadPtr;
160
161     /// ImageToLoadPtr comparator on priority (for image queue)
162     struct ImageToLoadPtrPriorityComparator
163     {
164       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
165         const 
166       {
167         return ( a->GetPriority() > b->GetPriority() );
168       }
169     };
170     /// ImageToLoadPtr comparator on inverse priority (for image to unload queue)
171     struct ImageToLoadPtrInversePriorityComparator
172     {
173       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
174         const 
175       {
176         return ( a->GetPriority() < b->GetPriority() );
177       }
178     };
179
180
181     /// ImageToLoadPtr comparator on filename (for image map)
182     struct ImageToLoadPtrFilenameComparator
183     {
184       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
185         const 
186       {
187         return ( a->GetFilename() < b->GetFilename() );
188       }
189     };
190
191     /// ImageToLoadPtr indexer for image queue
192     struct ImageToLoadPtrIndexer
193     {
194       int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
195     };
196     /// ImageToLoadPtr indexer for to unload image queue
197     struct ImageToUnloadPtrIndexer
198     {
199       int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
200     };
201
202     /// The callback from threaded readers when an image is read
203     void SignalImageRead(ImageToLoadPtr p, bool purge);
204   
205     /// The type of map of images 
206     typedef std::map<ImageToLoadPtr,vtkImageData*,
207                      ImageToLoadPtrFilenameComparator> ImageMapType;
208     /// The map of images
209     ImageMapType mImages;
210     /// Comparator for the image to load queue
211     ImageToLoadPtrPriorityComparator mComparator;
212     /// Indexer for the image to load queue 
213     ImageToLoadPtrIndexer mIndexer;
214     /// The image to load priority queue
215     IndexedHeap<ImageToLoadPtr,
216                 ImageToLoadPtrPriorityComparator,
217                 ImageToLoadPtrIndexer> mQueue;
218
219     /// The type of list of threaded readers
220         typedef std::vector<boost::shared_ptr<ThreadedImageReader> > ThreadedImageReaderListType;
221         //typedef std::vector<ThreadedImageReader* > ThreadedImageReaderListType;
222     ThreadedImageReaderListType mThreadedImageReaderList;
223     /// The number of currently running threaded readers
224     int mNumberOfThreadedReadersRunning;
225     /// The mutex used to access safely internal data from any thread
226     /// LG : Removed ! We now use the embedded mutex in User from which 
227     /// we inherit...
228     //  wxMutex mMutex;
229
230     /// For GetImage : the filename requested
231     std::string mRequestedFilename;
232     /// For GetImage : the image requested
233     vtkImageData* mRequestedImage;
234
235     /// If number of threads == 0 then uses an internal non-threaded reader
236     ImageReader* mReader;
237
238     /// The type of list of images loaded 
239     /// used to unload oldest image when memory limit exceeded
240    /// The image to unload priority queue
241     IndexedHeap<ImageToLoadPtr,
242                 ImageToLoadPtrInversePriorityComparator,
243                 ImageToUnloadPtrIndexer> mUnloadQueue;
244
245     void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
246     long mTotalMem;
247     long mTotalMemMax;
248
249
250   }; // class MultiThreadImageReader
251   //=====================================================================
252
253
254
255 } // namespace creaImageIO
256
257
258
259 #endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__