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