Actually YUV 4:2:0 planar stores all Y pixels first,then U pixels,then V pixels
To extract correct pixels use the following forumla:
//Refer wikipedia for further details
size.total = size.width * size.height;
y = yuv[position.y * size.width + position.x];
u = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total];
v = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total + (size.total / 4)];
// YUV2RGBTestApp2.cpp: Определяет точку входа для консольного приложения.//
enter code here
#include "stdafx.h"
#include <string>
#include <stdio.h>
unsigned char *g_pcRGBbuffer;
unsigned char *g_pcYUVBuffer;
int _tmain(int argc, _TCHAR* argv[])
{
int l_nSize = 1920 * 1080 * 1.5;
g_pcYUVBuffer = new unsigned char[l_nSize];
g_pcRGBbuffer = new unsigned char[1920 * 1080 * 3];
FILE *fp_source;
FILE *fp_rgb = NULL;
int l_ny, l_nu, l_nv, l_ni, RGBval;
int l_dr, l_dg, l_db;
fp_source = fopen("D:\\Sample_1920x1080.yuv", "rb");
int l_nj;
//converting yuv file to rgb file
if (fp_source) {
fp_rgb = fopen("D:\\Sample_1920x1080.rgb", "wb");
while (!feof(fp_source))
{
fread(g_pcYUVBuffer, 1, l_nSize, fp_source);
unsigned char *l_pcRGBbuffer = g_pcRGBbuffer;
for (int j = 0; j < 1080; j++)
{
for (int i = 0; i<1920; i++)
{
/*
Position for y,u,v components for yuv planar 4:2:0
Refer wikipedia for further reference
*/
int Y = g_pcYUVBuffer[j * 1920 + i];
int U = g_pcYUVBuffer[((j / 2) * 960) + (i / 2) + (1920 * 1080)];
int V = g_pcYUVBuffer[((j / 2) * 960) + (i / 2) + (1920 * 1080) + ((1920 * 1080) / 4)];
int R = 1.164*(Y - 16) + 1.596*(V - 128);
int G = 1.164*(Y - 16) - 0.813*(V - 128) - 0.391*(U - 128);
int B = 1.164*(Y - 16) + 2.018*(U - 128);
if (R>255)R = 255;
if (R<0)R = 0;
if (G>255)G = 255;
if (G<0)G = 0;
if (B>255)B = 255;
if (B<0)B = 0;
l_pcRGBbuffer[0] = R;
l_pcRGBbuffer[1] = G;
l_pcRGBbuffer[2] = B;
l_pcRGBbuffer += 3;
}
}
fwrite(g_pcRGBbuffer, 1, 1920 * 1080 * 3, fp_rgb);
}
printf("Video converted to rgb file \n ");
}
else {
printf("fail\n");
}
fclose(fp_rgb);
fclose(fp_source);
return 0;
}