objmovie.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. #include "sys.hpp" // for libcwd
  2. #include "debug.hpp" // for libcwd
  3. #include "objmovie.hpp"
  4. #include <external/tinyxml/tinyxml.h>
  5. #include <iostream>
  6. #include <math.h>
  7. #include <stdexcept>
  8. /////////////////////////////////////////
  9. using namespace std;
  10. class FileOpenError: public runtime_error
  11. {
  12. public:
  13. FileOpenError(const std::string& __arg="FATAl ERROR: failed open file\n"): runtime_error(__arg)
  14. {
  15. cerr << "FATAL ERROR: failed to open file " << __arg << "\n";
  16. }
  17. };
  18. MovieMetaFile::MovieMetaFile(const char* FileName): MovieMetaFileName(FileName)
  19. {
  20. Loaded = Load();
  21. }
  22. MovieMetaFile::~MovieMetaFile()
  23. {
  24. }
  25. bool MovieMetaFile::Load()
  26. {
  27. cout << "Load MovieMetaFile()\n"; fflush(stdout);
  28. int ErrorCode;
  29. TiXmlDocument doc(MovieMetaFileName.c_str());
  30. cout << "Loaded xml file\n"; fflush(stdout);
  31. if (doc.LoadFile()) {
  32. TiXmlElement *root=doc.RootElement();
  33. TiXmlElement *StimParasElement=(root->FirstChild("StimParas"))->ToElement();
  34. if (StimParasElement) {
  35. TiXmlElement *element=(StimParasElement->FirstChild("NXParas"))->ToElement();
  36. if (element) {
  37. ErrorCode = element->QueryIntAttribute("value", &NXParas);
  38. }
  39. element=(StimParasElement->FirstChild("NYParas"))->ToElement();
  40. if (element) {
  41. ErrorCode = element->QueryIntAttribute("value", &NYParas);
  42. }
  43. element=(StimParasElement->FirstChild("MovieFileName"))->ToElement();
  44. if (element) {
  45. MovieFileName = element->Attribute("value");
  46. }
  47. }
  48. Print();
  49. return true;
  50. } else {
  51. cerr << "ERROR: Failed Loading XML-MovieMetaFile " << MovieMetaFileName << "\n";
  52. return false;
  53. }
  54. }
  55. void MovieMetaFile::Print()
  56. {
  57. cout << "MovieMetaFile::Print()\n";
  58. cout << "MovieFileName=" << MovieFileName << "\n";
  59. cout << "XNPara=" << NXParas << "\n";
  60. cout << "YNPara=" << NYParas << "\n";
  61. }
  62. ////////////////////////////////////////
  63. MovieFilter2d::MovieFilter2d(): LastShiftedFrame(0), LastFrame(0)
  64. {
  65. }
  66. MovieFilter2d::MovieFilter2d(FILE *fw): LastShiftedFrame(0), LastFrame(0)
  67. {
  68. LoadFromFile(fw);
  69. }
  70. MovieFilter2d::~MovieFilter2d()
  71. {
  72. if (LastShiftedFrame != 0) delete [] LastShiftedFrame;
  73. if (LastFrame != 0) delete [] LastFrame;
  74. }
  75. bool MovieFilter2d::LoadFromFile(FILE *fw)
  76. {
  77. fread(&Header, sizeof(Header), 1, fw);
  78. Dout(dc::input, "OutputWidth=" << Header.outputwidth << " OutputHeight=" << Header.outputheight);
  79. FrameSize = Header.outputwidth*Header.outputheight;
  80. LastShiftedFrame = new float[FrameSize];
  81. LastFrame = new float[FrameSize];
  82. int ReadCount = fread(LastFrame, Header.width*Header.height*sizeof(*LastFrame), 1, fw);
  83. // if (ReadCount != 1) cout << "ReadCount = " << ReadCount << "****************\n\n\n";
  84. return (ReadCount == 1);
  85. }
  86. bool MovieFilter2d::LoadFilterFrame(FILE *fw)
  87. {
  88. return (fread(LastFrame, FrameSize*sizeof(*LastFrame), 1, fw) == 1);
  89. }
  90. int MovieFilter2d::GetFrameSize()
  91. {
  92. return FrameSize;
  93. }
  94. int MovieFilter2d::GetOutputWidth()
  95. {
  96. return Header.outputwidth;
  97. }
  98. int MovieFilter2d::GetOutputHeight()
  99. {
  100. return Header.outputheight;
  101. }
  102. float* MovieFilter2d::GetFramePointer()
  103. {
  104. return LastFrame;
  105. }
  106. float* MovieFilter2d::GetShiftedFramePointer()
  107. {
  108. return LastShiftedFrame;
  109. }
  110. bool MovieFilter2d::GetMinMaxValue(float &MinValue, float &MaxValue)
  111. {
  112. if (FrameSize > 0 || LastFrame!=0) {
  113. MinValue=*LastFrame;
  114. MaxValue=*LastFrame;
  115. for (int i=1;i<FrameSize;++i) {
  116. if (LastFrame[i]<MinValue) {
  117. MinValue=LastFrame[i];
  118. }
  119. if (LastFrame[i]>MaxValue) {
  120. MaxValue=LastFrame[i];
  121. }
  122. }
  123. } else {
  124. return false;
  125. }
  126. return true;
  127. }
  128. /**
  129. @brief shifts the original picture in x and y direction
  130. @param RelXShift relative shift of picture in x direction [0..1]
  131. @param RelYShift relative shift of picture in y direction [0..1]
  132. @author fm
  133. @since 29.10.2008
  134. */
  135. void MovieFilter2d::SetFrameShift(float RelXShift, float RelYShift)
  136. {
  137. // calculate absolute shift
  138. int owidth=Header.outputwidth;
  139. int oheight=Header.outputheight;
  140. int XShift=int(round(RelXShift*owidth)) % owidth;
  141. int YShift=int(round(RelYShift*oheight)) % oheight;
  142. // cout << "xshift=" << XShift << " yshift=" << YShift << "\n";
  143. // copy original picture to shifted picture, according to XShift and YShift
  144. int NewX, NewY;
  145. for (int y=0;y<oheight;++y) {
  146. NewY = (y + YShift) % oheight ;
  147. // cout << "y=" << y <<" NewY=" << NewY << "\n";
  148. for (int x=0;x<owidth;++x) {
  149. NewX = (x + XShift) % owidth;
  150. LastShiftedFrame[NewX+NewY*owidth] = LastFrame[x+y*owidth];
  151. }
  152. }
  153. }
  154. /////////////////
  155. ObjMovie::ObjMovie()
  156. : MovieFileName(), SwitchMaster(true), FrameNumber(0), fw(0)
  157. {
  158. gslr=GslSingleton::GetGslSingleton().GetGslRng();
  159. }
  160. ObjMovie::ObjMovie(
  161. const char* FileName)
  162. : MovieFileName(FileName), SwitchMaster(true), FrameNumber(0), fw(0)
  163. {
  164. LoadMovieFile(MovieFileName.c_str());
  165. gslr=GslSingleton::GetGslSingleton().GetGslRng();
  166. }
  167. ObjMovie::~ObjMovie()
  168. {
  169. for (vector<MovieFilter2d*>::iterator it=FilterList.begin(); it!=FilterList.end();++it)
  170. {
  171. delete (*it);
  172. }
  173. if (fw) {
  174. fclose(fw);
  175. }
  176. }
  177. int ObjMovie::LoadMovieFile(const char* FileName)
  178. {
  179. Dout(dc::input, "ObjMovie::LoadFile " << MovieFileName);
  180. Debug( libcw_do.inc_indent(2) );
  181. fw = fopen(FileName, "r");
  182. if (!fw) {
  183. throw FileOpenError(FileName);
  184. }
  185. fread(&MHeader, sizeof(MHeader), 1, fw);
  186. Dout(dc::input, "finfo=" << MHeader.finfo);
  187. Dout(dc::input, "version=" << MHeader.version);
  188. Dout(dc::input, "width= " << MHeader.width << " height=" << MHeader.height);
  189. //! \todo throw exception if no valid movie file (fm)
  190. fread(&NFilters, sizeof(NFilters), 1, fw);
  191. Dout(dc::input, "NFilters= " << NFilters);
  192. // read filters
  193. for (int i=0;i<NFilters;++i) FilterList.push_back(new MovieFilter2d(fw));
  194. fgetpos(fw, &FilePos_FirstFrame);
  195. // read frames
  196. InitializeFrameIndex();
  197. for (vector<MovieFilter2d*>::iterator it=FilterList.begin(); it!=FilterList.end();++it)
  198. {
  199. (*it)->LoadFilterFrame(fw);
  200. }
  201. // float MinVal = GetMinValue(0);
  202. Debug( libcw_do.dec_indent(2) );
  203. }
  204. float* ObjMovie::GetFramePointer(int FilterNr)
  205. {
  206. return FilterList[FilterNr]->GetFramePointer();
  207. }
  208. float* ObjMovie::GetShiftedFramePointer(int FilterNr)
  209. {
  210. return FilterList[FilterNr]->GetShiftedFramePointer();
  211. }
  212. int ObjMovie::GetFrameSize(int FilterNr)
  213. {
  214. return FilterList[FilterNr]->GetFrameSize();
  215. }
  216. int ObjMovie::GetOutputWidth(int FilterNr)
  217. {
  218. return FilterList[FilterNr]->GetOutputWidth();
  219. }
  220. int ObjMovie::GetOutputHeight(int FilterNr)
  221. {
  222. return FilterList[FilterNr]->GetOutputHeight();
  223. }
  224. void ObjMovie::ResetSwitchMaster()
  225. {
  226. SwitchMaster = true;
  227. SwitchMasterObj = 0;
  228. }
  229. bool ObjMovie::GetSwitchMaster()
  230. {
  231. // tell only one (the first) requester to be the SwitchMaster
  232. if (SwitchMaster)
  233. {
  234. SwitchMaster = false;
  235. return true;
  236. } else return false;
  237. }
  238. input* ObjMovie::GetSwitchMaster(input* Requester)
  239. {
  240. // tell only one (the first) requester to be the SwitchMaster
  241. if (SwitchMaster)
  242. {
  243. SwitchMaster = false;
  244. SwitchMasterObj = Requester;
  245. return 0;
  246. } else return SwitchMasterObj;
  247. }
  248. int ObjMovie::NextFrame()
  249. {
  250. // read frames
  251. ++FrameNumber;
  252. if ((FrameNumber >= NFrames) || feof(fw))
  253. {
  254. cout << "*************************feof(fw)==true \n ";
  255. fsetpos(fw, &FilePos_FirstFrame);
  256. FrameNumber=0;
  257. cout << "*************************RestartObjectMovieFile "
  258. << FrameNumber << "\n\n";
  259. }
  260. for (vector<MovieFilter2d*>::iterator it=FilterList.begin(); it!=FilterList.end();++it)
  261. {
  262. (*it)->LoadFilterFrame(fw);
  263. }
  264. return FrameNumber;
  265. }
  266. int ObjMovie::SetFrameShift(float RelXShift, float RelYShift)
  267. {
  268. for (vector<MovieFilter2d*>::iterator it=FilterList.begin(); it!=FilterList.end();++it)
  269. {
  270. (*it)->SetFrameShift(RelXShift,RelYShift);
  271. }
  272. }
  273. int ObjMovie::SetRandomShift()
  274. {
  275. float xshift=gsl_rng_uniform(gslr);
  276. float yshift=gsl_rng_uniform(gslr);
  277. SetFrameShift(xshift, yshift);
  278. }
  279. int ObjMovie::NextRandomFrame()
  280. {
  281. // read frames
  282. FrameNumber = gsl_rng_uniform_int(gslr, NFrames);
  283. CurFramePos = FrameIndex[FrameNumber];
  284. fsetpos(fw, &CurFramePos);
  285. for (vector<MovieFilter2d*>::iterator it=FilterList.begin(); it!=FilterList.end();++it)
  286. {
  287. (*it)->LoadFilterFrame(fw);
  288. }
  289. }
  290. int ObjMovie::GotoFrameNr(int _FrameNr)
  291. {
  292. if (_FrameNr < NFrames)
  293. {
  294. FrameNumber = _FrameNr;
  295. CurFramePos = FrameIndex[FrameNumber];
  296. fsetpos(fw, &CurFramePos);
  297. for (vector<MovieFilter2d*>::iterator it=FilterList.begin();
  298. it!=FilterList.end();++it)
  299. {
  300. (*it)->LoadFilterFrame(fw);
  301. }
  302. } else {
  303. cerr << "ERROR ObjMovie::GotoFrameNr: FrameNumber =" << _FrameNr << " too high (NFrames=" << NFrames << "\n";
  304. return 0;
  305. }
  306. //! \todo introduce exceptions for error handling
  307. return 1;
  308. }
  309. int ObjMovie::GetFrameNumber()
  310. {
  311. return FrameNumber;
  312. }
  313. int ObjMovie::GetNFrames()
  314. {
  315. return NFrames;
  316. }
  317. int ObjMovie::GetNFilters()
  318. {
  319. return NFilters;
  320. }
  321. int ObjMovie::InitializeFrameIndex()
  322. {
  323. fsetpos(fw, &FilePos_FirstFrame);
  324. NFrames=0;
  325. FrameNumber=0;
  326. Dout(dc::input, "InitializeFrameIndex");
  327. bool NoError=true;
  328. while (NoError) {
  329. fgetpos(fw, &CurFramePos);
  330. for (vector<MovieFilter2d*>::iterator it=FilterList.begin();
  331. it!=FilterList.end();++it)
  332. {
  333. NoError = (*it)->LoadFilterFrame(fw);
  334. }
  335. if (NoError) {
  336. FrameIndex.push_back(CurFramePos);
  337. ++NFrames;
  338. }
  339. }
  340. fsetpos(fw, &FilePos_FirstFrame);
  341. Dout(dc::input, "ObjMovieFile has " << NFrames << " Frames");
  342. }
  343. /**
  344. get the minimum value in the ObjMovie file
  345. noch nicht fertig!
  346. could be used to decide if on and off input layers should be used with the MovieFilter
  347. */
  348. float ObjMovie::GetMinValue(int FilterNr)
  349. {
  350. // store current frame number
  351. int OldFrameNumber = GetFrameNumber();
  352. // rewind movie to start frame
  353. int CurFrameNr=0;
  354. GotoFrameNr(0);
  355. float MinValue, MaxValue, GlobalMinValue, GlobalMaxValue;
  356. cout << "ObjMovie::GetMinValue()\n";
  357. // loop through every frame from start to end
  358. do {
  359. cout <<"FrameNr=" << FrameNumber <<"\n";
  360. // compare every pixel value of current frame (and selected filter) with global minimum
  361. } while (NextFrame()!=0);
  362. // restore old frame number
  363. GotoFrameNr(OldFrameNumber);
  364. }
  365. std::string GetDefaultMovieDir()
  366. {
  367. string MovieDir;
  368. if (getenv("OBJSIM_MOVIE_DIR")) {
  369. MovieDir = getenv("OBJSIM_MOVIE_DIR");
  370. cout << "set MovieDir from environment to " << MovieDir << std::endl;
  371. } else {
  372. cout << "environment variable OBJSIM_MOVIE_DIR is not set" << std::endl;
  373. }
  374. if (MovieDir.empty()) {
  375. MovieDir = string(getenv("HOME")) + "/prog/objsim/data/movies/";
  376. }
  377. if (MovieDir[MovieDir.length()-1] != '/')
  378. {
  379. MovieDir += "/";
  380. }
  381. cout << "DefaultMovieDir: " << MovieDir << "\n";
  382. return MovieDir;
  383. }
  384. /**
  385. @para FileName without .idlmov
  386. */
  387. ObjMovie* LoadObjMovie(const string& StimFileName, int & Width, int & Height, int & NFilters, int & NFrames, string MovieDir)
  388. {
  389. cout << "StimFileName=" << StimFileName << "\n";
  390. if (MovieDir.empty()) {
  391. MovieDir = GetDefaultMovieDir();
  392. }
  393. cout << "MovieDir=" << MovieDir << "\n";
  394. std::string MetaFileName = MovieDir + StimFileName + ".meta.xml";
  395. MovieMetaFile MetaFile(MetaFileName.c_str());
  396. std::string MovieFileName;
  397. if (MetaFile.Loaded) {
  398. MovieFileName = MetaFile.MovieFileName;
  399. } else {
  400. cout << "MovieMetaFile not loaded\n";
  401. MovieFileName = StimFileName + ".idlmov";
  402. cout << "using movie file name: MovieFileName\n";
  403. }
  404. std::string StimName;
  405. {
  406. StimName = MovieDir + MovieFileName;
  407. cout << "Load movie: " << StimName << "\n";
  408. }
  409. ObjMovie* MyMovie = new ObjMovie(StimName.c_str());
  410. Width = MyMovie->GetOutputWidth(0);
  411. Height = MyMovie->GetOutputHeight(0);
  412. NFrames = MyMovie->GetNFrames();
  413. NFilters = MyMovie->GetNFilters();
  414. return MyMovie;
  415. }