]> Creatis software - creaImageIO.git/blob - src2/creaImageIOMultiThreadImageReader.h
Created GimmickView.h
[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 Model
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   class MultiThreadImageReader : public MultiThreadImageReaderUser
70   {
71   public:
72     friend class ThreadedImageReader;
73
74     /// Ctor with the number of threads to use
75     MultiThreadImageReader(int number_of_threads = 1);
76     /// Dtor 
77     ~MultiThreadImageReader();
78
79     /// Starts the reader = create the threads which start to check 
80     /// periodically the queue of requested images to read
81     bool Start();
82     /// Stops the reader = stops the threads and delete the images loaded
83     void Stop();
84
85     /// Request the image "filename" with a given priority 
86     /// When the image is ready (or an error occurred) 
87     /// The observer's callback is invoked 
88     void Request( MultiThreadImageReaderUser* user,
89                   const std::string& filename, 
90                   int priority );
91     
92     /// Request the image "filename" immediately 
93         /// Blocks until image loaded
94     /// (no user callback but image returned)
95     vtkImageData* GetImage(const std::string& filename);
96
97     /// 
98     int GetMaximalPriority(); 
99     
100     ///
101     void OnMultiThreadImageReaderEvent( const std::string& filename,
102                                         EventType type,
103                                         vtkImageData* image);
104     
105   protected:
106     int GetMaximalPriorityWithoutLocking();
107     // 
108     class ImageToLoad
109     {
110     public:
111       ImageToLoad( MultiThreadImageReaderUser* user,
112                    const std::string& filename, 
113                    int prio=0) 
114         : mUser(user),
115           mFilename(filename), 
116           mPriority(prio), 
117           mIndex(-1), 
118           mUnloadIndex(-1), 
119           mImage(0)
120       {}
121       ~ImageToLoad()
122       {
123         if (mImage>0) 
124           {
125             //      std::cout << "Refs = "<<mImage->GetReferenceCount()<<std::endl;
126             mImage->Delete();
127           }
128       }
129       MultiThreadImageReaderUser* GetUser() const { return mUser; }
130       void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
131       const std::string& GetFilename() const { return mFilename; }
132       int GetPriority() const { return mPriority; }
133       void SetPriority(int p) { mPriority=p; }
134       int& Index() { return mIndex; }
135       int& UnloadIndex() { return mUnloadIndex; }
136       vtkImageData* GetImage() const { return mImage; }
137       void SetImage( vtkImageData* i ) { mImage=i; }
138     private:
139       MultiThreadImageReaderUser* mUser;
140       std::string mFilename;
141       int mPriority;
142       int mIndex;
143       int mUnloadIndex;
144       vtkImageData* mImage;
145     };
146     // 
147
148     /// Type of pointer on an ImageToLoad struct
149     typedef ImageToLoad* ImageToLoadPtr;
150
151     /// ImageToLoadPtr comparator on priority (for image queue)
152     struct ImageToLoadPtrPriorityComparator
153     {
154       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
155         const 
156       {
157         return ( a->GetPriority() > b->GetPriority() );
158       }
159     };
160     /// ImageToLoadPtr comparator on inverse priority (for image to unload queue)
161     struct ImageToLoadPtrInversePriorityComparator
162     {
163       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
164         const 
165       {
166         return ( a->GetPriority() < b->GetPriority() );
167       }
168     };
169
170
171     /// ImageToLoadPtr comparator on filename (for image map)
172     struct ImageToLoadPtrFilenameComparator
173     {
174       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
175         const 
176       {
177         return ( a->GetFilename() < b->GetFilename() );
178       }
179     };
180
181     /// ImageToLoadPtr indexer for image queue
182     struct ImageToLoadPtrIndexer
183     {
184       int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
185     };
186     /// ImageToLoadPtr indexer for to unload image queue
187     struct ImageToUnloadPtrIndexer
188     {
189       int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
190     };
191
192     /// The callback from threaded readers when an image is read
193     void SignalImageRead(ImageToLoadPtr p, bool purge);
194   
195     /// The type of map of images 
196     typedef std::map<ImageToLoadPtr,vtkImageData*,
197                      ImageToLoadPtrFilenameComparator> ImageMapType;
198     /// The map of images
199     ImageMapType mImages;
200     /// Comparator for the image to load queue
201     ImageToLoadPtrPriorityComparator mComparator;
202     /// Indexer for the image to load queue 
203     ImageToLoadPtrIndexer mIndexer;
204     /// The image to load priority queue
205     IndexedHeap<ImageToLoadPtr,
206                 ImageToLoadPtrPriorityComparator,
207                 ImageToLoadPtrIndexer> mQueue;
208
209     /// The type of list of threaded readers
210     typedef std::vector<ThreadedImageReader*> ThreadedImageReaderListType;
211     ThreadedImageReaderListType mThreadedImageReaderList;
212     /// The number of currently running threaded readers
213     int mNumberOfThreadedReadersRunning;
214     /// The mutex used to access safely internal data from any thread
215     /// LG : Removed ! We now use the embedded mutex in User from which 
216     /// we inherit...
217     //  wxMutex mMutex;
218
219     /// For GetImage : the filename requested
220     std::string mRequestedFilename;
221     /// For GetImage : the image requested
222     vtkImageData* mRequestedImage;
223
224     /// If number of threads == 0 then uses an internal non-threaded reader
225     ImageReader* mReader;
226
227     /// The type of list of images loaded 
228     /// used to unload oldest image when memory limit exceeded
229    /// The image to unload priority queue
230     IndexedHeap<ImageToLoadPtr,
231                 ImageToLoadPtrInversePriorityComparator,
232                 ImageToUnloadPtrIndexer> mUnloadQueue;
233
234     void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
235     long mTotalMem;
236     long mTotalMemMax;
237
238
239   }; // class MultiThreadImageReader
240   //=====================================================================
241
242
243
244 } // namespace creaImageIO
245
246
247
248 #endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__