/* # --------------------------------------------------------------------- # # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image # pour la Santé) # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton # Previous Authors : Laurent Guigues, Jean-Pierre Roux # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil # # This software is governed by the CeCILL-B license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL-B # license as circulated by CEA, CNRS and INRIA at the following URL # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html # or in the file LICENSE.txt. # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL-B license and that you accept its terms. # ------------------------------------------------------------------------ */ #ifndef __creaImageIOThreadedImageReader_h_INCLUDED__ #define __creaImageIOThreadedImageReader_h_INCLUDED__ #include #include #include #include #include #include #include namespace creaImageIO { /** * \ingroup IO */ //===================================================================== 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 that allows parallel lectures of several images 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); /// Function to read attributes for a file void getAttributes(const std::string filename, std::map &infos, std::vector i_attr); protected: bool mDone; int GetMaximalPriorityWithoutLocking(); ///Class that represents an image to be loaded 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; } std::map getAttributes(const std::vector i_attr); 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; //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__