#ifndef  __RV_IMG_H_INCLUDED_
#define  __RV_IMG_H_INCLUDED_



 
 #include <rvb\rvtypes.h> 


#define IMG_API  WINAPI


#define RV_CVT_BIN2RGB    -3
#define RV_CVT_BIN2GRAY   -2
#define RV_CVT_GRAY2RGB    -1

#define RV_CVT_RGB2GRAY    1
#define RV_CVT_GRAY2BIN    2
#define RV_CVT_RGB2BIN     3

//
#define RV_CVT_RGBA2RGB    5
#define RV_CVT_RGB2RGBA    -5

#define RV_ALIGN_BYTE_1     1
#define RV_ALIGN_BYTE_4     4


#pragma pack(push,1)

typedef struct __rv_hsv{
   float  hue;        //0-360
   float  saturation; //0-1
   float  value;      //0-1
}RvHsv;

typedef struct __rv_ycbcr{
   float  y;   //0-255
   float  cb;  //0-255
   float  cr;  //0-255
}RvYCbCr;

typedef struct __rv_yuv{
   float  y;
   float  u; 
   float  v;
}RvYuv;

#pragma pack(pop)


//不支持:RIT_EXT
extern "C" RvImage IMG_API rvCreateImage(RV_IMAGE_TYPE type, int width, int height);

//rvCreateImageEx可以建立虚拟图象，也可以建立正常图象
//如果建立虚拟图象，当pDataSource为NULL的时候，该图象可能没有可用的图象数据。
//这种情况下，可以使用rviFloodEx函数来附加图象数据。
//如果建立正常图象，当pDataSource不为空的时候，将pDataSource的图象数据
//直接拷贝到新创建的数据里面。
//
//如果建立虚拟图象，该图象的外部数据源必须保证在对虚拟图象操作的时候，
//始终有效（不被释放）。
//
//如果类型为RIT_EXT， 只能创建VIRTUAL 图像。
//
extern "C" RvImage IMG_API rvCreateImageEx(RV_IMAGE_TYPE type, int width, int height, BOOL bVirtual, void* pDataSource=NULL, size_t nDataSize=0);
 
//创建一个虚拟图像，类型：RGB, 长度120,宽度80
extern "C" RvImage IMG_API rvCreateDummy();

//创建一个1字节对齐的图像,
extern "C" RvImage IMG_API rvCreateImageE1(RV_IMAGE_TYPE type, int width, int height, BOOL bVirtual);

//创建扩展类型的RIT_EXT图像
extern "C" RvImage IMG_API rvCreateImageE2( int width, int height, int pitch);


//创建扩展类型的RIT_HSV, RIT_YCBCR, RIT_YUV图像
extern "C" RvImage IMG_API rvCreateImageE3(RV_IMAGE_TYPE type,  int width, int height);


extern "C" void IMG_API    rvDestroyImage(RvImage image);



 //如果desct == NULL进行INPLAY转换，相当于rviCast
extern "C"  BOOL IMG_API rviConvert(RvImage src, int code=RV_CVT_GRAY2RGB, RvImage dest=NULL );

//convert between gray, bin and rgb only
//rgba 转成 rgb的时候，忽略alpha通道
extern "C"  BOOL IMG_API rviCast(RvImage image,  RV_IMAGE_TYPE type);

 //该函数可以拷贝虚拟函数，可以虚拟图像转成常规图像, 1字节对齐转成4字节对齐
extern "C"  RvImage IMG_API rviCloneE1(RvImage src, BOOL bForceToNormal, RvImage dest =NULL);

//将虚拟图像转成常规图像（非虚拟）,4字节对齐
extern "C"  BOOL IMG_API rviCastToNormal(RvImage image);

 

//将32位图象转成24位图象，支持背景色。输入图象必须是32图
//如果bExtended为TRUE，则将图象象素与进行合成背景颜色进行合成。
extern "C"  BOOL IMG_API rviCvt32To24(RvImage image, RvColor backColor, BOOL bExtended =FALSE);


