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