/*==============================================================================*/
/* 2DLib main header file							*/
/*										*/
/* AUTHOR:	Gabor Nagy							*/
/* DATE:	1996-Nov-30 23:04:30						*/
/*										*/
/* 2DLib(TM) Copyright (C) 1995 By Gabor Nagy. All rights reserved.		*/
/*==============================================================================*/
#ifndef _EImage_h
#define _EImage_h

#include <stdio.h>
#define _EPXWindow

#include <Color/Color.h>

#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif


// Channel masks
//
#define	EpRED	0x01
#define	EpGREEN	0x02
#define	EpBLUE	0x04
#define	EpALPHA	0x08
#define	EpZ	0x10

#define EpRGBA	(0x0F)

#define EpALL	0xFFFFFFFF

// General return values
//
enum
{
 EpOK=0,
 EpSAME_SIZE,
 EpERROR,
 EpNOTHING_TO_DO,
 EpEND
};


typedef enum
{
 EpTOP_TO_BOTTOM=1,
 EpBOTTOM_TO_TOP
} EpOrientation;


// Key types for function curves
//
enum
{
 EpKY_LINEAR=0,
 EpKY_MIRROR,
 EpKY_COLINEAR,
 EpKY_FREE
};

typedef struct
{
 double	KeyFrame, KeyValue;
 int	KeyType;
} EpKeyFrameRec;


#define EpZERO_BLANKED	1

#define EpMAX_COLORNUM			  4096


typedef struct
{
 unsigned char	R, G, B, A;
} EpRGBA8Pixel;

typedef struct
{
 unsigned short	R, G, B, A;
} EpRGBA16Pixel;


typedef struct
{
 float		R, G, B, A;
} EpRGBAf32Pixel;

typedef unsigned int	EpPRGBA8Pixel;

typedef unsigned char	EpColorIndex8Pixel;
typedef unsigned short	EpColorIndex16Pixel;
typedef unsigned int	EpColorIndex32Pixel;

#define EpM_glCPackPRGBA(c)		glColor4ub(EcM_R_RGBA(c),EcM_G_RGBA(c),EcM_B_RGBA(c),EcM_A_RGBA(c))
#define EpM_glClearColorPRGBA(c)	glClearColor((float)(EcM_R_RGBA(c))*0.039064,(float)(EcM_G_RGBA(c))*0.039064,(float)(EcM_B_RGBA(c))*0.039064,(float)(EcM_A_RGBA(c))*0.039064)
#define EpM_glClearColorRGBAI(c)	glClearColor((float)((c).R)*0.0000152, (float)((c).G)*0.0000152, (float)((c).B)*0.0000152, (float)((c).A)*0.0000152)


/*----------------------------------------------*/
/* Dithering algorithms				*/
/*----------------------------------------------*/
enum
{
 EpDITHER_NONE=0,
 EpDITHER_BAYER44,
 EpDITHER_BAYER88,
 EpDITHER_MATDASH,
 EpDITHER_LINES,
 EpDITHER_HALFTONE,
 EpDITHER_FLOYD_STEINBERG,
 EpDITHER_FAX
};



/*----------------------------------------------*/
/* Pixel formats				*/
/*----------------------------------------------*/
					// Channels			effective bits	    bytes/pixel
					//------------------------------------------------------------------
#define EpPixelRGBA8		0x0001	// Red, Green, Blue, Alpha 	8 bits / channel	4
#define EpPixelRGBA16		0x0002	// Red, Green, Blue, Alpha 	16 bits / channel	8
#define EpPixelRGBAf32		0x0004	// Red, Green, Blue, Alpha	32 bit float		16
#define EpPixelRGBX8		0x0008	// Red, Green, Blue, None	8 bits / channel	4
#define EpPixelRGBX16		0x0010	// Red, Green, Blue, None	16 bits / channel	8
#define EpPixelRGBXf32		0x0020	// Red, Green, Blue, None	32 bit float		16
#define EpPixelRGB8		0x0040	// Red, Green, Blue		8 bits / channel	3
#define EpPixelRGB16		0x0080	// Red, Green, Blue		8 bits / channel	6
#define EpPixelRGBf32		0x0100	// Red, Green, Blue		32 bit float		12
#define EpPixelGRAY8		0x0200	// Gray				8			1
#define EpPixelGRAY16		0x0400	// Gray				16			2
#define EpPixelGRAY32		0x0800	// Gray				32			4
#define EpPixelCOLORINDEX8	0x1000	// Colorindex			8			1
#define EpPixelCOLORINDEX16	0x2000	// Colorindex			16			2
#define EpPixelCOLORINDEX32	0x4000	// Colorindex			32			4
#define EpPixelALL		0x7FFF
#define EpPixelFROM_DRAWWIDGET	0xFFFFF