//alpha通道与像素乘。
extern "C"  BOOL IMG_API rviCvt32To24E1(RvImage image);


//imRgba格式为RGBA，imRgb格式为RGB，并且二者大小必须相同
extern "C"  BOOL IMG_API rviCvt32To24Ex(RvImage imRgba, RvImage imRgb, RvColor backColor, BOOL bExtended =FALSE);

//将24位位图转换成32位位图，支持设置alpha通道。
extern "C"  BOOL IMG_API rviCvt24To32(RvImage image,  RvByte alpha);
extern "C"  BOOL IMG_API rviCvt24To32Ex(RvImage imRgb , RvImage imRgba, RvByte alpha);

//24位图像转成32位，并且将与背景图相等的像素透明处理
//bBorderOnly =TRUE，仅透明处理于边界相连的像素
extern "C"  BOOL IMG_API rviCvt24To32E1(RvImage image,  RvColor backColor, BOOL bBorderOnly );

//将24位位图转换成8位位图 。
#define RV_CVT_24_8_DIRECT  0   //Gray = R*0.299 + G*0.587 + B*0.114
#define RV_CVT_24_8_HSV     1   //Gray = value of HSV
#define RV_CVT_24_8_MAX     2   //MAX(R,G,B)
#define RV_CVT_24_8_MIN     3   //MIN(R,G,B)
#define RV_CVT_24_8_AVG     4   //Gray =( R  + G  + B )/3

 
extern "C"  BOOL IMG_API rviCvt24To8(RvImage image,  int method);
extern "C"  BOOL IMG_API rviCvt24To8Ex(RvImage imRgb , RvImage imGray, int method);



 



//获取单通道的时候，dest类型可以是rgb或gray类型，如果dest为NULL，将创建一个新
//的类型为gray的图像
//如果dest类型不是rgb或gray类型，且是虚拟函数，将直接返回退出。
//否则将dest转换成gray类型。
extern "C" RvImage IMG_API rviGetRedChannel(const RvImage src, RvImage dest=NULL);
extern "C" RvImage IMG_API rviGetGreenChannel(const RvImage src, RvImage dest=NULL);
extern "C" RvImage IMG_API rviGetBlueChannel(const RvImage src, RvImage dest=NULL);
extern "C" RvImage IMG_API rviGetAlphaChannel(const RvImage src, RvImage dest=NULL);

extern "C" RvImage IMG_API rviMergeRGB(const RvImage red, const RvImage green, const RvImage blue, RvImage dest=NULL);

//red ,green ,blue应该有相同大小和类型
//dest必须是rgba
extern "C" RvImage IMG_API rviMergeRGBA(const RvImage red, const RvImage green, const RvImage blue, const RvImage alpha, RvImage dest=NULL);
extern "C" RvImage IMG_API rviMergeRGBAEx(const RvImage rgb, const RvImage alpha,RvImage dest=NULL);

 

extern "C" void IMG_API rviFlood(RvImage image,  RvByte level);

//如果图象是虚拟的（virtual），输入的数据直接被引用到图象数据指针后面。
//当然，输入的数据大小与图象对象本身的大小必须是一样的。
//如果为虚拟图象，该图象的外部数据源必须保证在对虚拟图象操作的时候，
//始终有效（不被释放）。
//
//当图象为虚拟的时候，如果pImageData为NULL， 该虚拟图象的数据指针将
//设置为空。
//
extern "C" void IMG_API rviFloodEx(RvImage image, const void* pImageData, size_t nDataSize );

//从矩阵里面填充，按照矩阵里面最大值和最小值自动转换为图像支持的像素范围
//矩阵通道的与图像支持的通道数要一致
//矩阵的宽度和高度与图像的高度和宽度要一致。
//该函数使用不当可能引起严重程序异常。
extern "C" void IMG_API rviFloodMat(RvImage image, int dataType, const void* pImageData, size_t nDataSize );

extern "C" void IMG_API rviFloodMat2(RvImage image, RvMatrix source );


