const double RtoY[3][3] = { 0.299, 0.587, 0.114,
-0.1687, -0.3313, 0.5,
0.5, -0.4187, -0.0813 };
const double YtoR[3][3] = { 1.0, 0.0, 1.402,
1.0, -0.34414, -0.71414,
1.0, 1.772, 0.0 };
typedef struct FrameStruct {
uint8_t *Y, *Cr, *Cb;
uint8_t *datas;
uint32_t channelLength;
uint32_t width, height;
FrameStruct() {
width = height = channelLength = 0;
Y = Cr = Cb = NULL;
datas = NULL;
}
~FrameStruct() {
if (datas != NULL) {
delete[] datas;
}
}
} FrameS;
typedef struct ImageStruct {
uint8_t *datas;
uint32_t width, height;
ImageStruct() {
datas = NULL;
width = height = 0;
}
~ImageStruct() {
if (datas != NULL) {
delete[] datas;
}
}
} ImageS;
RGB to YUV:
void ConvertRGBToYUV( ImageS *rgb , FrameS *yuv ) {
int offset, dat;
int cnt = 0;
double signal;
yuv->width = rgb->width;
yuv->height = rgb->height;
yuv->channelLength = rgb->width * yuv->height;
for(uint32_t y = 0 ; y < rgb->height ; ++y) {
/// width * 3: one pixel is 24 bit( 3 byte ) /
for(uint32_t x = 0 ; x < rgb->width * 3 ; x += 3) {
for(int i = 0 ; i < 3 ; ++i ) {
offset = yuv->channelLength * i;
dat = 0;
int step = x;
for(int j = 0 ; j < 3 ; ++j , ++step) {
signal = (double)rgb->datas[y * rgb->width * 3 + step];
dat += (int)( signal * RtoY[i][j] );
}
yuv->datas[cnt + offset] = (int8_t)(dat + ( i <= 0 ? 0.0 : 128.0 ));
}
cnt++;
}
}
yuv->Y = yuv->datas;
yuv->Cb = &yuv->datas[yuv->channelLength];
yuv->Cr = &yuv->datas[yuv->channelLength * 2];
}
YUV to RGB:
void ConvertYUVToRGB( FrameS *yuv , ImageS *rgb ){
int offset, dat, cnt;
cnt = 0;
rgb->width = yuv->width; rgb->height = yuv->height;
for(uint32_t y = 0; y < yuv->height; ++y) {
for(uint32_t x = 0; x < yuv->width; ++x) {
for(int i = 0; i < 3; ++i) {
dat = 0;
for(int j = 0 ; j < 3 ; ++j) {
offset = yuv->channelLength * j;
dat += (int)((double)(yuv->datas[y * yuv->width + x + offset] -
(j > 0 ? 128.0 : 0.0)) * YtoR[i][j]);
}
if( dat > 255 ) { dat = 255; }
if( dat < 0 ) { dat = 0; }
rgb->datas[cnt++] = (uint8_t)dat;
}
}
}
}