下列是YCbCrConversion函数的代码(来自micron技术),不明白precalc_xy_raw,precalc_xy所代表的含义,另外,为什么还要定义r1, b1, g1呢?望大侠能指点,谢谢!!/*
* YCbCrConversion
* ---------------
* function: Convert YCbCr 4:2:2 to RGB 8:8:8:8 (last 8 bits are undefined)
* in: pointer to 16bpp YUV buffer (Y, Cb, Y, Cr, Y, Cb, ...)
* out pointer to 32bpp RGB buffer
* special uses a hardcoded float to int conversion routine for increased speed.
*/#define FLOAT_MANTISSA_BITS 23
#define FLOAT_MANTISSA_MASK ((1<<(FLOAT_MANTISSA_BITS))-1)/* Non-negative float values */
#define Float2Int(_flt_, _int_) \
(*((float *)(&(_int_)))=(_flt_)+((float)(1<<(FLOAT_MANTISSA_BITS))), \
(_int_)&=FLOAT_MANTISSA_MASK)void YCbCrConversion(unsigned char *pIn, unsigned char *pOut, int nWidth, int nHeight)
{
float Y0, Cb, Y1, Cr;
float R0, G0, B0, R1, G1, B1;
float B_Cb128,R_Cr128,G_CrCb128;
int r0, b0, g0, r1, b1, g1; int precalc_xy_raw = 0;
int precalc_xy = 0; for (int i=0;i<nWidth*nHeight/2;i++)
{
/*
* optimized code for YCbCr to RGB conversion
*/
Cb = (float)pIn[precalc_xy_raw++]-128.0f;
Y0 = 1.164f * ((float)pIn[precalc_xy_raw++]-16.0f);
Cr = (float)pIn[precalc_xy_raw++]-128.0f;
Y1 = 1.164f * ((float)pIn[precalc_xy_raw++]-16.0f);
R_Cr128 = 1.596f*Cr;
G_CrCb128 = -0.813f*Cr - 0.391f*Cb;
B_Cb128 = 2.018f*Cb; R0 = Y0 + R_Cr128;
G0 = Y0 + G_CrCb128;
B0 = Y0 + B_Cb128;
R1 = Y1 + R_Cr128;
G1 = Y1 + G_CrCb128;
B1 = Y1 + B_Cb128; if (R0<0.0f) R0=0.0f;
if (G0<0.0f) G0=0.0f;
if (B0<0.0f) B0=0.0f; if (R0>255.0f) R0 = 255.0f;
if (G0>255.0f) G0 = 255.0f;
if (B0>255.0f) B0 = 255.0f; if (R1<0.0f) R1=0.0f;
if (G1<0.0f) G1=0.0f;
if (B1<0.0f) B1=0.0f; if (R1>255.0f) R1 = 255.0f;
if (G1>255.0f) G1 = 255.0f;
if (B1>255.0f) B1 = 255.0f;
Float2Int(R0, r0);
Float2Int(G0, g0);
Float2Int(B0, b0); Float2Int(R1, r1);
Float2Int(G1, g1);
Float2Int(B1, b1);
pOut[precalc_xy++] = (unsigned char)b0;
pOut[precalc_xy++] = (unsigned char)g0;
pOut[precalc_xy++] = (unsigned char)r0;
precalc_xy++; pOut[precalc_xy++] = (unsigned char)b1;
pOut[precalc_xy++] = (unsigned char)g1;
pOut[precalc_xy++] = (unsigned char)r1;
precalc_xy++;
}
}
* YCbCrConversion
* ---------------
* function: Convert YCbCr 4:2:2 to RGB 8:8:8:8 (last 8 bits are undefined)
* in: pointer to 16bpp YUV buffer (Y, Cb, Y, Cr, Y, Cb, ...)
* out pointer to 32bpp RGB buffer
* special uses a hardcoded float to int conversion routine for increased speed.
*/#define FLOAT_MANTISSA_BITS 23
#define FLOAT_MANTISSA_MASK ((1<<(FLOAT_MANTISSA_BITS))-1)/* Non-negative float values */
#define Float2Int(_flt_, _int_) \
(*((float *)(&(_int_)))=(_flt_)+((float)(1<<(FLOAT_MANTISSA_BITS))), \
(_int_)&=FLOAT_MANTISSA_MASK)void YCbCrConversion(unsigned char *pIn, unsigned char *pOut, int nWidth, int nHeight)
{
float Y0, Cb, Y1, Cr;
float R0, G0, B0, R1, G1, B1;
float B_Cb128,R_Cr128,G_CrCb128;
int r0, b0, g0, r1, b1, g1; int precalc_xy_raw = 0;
int precalc_xy = 0; for (int i=0;i<nWidth*nHeight/2;i++)
{
/*
* optimized code for YCbCr to RGB conversion
*/
Cb = (float)pIn[precalc_xy_raw++]-128.0f;
Y0 = 1.164f * ((float)pIn[precalc_xy_raw++]-16.0f);
Cr = (float)pIn[precalc_xy_raw++]-128.0f;
Y1 = 1.164f * ((float)pIn[precalc_xy_raw++]-16.0f);
R_Cr128 = 1.596f*Cr;
G_CrCb128 = -0.813f*Cr - 0.391f*Cb;
B_Cb128 = 2.018f*Cb; R0 = Y0 + R_Cr128;
G0 = Y0 + G_CrCb128;
B0 = Y0 + B_Cb128;
R1 = Y1 + R_Cr128;
G1 = Y1 + G_CrCb128;
B1 = Y1 + B_Cb128; if (R0<0.0f) R0=0.0f;
if (G0<0.0f) G0=0.0f;
if (B0<0.0f) B0=0.0f; if (R0>255.0f) R0 = 255.0f;
if (G0>255.0f) G0 = 255.0f;
if (B0>255.0f) B0 = 255.0f; if (R1<0.0f) R1=0.0f;
if (G1<0.0f) G1=0.0f;
if (B1<0.0f) B1=0.0f; if (R1>255.0f) R1 = 255.0f;
if (G1>255.0f) G1 = 255.0f;
if (B1>255.0f) B1 = 255.0f;
Float2Int(R0, r0);
Float2Int(G0, g0);
Float2Int(B0, b0); Float2Int(R1, r1);
Float2Int(G1, g1);
Float2Int(B1, b1);
pOut[precalc_xy++] = (unsigned char)b0;
pOut[precalc_xy++] = (unsigned char)g0;
pOut[precalc_xy++] = (unsigned char)r0;
precalc_xy++; pOut[precalc_xy++] = (unsigned char)b1;
pOut[precalc_xy++] = (unsigned char)g1;
pOut[precalc_xy++] = (unsigned char)r1;
precalc_xy++;
}
}
看这里:
Cb = (float)pIn[precalc_xy_raw++]-128.0f;
Y0 = 1.164f * ((float)pIn[precalc_xy_raw++]-16.0f);
Cr = (float)pIn[precalc_xy_raw++]-128.0f;
Y1 = 1.164f * ((float)pIn[precalc_xy_raw++]-16.0f); 第一次循环
Cb = (float)pIn[0]-128.0f;
Y0 = 1.164f * ((float)pIn[1]-16.0f);
Cr = (float)pIn[2]-128.0f;
Y1 = 1.164f * ((float)pIn[3]-16.0f);意思很明显了吧
precalc_xy也就是代表输出的对应的位置,因为是16位转到32位,
16位是占四个字节,32位占8个字节
所有才有
float Y0, Cb, Y1, Cr;
float R0, G0, B0, R1, G1, B1;
这样的定义
请问如下:
第一次循环:
pOut[0] = (unsigned char)b0;
pOut[1] = (unsigned char)g0;
pOut[2] = (unsigned char)r0;
precalc_xy++; 这时precalc_xy=3,为什么还要precalc_xy自增一次呢?是不是跟Sensor有关 pOut[4] = (unsigned char)b1;
pOut[5] = (unsigned char)g1;
pOut[6] = (unsigned char)r1;
precalc_xy++; 这时这时precalc_xy=7,为什么还要precalc_xy又自增一次呢?是不是跟Sensor有关
望各位指点,谢谢!!
还有就是
precalc_xy也就是代表输出的对应的位置,因为是16位转到32位,
16位是占四个字节,32位占8个字节
所有才有
float Y0, Cb, Y1, Cr;
float R0, G0, B0, R1, G1, B1;
这样的定义
16位应该占2个字节吧,32位占4个字节,不知道对不对?
为什么要定义float R0, G0, B0, R1, G1, B1;
定义R0, G0, B0;还需要定义R1, G1, B1;有啥用?
望各位能指点?