X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src2%2FcreaImageIOMultiThreadImageReader.h;fp=src2%2FcreaImageIOMultiThreadImageReader.h;h=d72981d23479fa44019a1f055e8f28c04d235c29;hb=cbf693fa62cd51f4ca5c881838bbb609edc447b0;hp=0000000000000000000000000000000000000000;hpb=7cbaed9c7b7fcc2a5b8ab1d82ba27797c76df455;p=creaImageIO.git diff --git a/src2/creaImageIOMultiThreadImageReader.h b/src2/creaImageIOMultiThreadImageReader.h new file mode 100644 index 0000000..d72981d --- /dev/null +++ b/src2/creaImageIOMultiThreadImageReader.h @@ -0,0 +1,246 @@ +#ifndef __creaImageIOThreadedImageReader_h_INCLUDED__ +#define __creaImageIOThreadedImageReader_h_INCLUDED__ + +#include +#include +#include +#include +#include +#include +#include + +namespace creaImageIO +{ + + //===================================================================== + class ThreadedImageReader; + class MultiThreadImageReader; + //===================================================================== + + //===================================================================== + class CREAIMAGEIO_EXPORT MultiThreadImageReaderUser + { + public: + friend class ThreadedImageReader; + friend class MultiThreadImageReader; + + MultiThreadImageReaderUser() {} + virtual ~MultiThreadImageReaderUser() {} + + typedef enum + { + ThreadedReaderStarted, + ThreadedReaderStopped, + ImageLoaded, + ImageUnloaded, + Error + } + EventType; + /// The virtual method to overload by MultiThreadImageReader users + /// It is called when an image has been loaded or unloaded + /// Provides : + /// * The image file name which was requested + /// * The type of event + /// * If type==ImageLoaded the image pointer, else NULL pointer + virtual void OnMultiThreadImageReaderEvent( const std::string& filename, + EventType type, + vtkImageData* image) + {} + inline void MultiThreadImageReaderEventLock() + { mMultiThreadImageReaderUserMutex.Lock(); } + inline void MultiThreadImageReaderEventUnlock() + { mMultiThreadImageReaderUserMutex.Unlock(); } + inline wxMutex& GetMultiThreadImageReaderUserMutex() + { return mMultiThreadImageReaderUserMutex; } + private: + /// + void MultiThreadImageReaderSendEvent( const std::string& filename, + EventType type, + vtkImageData* image); + wxMutex mMultiThreadImageReaderUserMutex; + }; + //===================================================================== + + //===================================================================== + /// + /// TAKE CARE : For the moment it only supports a **SINGLE USER** + class MultiThreadImageReader : public MultiThreadImageReaderUser + { + public: + friend class ThreadedImageReader; + + /// Ctor with the number of threads to use + MultiThreadImageReader(int number_of_threads = 1); + /// Dtor + ~MultiThreadImageReader(); + + /// Starts the reader = create the threads which start to check + /// periodically the queue of requested images to read + bool Start(); + /// Stops the reader = stops the threads and delete the images loaded + void Stop(); + + /// Request the image "filename" with a given priority + /// When the image is ready (or an error occurred) + /// The observer's callback is invoked + void Request( MultiThreadImageReaderUser* user, + const std::string& filename, + int priority ); + + /// Request the image "filename" immediately + /// Blocks until image loaded + /// (no user callback but image returned) + vtkImageData* GetImage(const std::string& filename); + + /// + int GetMaximalPriority(); + + /// + void OnMultiThreadImageReaderEvent( const std::string& filename, + EventType type, + vtkImageData* image); + + protected: + int GetMaximalPriorityWithoutLocking(); + // + class ImageToLoad + { + public: + ImageToLoad( MultiThreadImageReaderUser* user, + const std::string& filename, + int prio=0) + : mUser(user), + mFilename(filename), + mPriority(prio), + mIndex(-1), + mUnloadIndex(-1), + mImage(0) + {} + ~ImageToLoad() + { + if (mImage>0) + { + // std::cout << "Refs = "<GetReferenceCount()<Delete(); + } + } + MultiThreadImageReaderUser* GetUser() const { return mUser; } + void SetUser( MultiThreadImageReaderUser* u ) { mUser = u; } + const std::string& GetFilename() const { return mFilename; } + int GetPriority() const { return mPriority; } + void SetPriority(int p) { mPriority=p; } + int& Index() { return mIndex; } + int& UnloadIndex() { return mUnloadIndex; } + vtkImageData* GetImage() const { return mImage; } + void SetImage( vtkImageData* i ) { mImage=i; } + private: + MultiThreadImageReaderUser* mUser; + std::string mFilename; + int mPriority; + int mIndex; + int mUnloadIndex; + vtkImageData* mImage; + }; + // + + /// Type of pointer on an ImageToLoad struct + typedef ImageToLoad* ImageToLoadPtr; + + /// ImageToLoadPtr comparator on priority (for image queue) + struct ImageToLoadPtrPriorityComparator + { + bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b) + const + { + return ( a->GetPriority() > b->GetPriority() ); + } + }; + /// ImageToLoadPtr comparator on inverse priority (for image to unload queue) + struct ImageToLoadPtrInversePriorityComparator + { + bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b) + const + { + return ( a->GetPriority() < b->GetPriority() ); + } + }; + + + /// ImageToLoadPtr comparator on filename (for image map) + struct ImageToLoadPtrFilenameComparator + { + bool operator() (ImageToLoadPtr const & a, ImageToLoadPtr const & b) + const + { + return ( a->GetFilename() < b->GetFilename() ); + } + }; + + /// ImageToLoadPtr indexer for image queue + struct ImageToLoadPtrIndexer + { + int& operator()(ImageToLoadPtr & t) const { return t->Index(); } + }; + /// ImageToLoadPtr indexer for to unload image queue + struct ImageToUnloadPtrIndexer + { + int& operator()(ImageToLoadPtr & t) const { return t->UnloadIndex(); } + }; + + /// The callback from threaded readers when an image is read + void SignalImageRead(ImageToLoadPtr p, bool purge); + + /// The type of map of images + typedef std::map ImageMapType; + /// The map of images + ImageMapType mImages; + /// Comparator for the image to load queue + ImageToLoadPtrPriorityComparator mComparator; + /// Indexer for the image to load queue + ImageToLoadPtrIndexer mIndexer; + /// The image to load priority queue + IndexedHeap mQueue; + + /// The type of list of threaded readers + typedef std::vector ThreadedImageReaderListType; + ThreadedImageReaderListType mThreadedImageReaderList; + /// The number of currently running threaded readers + int mNumberOfThreadedReadersRunning; + /// The mutex used to access safely internal data from any thread + /// LG : Removed ! We now use the embedded mutex in User from which + /// we inherit... + // wxMutex mMutex; + + /// For GetImage : the filename requested + std::string mRequestedFilename; + /// For GetImage : the image requested + vtkImageData* mRequestedImage; + + /// If number of threads == 0 then uses an internal non-threaded reader + ImageReader* mReader; + + /// The type of list of images loaded + /// used to unload oldest image when memory limit exceeded + /// The image to unload priority queue + IndexedHeap mUnloadQueue; + + void UpdateUnloadPriority(ImageToLoadPtr p, int priority); + long mTotalMem; + long mTotalMemMax; + + + }; // class MultiThreadImageReader + //===================================================================== + + + +} // namespace creaImageIO + + + +#endif // #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__