// Subtract.cpp: implementation of the CSubtract class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "YUVtoRGB.h"
#include "Subtract.h"
#include "PPMandPGMlibrary.h"
#include <math.h>

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSubtract::CSubtract()
{

}

CSubtract::~CSubtract()
{

}

void CSubtract::BGSubtraction() //produce 50 background-subtracted images
{
    FILE *fp;
	char name[400] = "stream.yuv";
    char name1[400] = "";
    GGImage *yuv = NULL;
    GGImage *sub = NULL;
	unsigned char *pt, *out;

    PickMode(MODE1);

    fp = fopen(name, "rb");
	yuv = AllocGGImagePPM(ImageW, ImageH);
    sub = AllocGGImagePPM(ImageW, ImageH);
    int j = 0;
    int a = 0;
    int k = 0;

    while(fread(yuv->data, ImageType/*153600*/, 1, fp) && (j < IMAGES)) //read the YUV data from the YUV file
    {
        pt = yuv->data;
        out = sub->data;

        Y1 = 0;
        Y2 = 0;
        //average the Y values of 10 images
        a = 0;
        for (int i = 0; i < ImageFor/*38400*/; i++)
		{	
            U = *pt++; //for 320x240
            Y1 = *pt++; //for 320x240
            V = *pt++; //for 320x240
            Y2 = *pt++; //for 320x240

			y1[j][a++] = Y1; //put all the Y1 pixels in an array
			y1[j][a++] = Y2; //put all the Y2 pixels in an array
		 }

         j = j + 1;
     }
     fclose(fp);


     for (int n = 0; n < IMAGES; n++)
     {
         out = sub->data;

         for (int m = 0; m < ImagePixel/*76800*/; m++)
         {
             Y1Sub[n][m] = fabs(y1[n][m] - AvgY1a[m]);
             *out++ = (unsigned char) MIN(255, MAX(0, Y1Sub[n][m]));
             *out++ = (unsigned char) MIN(255, MAX(0, Y1Sub[n][m]));
             *out++ = (unsigned char) MIN(255, MAX(0, Y1Sub[n][m]));
         }
         cout << n << endl;
         sprintf(name1, "sub_%4.4d.ppm", n);
         SaveGGImagePPM(name1, sub);
     }
}
		
//pick video mode
void CSubtract::PickMode(int nMode)
{
    if (nMode == 0) //4:4:4
    {
        ImageW = 160;
        ImageH = 120;
        ImagePixel = ImageW * ImageH;
        ImageType = ImagePixel;
        ImageFor = ImagePixel;
    }
    
    if (nMode == 1) //4:2:2
    {
        ImageW = 320;
        ImageH = 240;
        ImagePixel = ImageW * ImageH;
        ImageType = 2*ImagePixel;
        ImageFor = ImagePixel/2;
    }

    if (nMode == 2) //4:2:2
    {
        ImageW = 640;
        ImageH = 480;
        ImagePixel = ImageW * ImageH;
        ImageType = 2*ImagePixel;
        ImageFor = ImagePixel/2;
    }


}

void CSubtract::Averaging() //produce the average background image
{
    FILE *fp;
	char name[400] = "bg.yuv";
    char name1[400] = "";
    GGImage *yuv = NULL;
	GGImage *bg = NULL;
	unsigned char *pt, *avg;

    PickMode(MODE1);

    fp = fopen(name, "rb");
	yuv = AllocGGImagePPM(ImageW, ImageH);
    bg = AllocGGImagePPM(ImageW, ImageH);

    int j = 0;
    int a = 0;
    int k = 0;

    while(fread(yuv->data, ImageType/*153600*/, 1, fp) && (j < IMAGES)) //read the YUV data from the YUV file
    {
        pt = yuv->data;
        avg = bg->data;
        Y1 = 0;
        Y2 = 0;
        //average the Y values of 10 images
        a = 0;
        for (int i = 0; i < ImageFor/*38400*/; i++)
		{	
            U = *pt++; //for 320x240
            Y1 = *pt++; //for 320x240
            V = *pt++; //for 320x240
            Y2 = *pt++; //for 320x240

			y1[j][a++] = Y1; //put all the Y1 pixels in an array
			y1[j][a++] = Y2; //put all the Y2 pixels in an array
		 }

         j = j + 1;
     }

    fclose(fp);

     for (int x = 0; x < ImagePixel/*76800*/; x++)
     {
         AvgY1 = 0;

         for (int z = 0; z < IMAGES; z++)
         {
             AvgY1 += y1[z][x]; //sum pixel-x in the 1st image up to pixel-x in the nth image (sum up n numbers)
         }

         AvgY1a[x] = AvgY1/IMAGES;

         *avg++ = (unsigned char) MIN(255, MAX(0, AvgY1a[x]));
         *avg++ = (unsigned char) MIN(255, MAX(0, AvgY1a[x]));
         *avg++ = (unsigned char) MIN(255, MAX(0, AvgY1a[x]));
     }

     sprintf(name1, "avg_%4.4d.ppm", x);
     SaveGGImagePPM(name1, bg);

}