/*----------------------------------------------*/
/* For transferring an image trough network	*/
/*----------------------------------------------*/
enum
{
 EpN_IMAGEFORMAT_Z_RGBA_8=1,		// Z-pixmap type, 8 bits/channel: AAAAAAAABBBBBBBBGGGGGGGGRRRRRRRR
 EpN_IMAGEFORMAT_Z_RGB_8,		// Z-pixmap type, 8 bits/channel: BBBBBBBBGGGGGGGGRRRRRRRR
 EpN_IMAGEFORMAT_Z_RGB_5,		// Z-pixmap type, 5 bits/channel: XBBBBBGGGGGRRRRR
 EpN_IMAGEFORMAT_Z_RGB_565,		// Z-pixmap type, 5-6-5 bits/channel: BBBBBGGGGGGRRRRR
 EpN_IMAGEFORMAT_Z_RGB_4,		// Z-pixmap type, 4 bits/channel: XXXXBBBBGGGGRRRR
 EpN_IMAGEFORMAT_Z_RGB_4_D,		// Z-pixmap type, 4 bits/channel: XXXXBBBBGGGGRRRR dithered
 EpN_IMAGEFORMAT_Z_RGB_332,		// Z-pixmap type, 3-3-2 bits/channel: BBGGGRRR
 EpN_IMAGEFORMAT_Z_Gray_8,		// Z-pixmap type, 8 bits/pixel: Grayscale (luma)
 EpN_IMAGEFORMAT_Z_Red_8,		// Z-pixmap type, 8 bits/pixel: Red channel only
 EpN_IMAGEFORMAT_Z_Green_8,		// Z-pixmap type, 8 bits/pixel: Green channel only
 EpN_IMAGEFORMAT_Z_Blue_8,		// Z-pixmap type, 8 bits/pixel: Blue channel only
 EpN_IMAGEFORMAT_Z_Alpha_8,		// Z-pixmap type, 8 bits/pixel: Alpha channel only
 EpN_IMAGEFORMAT_Z_ColorIndex,		// Z-pixmap type, Depth bits/pixel: Colorindex
 EpN_IMAGEFORMAT_P_RGBA,		// Separate bitplanes, Depth/4 bits/pixel: Red, Green, Blue, Alpha
 EpN_IMAGEFORMAT_P_RGB,			// Separate bitplanes, Depth/3 bits/pixel: Red, Green, Blue
 EpN_IMAGEFORMAT_P_Gray,		// Separate bitplanes, Depth bits/pixel: Grayscale
 EpN_IMAGEFORMAT_P_ColorIndex,		// Separate bitplanes, Depth bits/pixel: Colorindex
 EpN_IMAGEFORMAT_Z_JPEG_RGB_8		// Z-pixmap type, 8 bits/channel: Red, Green, Blue compressed with JPEG
};

#define EpN_IMAGEFORMAT_FIRST	EpN_IMAGEFORMAT_Z_RGBA_8
#define EpN_IMAGEFORMAT_LAST	EpN_IMAGEFORMAT_Z_JPEG_RGB_8

#define	EpN_ImgHeaderSize	268



#define EpPALETTEFORMAT_ARGB16		1		// 16 bits (4 bits per channel): Alpha, Blue, Green, Red
#define EpPALETTEFORMAT_ARGB32		(1<<1)		// 32 bits (8 bits per channel): Alpha, Blue, Green, Red
#define EpPALETTEFORMAT_ARGB64		(1<<2)		// 64 bits (16 bits per channel): Alpha, Blue, Green, Red
#define EpPALETTEFORMAT_RGBA32		(1<<3)		// 32 bits (8 bits per channel): Red, Green, Blue, Alpha



