00001 #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__
00002 #define __creaImageIOThreadedImageReader_h_INCLUDED__
00003
00004 #include <creaImageIOSystem.h>
00005 #include <creaImageIOImageReader.h>
00006 #include <creaImageIOIndexedHeap.h>
00007 #include <map>
00008 #include <deque>
00009 #include <wx/thread.h>
00010 #include <queue>
00011
00012 namespace creaImageIO
00013 {
00017
00018 class ThreadedImageReader;
00019 class MultiThreadImageReader;
00020
00021
00022
00023 class CREAIMAGEIO_EXPORT MultiThreadImageReaderUser
00024 {
00025 public:
00026 friend class ThreadedImageReader;
00027 friend class MultiThreadImageReader;
00028
00029 MultiThreadImageReaderUser() {}
00030 virtual ~MultiThreadImageReaderUser() {}
00031
00032 typedef enum
00033 {
00034 ThreadedReaderStarted,
00035 ThreadedReaderStopped,
00036 ImageLoaded,
00037 ImageUnloaded,
00038 Error
00039 }
00040 EventType;
00047 virtual void OnMultiThreadImageReaderEvent( const std::string& filename,
00048 EventType type,
00049 vtkImageData* image)
00050 {}
00051 inline void MultiThreadImageReaderEventLock()
00052 { mMultiThreadImageReaderUserMutex.Lock(); }
00053 inline void MultiThreadImageReaderEventUnlock()
00054 { mMultiThreadImageReaderUserMutex.Unlock(); }
00055 inline wxMutex& GetMultiThreadImageReaderUserMutex()
00056 { return mMultiThreadImageReaderUserMutex; }
00057 private:
00059 void MultiThreadImageReaderSendEvent( const std::string& filename,
00060 EventType type,
00061 vtkImageData* image);
00062 wxMutex mMultiThreadImageReaderUserMutex;
00063 };
00064
00065
00066
00069
00071 class MultiThreadImageReader : public MultiThreadImageReaderUser
00072 {
00073 public:
00074 friend class ThreadedImageReader;
00075
00077 MultiThreadImageReader(int number_of_threads = 1);
00079 ~MultiThreadImageReader();
00080
00083 bool Start();
00085 void Stop();
00086
00090 void Request( MultiThreadImageReaderUser* user,
00091 const std::string& filename,
00092 int priority );
00093
00097 vtkImageData* GetImage(const std::string& filename);
00098
00100 int GetMaximalPriority();
00101
00103 void OnMultiThreadImageReaderEvent( const std::string& filename,
00104 EventType type,
00105 vtkImageData* image);
00106
00107 protected:
00108 int GetMaximalPriorityWithoutLocking();
00110 class ImageToLoad
00111 {
00112 public:
00113 ImageToLoad( MultiThreadImageReaderUser* user,
00114 const std::string& filename,
00115 int prio=0)
00116 : mUser(user),
00117 mFilename(filename),
00118 mPriority(prio),
00119 mIndex(-1),
00120 mUnloadIndex(-1),
00121 mImage(0)
00122 {}
00123 ~ImageToLoad()
00124 {
00125 if (mImage>0)
00126 {
00127
00128 mImage->Delete();
00129 }
00130 }
00131 MultiThreadImageReaderUser* GetUser() const { return mUser; }
00132 void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; }
00133 const std::string& GetFilename() const { return mFilename; }
00134 int GetPriority() const { return mPriority; }
00135 void SetPriority(int p) { mPriority=p; }
00136 int& Index() { return mIndex; }
00137 int& UnloadIndex() { return mUnloadIndex; }
00138 vtkImageData* GetImage() const { return mImage; }
00139 void SetImage( vtkImageData* i ) { mImage=i; }
00140 private:
00141 MultiThreadImageReaderUser* mUser;
00142 std::string mFilename;
00143 int mPriority;
00144 int mIndex;
00145 int mUnloadIndex;
00146 vtkImageData* mImage;
00147 };
00148
00149
00151 typedef ImageToLoad* ImageToLoadPtr;
00152
00154 struct ImageToLoadPtrPriorityComparator
00155 {
00156 bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
00157 const
00158 {
00159 return ( a->GetPriority() > b->GetPriority() );
00160 }
00161 };
00163 struct ImageToLoadPtrInversePriorityComparator
00164 {
00165 bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
00166 const
00167 {
00168 return ( a->GetPriority() < b->GetPriority() );
00169 }
00170 };
00171
00172
00174 struct ImageToLoadPtrFilenameComparator
00175 {
00176 bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b)
00177 const
00178 {
00179 return ( a->GetFilename() < b->GetFilename() );
00180 }
00181 };
00182
00184 struct ImageToLoadPtrIndexer
00185 {
00186 int& operator()(ImageToLoadPtr & t) const { return t->Index(); }
00187 };
00189 struct ImageToUnloadPtrIndexer
00190 {
00191 int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); }
00192 };
00193
00195 void SignalImageRead(ImageToLoadPtr p, bool purge);
00196
00198 typedef std::map<ImageToLoadPtr,vtkImageData*,
00199 ImageToLoadPtrFilenameComparator> ImageMapType;
00201 ImageMapType mImages;
00203 ImageToLoadPtrPriorityComparator mComparator;
00205 ImageToLoadPtrIndexer mIndexer;
00207 IndexedHeap<ImageToLoadPtr,
00208 ImageToLoadPtrPriorityComparator,
00209 ImageToLoadPtrIndexer> mQueue;
00210
00212 typedef std::vector<ThreadedImageReader*> ThreadedImageReaderListType;
00213 ThreadedImageReaderListType mThreadedImageReaderList;
00215 int mNumberOfThreadedReadersRunning;
00219
00220
00222 std::string mRequestedFilename;
00224 vtkImageData* mRequestedImage;
00225
00227 ImageReader* mReader;
00228
00232 IndexedHeap<ImageToLoadPtr,
00233 ImageToLoadPtrInversePriorityComparator,
00234 ImageToUnloadPtrIndexer> mUnloadQueue;
00235
00236 void UpdateUnloadPriority(ImageToLoadPtr p, int priority);
00237 long mTotalMem;
00238 long mTotalMemMax;
00239
00240
00241 };
00242
00243
00244
00245
00246 }
00247
00248
00249
00250 #endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__