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