/*--------------------------------------------------------------*/
/* Image structure for inlining into C/C++ source		*/
/*--------------------------------------------------------------*/
typedef struct
{
 int		XSize, YSize, PixelFormat;
 unsigned char*	RGBA8Image;
} EpCImage;


/*--------------------------------------------------------------*/
/* Image record for file-IO and image manipulating functions	*/
/*--------------------------------------------------------------*/
typedef struct
{
 unsigned int		RefCnt;			// Reference count

 char*			FileName;

 unsigned int		PixelFormats;		// Storage formats provided
 char			LineAlignment,
			PaletteFormat;
 int			QFactor;		// Quality-factor for lossy compr. algorithms like JPEG
 unsigned int		XSize, YSize;
 EpColorIndex8Pixel*	ColorIndex8Image;	// ColorIndex representation with 8 bits
 EpColorIndex16Pixel*	ColorIndex16Image;	// ColorIndex representation with 16 bits
 EpColorIndex32Pixel*	ColorIndex32Image;	// ColorIndex representation with 32 bits
 EpRGBA8Pixel*		RGBA8Image;		// Truecolor representation with 8 bits per channel (RRGGBBAA)
 EpRGBA16Pixel*		RGBA16Image;		// Truecolor representation with 16 bits per channel (RRRRGGGGBBBBAAAA)
 EpRGBAf32Pixel*	RGBAf32Image;		// High dynamic range Truecolor representation with 32-bit floats per channel
 EcRGBAiColor*		RGBAiColors;		// Color palette for color-indexed images
 unsigned int*		PixelValues;
 unsigned int		NumOfColors;
 unsigned int		NumOfValidPixels;	// For read, if a file is not a complete image
} EpImage;




/*--------------------------------------*/
/* Special Image file format IDs	*/
/*--------------------------------------*/
#define EpFileFormatNONE		NULL
#define EpFileFormatFROM_EXTENSION	NULL	// Get format from filename extension (saving)
#define EpFileFormatAUTOMATIC		NULL	// Automatic format recognition (reading)


typedef struct EpImageFile_S	EpImageFile;


typedef int	(*EpIOProc)(EpImageFile*, EpImage*);
typedef int	(*EpIOOpenProc)(EpImageFile*, EpImage*);
typedef int	(*EpIOCloseProc)(EpImageFile*);

typedef struct
{
 char*		Name;			// Format name
 char**		FileNameExtensions;	// File name extensions
 EpIOOpenProc	OpenProc;		// Function to open an image file and read its header, or close it
 EpIOCloseProc	CloseProc;		// Function to close image file and free allocated resources
 EpIOProc	ReadProc;		// Function to read an image file
 EpIOProc	WriteProc;		// Function to write an image to a file
 unsigned int	SupportedPixelFormats;
} EpImageIOFormat;


struct EpImageFile_S
{
 char*			Name;		// Name of the file
 EpImageIOFormat*	Format;
 void*			Handle;
 FILE*			File;
 int			RegionX, RegionY;
 unsigned int		RegionXSize, RegionYSize;
};


// Plugins
//
#define	EpPLUGIN_ALLOC_STEP	2

enum
{
 EpPISTATUS_OK=0,
 EpPISTATUS_ERROR
};




// Scaling filter types
//
enum
{
 EpFILTER_NONE=0,
 EpFILTER_IMPULSE,
 EpFILTER_BOX,
 EpFILTER_TRIANGLE,
 EpFILTER_QUADRATIC,
 EpFILTER_MITCHELL,
 EpFILTER_GAUSSIAN
};



extern double			Ep_CurrentFrame;

