]> Creatis software - creaImageIO.git/blob - src2/creaImageIOMultiThreadImageReader.h
*** empty log message ***
[creaImageIO.git] / src2 / 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   protected:
110           bool mDone;
111     int GetMaximalPriorityWithoutLocking();
112     ///Class that represents an image to be loaded
113     class ImageToLoad
114     {
115     public:
116       ImageToLoad( MultiThreadImageReaderUser* user,
117                    const std::string& filename, 
118                    int prio=0) 
119         : mUser(user),
120           mFilename(filename), 
121           mPriority(prio), 
122           mIndex(-1), 
123           mUnloadIndex(-1), 
124           mImage(0)
125       {}
126       ~ImageToLoad()
127       {
128         if (mImage>0) 
129           {
130             //      std::cout << "Refs = "<<mImage->GetReferenceCount()<<std::endl;
131             mImage->Delete();
132           }
133       }
134       MultiThreadImageReaderUser* GetUser() const { return mUser; }
135       void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
136       const std::string& GetFilename() const { return mFilename; }
137       int GetPriority() const { return mPriority; }
138       void SetPriority(int p) { mPriority=p; }
139       int& Index() { return mIndex; }
140       int& UnloadIndex() { return mUnloadIndex; }
141       vtkImageData* GetImage() const { return mImage; }
142       void SetImage( vtkImageData* i ) { mImage=i; }
143     private:
144       MultiThreadImageReaderUser* mUser;
145       std::string mFilename;
146       int mPriority;
147       int mIndex;
148       int mUnloadIndex;
149       vtkImageData* mImage;
150     };
151     // 
152
153     /// Type of pointer on an ImageToLoad struct
154     typedef ImageToLoad* ImageToLoadPtr;
155
156     /// ImageToLoadPtr comparator on priority (for image queue)
157     struct ImageToLoadPtrPriorityComparator
158     {
159       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
160         const 
161       {
162         return ( a->GetPriority() > b->GetPriority() );
163       }
164     };
165     /// ImageToLoadPtr comparator on inverse priority (for image to unload queue)
166     struct ImageToLoadPtrInversePriorityComparator
167     {
168       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
169         const 
170       {
171         return ( a->GetPriority() < b->GetPriority() );
172       }
173     };
174
175
176     /// ImageToLoadPtr comparator on filename (for image map)
177     struct ImageToLoadPtrFilenameComparator
178     {
179       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
180         const 
181       {
182         return ( a->GetFilename() < b->GetFilename() );
183       }
184     };
185
186     /// ImageToLoadPtr indexer for image queue
187     struct ImageToLoadPtrIndexer
188     {
189       int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
190     };
191     /// ImageToLoadPtr indexer for to unload image queue
192     struct ImageToUnloadPtrIndexer
193     {
194       int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
195     };
196
197     /// The callback from threaded readers when an image is read
198     void SignalImageRead(ImageToLoadPtr p, bool purge);
199   
200     /// The type of map of images 
201     typedef std::map<ImageToLoadPtr,vtkImageData*,
202                      ImageToLoadPtrFilenameComparator> ImageMapType;
203     /// The map of images
204     ImageMapType mImages;
205     /// Comparator for the image to load queue
206     ImageToLoadPtrPriorityComparator mComparator;
207     /// Indexer for the image to load queue 
208     ImageToLoadPtrIndexer mIndexer;
209     /// The image to load priority queue
210     IndexedHeap<ImageToLoadPtr,
211                 ImageToLoadPtrPriorityComparator,
212                 ImageToLoadPtrIndexer> mQueue;
213
214     /// The type of list of threaded readers
215         typedef std::vector<boost::shared_ptr<ThreadedImageReader> > ThreadedImageReaderListType;
216         //typedef std::vector<ThreadedImageReader* > ThreadedImageReaderListType;
217     ThreadedImageReaderListType mThreadedImageReaderList;
218     /// The number of currently running threaded readers
219     int mNumberOfThreadedReadersRunning;
220     /// The mutex used to access safely internal data from any thread
221     /// LG : Removed ! We now use the embedded mutex in User from which 
222     /// we inherit...
223     //  wxMutex mMutex;
224
225     /// For GetImage : the filename requested
226     std::string mRequestedFilename;
227     /// For GetImage : the image requested
228     vtkImageData* mRequestedImage;
229
230     /// If number of threads == 0 then uses an internal non-threaded reader
231     ImageReader* mReader;
232
233     /// The type of list of images loaded 
234     /// used to unload oldest image when memory limit exceeded
235    /// The image to unload priority queue
236     IndexedHeap<ImageToLoadPtr,
237                 ImageToLoadPtrInversePriorityComparator,
238                 ImageToUnloadPtrIndexer> mUnloadQueue;
239
240     void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
241     long mTotalMem;
242     long mTotalMemMax;
243
244
245   }; // class MultiThreadImageReader
246   //=====================================================================
247
248
249
250 } // namespace creaImageIO
251
252
253
254 #endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__