00001
00024 #ifndef _HUGINAPP_IMAGECACHE_H
00025 #define _HUGINAPP_IMAGECACHE_H
00026
00027 #include <hugin_shared.h>
00028 #include <map>
00029 #include <boost/shared_ptr.hpp>
00030 #include <boost/signal.hpp>
00031 #include <vigra/stdimage.hxx>
00032 #include <vigra/imageinfo.hxx>
00033 #include <hugin_utils/utils.h>
00034 #include <appbase/ProgressDisplayOld.h>
00035
00036 #define HUGIN_IMGCACHE_MAPPING_INTEGER 0l
00037 #define HUGIN_IMGCACHE_MAPPING_FLOAT 1l
00038
00039
00040 namespace HuginBase {
00041
00050 class IMPEX ImageCache
00051 {
00052
00053 public:
00055 typedef boost::shared_ptr<vigra::BRGBImage> ImageCacheRGB8Ptr;
00056 typedef boost::shared_ptr<vigra::UInt16RGBImage> ImageCacheRGB16Ptr;
00057 typedef boost::shared_ptr<vigra::FRGBImage> ImageCacheRGBFloatPtr;
00058 typedef boost::shared_ptr<vigra::BImage> ImageCache8Ptr;
00059
00061 struct IMPEX Entry
00062 {
00063 ImageCacheRGB8Ptr image8;
00064 ImageCacheRGB16Ptr image16;
00065 ImageCacheRGBFloatPtr imageFloat;
00066 ImageCache8Ptr mask;
00067
00068 std::string origType;
00069 int lastAccess;
00070
00071 public:
00073 Entry()
00074 : image8(ImageCacheRGB8Ptr(new vigra::BRGBImage)),
00075 image16(ImageCacheRGB16Ptr(new vigra::UInt16RGBImage)),
00076 imageFloat(ImageCacheRGBFloatPtr(new vigra::FRGBImage)),
00077 mask(ImageCache8Ptr(new vigra::BImage))
00078 {
00079 DEBUG_TRACE("Constructing an empty ImageCache::Entry");
00080 };
00081
00083 Entry(ImageCacheRGB8Ptr & img,
00084 ImageCacheRGB16Ptr & img16,
00085 ImageCacheRGBFloatPtr & imgFloat,
00086 ImageCache8Ptr & imgMask,
00087 const std::string & typ)
00088 : image8(img), image16(img16), imageFloat(imgFloat), mask(imgMask), origType(typ), lastAccess(0)
00089 {
00090 DEBUG_TRACE("Constructing ImageCache::Entry");
00091 };
00092
00094 ~Entry()
00095 {
00096 DEBUG_TRACE("Deleting ImageCacheEntry");
00097 };
00098
00100 ImageCacheRGB8Ptr get8BitImage();
00101 };
00102
00104 typedef boost::shared_ptr<Entry> EntryPtr;
00105
00109 class Request
00110 {
00111 public:
00112 Request(std::string filename, bool request_small)
00113 :m_filename(filename), m_isSmall(request_small)
00114 {};
00123 boost::signal<void(EntryPtr, std::string, bool)> ready;
00124 bool getIsSmall() const
00125 {return m_isSmall;};
00126 const std::string & getFilename() const
00127 {return m_filename;};
00128 protected:
00129 std::string m_filename;
00130 bool m_isSmall;
00131 };
00132
00143 typedef boost::shared_ptr<Request> RequestPtr;
00144
00145 private:
00146
00147 ImageCache()
00148 : m_progress(NULL), m_accessCounter(0),
00149 asyncLoadCompleteSignal(0), upperBound(100*1024*1024l)
00150 {};
00151
00152 public:
00155 virtual ~ImageCache()
00156 {
00157 images.clear();
00158 instance = NULL;
00159 }
00160
00162 static ImageCache & getInstance();
00163
00164 private:
00165 static ImageCache* instance;
00166
00167
00168 public:
00180 EntryPtr getImage(const std::string & filename);
00181
00189 EntryPtr getImageIfAvailable(const std::string & filename);
00190
00200 EntryPtr getSmallImage(const std::string & filename);
00201
00211 EntryPtr getSmallImageIfAvailable(const std::string & filename);
00212
00219 RequestPtr requestAsyncImage(const std::string & filename);
00220
00227 RequestPtr requestAsyncSmallImage(const std::string & filename);
00228
00232 void removeImage(const std::string & filename);
00233
00239 void flush();
00240
00245 void softFlush();
00248 void SetUpperLimit(long newUpperLimit) { upperBound=newUpperLimit; };
00249
00260 void (*asyncLoadCompleteSignal)(RequestPtr, EntryPtr);
00261
00269 void postEvent(RequestPtr request, EntryPtr entry);
00270
00271 private:
00272 long upperBound;
00273
00274 template <class SrcPixelType,
00275 class DestIterator, class DestAccessor>
00276 static void importAndConvertImage(const vigra::ImageImportInfo& info,
00277 vigra::pair<DestIterator, DestAccessor> dest,
00278 const std::string& type);
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 template <class SrcPixelType,
00293 class DestIterator, class DestAccessor,
00294 class MaskIterator, class MaskAccessor>
00295 static void importAndConvertAlphaImage(const vigra::ImageImportInfo & info,
00296 vigra::pair<DestIterator, DestAccessor> dest,
00297 vigra::pair<MaskIterator, MaskAccessor> mask,
00298 const std::string & type);
00299
00300
00301 public:
00303 void setProgressDisplay(AppBase::MultiProgressDisplay* disp)
00304 { m_progress = disp; }
00305
00307 void clearProgressDisplay(AppBase::MultiProgressDisplay* disp)
00308 { m_progress = NULL; }
00309
00310
00311 private:
00312 std::map<std::string, EntryPtr> images;
00313
00314
00315 AppBase::MultiProgressDisplay* m_progress;
00316
00317 int m_accessCounter;
00318
00319
00320 std::map<std::string, RequestPtr> m_requests;
00321
00322
00323 std::map<std::string, RequestPtr> m_smallRequests;
00324
00326 void spawnAsyncThread();
00327
00336 static void loadSafely(RequestPtr request, EntryPtr large = EntryPtr());
00337
00341 static EntryPtr loadImageSafely(const std::string & filename);
00342
00347 static EntryPtr loadSmallImageSafely(EntryPtr entry);
00348
00349 public:
00363
00364
00365
00366 private:
00367
00368 struct PyramidKey
00369 {
00370 std::string filename;
00371 int level;
00372
00373 public:
00374 PyramidKey(const std::string& str, int lv)
00375 : filename(str), level(lv)
00376 {};
00377
00378 std::string toString()
00379 { return filename + hugin_utils::lexical_cast<std::string>(level); }
00380 };
00381
00382 std::map<std::string, vigra::BImage *> pyrImages;
00383 };
00384
00385
00386 }
00387 #endif // _IMAGECACHE_H