extern EpColorIndex8Pixel*	Ep_ImageDuplicateColorIndex8Image(EpImage* LImage);
extern EpColorIndex16Pixel*	Ep_ImageDuplicateColorIndex16Image(EpImage* LImage);
extern EpColorIndex32Pixel*	Ep_ImageDuplicateColorIndex32Image(EpImage* LImage);
extern EpRGBA8Pixel*		Ep_ImageDuplicateRGBA8Image(EpImage* LImage);
extern EpRGBA16Pixel*		Ep_ImageDuplicateRGBA16Image(EpImage* LImage);
extern EpRGBAf32Pixel*		Ep_ImageDuplicateRGBAf32Image(EpImage* LImage);


extern EpRGBA8Pixel*		Ep_ImageRGBA16ToRGBA8(EpImage* LImage);
extern EpRGBA8Pixel*		Ep_ImageRGBAf32ToRGBA8(EpImage* LImage);

extern void			Ep_ImageDefault(EpImage* LImage);
extern EpImage*			Ep_ImageAllocate(int LXSize, int LYSize, int LPixelFormats);
extern void			Ep_ImageFree(EpImage*, EBool);
extern void			Ep_ImageFreeStruct(EpImage* LImage);

extern void			Ep_ImageCopy(EpImage* LImageS, EpImage* LImageD);

extern EBool			Ep_ImageHasAlpha(EpImage* LImage);

extern int			Ep_ImagePasteWithAlpha(EpImage* LImageDecal, EpImage* LImageBackground, EpImage* LImageOut, int LSourceX, int LSourceY, int LSourceXSize, int LSourceYSize, int LDestX, int LDestY);

extern EBool			Ep_ImageGetPixelColor(EpImage* LImage, int LX, int LY, EcRGBAiColor* LColorRet);
extern EBool			Ep_ImageGetPixelColorF(EpImage* LImage, int LX, int LY, EcRGBAfColor* LColorRet);
extern EBool			Ep_ImageSetPixelColor(EpImage* LImage, int LX, int LY, EcRGBAiColor* LColor);


extern EpRGBA8Pixel*		Ep_ImageCreateRGBA8(EpImage* LImage);


extern int			Ep_ImageResize(EpImage* LImage, unsigned int LNewXSize, unsigned int LNewYSize, unsigned int LFlags, EBool LFreeOld);
extern EBool 			Ep_ImageClear(EpImage* LImage, EpImage* LResultImage, EcRGBAiColor* LColor, unsigned int LChannels);

extern int			Ep_ImageCrop(EpImage* LImageIn, EpImage* LImageOut, int LLeft, int LRight, int LTop, int LBottom, EcRGBAiColor* LMarginColor);


/*------------------------------*/
/* ImageOps.c			*/
/*------------------------------*/
extern int			Ep_ImageFlipH(EpImage* LSImage, EpImage* LDImage);
extern int			Ep_ImageFlipV(EpImage* LSImage, EpImage* LDImage);

extern int			Ep_ImageInvert(EpImage* LSImage, EpImage* LDImage);
extern int			Ep_ImageRotateRight90(EpImage* LSImage, EpImage* LDImage);


extern int			Ep_ImageColorBalance(EpImage* LImage, register EpImage* LImageD, int LRFactor, int LGFactor, int LBFactor, int LAFactor, int LRedBias, int LGreenBias, int LBlueBias, int LAlphaBias);
extern int			Ep_ImageColorDither(EpImage* LImage, EpImage* LImageD, int LRLevels, int LGLevels, int LBLevels, int LMethod, EBool LInteractive);

extern EpRGBA8Pixel*		Ep_Convolve3x3(EpImage* LImage, EpRGBA8Pixel* LResultRGBA8Image, float LMatrix[3][3]);
extern EpRGBA8Pixel*		Ep_Convolve5x5(EpImage* LImage, EpRGBA8Pixel* LResultRGBA8Image, float LMatrix[5][5]);

extern EBool			Ep_ImageSetAlphaByTransparentColor(EpImage* LSImage, EpImage* LDImage, EcRGBAiColor* LTransparentColor);

extern int			Ep_ImagesStitch(EpImage** LSImages, unsigned int LNumOfColumns, unsigned int LNumOfRows, EpImage* LDImage, EBool LScaleToFit);