//支持虚拟图象拷贝，dest图象在clone以后，与原图象是完全一致的。
extern "C" RvImage IMG_API rviClone(const RvImage src, RvImage dest=NULL );

//拷贝图象，不管dest是否为虚拟图象， dest最终将转换为常规图象，即有自己的数据图象区。
//并将src里面的图象数据拷贝到自己的数据缓冲区。
extern "C" RvImage IMG_API   rviDuplicate(const RvImage src, RvImage dest=NULL);

//rviSetsize is deprecated. use rviResize instead
extern "C" BOOL IMG_API   rviSetSize(RvImage image, int width,   int height);

extern "C" BOOL IMG_API   rviResize(RvImage image, int width,   int height);

 extern "C" void IMG_API  rviClear(RvImage image);

extern "C" void*  IMG_API   rviGetData(  RvImage image);
#define  rviGetBuffer(image)   ((RvByte*)rviGetData(image))

extern "C" int  IMG_API     rviGetWidth(const RvImage image);
extern "C" int  IMG_API     rviGetHeight(const RvImage image);

//判断图象的长，宽，图象类型是否一致。
extern "C" BOOL  IMG_API     rviIsDimSame(const RvImage image1, const RvImage image2);

extern "C" BOOL  IMG_API     rviIsVirtual(const RvImage image);



//返回图象数据区大小，以字节为单位
extern "C" size_t   IMG_API    rviGetSize(const RvImage image);

extern "C" int   IMG_API    rviGetPitch(const RvImage image);
//extern "C" void   IMG_API   rviGetRange(const RvImage image, float* pLower, float* pUpper);
 
//过时,请使用rviGetImageType或rvGetImageType代替
extern "C" RV_IMAGE_TYPE  IMG_API rviGetType(const RvImage image);

extern "C" RV_IMAGE_TYPE  IMG_API rviGetImageType(const RvImage image);
#define rvGetImageType(image)  rviGetImageType(image)
 
extern "C" int  IMG_API rviGetDepth(const RvImage image);
extern "C" int  IMG_API rviGetChannels(const RvImage image);
extern "C" int  IMG_API rviBytesPerPixel(const RvImage image);





 extern "C" int  IMG_API rviGetAlignBytes(const RvImage image);
//extern "C" void            IMG_API rviSetOriginType( RvImage image, RV_ORIGIN_TYPE type);

 

extern "C" RvImage IMG_API    rviConvertRgbToYuv(RvImage imRgb, RvImage imYuv);
extern "C" RvImage IMG_API    rviConvertRgbToYCbCr(RvImage imRgb, RvImage imYCbCr);
extern "C" RvImage IMG_API    rviConvertRgbToHsv(RvImage imRgb, RvImage imHsv);

extern "C" RvImage IMG_API    rviConvertYuvToRgb(RvImage imYuv, RvImage imRgb);
extern "C" RvImage IMG_API    rviConvertYCbCrToRgb(RvImage  imYCbCr , RvImage imRgb);
extern "C" RvImage IMG_API    rviConvertHsvToRgb(RvImage imHsv, RvImage imRgb);

#define RV_CHANNEL_H    0
#define RV_CHANNEL_S    1
#define RV_CHANNEL_V    2
extern "C" RvImage IMG_API   rviGetHsvChannel(const RvImage imHsv, int channel, RvImage imGray);
//输入的图像全部为灰度图
extern "C" RvImage IMG_API   rviMergeHSV(const RvImage imH, const RvImage imS, const RvImage imV, RvImage imHsv);


#define RV_CHANNEL_Y     0
#define RV_CHANNEL_CB    1
#define RV_CHANNEL_CR    2
extern "C" RvImage IMG_API   rviGetYCbCrChannel(const RvImage imYcbcr, int channel, RvImage imSub);
//输入的图像全部为灰度图
extern "C" RvImage IMG_API   rviMergeYCbCr(const RvImage imY, const RvImage imCb, const RvImage imCr, RvImage imYCbCr);

  

#endif