// Convert.cpp: implementation of the CConvert class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "YUVtoRGB.h"
#include "Convert.h"
#include "Subtract.h"
#include "PPMandPGMlibrary.h"
#include "Global.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//#define MIN(a, b) (a) < (b) ? (a) : (b)
//#define MAX(a, b) (a) > (b) ? (a) : (b)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSubtract Sub;

CConvert::CConvert()
{

}

CConvert::~CConvert()
{

}

void CConvert::YUVtoRGB()
{

	FILE *fp;
	char name[400] = "stream.yuv";
	char name1[400] = "";
	GGImage *rgb = NULL;
	GGImage *yuv = NULL;
	unsigned char *pt, *out;

    Sub.PickMode(MODE1);
	fp = fopen(name, "rb");

	yuv = AllocGGImagePPM(Sub.ImageW, Sub.ImageH);
    rgb = AllocGGImagePPM(Sub.ImageW, Sub.ImageH);
	//yuv = AllocGGImagePPM(640, 480);
	//rgb = AllocGGImagePPM(640, 480);

    int imgcnt = 0;

	while(fread(yuv->data, Sub.ImageType/*153600*/, 1, fp)) //read yuv data from yuv file
	{
		pt = yuv->data;
		out = rgb->data;
		imgcnt++;
		cout << imgcnt << endl;

		for (int i = 0; i < Sub.ImageFor/*38400*/; i++)
        {	
			U = *pt++; //for 320x240
			Y1 = *pt++; //for 320x240
			V = *pt++; //for 320x240
			Y2 = *pt++; //for 320x240

			Y1 = Y1 / 255; 
			Y2 = Y2 / 255; 
			U = (0.874/255) * U - 0.437; //convert U from [0,255] (int) to [-0.437, 0.437]
			V = (1.23/255) * V - 0.615; //convert V from [0, 255] (int) to [-0.615, 0.615]

			R1 = (Y1 + V * 1.140)*255;
			G1 = (Y1 - 0.394 * U - 0.581 * V)*255;
			B1 = (Y1 + 2.028 * U)*255;

			R2 = (Y2 + V * 1.140)*255;
			G2 = (Y2 - 0.394 * U - 0.581 * V)*255;
			B2 = (Y2 + 2.028 * U)*255;

			*out++ = (unsigned char) MIN(255, MAX(0, R1)); //for 320x240
			*out++ = (unsigned char) MIN(255, MAX(0, G1));
			*out++ = (unsigned char) MIN(255, MAX(0, B1));

			*out++ = (unsigned char) MIN(255, MAX(0, R2));
			*out++ = (unsigned char) MIN(255, MAX(0, G2));
			*out++ = (unsigned char) MIN(255, MAX(0, B2));
		}
		sprintf(name1, "rgb_%4.4d.ppm", imgcnt);
		SaveGGImagePPM(name1, rgb);
	}

	fclose(fp);
}

void CConvert::BGtoRGB()
{
    FILE *fp;
    char name[400] = "bg.yuv";
	char name1[400] = "";
	GGImage *rgb = NULL;
	GGImage *yuv = NULL;
	unsigned char *pt, *out;

    Sub.PickMode(MODE1);
	fp = fopen(name, "rb");

	yuv = AllocGGImagePPM(Sub.ImageW, Sub.ImageH);
    rgb = AllocGGImagePPM(Sub.ImageW, Sub.ImageH);
	//yuv = AllocGGImagePPM(640, 480);
	//rgb = AllocGGImagePPM(640, 480);

    int imgcnt = 0;

	while(fread(yuv->data, Sub.ImageType/*153600*/, 1, fp)) //read yuv data from yuv file
	{
		pt = yuv->data;
		out = rgb->data;
		imgcnt++;
		cout << imgcnt << endl;

		for (int i = 0; i < Sub.ImageFor/*38400*/; i++)
        {	
			U = *pt++; //for 320x240
			Y1 = *pt++; //for 320x240
			V = *pt++; //for 320x240
			Y2 = *pt++; //for 320x240

			Y1 = Y1 / 255; 
			Y2 = Y2 / 255; 
			U = (0.874/255) * U - 0.437; //convert U from [0,255] (int) to [-0.437, 0.437]
			V = (1.23/255) * V - 0.615; //convert V from [0, 255] (int) to [-0.615, 0.615]

			R1 = (Y1 + V * 1.140)*255;
			G1 = (Y1 - 0.394 * U - 0.581 * V)*255;
			B1 = (Y1 + 2.028 * U)*255;

			R2 = (Y2 + V * 1.140)*255;
			G2 = (Y2 - 0.394 * U - 0.581 * V)*255;
			B2 = (Y2 + 2.028 * U)*255;

			*out++ = (unsigned char) MIN(255, MAX(0, R1)); //for 320x240
			*out++ = (unsigned char) MIN(255, MAX(0, G1));
			*out++ = (unsigned char) MIN(255, MAX(0, B1));

			*out++ = (unsigned char) MIN(255, MAX(0, R2));
			*out++ = (unsigned char) MIN(255, MAX(0, G2));
			*out++ = (unsigned char) MIN(255, MAX(0, B2));
		}
		
        sprintf(name1, "bgrgb_%4.4d.ppm", imgcnt);
		SaveGGImagePPM(name1, rgb);
	}

	fclose(fp);
}
