00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _Image3DSet_hxx
00020 #define _Image3DSet_hxx
00021
00022
00023
00024
00025 template <class ImageType>
00026 ostream& operator<<(ostream& s, const Image3DSet<ImageType>& set)
00027 {
00028 s << "FileList size: " << set.fileNames.size() << endl;
00029 s << "Statuslist size: " << set.status.size() << endl;
00030 s << "ImageType*list size: " << set.images.size() << endl;
00031 s << "LastTimeUsedlist size: " << set.lastTimeUsed.size() << endl;
00032 s << "nbImages: " << set.nbImages << endl;
00033 for (uint n=0; n<set.fileNames.size(); n++)
00034 {
00035 s <<"Filename: " << set.fileNames[n] << " Status: " << set.status[n] << endl;
00036 }
00037 return s;
00038 }
00039
00040 template <class ImageType>
00041 Image3DSet<ImageType>::Image3DSet(const vector<string> & _fileNames,bool _fileIsReadOnly,bool _isMemOnly):
00042 fileNames(_fileNames),
00043 nbImages(_fileNames.size()),
00044 fileIsReadOnly(_fileIsReadOnly),
00045 isMemOnly(_isMemOnly),
00046 lruGap(0),
00047 startTime(DTime())
00048 {
00049 images.assign(nbImages,(ImageType*)NULL);
00050 status.assign(nbImages,ON_FILE);
00051 lastTimeUsed.assign(nbImages,0);
00052 }
00053
00054 template <class ImageType>
00055 Image3DSet<ImageType>::Image3DSet(bool _fileIsReadOnly,bool _isMemOnly):
00056 nbImages(0),
00057 fileIsReadOnly(_fileIsReadOnly),
00058 isMemOnly(_isMemOnly),
00059 lruGap(0),
00060 startTime(DTime())
00061 {
00062 ;
00063 }
00064
00065 template <class ImageType>
00066 Image3DSet<ImageType>::Image3DSet(const Image3DSet<ImageType>& _other):
00067 fileNames(_other.fileNames),
00068 nbImages(_other.Size()),
00069 fileIsReadOnly(_other.fileIsReadOnly),
00070 isMemOnly(_other.isMemOnly),
00071 lruGap(0),
00072 startTime(DTime())
00073 {
00074 images.assign(nbImages,(ImageType*)NULL);
00075 status.assign(nbImages,ON_FILE);
00076 lastTimeUsed.assign(nbImages,0);
00077 }
00078
00079
00080 template <class ImageType>
00081 Image3DSet<ImageType>::~Image3DSet()
00082 {
00083 if(!isMemOnly && !fileIsReadOnly){FlushAllToDisk();}
00084 DeleteImages();
00085 }
00086
00087 template <class ImageType>
00088 void
00089 Image3DSet<ImageType>::Clear(bool _fileIsReadOnly,bool _isMemOnly)
00090 {
00091 if(!isMemOnly && !fileIsReadOnly){FlushAllToDisk();}
00092 DeleteImages();
00093 fileIsReadOnly = _fileIsReadOnly;
00094 isMemOnly = _isMemOnly;
00095 fileNames.clear();
00096 status.clear();
00097 lastTimeUsed.clear();
00098 nbImages = 0;
00099 startTime = DTime();
00100 lruGap = 0;
00101 }
00102
00104 template <class ImageType>
00105 void
00106 Image3DSet<ImageType>::LoadImage(int i) const
00107 {
00108
00109 mprintf("Image3DSet::LoadImage: loading image %d:\"%s\"\n",i,fileNames[i].c_str());
00110 if(!Fits(i)){FlushToDisk(LeastRecentlyUsed());}
00111 if(status[i]==IN_MEM){ThrowError("Image3DSet::LoadImage image already in mem? image:%d",i);}
00112 images[i]=new ImageType(fileNames[i]);
00113 status[i]=IN_MEM;
00114 }
00116 template <class ImageType>
00117 int
00118 Image3DSet<ImageType>::LeastRecentlyUsed() const
00119 {
00120 double lruTime=lastTimeUsed[0];
00121 int n=0;
00122 for(int i=1;i<nbImages;i++)
00123 {
00124 if(lastTimeUsed[i]<lruTime){n=i;lruTime=lastTimeUsed[i];}
00125 }
00126 return n;
00127 }
00128
00130 template <class ImageType>
00131 void Image3DSet<ImageType>::FlushToDisk(int i) const
00132 {
00133 if(isMemOnly){ThrowError("Image3DSet::SaveImage memOnly!");}
00134 if(status[i]==ON_FILE){ThrowError("Image3DSet::SaveImage image already on file? image:%d",i);}
00135 images[i]->WriteToFile(fileNames[i]);
00136 delete images[i];
00137 images[i]=NULL;
00138 status[i]=ON_FILE;
00139 }
00140
00142 template <class ImageType>
00143 void Image3DSet<ImageType>::LoadAllImages()
00144 {
00145 for (int i=0; i<nbImages; i++){LoadImage(i);}
00146 }
00147
00149 template <class ImageType>
00150 void
00151 Image3DSet<ImageType>::FlushAllToDisk()
00152 {
00153 for (int i=0; i<nbImages; i++){FlushToDisk(i);}
00154 }
00155
00157
00162 template <class ImageType>
00163 const ImageType &
00164 Image3DSet<ImageType>::GetImage(int position) const
00165 {
00166 if(position>=nbImages)
00167 {ThrowError("Image3DSet::GetImage: pos=%d is pastend of image set(%d)",position,nbImages);}
00168
00169 if(status[position]!=IN_MEM)
00170 {
00171 LoadImage(position);
00172 }
00173 if(!((lruGap++)%10)){lastTimeUsed[position]=DTime(startTime);}
00174 return *(images[position]);
00175 }
00176
00177 template <class ImageType>
00178 ImageType &
00179 Image3DSet<ImageType>::GetImage(int position)
00180 {
00181 if(position>=nbImages)
00182 {ThrowError("Image3DSet::GetImage: pos=%d is pastend of image set(%d)",position,nbImages);}
00183
00184 if(status[position]!=IN_MEM)
00185 {
00186 LoadImage(position);
00187 }
00188 if(!((lruGap++)%10)){lastTimeUsed[position]=DTime(startTime);}
00189 return *(images[position]);
00190 }
00191
00192 template <class ImageType>
00193 void Image3DSet<ImageType>::DeleteImages()
00194 {
00195 for(uint i=0;i<images.size();i++)
00196 {
00197 if(images[i]){delete images[i];}
00198 }
00199 }
00200
00201
00203 template <class ImageType>
00204 int
00205 Image3DSet<ImageType>::AddImage(ImageType *image,const string &fileName)
00206 {
00207
00208
00209 nbImages++;
00210 fileNames.push_back(fileName);
00211 images.push_back(image);
00212 status.push_back(IN_MEM);
00213 lastTimeUsed.push_back(DTime(startTime));
00214 if(
00215 (int)fileNames.size() !=nbImages ||
00216 (int)images.size() !=nbImages ||
00217 (int)status.size() !=nbImages ||
00218 (int)lastTimeUsed.size()!=nbImages )
00219 {
00220 ThrowError("Image3DSet::AddImage:incoherence in vect sizes");
00221 }
00222 return nbImages-1;
00223 }
00224
00225 template<class ImageType>
00226 int
00227 Image3DSet<ImageType>::GetPosition(const string &filename)
00228 {
00229 int n = 0;
00230 vector<string>::iterator plist;
00231 plist = fileNames.begin();
00232 while(((*plist) != filename)&& (n < nbImages))
00233 {
00234 plist++;
00235 n++;
00236 };
00237 if (n >= nbImages)
00238 ThrowError(string("Image3DSet::GetPosition filename not found in filelist: " + filename).c_str());
00239
00240 return n;
00241 }
00242
00243
00245
00250 template <class ImageType>
00251 ImageType* Image3DSet<ImageType>::RemoveImage(const string &filename)
00252 {
00253 return RemoveImage(GetPosition(filename));
00254 }
00255
00256 template <class ImageType>
00257 ImageType* Image3DSet<ImageType>::RemoveImage(int position)
00258 {
00259 if (nbImages <= position)
00260 return NULL;
00261
00262
00263 ImageType* rPointer;
00264 if (status[position] != IN_MEM){LoadImage(position);}
00265
00266 rPointer=images[position];
00267 images.erase(images.begin()+position);
00268
00269
00270 if (fileNames.size()){fileNames.erase(fileNames.begin()+position);}
00271
00272
00273 status.erase(status.begin()+position);
00274
00275
00276 lastTimeUsed.erase(lastTimeUsed.begin()+position);
00277
00278 nbImages--;
00279 return rPointer;
00280 }
00281
00283 template<class ImageType>
00284 bool Image3DSet<ImageType>::IsAllSameSize()
00285 {
00286 if (!nbImages)
00287 return true;
00288 Size3D sizeOfFirst = GetImage(0).Size();
00289 for (int i=1; i<nbImages; i++)
00290 {
00291 Size3D sizeOfNext = GetImage(i).Size();
00292 if (sizeOfFirst != sizeOfNext)
00293 return false;
00294 }
00295 return true;
00296 }
00297
00299 template<class ImageType>
00300 vector<string>
00301 Image3DSet<ImageType>::ImagesThatAreAlike()
00302 {
00303 int i1, i2;
00304 vector<string> ret;
00305 for (i1 = 0; i1 < Size(); i1++)
00306 {
00307 bool firstMatch = true;
00308 for (i2 = i1 + 1; i2 < Size(); i2++)
00309 {
00310 if (GetImage(i1) == GetImage(i2))
00311 {
00312 if (firstMatch)
00313 {
00314 if (isMemOnly)
00315 ret.push_back(SPrintf("%d", i1));
00316 else
00317 ret.push_back(GetFilename(i1));
00318 firstMatch = false;
00319 }
00320 if (isMemOnly)
00321 ret.push_back(SPrintf("%d", i2));
00322 else
00323 ret.push_back(GetFilename(i2));
00324 }
00325 }
00326 }
00327 return ret;
00328 }
00329 #endif // _Image3DSet_hxx