#include "sys.hpp" // for libcwd #include "debug.hpp" // for libcwd #include "objmovie.hpp" #include #include #include #include ///////////////////////////////////////// using namespace std; class FileOpenError: public runtime_error { public: FileOpenError(const std::string& __arg="FATAl ERROR: failed open file\n"): runtime_error(__arg) { cerr << "FATAL ERROR: failed to open file " << __arg << "\n"; } }; MovieMetaFile::MovieMetaFile(const char* FileName): MovieMetaFileName(FileName) { Loaded = Load(); } MovieMetaFile::~MovieMetaFile() { } bool MovieMetaFile::Load() { cout << "Load MovieMetaFile()\n"; fflush(stdout); int ErrorCode; TiXmlDocument doc(MovieMetaFileName.c_str()); cout << "Loaded xml file\n"; fflush(stdout); if (doc.LoadFile()) { TiXmlElement *root=doc.RootElement(); TiXmlElement *StimParasElement=(root->FirstChild("StimParas"))->ToElement(); if (StimParasElement) { TiXmlElement *element=(StimParasElement->FirstChild("NXParas"))->ToElement(); if (element) { ErrorCode = element->QueryIntAttribute("value", &NXParas); } element=(StimParasElement->FirstChild("NYParas"))->ToElement(); if (element) { ErrorCode = element->QueryIntAttribute("value", &NYParas); } element=(StimParasElement->FirstChild("MovieFileName"))->ToElement(); if (element) { MovieFileName = element->Attribute("value"); } } Print(); return true; } else { cerr << "ERROR: Failed Loading XML-MovieMetaFile " << MovieMetaFileName << "\n"; return false; } } void MovieMetaFile::Print() { cout << "MovieMetaFile::Print()\n"; cout << "MovieFileName=" << MovieFileName << "\n"; cout << "XNPara=" << NXParas << "\n"; cout << "YNPara=" << NYParas << "\n"; } //////////////////////////////////////// MovieFilter2d::MovieFilter2d(): LastShiftedFrame(0), LastFrame(0) { } MovieFilter2d::MovieFilter2d(FILE *fw): LastShiftedFrame(0), LastFrame(0) { LoadFromFile(fw); } MovieFilter2d::~MovieFilter2d() { if (LastShiftedFrame != 0) delete [] LastShiftedFrame; if (LastFrame != 0) delete [] LastFrame; } bool MovieFilter2d::LoadFromFile(FILE *fw) { fread(&Header, sizeof(Header), 1, fw); Dout(dc::input, "OutputWidth=" << Header.outputwidth << " OutputHeight=" << Header.outputheight); FrameSize = Header.outputwidth*Header.outputheight; LastShiftedFrame = new float[FrameSize]; LastFrame = new float[FrameSize]; int ReadCount = fread(LastFrame, Header.width*Header.height*sizeof(*LastFrame), 1, fw); // if (ReadCount != 1) cout << "ReadCount = " << ReadCount << "****************\n\n\n"; return (ReadCount == 1); } bool MovieFilter2d::LoadFilterFrame(FILE *fw) { return (fread(LastFrame, FrameSize*sizeof(*LastFrame), 1, fw) == 1); } int MovieFilter2d::GetFrameSize() { return FrameSize; } int MovieFilter2d::GetOutputWidth() { return Header.outputwidth; } int MovieFilter2d::GetOutputHeight() { return Header.outputheight; } float* MovieFilter2d::GetFramePointer() { return LastFrame; } float* MovieFilter2d::GetShiftedFramePointer() { return LastShiftedFrame; } bool MovieFilter2d::GetMinMaxValue(float &MinValue, float &MaxValue) { if (FrameSize > 0 || LastFrame!=0) { MinValue=*LastFrame; MaxValue=*LastFrame; for (int i=1;iMaxValue) { MaxValue=LastFrame[i]; } } } else { return false; } return true; } /** @brief shifts the original picture in x and y direction @param RelXShift relative shift of picture in x direction [0..1] @param RelYShift relative shift of picture in y direction [0..1] @author fm @since 29.10.2008 */ void MovieFilter2d::SetFrameShift(float RelXShift, float RelYShift) { // calculate absolute shift int owidth=Header.outputwidth; int oheight=Header.outputheight; int XShift=int(round(RelXShift*owidth)) % owidth; int YShift=int(round(RelYShift*oheight)) % oheight; // cout << "xshift=" << XShift << " yshift=" << YShift << "\n"; // copy original picture to shifted picture, according to XShift and YShift int NewX, NewY; for (int y=0;y::iterator it=FilterList.begin(); it!=FilterList.end();++it) { delete (*it); } if (fw) { fclose(fw); } } int ObjMovie::LoadMovieFile(const char* FileName) { Dout(dc::input, "ObjMovie::LoadFile " << MovieFileName); Debug( libcw_do.inc_indent(2) ); fw = fopen(FileName, "r"); if (!fw) { throw FileOpenError(FileName); } fread(&MHeader, sizeof(MHeader), 1, fw); Dout(dc::input, "finfo=" << MHeader.finfo); Dout(dc::input, "version=" << MHeader.version); Dout(dc::input, "width= " << MHeader.width << " height=" << MHeader.height); //! \todo throw exception if no valid movie file (fm) fread(&NFilters, sizeof(NFilters), 1, fw); Dout(dc::input, "NFilters= " << NFilters); // read filters for (int i=0;i::iterator it=FilterList.begin(); it!=FilterList.end();++it) { (*it)->LoadFilterFrame(fw); } // float MinVal = GetMinValue(0); Debug( libcw_do.dec_indent(2) ); } float* ObjMovie::GetFramePointer(int FilterNr) { return FilterList[FilterNr]->GetFramePointer(); } float* ObjMovie::GetShiftedFramePointer(int FilterNr) { return FilterList[FilterNr]->GetShiftedFramePointer(); } int ObjMovie::GetFrameSize(int FilterNr) { return FilterList[FilterNr]->GetFrameSize(); } int ObjMovie::GetOutputWidth(int FilterNr) { return FilterList[FilterNr]->GetOutputWidth(); } int ObjMovie::GetOutputHeight(int FilterNr) { return FilterList[FilterNr]->GetOutputHeight(); } void ObjMovie::ResetSwitchMaster() { SwitchMaster = true; SwitchMasterObj = 0; } bool ObjMovie::GetSwitchMaster() { // tell only one (the first) requester to be the SwitchMaster if (SwitchMaster) { SwitchMaster = false; return true; } else return false; } input* ObjMovie::GetSwitchMaster(input* Requester) { // tell only one (the first) requester to be the SwitchMaster if (SwitchMaster) { SwitchMaster = false; SwitchMasterObj = Requester; return 0; } else return SwitchMasterObj; } int ObjMovie::NextFrame() { // read frames ++FrameNumber; if ((FrameNumber >= NFrames) || feof(fw)) { cout << "*************************feof(fw)==true \n "; fsetpos(fw, &FilePos_FirstFrame); FrameNumber=0; cout << "*************************RestartObjectMovieFile " << FrameNumber << "\n\n"; } for (vector::iterator it=FilterList.begin(); it!=FilterList.end();++it) { (*it)->LoadFilterFrame(fw); } return FrameNumber; } int ObjMovie::SetFrameShift(float RelXShift, float RelYShift) { for (vector::iterator it=FilterList.begin(); it!=FilterList.end();++it) { (*it)->SetFrameShift(RelXShift,RelYShift); } } int ObjMovie::SetRandomShift() { float xshift=gsl_rng_uniform(gslr); float yshift=gsl_rng_uniform(gslr); SetFrameShift(xshift, yshift); } int ObjMovie::NextRandomFrame() { // read frames FrameNumber = gsl_rng_uniform_int(gslr, NFrames); CurFramePos = FrameIndex[FrameNumber]; fsetpos(fw, &CurFramePos); for (vector::iterator it=FilterList.begin(); it!=FilterList.end();++it) { (*it)->LoadFilterFrame(fw); } } int ObjMovie::GotoFrameNr(int _FrameNr) { if (_FrameNr < NFrames) { FrameNumber = _FrameNr; CurFramePos = FrameIndex[FrameNumber]; fsetpos(fw, &CurFramePos); for (vector::iterator it=FilterList.begin(); it!=FilterList.end();++it) { (*it)->LoadFilterFrame(fw); } } else { cerr << "ERROR ObjMovie::GotoFrameNr: FrameNumber =" << _FrameNr << " too high (NFrames=" << NFrames << "\n"; return 0; } //! \todo introduce exceptions for error handling return 1; } int ObjMovie::GetFrameNumber() { return FrameNumber; } int ObjMovie::GetNFrames() { return NFrames; } int ObjMovie::GetNFilters() { return NFilters; } int ObjMovie::InitializeFrameIndex() { fsetpos(fw, &FilePos_FirstFrame); NFrames=0; FrameNumber=0; Dout(dc::input, "InitializeFrameIndex"); bool NoError=true; while (NoError) { fgetpos(fw, &CurFramePos); for (vector::iterator it=FilterList.begin(); it!=FilterList.end();++it) { NoError = (*it)->LoadFilterFrame(fw); } if (NoError) { FrameIndex.push_back(CurFramePos); ++NFrames; } } fsetpos(fw, &FilePos_FirstFrame); Dout(dc::input, "ObjMovieFile has " << NFrames << " Frames"); } /** get the minimum value in the ObjMovie file noch nicht fertig! could be used to decide if on and off input layers should be used with the MovieFilter */ float ObjMovie::GetMinValue(int FilterNr) { // store current frame number int OldFrameNumber = GetFrameNumber(); // rewind movie to start frame int CurFrameNr=0; GotoFrameNr(0); float MinValue, MaxValue, GlobalMinValue, GlobalMaxValue; cout << "ObjMovie::GetMinValue()\n"; // loop through every frame from start to end do { cout <<"FrameNr=" << FrameNumber <<"\n"; // compare every pixel value of current frame (and selected filter) with global minimum } while (NextFrame()!=0); // restore old frame number GotoFrameNr(OldFrameNumber); } std::string GetDefaultMovieDir() { string MovieDir; if (getenv("OBJSIM_MOVIE_DIR")) { MovieDir = getenv("OBJSIM_MOVIE_DIR"); cout << "set MovieDir from environment to " << MovieDir << std::endl; } else { cout << "environment variable OBJSIM_MOVIE_DIR is not set" << std::endl; } if (MovieDir.empty()) { MovieDir = string(getenv("HOME")) + "/prog/objsim/data/movies/"; } if (MovieDir[MovieDir.length()-1] != '/') { MovieDir += "/"; } cout << "DefaultMovieDir: " << MovieDir << "\n"; return MovieDir; } /** @para FileName without .idlmov */ ObjMovie* LoadObjMovie(const string& StimFileName, int & Width, int & Height, int & NFilters, int & NFrames, string MovieDir) { cout << "StimFileName=" << StimFileName << "\n"; if (MovieDir.empty()) { MovieDir = GetDefaultMovieDir(); } cout << "MovieDir=" << MovieDir << "\n"; std::string MetaFileName = MovieDir + StimFileName + ".meta.xml"; MovieMetaFile MetaFile(MetaFileName.c_str()); std::string MovieFileName; if (MetaFile.Loaded) { MovieFileName = MetaFile.MovieFileName; } else { cout << "MovieMetaFile not loaded\n"; MovieFileName = StimFileName + ".idlmov"; cout << "using movie file name: MovieFileName\n"; } std::string StimName; { StimName = MovieDir + MovieFileName; cout << "Load movie: " << StimName << "\n"; } ObjMovie* MyMovie = new ObjMovie(StimName.c_str()); Width = MyMovie->GetOutputWidth(0); Height = MyMovie->GetOutputHeight(0); NFrames = MyMovie->GetNFrames(); NFilters = MyMovie->GetNFilters(); return MyMovie; }