/***************************************************************************************************************:')

CoordSystem2Img.h

Coordinate space handling in images.

Fabrice Le Bars

Created: 2009-01-07

Version status: To test and validate

***************************************************************************************************************:)*/

#ifndef COORDSYSTEM2IMG_H
#define COORDSYSTEM2IMG_H

#include "CoordSystem.h"

/*
Structure that enables the use of a coordinate space in an image instead of 
using its lines and rows.
*/
struct _COORDSYSTEM2IMG
{
	COORDSYSTEM cs;
	UINT width;
	UINT height;
	double XJRatio;
	double YIRatio;
	double JXRatio;
	double IYRatio;
};
typedef struct _COORDSYSTEM2IMG COORDSYSTEM2IMG;

/*
Initialize a structure COORDSYSTEM2IMG.
See the description of the COORDSYSTEM2IMG structure for more information.

COORDSYSTEM2IMG* pCS2Img : (INOUT) Valid pointer to the structure.
COORDSYSTEM* pCS : (IN) Coordinate space to use.
UINT width : (IN) Width of the picture.
UINT height : (IN) Height of the picture.

Return : EXIT_SUCCESS or EXIT_FAILURE if there is an error.
*/
inline int InitCS2Img(COORDSYSTEM2IMG* pCS2Img, COORDSYSTEM* pCS, UINT width, UINT height)
{
	// x = xMin -> j = 0
	// x = xMax -> j = width-1
	// y = yMin -> i = height-1
	// y = yMax -> i = 0

	pCS2Img->cs = *pCS;

	pCS2Img->width = width;
	pCS2Img->height = height;

	pCS2Img->XJRatio = (pCS2Img->cs.xMax - pCS2Img->cs.xMin) / (double)(pCS2Img->width - 1);
	pCS2Img->YIRatio = (pCS2Img->cs.yMin - pCS2Img->cs.yMax) / (double)(pCS2Img->height - 1);

	pCS2Img->JXRatio = 1.0/pCS2Img->XJRatio;
	pCS2Img->IYRatio = 1.0/pCS2Img->YIRatio;

	return EXIT_SUCCESS;
}

inline int XYCS2IJImg(COORDSYSTEM2IMG* pCS2Img, double x, double y, int* pI, int* pJ)
{
	*pI = (int)((y - pCS2Img->cs.yMax) * pCS2Img->IYRatio);
	*pJ = (int)((x - pCS2Img->cs.xMin) * pCS2Img->JXRatio);

	return EXIT_SUCCESS;
}

inline int IJImg2XYCS(COORDSYSTEM2IMG* pCS2Img, int i, int j, double* pX, double* pY)
{
	*pX = pCS2Img->XJRatio * (double)j + pCS2Img->cs.xMin;
	*pY = pCS2Img->YIRatio * (double)i + pCS2Img->cs.yMax;

	return EXIT_SUCCESS;
}

inline int GetCSPixelSize(COORDSYSTEM2IMG* pCS2Img, double* pSizeX, double* pSizeY)
{
	*pSizeX = fabs(pCS2Img->XJRatio);
	*pSizeY = fabs(pCS2Img->YIRatio);

	return EXIT_SUCCESS;
}

inline int XCS2JImg(COORDSYSTEM2IMG* pCS2Img, double x)
{
	return (int)((x - pCS2Img->cs.xMin) * pCS2Img->JXRatio);
}

inline int YCS2IImg(COORDSYSTEM2IMG* pCS2Img, double y)
{
	return (int)((y - pCS2Img->cs.yMax) * pCS2Img->IYRatio);
}

inline double IImg2YCS(COORDSYSTEM2IMG* pCS2Img, int i)
{
	return pCS2Img->YIRatio * (double)i + pCS2Img->cs.yMax;
}

inline double JImg2XCS(COORDSYSTEM2IMG* pCS2Img, int j)
{
	return pCS2Img->XJRatio * (double)j + pCS2Img->cs.xMin;
}

inline double GetCSPixelSizeX(COORDSYSTEM2IMG* pCS2Img)
{
	return fabs(pCS2Img->XJRatio);
}

inline double GetCSPixelSizeY(COORDSYSTEM2IMG* pCS2Img)
{
	return fabs(pCS2Img->YIRatio);
}

#endif // COORDSYSTEM2IMG_H
