#include "stdafx.h"
{
int i = 0, j = 0;
int widthStep = width * channel;
int edgeWidthStep = widthEdge * channel;
int grayImageSize = widthEdge * height;
unsigned char *pCurSrcY = NULL;
unsigned char *pCurSrcUV = NULL;
unsigned char *pCurSrcRowY = NULL;
unsigned char *pCurSrcRowUV = NULL;
unsigned char *pCurDst = NULL;
unsigned char *pRowDst = NULL;
unsigned char R = 0;
unsigned char G = 0;
unsigned char B = 0;
unsigned char Y = 0;
unsigned char U = 0;
unsigned char V = 0;
unsigned char cb = 0, cr = 0;
pCurSrcY = inputImageSource;
pCurSrcRowY = pCurSrcY;
pCurSrcUV = inputImageSource + grayImageSize;
pCurSrcRowUV = pCurSrcUV;
pCurDst = inputRGBimage;
pRowDst = pCurDst;
for(i = 0; i < height;pRowDst += widthStep, pCurSrcRowY += widthEdge, pCurSrcRowUV += (i%2) * widthEdge, ++i)
{
pCurDst = pRowDst;
pCurSrcY = pCurSrcRowY;
pCurSrcUV = pCurSrcRowUV;
for( j = 0; j < width; pCurDst += channel,++pCurSrcY,pCurSrcUV+=(j%2) * 2, ++j)
{
Y = pCurSrcY[0];
cb = pCurSrcUV[0];
cr = pCurSrcUV[1];
int temp = (int)(1.164 * Y + 1.596 * cr - 222.912 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
R = (unsigned char)temp;
temp = (int)(1.164 * Y - 0.391 * cb - 0.813 * cr + 135.488 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
G = (unsigned char)temp;
temp = (int)(1.164 * Y + 2.018 * cb - 276.928 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
B = (unsigned char)temp;
pCurDst[0] = B;
pCurDst[1] = G;
pCurDst[2] = R;
}
}
}
void RGB2NV21(unsigned char *YUV420Image,unsigned char *RGBimage, int width,int height, int channel)
{
int i = 0, j = 0;
int widthStep = width * channel;
int grayImageSize = width * height;
unsigned char *pCurDstY = NULL;
unsigned char *pCurDstUV = NULL;
unsigned char *pCurDstRowY = NULL;
unsigned char *pCurDstRowUV = NULL;
unsigned char *pCurSrcRGB = NULL;
unsigned char *pRowSrcRGB = NULL;
unsigned char R = 0;
unsigned char G = 0;
unsigned char B = 0;
unsigned char Y = 0;
unsigned char U = 0;
unsigned char V = 0;
unsigned char cb = 0, cr = 0;
pCurDstY = YUV420Image;
pCurDstRowY = pCurDstY;
pCurDstUV = YUV420Image + grayImageSize;
pCurDstRowUV = pCurDstUV;
pCurSrcRGB = RGBimage;
pRowSrcRGB = pCurSrcRGB;
for(i = 0; i < height;pRowSrcRGB += widthStep, pCurDstRowY += width, pCurDstRowUV += (i%2) * width, ++i)
{
pCurSrcRGB = pRowSrcRGB;
pCurDstY = pCurDstRowY;
pCurDstUV = pCurDstRowUV;
for( j = 0; j < width; pCurSrcRGB += channel,++pCurDstY,pCurDstUV+=(j%2) * 2, ++j)
{
B = pCurSrcRGB[0];
G = pCurSrcRGB[1];
R = pCurSrcRGB[2];
//Y = 0.257*R+0.564*G+0.098*B+16
//Cb = -0.148*R-0.291*G+0.439*B+128
//Cr = 0.439*R-0.368*G-0.071*B+128
int temp = (int)(0.257 * R + 0.564 * G + 0.098 * B + 16);
pCurDstY[0] = (unsigned char)temp;
temp = (int)(-0.148 * R - 0.291 * G + 0.439 * B + 128);
pCurDstUV[0] = (unsigned char)temp;
temp = (int)(0.439 * R - 0.368 * G - 0.071 * B + 128);
pCurDstUV[1] = (unsigned char)temp;
}
}
#if 0
/**/
FILE *fp = fopen("YUVIMAGE.dat","w+");
unsigned int imageSize = width * height*3/2;
fwrite(YUV420Image,1,imageSize, fp);
fclose(fp);
#endif
}
/*
The coefficients are multiplied bu 2^14.
*/
#define GET_YC(r, g, b, sh) (((4209 * (int)r + 8264 * (int)g + 1605 * (int)b + 8192) >> 14) + (int)sh)
#define GET_CB(r, g, b, sh) (((-2425 * (int)r - 4767 * (int)g + 7143 * (int)b + 8192) >> 14) + (int)sh)
#define GET_CR(r, g, b, sh) (((7193 * (int)r - 6029 * (int)g - 1163 * (int)b + 8192) >> 14) + (int)sh)
MULTISENSOR_API void rgb2YCbCr(unsigned char * pRGB, unsigned char * pYCbCr, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
unsigned char * pSrc, * pDest;
register int r, g, b;
int i, j;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pRGB;
pDest = pYCbCr;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
r = (int)pSrc[2];
g = (int)pSrc[1];
b = (int)pSrc[0];
pDest[0] = (unsigned char)GET_YC(r, g, b, 16);
pDest[1] = (unsigned char)GET_CB(r, g, b, 128);
pDest[2] = (unsigned char)GET_CR(r, g, b, 128);
}
}
}
#define GET_YC_CONT(yc) (19071 * (int)(yc))
#define GET_R(yc_cont, cr) ((yc_cont + 26149 * (int)(cr) + 8192) >> 14)
#define GET_G(yc_cont, cb, cr) ((yc_cont - 6423 * (int)(cb) - 13320 * (int)(cr) + 8192) >> 14)
#define GET_B(yc_cont, cb) ((yc_cont + 33047 * (int)(cb) + 8192) >> 14)
MULTISENSOR_API void yCbCr2Rgb(unsigned char * pYCbCr, unsigned char * pRGB, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
int ycCont, cb, cr;
unsigned char * pSrc, * pDest;
int i, j;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pYCbCr;
pDest = pRGB;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
ycCont = (int)GET_YC_CONT(pSrc[0] - 16);
cb = (int)pSrc[1] - 128;
cr = (int)pSrc[2] - 128;
pDest[2] = clip256(GET_R(ycCont, cr));
pDest[1] = clip256(GET_G(ycCont, cb, cr));
pDest[0] = clip256(GET_B(ycCont, cb));
}
}
}
#define GET_Y(r, g, b) ((4899 * (int)(r) + 9617 * (int)(g) + 1868 * (int)(b)) >> 14)
MULTISENSOR_API void getImageGrey(unsigned char * pRGB, unsigned char * pGrey, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep, const int iOutWidthStep)
{
unsigned char * pSrc, * pDest;
int i, j;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pGrey += iOutWidthStep)
{
pSrc = pRGB;
pDest = pGrey;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest++)
{
pDest[0] = (unsigned char)GET_Y(pSrc[2], pSrc[1], pSrc[0]);
}
}
}
inline short clipValue(const int iValue, const short iUpLimit)
{
if(iValue < 0)
return 0;
else if(iValue > (int)iUpLimit)
return iUpLimit;
else
return (short)iValue;
}
MULTISENSOR_API void rgb2YCbCr16(short * pRGB, short * pYCbCr, const int iBitPerSample, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
short * pSrc, * pDest;
int iYcSh, iCSh;
register int r, g, b;
int i, j;
if(iBitPerSample < 8)
return ;
iYcSh = 16 << (iBitPerSample - 8);
iCSh = 128 << (iBitPerSample - 8);
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pRGB;
pDest = pYCbCr;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
r = (int)pSrc[2];
g = (int)pSrc[1];
b = (int)pSrc[0];
pDest[0] = (short)GET_YC(r, g, b, iYcSh);
pDest[1] = (short)GET_CB(r, g, b, iCSh);
pDest[2] = (short)GET_CR(r, g, b, iCSh);
}
}
}
MULTISENSOR_API void yCbCr2Rgb16(short * pYCbCr, short * pRGB, const int iBitPerSample, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
int ycCont, cb, cr;
short * pSrc, * pDest;
int iYcSh, iCSh, iUpLimit;
int i, j;
if(iBitPerSample < 8)
return ;
iYcSh = 16 << (iBitPerSample - 8);
iCSh = 128 << (iBitPerSample - 8);
iUpLimit = (1 << iBitPerSample) - 1;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pYCbCr;
pDest = pRGB;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
ycCont = (int)GET_YC_CONT(pSrc[0] - iYcSh);
cb = (int)pSrc[1] - iCSh;
cr = (int)pSrc[2] - iCSh;
pDest[2] = clipValue(GET_R(ycCont, cr), iUpLimit);
pDest[1] = clipValue(GET_G(ycCont, cb, cr), iUpLimit);
pDest[0] = clipValue(GET_B(ycCont, cb), iUpLimit);
}
}
}
#include "utils.h"
{
int i = 0, j = 0;
int widthStep = width * channel;
int edgeWidthStep = widthEdge * channel;
int grayImageSize = widthEdge * height;
unsigned char *pCurSrcY = NULL;
unsigned char *pCurSrcUV = NULL;
unsigned char *pCurSrcRowY = NULL;
unsigned char *pCurSrcRowUV = NULL;
unsigned char *pCurDst = NULL;
unsigned char *pRowDst = NULL;
unsigned char R = 0;
unsigned char G = 0;
unsigned char B = 0;
unsigned char Y = 0;
unsigned char U = 0;
unsigned char V = 0;
unsigned char cb = 0, cr = 0;
pCurSrcY = inputImageSource;
pCurSrcRowY = pCurSrcY;
pCurSrcUV = inputImageSource + grayImageSize;
pCurSrcRowUV = pCurSrcUV;
pCurDst = inputRGBimage;
pRowDst = pCurDst;
for(i = 0; i < height;pRowDst += widthStep, pCurSrcRowY += widthEdge, pCurSrcRowUV += (i%2) * widthEdge, ++i)
{
pCurDst = pRowDst;
pCurSrcY = pCurSrcRowY;
pCurSrcUV = pCurSrcRowUV;
for( j = 0; j < width; pCurDst += channel,++pCurSrcY,pCurSrcUV+=(j%2) * 2, ++j)
{
Y = pCurSrcY[0];
cb = pCurSrcUV[0];
cr = pCurSrcUV[1];
int temp = (int)(1.164 * Y + 1.596 * cr - 222.912 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
R = (unsigned char)temp;
temp = (int)(1.164 * Y - 0.391 * cb - 0.813 * cr + 135.488 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
G = (unsigned char)temp;
temp = (int)(1.164 * Y + 2.018 * cb - 276.928 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
B = (unsigned char)temp;
pCurDst[0] = B;
pCurDst[1] = G;
pCurDst[2] = R;
}
}
}
void RGB2NV21(unsigned char *YUV420Image,unsigned char *RGBimage, int width,int height, int channel)
{
int i = 0, j = 0;
int widthStep = width * channel;
int grayImageSize = width * height;
unsigned char *pCurDstY = NULL;
unsigned char *pCurDstUV = NULL;
unsigned char *pCurDstRowY = NULL;
unsigned char *pCurDstRowUV = NULL;
unsigned char *pCurSrcRGB = NULL;
unsigned char *pRowSrcRGB = NULL;
unsigned char R = 0;
unsigned char G = 0;
unsigned char B = 0;
unsigned char Y = 0;
unsigned char U = 0;
unsigned char V = 0;
unsigned char cb = 0, cr = 0;
pCurDstY = YUV420Image;
pCurDstRowY = pCurDstY;
pCurDstUV = YUV420Image + grayImageSize;
pCurDstRowUV = pCurDstUV;
pCurSrcRGB = RGBimage;
pRowSrcRGB = pCurSrcRGB;
for(i = 0; i < height;pRowSrcRGB += widthStep, pCurDstRowY += width, pCurDstRowUV += (i%2) * width, ++i)
{
pCurSrcRGB = pRowSrcRGB;
pCurDstY = pCurDstRowY;
pCurDstUV = pCurDstRowUV;
for( j = 0; j < width; pCurSrcRGB += channel,++pCurDstY,pCurDstUV+=(j%2) * 2, ++j)
{
B = pCurSrcRGB[0];
G = pCurSrcRGB[1];
R = pCurSrcRGB[2];
//Y = 0.257*R+0.564*G+0.098*B+16
//Cb = -0.148*R-0.291*G+0.439*B+128
//Cr = 0.439*R-0.368*G-0.071*B+128
int temp = (int)(0.257 * R + 0.564 * G + 0.098 * B + 16);
pCurDstY[0] = (unsigned char)temp;
temp = (int)(-0.148 * R - 0.291 * G + 0.439 * B + 128);
pCurDstUV[0] = (unsigned char)temp;
temp = (int)(0.439 * R - 0.368 * G - 0.071 * B + 128);
pCurDstUV[1] = (unsigned char)temp;
}
}
#if 0
/**/
FILE *fp = fopen("YUVIMAGE.dat","w+");
unsigned int imageSize = width * height*3/2;
fwrite(YUV420Image,1,imageSize, fp);
fclose(fp);
#endif
}
/*
The coefficients are multiplied bu 2^14.
*/
#define GET_YC(r, g, b, sh) (((4209 * (int)r + 8264 * (int)g + 1605 * (int)b + 8192) >> 14) + (int)sh)
#define GET_CB(r, g, b, sh) (((-2425 * (int)r - 4767 * (int)g + 7143 * (int)b + 8192) >> 14) + (int)sh)
#define GET_CR(r, g, b, sh) (((7193 * (int)r - 6029 * (int)g - 1163 * (int)b + 8192) >> 14) + (int)sh)
MULTISENSOR_API void rgb2YCbCr(unsigned char * pRGB, unsigned char * pYCbCr, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
unsigned char * pSrc, * pDest;
register int r, g, b;
int i, j;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pRGB;
pDest = pYCbCr;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
r = (int)pSrc[2];
g = (int)pSrc[1];
b = (int)pSrc[0];
pDest[0] = (unsigned char)GET_YC(r, g, b, 16);
pDest[1] = (unsigned char)GET_CB(r, g, b, 128);
pDest[2] = (unsigned char)GET_CR(r, g, b, 128);
}
}
}
#define GET_YC_CONT(yc) (19071 * (int)(yc))
#define GET_R(yc_cont, cr) ((yc_cont + 26149 * (int)(cr) + 8192) >> 14)
#define GET_G(yc_cont, cb, cr) ((yc_cont - 6423 * (int)(cb) - 13320 * (int)(cr) + 8192) >> 14)
#define GET_B(yc_cont, cb) ((yc_cont + 33047 * (int)(cb) + 8192) >> 14)
MULTISENSOR_API void yCbCr2Rgb(unsigned char * pYCbCr, unsigned char * pRGB, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
int ycCont, cb, cr;
unsigned char * pSrc, * pDest;
int i, j;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pYCbCr;
pDest = pRGB;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
ycCont = (int)GET_YC_CONT(pSrc[0] - 16);
cb = (int)pSrc[1] - 128;
cr = (int)pSrc[2] - 128;
pDest[2] = clip256(GET_R(ycCont, cr));
pDest[1] = clip256(GET_G(ycCont, cb, cr));
pDest[0] = clip256(GET_B(ycCont, cb));
}
}
}
#define GET_Y(r, g, b) ((4899 * (int)(r) + 9617 * (int)(g) + 1868 * (int)(b)) >> 14)
MULTISENSOR_API void getImageGrey(unsigned char * pRGB, unsigned char * pGrey, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep, const int iOutWidthStep)
{
unsigned char * pSrc, * pDest;
int i, j;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pGrey += iOutWidthStep)
{
pSrc = pRGB;
pDest = pGrey;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest++)
{
pDest[0] = (unsigned char)GET_Y(pSrc[2], pSrc[1], pSrc[0]);
}
}
}
inline short clipValue(const int iValue, const short iUpLimit)
{
if(iValue < 0)
return 0;
else if(iValue > (int)iUpLimit)
return iUpLimit;
else
return (short)iValue;
}
MULTISENSOR_API void rgb2YCbCr16(short * pRGB, short * pYCbCr, const int iBitPerSample, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
short * pSrc, * pDest;
int iYcSh, iCSh;
register int r, g, b;
int i, j;
if(iBitPerSample < 8)
return ;
iYcSh = 16 << (iBitPerSample - 8);
iCSh = 128 << (iBitPerSample - 8);
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pRGB;
pDest = pYCbCr;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
r = (int)pSrc[2];
g = (int)pSrc[1];
b = (int)pSrc[0];
pDest[0] = (short)GET_YC(r, g, b, iYcSh);
pDest[1] = (short)GET_CB(r, g, b, iCSh);
pDest[2] = (short)GET_CR(r, g, b, iCSh);
}
}
}
MULTISENSOR_API void yCbCr2Rgb16(short * pYCbCr, short * pRGB, const int iBitPerSample, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
int ycCont, cb, cr;
short * pSrc, * pDest;
int iYcSh, iCSh, iUpLimit;
int i, j;
if(iBitPerSample < 8)
return ;
iYcSh = 16 << (iBitPerSample - 8);
iCSh = 128 << (iBitPerSample - 8);
iUpLimit = (1 << iBitPerSample) - 1;
for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pYCbCr;
pDest = pRGB;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
ycCont = (int)GET_YC_CONT(pSrc[0] - iYcSh);
cb = (int)pSrc[1] - iCSh;
cr = (int)pSrc[2] - iCSh;
pDest[2] = clipValue(GET_R(ycCont, cr), iUpLimit);
pDest[1] = clipValue(GET_G(ycCont, cb, cr), iUpLimit);
pDest[0] = clipValue(GET_B(ycCont, cb), iUpLimit);
}
}
}