text: /* +------------------------------------------------------------------------+
     |                     Mobile Robot Programming Toolkit (MRPT)            |
     |                          https://www.mrpt.org/                         |
     |                                                                        |
     | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file     |
     | See: https://www.mrpt.org/Authors - All rights reserved.               |
     | Released under BSD License. See: https://www.mrpt.org/License          |
     +------------------------------------------------------------------------+ */
  
  #include "vision-precomp.h"  // Precompiled headers
  
  #include <mrpt/vision/CVideoFileWriter.h>
  
  // Universal include for all versions of OpenCV
  #include <mrpt/3rdparty/do_opencv_includes.h>
  
  #define M_WRITER                 \
  	(const_cast<CvVideoWriter*>( \
  		static_cast<const CvVideoWriter*>(m_video.get())))
  #define M_WRITER_PTR (reinterpret_cast<CvVideoWriter**>(m_video.getPtrToPtr()))
  
  using namespace mrpt;
  using namespace mrpt::vision;
  using namespace mrpt::img;
  using namespace mrpt::system;
  
  /* ----------------------------------------------------------
  						Ctor
     ---------------------------------------------------------- */
  CVideoFileWriter::CVideoFileWriter() : m_video(), m_img_size(0, 0) {}
  /* ----------------------------------------------------------
  						Dtor
     ---------------------------------------------------------- */
  CVideoFileWriter::~CVideoFileWriter() { close(); }
  /* ----------------------------------------------------------
  						open
     ---------------------------------------------------------- */
  bool CVideoFileWriter::open(
  	const std::string& out_file, double fps,
  	const mrpt::img::TImageSize& frameSize, const std::string& fourcc,
  	bool isColor)
  {
  #if MRPT_HAS_OPENCV
  	close();
  
  	int cc;
  
  	if (fourcc.empty())
  	{
  		cc = CV_FOURCC_DEFAULT;  // Default
  	}
  	else if (fourcc.size() == 4)
  	{
  		cc = CV_FOURCC(fourcc[0], fourcc[1], fourcc[2], fourcc[3]);
  	}
  	else
  	{
  		std::cerr << "[CVideoFileWriter::open] fourcc string must be four "
  					 "character length or empty for default."
  				  << std::endl;
  		return false;
  	}
  
  	m_video = cvCreateVideoWriter(
  		out_file.c_str(), cc, fps, cvSize(frameSize.x, frameSize.y),
  		isColor ? 1 : 0);
  
  	m_img_size = frameSize;
  
  	return m_video.get() != nullptr;
  #else
  	std::cerr << "[CVideoFileWriter::open] ERROR: MRPT was compiled without "
  				 "OpenCV support "
  			  << std::endl;
  	return false;
  #endif
  }
  
  /* ----------------------------------------------------------
  						close
     ---------------------------------------------------------- */
  void CVideoFileWriter::close()
  {
  #if MRPT_HAS_OPENCV
  	if (!M_WRITER) return;
  	cvReleaseVideoWriter(M_WRITER_PTR);
  	*M_WRITER_PTR = nullptr;
  #endif
  }
  
  /* ----------------------------------------------------------
  						isOpen
     ---------------------------------------------------------- */
  bool CVideoFileWriter::isOpen() const
  {
  #if MRPT_HAS_OPENCV
  	return (M_WRITER != nullptr);
  #else
  	return false;
  #endif
  }
  
  /* ----------------------------------------------------------
  						operator <<
     ---------------------------------------------------------- */
  const CVideoFileWriter& CVideoFileWriter::operator<<(
  	const mrpt::img::CImage& img) const
  {
  	if (!m_video.get()) THROW_EXCEPTION("Call open first");
  
  	if ((size_t)m_img_size.x != img.getWidth() ||
  		(size_t)m_img_size.y != img.getHeight())
  		THROW_EXCEPTION(format(
  			"Video frame size is %ix%i but image is %ux%u", m_img_size.x,
  			m_img_size.y, (unsigned)img.getWidth(), (unsigned)img.getHeight()));
  
  #if MRPT_HAS_OPENCV
  	cv::Mat m = img.asCvMat<cv::Mat>(SHALLOW_COPY);
  	IplImage ipl = cvIplImage(m);
  	if (!cvWriteFrame(M_WRITER, &ipl))
  		THROW_EXCEPTION("Error writing image frame to video file");
  #endif
  	return *this;
  }
  
  /* ----------------------------------------------------------
  						writeImage
     ---------------------------------------------------------- */
  bool CVideoFileWriter::writeImage(const mrpt::img::CImage& img) const
  {
  	if (!m_video.get()) return false;
  
  	if ((size_t)m_img_size.x != img.getWidth() ||
  		(size_t)m_img_size.y != img.getHeight())
  	{
  		std::cout << format(
  						 "[CVideoFileWriter::writeImage] Error: video frame "
  						 "size is %ix%i but image is %ux%u",
  						 m_img_size.x, m_img_size.y, (unsigned)img.getWidth(),
  						 (unsigned)img.getHeight())
  				  << std::endl;
  		return false;
  	}
  
  #if MRPT_HAS_OPENCV
  	cv::Mat m = img.asCvMat<cv::Mat>(SHALLOW_COPY);
  	IplImage ipl = cvIplImage(m);
  	return 0 != cvWriteFrame(M_WRITER, &ipl);
  #else
  	return false;
  #endif
  }
  