/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2023, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */
#pragma once

#include <mrpt/img/CImage.h>
#include <mrpt/img/TCamera.h>

namespace mrpt::vision
{
/** Use this class to undistort monocular images if the same distortion map is
 * used over and over again.
 *  Using this class is much more efficient that calling
 * mrpt::img::CImage::rectifyImage or OpenCV's cvUndistort2(), since
 *  the remapping data is computed only once for the camera parameters (typical
 * times: 640x480 image -> 70% build map / 30% actual undistort).
 *
 *  Works with grayscale or color images.
 *
 * Example of usage:
 * \code
 *   CUndistortMap   unmap;
 *   mrpt::img::TCamera  cam_params;
 *
 *   unmap.setFromCamParams( cam_params );
 *
 *   mrpt::img::CImage  img, img_out;
 *
 *   while (true) {
 *     unmap.undistort(img, img_out);  // or:
 *     unmap.undistort(img);  // output in place
 *   }
 *
 * \endcode
 *
 * \sa CStereoRectifyMap, mrpt::img::TCamera, the application <a
 * href="http://www.mrpt.org/Application:camera-calib" >camera-calib</a> for
 * calibrating a camera.
 * \ingroup mrpt_vision_grp
 */
class CUndistortMap
{
   public:
	/** Default ctor */
	CUndistortMap();

	/** Prepares the mapping from the distortion parameters of a camera.
	 * Must be called before invoking \a undistort().
	 */
	void setFromCamParams(const mrpt::img::TCamera& params);

	/** Undistort the input image and saves the result in the output one - \a
	 * setFromCamParams() must have been set prior to calling this.
	 */
	void undistort(
		const mrpt::img::CImage& in_img, mrpt::img::CImage& out_img) const;

	/** Undistort the input image and saves the result in-place- \a
	 * setFromCamParams() must have been set prior to calling this.
	 */
	void undistort(mrpt::img::CImage& in_out_img) const;

	/** Returns the camera parameters which were used to generate the distortion
	 * map, as passed by the user to \a setFromCamParams */
	inline const mrpt::img::TCamera& getCameraParams() const
	{
		return m_camera_params;
	}

	/** Returns true if \a setFromCamParams() has been already called, false
	 * otherwise.
	 *  Can be used within loops to determine the first usage of the object and
	 * when it needs to be initialized.
	 */
	inline bool isSet() const { return !m_dat_mapx.empty(); }

   private:
	std::vector<int16_t> m_dat_mapx;
	std::vector<uint16_t> m_dat_mapy;

	/** A copy of the data provided by the user */
	mrpt::img::TCamera m_camera_params;

};	// end class
}  // namespace mrpt::vision
