]> Creatis software - creaImageIO.git/blob - src/creaImageIOMultiThreadImageReader.h
#3218 creaImageIO Feature New Normal - vtk8itk4wx3-mingw64
[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(NULL)
155       {}
156           
157       ~ImageToLoad()
158       {
159                 if (mImage != NULL) 
160                 {
161                         //          std::cout << "Refs = "<<mImage->GetReferenceCount()<<std::endl;
162                         mImage->Delete();
163                 } // if
164       }
165           
166       MultiThreadImageReaderUser* GetUser() const { return mUser; }
167       void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
168       const std::string& GetFilename() const { return mFilename; }
169       int GetPriority() const { return mPriority; }
170       void SetPriority(int p) { mPriority=p; }
171       int& Index() { return mIndex; }
172       int& UnloadIndex() { return mUnloadIndex; }
173       vtkImageData* GetImage() const { return mImage; }
174       void SetImage( vtkImageData* i ) { mImage=i; }
175
176           std::map<std::string, std::string> getAttributes(const std::vector<std::string> i_attr);
177     private:
178       MultiThreadImageReaderUser        *mUser;
179       std::string                                       mFilename;
180       int                                                       mPriority;
181       int                                                       mIndex;
182       int                                                       mUnloadIndex;
183       vtkImageData                                      *mImage;
184     };
185     // 
186
187     /// Type of pointer on an ImageToLoad struct
188     typedef ImageToLoad *ImageToLoadPtr;
189
190     /// ImageToLoadPtr comparator on priority (for image queue)
191     struct ImageToLoadPtrPriorityComparator
192     {
193       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
194         const 
195       {
196         return ( a->GetPriority() > b->GetPriority() );
197       }
198     };
199     /// ImageToLoadPtr comparator on inverse priority (for image to unload queue)
200     struct ImageToLoadPtrInversePriorityComparator
201     {
202       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
203         const 
204       {
205         return ( a->GetPriority() < b->GetPriority() );
206       }
207     };
208
209
210     /// ImageToLoadPtr comparator on filename (for image map)
211     struct ImageToLoadPtrFilenameComparator
212     {
213       bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
214         const 
215       {
216         return ( a->GetFilename() < b->GetFilename() );
217       }
218     };
219
220     /// ImageToLoadPtr indexer for image queue
221     struct ImageToLoadPtrIndexer
222     {
223       int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
224     };
225     /// ImageToLoadPtr indexer for to unload image queue
226     struct ImageToUnloadPtrIndexer
227     {
228       int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
229     };
230
231     /// The callback from threaded readers when an image is read
232     void SignalImageRead(ImageToLoadPtr p, bool purge);
233
234         void CleanMImagesMap();
235
236
237         
238     /// The type of map of images 
239     typedef std::map<ImageToLoadPtr,vtkImageData*,   ImageToLoadPtrFilenameComparator> ImageMapType;
240     /// The map of images
241     ImageMapType mImages;
242     /// Comparator for the image to load queue
243     ImageToLoadPtrPriorityComparator mComparator;
244     /// Indexer for the image to load queue 
245     ImageToLoadPtrIndexer mIndexer;
246     /// The image to load priority queue
247     IndexedHeap<ImageToLoadPtr,
248                 ImageToLoadPtrPriorityComparator,
249                 ImageToLoadPtrIndexer> mQueue;
250
251     /// The type of list of threaded readers
252         typedef std::vector<boost::shared_ptr<ThreadedImageReader> > ThreadedImageReaderListType;
253         //typedef std::vector<ThreadedImageReader* > ThreadedImageReaderListType;
254     ThreadedImageReaderListType mThreadedImageReaderList;
255     /// The number of currently running threaded readers
256     int mNumberOfThreadedReadersRunning;
257     /// The mutex used to access safely internal data from any thread
258     /// LG : Removed ! We now use the embedded mutex in User from which 
259     /// we inherit...
260     //  wxMutex mMutex;
261
262     /// For GetImage : the filename requested
263     std::string mRequestedFilename;
264     /// For GetImage : the image requested
265     vtkImageData* mRequestedImage;
266
267     /// If number of threads == 0 then uses an internal non-threaded reader
268     ImageReader* mReader;
269
270     /// The type of list of images loaded 
271     /// used to unload oldest image when memory limit exceeded
272    /// The image to unload priority queue
273     IndexedHeap<ImageToLoadPtr,
274                 ImageToLoadPtrInversePriorityComparator,
275                 ImageToUnloadPtrIndexer> mUnloadQueue;
276
277     void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
278     long mTotalMem;
279     long mTotalMemMax;
280
281
282   }; // class MultiThreadImageReader
283   //=====================================================================
284
285
286
287 } // namespace creaImageIO
288
289
290
291 #endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__