PageRenderTime 278ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/source/3rd_party/opencv/sources/modules/highgui/src/cap_images.cpp

https://gitlab.com/Ruggero/SparkEngine_Desktop
C++ | 394 lines | 272 code | 65 blank | 57 comment | 40 complexity | c67adfba003e40351f7cc7bd388dbeac MD5 | raw file
  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  5. // By downloading, copying, installing or using the software you agree to this license.
  6. // If you do not agree to this license, do not download, install,
  7. // copy or use the software.
  8. //
  9. //
  10. // Intel License Agreement
  11. // For Open Source Computer Vision Library
  12. //
  13. // Copyright (C) 2008, Nils Hasler, all rights reserved.
  14. // Third party copyrights are property of their respective owners.
  15. //
  16. // Redistribution and use in source and binary forms, with or without modification,
  17. // are permitted provided that the following conditions are met:
  18. //
  19. // * Redistribution's of source code must retain the above copyright notice,
  20. // this list of conditions and the following disclaimer.
  21. //
  22. // * Redistribution's in binary form must reproduce the above copyright notice,
  23. // this list of conditions and the following disclaimer in the documentation
  24. // and/or other materials provided with the distribution.
  25. //
  26. // * The name of Intel Corporation may not be used to endorse or promote products
  27. // derived from this software without specific prior written permission.
  28. //
  29. // This software is provided by the copyright holders and contributors "as is" and
  30. // any express or implied warranties, including, but not limited to, the implied
  31. // warranties of merchantability and fitness for a particular purpose are disclaimed.
  32. // In no event shall the Intel Corporation or contributors be liable for any direct,
  33. // indirect, incidental, special, exemplary, or consequential damages
  34. // (including, but not limited to, procurement of substitute goods or services;
  35. // loss of use, data, or profits; or business interruption) however caused
  36. // and on any theory of liability, whether in contract, strict liability,
  37. // or tort (including negligence or otherwise) arising in any way out of
  38. // the use of this software, even if advised of the possibility of such damage.
  39. //
  40. //M*/
  41. // Author: Nils Hasler <hasler@mpi-inf.mpg.de>
  42. //
  43. // Max-Planck-Institut Informatik
  44. //
  45. // capture video from a sequence of images
  46. // the filename when opening can either be a printf pattern such as
  47. // video%04d.png or the first frame of the sequence i.e. video0001.png
  48. //
  49. #include "precomp.hpp"
  50. #include <sys/stat.h>
  51. #ifdef NDEBUG
  52. #define CV_WARN(message)
  53. #else
  54. #define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
  55. #endif
  56. #ifndef _MAX_PATH
  57. #define _MAX_PATH 1024
  58. #endif
  59. class CvCapture_Images : public CvCapture
  60. {
  61. public:
  62. CvCapture_Images()
  63. {
  64. filename = NULL;
  65. currentframe = firstframe = 0;
  66. length = 0;
  67. frame = NULL;
  68. grabbedInOpen = false;
  69. }
  70. virtual ~CvCapture_Images()
  71. {
  72. close();
  73. }
  74. virtual bool open(const char* _filename);
  75. virtual void close();
  76. virtual double getProperty(int);
  77. virtual bool setProperty(int, double);
  78. virtual bool grabFrame();
  79. virtual IplImage* retrieveFrame(int);
  80. protected:
  81. char* filename; // actually a printf-pattern
  82. unsigned currentframe;
  83. unsigned firstframe; // number of first frame
  84. unsigned length; // length of sequence
  85. IplImage* frame;
  86. bool grabbedInOpen;
  87. };
  88. void CvCapture_Images::close()
  89. {
  90. if( filename )
  91. {
  92. free(filename);
  93. filename = NULL;
  94. }
  95. currentframe = firstframe = 0;
  96. length = 0;
  97. cvReleaseImage( &frame );
  98. }
  99. bool CvCapture_Images::grabFrame()
  100. {
  101. char str[_MAX_PATH];
  102. sprintf(str, filename, firstframe + currentframe);
  103. if (grabbedInOpen)
  104. {
  105. grabbedInOpen = false;
  106. ++currentframe;
  107. return frame != NULL;
  108. }
  109. cvReleaseImage(&frame);
  110. frame = cvLoadImage(str, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
  111. if( frame )
  112. currentframe++;
  113. return frame != NULL;
  114. }
  115. IplImage* CvCapture_Images::retrieveFrame(int)
  116. {
  117. return grabbedInOpen ? NULL : frame;
  118. }
  119. double CvCapture_Images::getProperty(int id)
  120. {
  121. switch(id)
  122. {
  123. case CV_CAP_PROP_POS_MSEC:
  124. CV_WARN("collections of images don't have framerates\n");
  125. return 0;
  126. case CV_CAP_PROP_POS_FRAMES:
  127. return currentframe;
  128. case CV_CAP_PROP_POS_AVI_RATIO:
  129. return (double)currentframe / (double)(length - 1);
  130. case CV_CAP_PROP_FRAME_WIDTH:
  131. return frame ? frame->width : 0;
  132. case CV_CAP_PROP_FRAME_HEIGHT:
  133. return frame ? frame->height : 0;
  134. case CV_CAP_PROP_FPS:
  135. CV_WARN("collections of images don't have framerates\n");
  136. return 1;
  137. case CV_CAP_PROP_FOURCC:
  138. CV_WARN("collections of images don't have 4-character codes\n");
  139. return 0;
  140. }
  141. return 0;
  142. }
  143. bool CvCapture_Images::setProperty(int id, double value)
  144. {
  145. switch(id)
  146. {
  147. case CV_CAP_PROP_POS_MSEC:
  148. case CV_CAP_PROP_POS_FRAMES:
  149. if(value < 0) {
  150. CV_WARN("seeking to negative positions does not work - clamping\n");
  151. value = 0;
  152. }
  153. if(value >= length) {
  154. CV_WARN("seeking beyond end of sequence - clamping\n");
  155. value = length - 1;
  156. }
  157. currentframe = cvRound(value);
  158. if (currentframe != 0)
  159. grabbedInOpen = false; // grabbed frame is not valid anymore
  160. return true;
  161. case CV_CAP_PROP_POS_AVI_RATIO:
  162. if(value > 1) {
  163. CV_WARN("seeking beyond end of sequence - clamping\n");
  164. value = 1;
  165. } else if(value < 0) {
  166. CV_WARN("seeking to negative positions does not work - clamping\n");
  167. value = 0;
  168. }
  169. currentframe = cvRound((length - 1) * value);
  170. if (currentframe != 0)
  171. grabbedInOpen = false; // grabbed frame is not valid anymore
  172. return true;
  173. }
  174. CV_WARN("unknown/unhandled property\n");
  175. return false;
  176. }
  177. static char* icvExtractPattern(const char *filename, unsigned *offset)
  178. {
  179. char *name = (char *)filename;
  180. if( !filename )
  181. return 0;
  182. // check whether this is a valid image sequence filename
  183. char *at = strchr(name, '%');
  184. if(at)
  185. {
  186. int dummy;
  187. if(sscanf(at + 1, "%ud", &dummy) != 1)
  188. return 0;
  189. name = strdup(filename);
  190. }
  191. else // no pattern filename was given - extract the pattern
  192. {
  193. at = name;
  194. // ignore directory names
  195. char *slash = strrchr(at, '/');
  196. if (slash) at = slash + 1;
  197. #ifdef _WIN32
  198. slash = strrchr(at, '\\');
  199. if (slash) at = slash + 1;
  200. #endif
  201. while (*at && !isdigit(*at)) at++;
  202. if(!*at)
  203. return 0;
  204. sscanf(at, "%u", offset);
  205. int size = (int)strlen(filename) + 20;
  206. name = (char *)malloc(size);
  207. strncpy(name, filename, at - filename);
  208. name[at - filename] = 0;
  209. strcat(name, "%0");
  210. int i;
  211. char *extension;
  212. for(i = 0, extension = at; isdigit(at[i]); i++, extension++)
  213. ;
  214. char places[10];
  215. sprintf(places, "%dd", i);
  216. strcat(name, places);
  217. strcat(name, extension);
  218. }
  219. return name;
  220. }
  221. bool CvCapture_Images::open(const char * _filename)
  222. {
  223. unsigned offset = 0;
  224. close();
  225. filename = icvExtractPattern(_filename, &offset);
  226. if(!filename)
  227. return false;
  228. // determine the length of the sequence
  229. length = 0;
  230. char str[_MAX_PATH];
  231. for(;;)
  232. {
  233. sprintf(str, filename, offset + length);
  234. struct stat s;
  235. if(stat(str, &s))
  236. {
  237. if(length == 0 && offset == 0) // allow starting with 0 or 1
  238. {
  239. offset++;
  240. continue;
  241. }
  242. }
  243. if(!cvHaveImageReader(str))
  244. break;
  245. length++;
  246. }
  247. if(length == 0)
  248. {
  249. close();
  250. return false;
  251. }
  252. firstframe = offset;
  253. // grab frame to enable properties retrieval
  254. bool grabRes = grabFrame();
  255. grabbedInOpen = true;
  256. currentframe = 0;
  257. return grabRes;
  258. }
  259. CvCapture* cvCreateFileCapture_Images(const char * filename)
  260. {
  261. CvCapture_Images* capture = new CvCapture_Images;
  262. if( capture->open(filename) )
  263. return capture;
  264. delete capture;
  265. return NULL;
  266. }
  267. //
  268. //
  269. // image sequence writer
  270. //
  271. //
  272. class CvVideoWriter_Images : public CvVideoWriter
  273. {
  274. public:
  275. CvVideoWriter_Images()
  276. {
  277. filename = 0;
  278. currentframe = 0;
  279. }
  280. virtual ~CvVideoWriter_Images() { close(); }
  281. virtual bool open( const char* _filename );
  282. virtual void close();
  283. virtual bool writeFrame( const IplImage* );
  284. protected:
  285. char* filename;
  286. unsigned currentframe;
  287. };
  288. bool CvVideoWriter_Images::writeFrame( const IplImage* image )
  289. {
  290. char str[_MAX_PATH];
  291. sprintf(str, filename, currentframe);
  292. int ret = cvSaveImage(str, image);
  293. currentframe++;
  294. return ret > 0;
  295. }
  296. void CvVideoWriter_Images::close()
  297. {
  298. if( filename )
  299. {
  300. free( filename );
  301. filename = 0;
  302. }
  303. currentframe = 0;
  304. }
  305. bool CvVideoWriter_Images::open( const char* _filename )
  306. {
  307. unsigned offset = 0;
  308. close();
  309. filename = icvExtractPattern(_filename, &offset);
  310. if(!filename)
  311. return false;
  312. char str[_MAX_PATH];
  313. sprintf(str, filename, 0);
  314. if(!cvHaveImageWriter(str))
  315. {
  316. close();
  317. return false;
  318. }
  319. currentframe = offset;
  320. return true;
  321. }
  322. CvVideoWriter* cvCreateVideoWriter_Images( const char* filename )
  323. {
  324. CvVideoWriter_Images *writer = new CvVideoWriter_Images;
  325. if( writer->open( filename ))
  326. return writer;
  327. delete writer;
  328. return 0;
  329. }