/*------------------------------*/
/* Scale.c			*/
/*------------------------------*/
extern EBool			Ep_ImageScale(EpImage* LImageS, EpImage* LImageD, int LNewXSize, int LNewYSize, int LFilterType, double LBlurFactor, EBool LProcInd);
extern EBool			Ep_ImageScaleAlpha(EpImage* LImageS, EpImage* LImageD, int LNewXSize, int LNewYSize, int LFilterType, double LBlurFactor, EBool LProcInd);


/*------------------------------*/
/* Image File IO		*/
/*------------------------------*/
extern EpImageIOFormat**	Ep_ImageFileFormats;
extern unsigned int		Ep_NumOfImageFileFormats;

extern char**			Ep_IOGetExtensions();

extern char*			Ep_GetBaseFileName(char* LFileName, char* LNameRet, unsigned int LMaxLen);

extern EpImageIOFormat*		Ep_GetImageFormatByExtension(char* LExtension);
extern unsigned long*		Ep_ABGRToRGBA(unsigned long* LABGRImage, unsigned int LXSize, unsigned int LYSize);

extern EpImageIOFormat*		Ep_ImageIOFilterAdd(char* LName, EpIOOpenProc LOpenProc, EpIOCloseProc LCloseProc, EpIOProc LReadProc, EpIOProc LWriteProc, char** LFileNameExtensions, unsigned int LSupportedPixelFormats);
extern void			Ep_ImageIOFilterRemove(EpImageIOFormat* LFileFormat);
extern void			Ep_ImageIOFilterDeactivate(EpImageIOFormat* LFileFormat);

extern EpImageFile*		Ep_ImageFileOpen(char* LFileName, EpImageIOFormat* LFileFormat, EpImageIOFormat** LFileFormatRet, EpImage* LImageD);
extern void			Ep_ImageFileClose(EpImageFile* LImageFile);

extern int			Ep_ImageFileReadRegion(EpImageFile* LImageFile, int LX, int LY, unsigned int LXSize, unsigned int LYSize, EpImage* LImage);
extern int			Ep_ImageReadFromFile(char* LFileName, EpImageIOFormat* LFileFormat, EpImageIOFormat** LFileFormatRet, EpImage* LImageD);
extern int			Ep_ImageReadNumberedFile(char* LBaseFileName, int LFrameNumber, char* LFileExtension, int* LDigitsPtr, EpImageIOFormat* LFileFormat, EpImageIOFormat** LFileFormatRet, EpImage* LImage);

extern int			Ep_ImageSaveToFile(char* LFileName, char* LNameReturn, int LNameMaxLen, EpImage* LImage, EpImageIOFormat* LFileFormat);

extern EpImageFile*		Ep_ImageFileAllocate();
extern void			Ep_ImageFileFree(EpImageFile* LImageFile);


/*------------------------------*/
/* Macros			*/
/*------------------------------*/

/*==============================================================================================*/
/* Create an EpImage from a "CArray" image (inlined RGBA8Image: mostly used for icons)		*/
/*==============================================================================================*/
#define EpM_RGBA8ImageFromCArray(mImage, mXSize, mYSize, mRGBA8Image)\
 if(((mImage)=Ep_ImageAllocate(0, 0, 0))!=NULL)\
 {\
  (mImage)->XSize=mXSize;(mImage)->YSize=mYSize;(mImage)->RGBA8Image=(EpRGBA8Pixel*)(mRGBA8Image);(mImage)->PixelFormats=EpPixelRGBA8;\
 }

/*==============================================================================================*/
/* Create an EpImage from a "CStruct" image (inlined image: mostly used for icons)		*/
/*==============================================================================================*/
#define EpM_RGBA8ImageFromCStruct(mImage, mCImage)\
 if(((mImage)=Ep_ImageAllocate(0, 0, 0))!=NULL)\
 {\
  (mImage)->XSize=(mCImage).XSize;(mImage)->YSize=(mCImage).YSize;(mImage)->RGBA8Image=(EpRGBA8Pixel*)((mCImage).RGBA8Image);(mImage)->PixelFormats=EpPixelRGBA8;\
 }


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration which encloses file.
#endif


#endif // _EImage_h
