Esempio n. 1
0
bool ScreenGrabber::tick()
{
  if (done)
    return false;
  av_packet_unref(&packet);
  auto err = av_read_frame(formatContext, &packet);
  if (err != 0)
    return false;
  auto timeBase = formatContext->streams[0]->time_base;
  if (initialPts == -1)
    initialPts = packet.pts;
  if (++totalFrames % 100 == 0)
  {
    std::clog << totalFrames * timeBase.den / (packet.pts - initialPts) / timeBase.num << "FPS\n";
    totalFrames = 0;
    initialPts = -1;
  }
  if (currentTs == -1)
  {
    currentTs = packet.pts + timeBase.den / timeBase.num / OutputFrameRate;
    reminer += timeBase.den % (timeBase.num * OutputFrameRate);
    if (reminer >= timeBase.num * OutputFrameRate)
    {
      reminer -= timeBase.num * OutputFrameRate;
      ++currentTs;
    }
  }
  auto screenCapture = packet.data;
  const auto X = width - WebcamWidth - 10;
  const auto Y = height - WebcamHeight - 10;
  for (auto j = 0; j < WebcamHeight; ++j)
    memcpy(&screenCapture[(X + (j + Y) * width) * 4],
           &webcamCapture[j * WebcamWidth * 4],
           WebcamWidth * 4);
  rgb2yuv(screenCapture + 0 * 4 * width * height / 4,
          begin(yuv) + 0 * width * height / 4,
          begin(yuv) + 0 * width * height / 4 / 4 + width * height,
          begin(yuv) + 0 * width * height / 4 / 4 + 5 * width * height / 4,
          height / 2);

  while (packet.pts > currentTs)
  {
    std::cout << "FRAME\n";
    std::cout.write((const char *)&yuv[0], yuv.size());
    currentTs += timeBase.den / timeBase.num / OutputFrameRate;
    reminer += timeBase.den % (timeBase.num * OutputFrameRate);
    if (reminer >= timeBase.num * OutputFrameRate)
    {
      reminer -= timeBase.num * OutputFrameRate;
      ++currentTs;
    }
  }
  return true;
}
Esempio n. 2
0
void outputimgyuv(char *fname,unsigned char *img,int ny,int nx)
{
  FILE *fimg;
  int iy,ix,i,j,imagesize,loc1,loc2,loc3,loc0;
  unsigned char *tmp;

  rgb2yuv(img,ny*nx*3);

  imagesize = ny*nx;
  tmp=(unsigned char *)malloc(imagesize*sizeof(unsigned char));
  fimg=fopen(fname,"wb");

  for (i=0,j=0;i<imagesize;i++,j+=3) tmp[i] = img[j];
  fwrite(tmp, sizeof(unsigned char), imagesize, fimg);

  i=0;
  for (iy=0;iy<ny;iy+=2)
  {
    for (ix=0;ix<nx;ix+=2)
    {
      loc0 = LOC(iy,ix,1,nx,3);
      loc1 = loc0+3;
      loc2 = loc0+3*nx;
      loc3 = loc2+3;
      tmp[i] = (unsigned char) round2int(( ((float) img[loc0]) + 
          img[loc1]+img[loc2]+img[loc3]) /4);
      i++;
    }
  }
  fwrite(tmp, sizeof(unsigned char), imagesize/4, fimg);

  i=0;
  for (iy=0;iy<ny;iy+=2)
  {
    for (ix=0;ix<nx;ix+=2)
    {
      loc0 = LOC(iy,ix,2,nx,3);
      loc1 = loc0+3;
      loc2 = loc0+3*nx;
      loc3 = loc2+3;
      tmp[i] = (unsigned char) round2int(( ((float) img[loc0]) + 
          img[loc1]+img[loc2]+img[loc3]) /4);
      i++;
    }
  }
  fwrite(tmp, sizeof(unsigned char), imagesize/4, fimg);

  free(tmp);
  fclose (fimg);
}
Esempio n. 3
0
void run_cpu_color_test(PPM_IMG img_in)
{
    StopWatchInterface *timer=NULL;
    printf("Starting CPU processing...\n");

    sdkCreateTimer(&timer);
    sdkStartTimer(&timer);
    img_obuf_yuv_cpu = rgb2yuv(img_in); //Start RGB 2 YUV
    sdkStopTimer(&timer);
    printf("RGB to YUV conversion time: %f (ms)\n", sdkGetTimerValue(&timer));
    sdkDeleteTimer(&timer);

    sdkCreateTimer(&timer);
    sdkStartTimer(&timer);
    img_obuf_rgb_cpu = yuv2rgb(img_obuf_yuv_cpu); //Start YUV 2 RGB
    sdkStopTimer(&timer);
    printf("YUV to RGB conversion time: %f (ms)\n", sdkGetTimerValue(&timer));
    sdkDeleteTimer(&timer);    

    write_yuv(img_obuf_yuv_cpu, "out_yuv.yuv");
    write_ppm(img_obuf_rgb_cpu, "out_rgb.ppm");
}
Esempio n. 4
0
Image ColorConvert::apply(Image im, string from, string to) {
    // check for the trivial case
    assert(from != to, "color conversion from %s to %s is pointless\n", from.c_str(), to.c_str());

    // unsupported destination color spaces
    if (to == "yuyv" ||
        to == "uyvy") {
        panic("Unsupported destination color space: %s\n", to.c_str());
    }

    // direct conversions that don't have to go via rgb
    if (from == "yuyv" && to == "yuv") {
        return yuyv2yuv(im);
    } else if (from == "uyvy" && to == "yuv") {
        return uyvy2yuv(im);
    } else if (from == "xyz" && to == "lab") {
        return xyz2lab(im);
    } else if (from == "lab" && to == "xyz") {
        return lab2xyz(im);
    } else if (from == "argb" && to == "xyz") {
        return argb2xyz(im);
    } else if (from == "xyz" && to == "argb") {
        return xyz2argb(im);
    } else if (from != "rgb" && to != "rgb") {
        // conversions that go through rgb
        Image halfway = apply(im, from, "rgb");
        return apply(halfway, "rgb", to);
    } else if (from == "rgb") { // from rgb
        if (to == "hsv" || to == "hsl" || to == "hsb") {
            return rgb2hsv(im);
        } else if (to == "yuv") {
            return rgb2yuv(im);
        } else if (to == "xyz") {
            return rgb2xyz(im);
        } else if (to == "y" || to == "gray" ||
                   to == "grayscale" || to == "luminance") {
            return rgb2y(im);
        } else if (to == "lab") {
            return rgb2lab(im);
        } else if (to == "argb") {
            return rgb2argb(im);
        } else {
            panic("Unknown color space %s\n", to.c_str());
        }
    } else { //(to == "rgb")
        if (from == "hsv" || from == "hsl" || from == "hsb") {
            return hsv2rgb(im);
        } else if (from == "yuv") {
            return yuv2rgb(im);
        } else if (from == "xyz") {
            return xyz2rgb(im);
        } else if (from == "y" || from == "gray" ||
                   from == "grayscale" || from == "luminance") {
            return y2rgb(im);
        } else if (from == "lab") {
            return lab2rgb(im);
        } else if (from == "uyvy") {
            return uyvy2rgb(im);
        } else if (from == "yuyv") {
            return yuyv2rgb(im);
        } else if (from == "argb") {
            return argb2rgb(im);
        } else {
            panic("Unknown color space %s\n", from.c_str());
        }
    }

    // keep the compiler happy
    return Image();

}
Esempio n. 5
0
/* subtitles projection */
/* for subrip file with SSA tags, those values are always correct.*/
/* But for SSA files, those values are the default ones. we have */
/* to use PlayResX and PlayResY defined in [Script Info] section. */
/* not implemented yet... */
#define SPU_PROJECTION_X  384
#define SPU_PROJECTION_Y  288



#define rgb2yuv(R,G,B) ((((((66*R+129*G+25*B+128)>>8)+16)<<8)|(((112*R-94*G-18*B+128)>>8)+128))<<8|(((-38*R-74*G+112*B+128)>>8)+128))

static const uint32_t sub_palette[22]={
/* RED */
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(50,10,10),
  rgb2yuv(120,20,20),
  rgb2yuv(185,50,50),
  rgb2yuv(255,70,70),
/* BLUE */
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
  rgb2yuv(0,0,0),
Esempio n. 6
0
File: bm3d.c Progetto: yxliang/BM3D
int bm3d (char* const infile, 			// name of input file
			 char* const kind, 				// kind of shrinkage (ht, wnr, avg)
			 int const block_size, 			// size of internal processed blocks
			 int const block_step, 			// step size between blocks
			 int const sigma, 				// standard deviation of noise
			 int const max_blocks,			// maximum number of block in one 3D array
			 int const h_search,				// horizontal width of search window
			 int const v_search, 			// vertical width of search window
			 double const th_2d,				// threshold for the 2D transformation
			 double const tau_match, 		// match value for block-matching
			 double const th_3d,				// threshold for the 3D transformtaion
			 int const block_marking) {	// indicates the action of block marking
	png_img img;								// noisy input image
	png_img org;								// temporary image for marking the blocks
	FILE* log = 0;								// log-file for all kinds of messages
	char logfile[30];							// name of the log-file including path
	char path[30];								// universally used path-name
	char prefix[20];							// universally used prefix-name
	char pure_name[30];
	int h_search_true;						// true value of horizontal search window size after validation
	int v_search_true;						// true value of vertical search window size after validation
	list_t y_list = 0;						// list of groups	of the y-channel
	list_t u_list = 0;						// list of groups of the u-channel
	list_t v_list = 0;						// list of groups of the v-channel
	clock_t start, end;						// time variables for counting durations
	double time;

	// ----------------------------------------------------------------------
	// OPEN LOG-FILE FOR WRITING
	// ----------------------------------------------------------------------

	// obtain filename without path and extension
	if (exclude_extension(infile, pure_name) != 0) {
		return 1;
	}

	sprintf (logfile, "log/log_%s_%s[%d].txt", pure_name, kind, sigma);

	log = fopen (logfile, "a");

	if (log == NULL) {
		generate_error ("Unable to open log-file for writing ...");
		return 1;
	}

	// ----------------------------------------------------------------------
	// INPUT READING AND VALIDATION
	// ----------------------------------------------------------------------
	// read input image
	if (png_read(&img, infile) != 0) {
		return 1;
	}

	// read temporary image
	if (png_read(&org, infile) != 0) {
		return 1;
	}

	// control color type
	if (img.color != PNG_COLOR_TYPE_RGB) {
		generate_error ("Wrong color type...");
		return 1;
	}

	// control number of channels
	if (img.channels != 3) {
		generate_error ("Wrong number of channels...");
		return 1;
	}

	// ----------------------------------------------------------------------
	// PARAMETER VALIDATION
	// ----------------------------------------------------------------------
	// verify kind of shrinkage
	if (strcmp(kind, "none") && strcmp(kind, "avg") && strcmp(kind, "ht") && strcmp(kind, "wnr")) {
		generate_error ("Unknown kind of shrinkage...");
		return 1;
	}

	// verify block size
	if ((block_size!=7) && (block_size!=9) && (block_size!=11) && (block_size!=13)) {
		generate_error ("Wrong value for block size...\nValid values: 7, 9, 11, 13");
		return 1;
	}
	
	// verify block step
	if ((block_step<5) || (block_step>15)) {
		generate_error ("Block step is out of valid Range...\nValid range: 5..15");
		return 1;
	}

	// control search window dimensions
	h_search_true = ((h_search > img.width) || (h_search <= 0)) ? img.width : h_search;
	v_search_true = ((v_search > img.height) || (v_search <= 0)) ? img.height : v_search;

	// ----------------------------------------------------------------------
	// PRINTING OF STATUS INFORMATION
	// ----------------------------------------------------------------------
	fprintf (log, "-------------------------------------------------------------------------\n");
	fprintf (log, "-------------------------------------------------------------------------\n");
	fprintf (log, "[INFO] ... image dimensions: %dx%d\n", img.width, img.height);
	fprintf (log, "[INFO] ... kind of shrinkage: %s\n", kind);
	fprintf (log, "[INFO] ... block size: %d\n", block_size);
	fprintf (log, "[INFO] ... block step: %d\n", block_step);
	fprintf (log, "[INFO] ... sigma: %d\n", sigma);
	fprintf (log, "[INFO] ... maximum number of blocks: %d\n", max_blocks);
	fprintf (log, "[INFO] ... horizontal search window size: %d\n", h_search_true);
	fprintf (log, "[INFO] ... vertical search window size: %d\n", v_search_true);
	fprintf (log, "[INFO] ... threshold 2D: %f\n", th_2d);
	fprintf (log, "[INFO] ... tau-match 2D: %f\n", tau_match);
	fprintf (log, "[INFO] ... threshold 3D: %f\n", th_3d);
	fprintf (log, "[INFO] ... block marking: %s\n\n", block_marking ? "yes" : "no");


	// ----------------------------------------------------------------------
	// COLORSPACE CONVERSION & WRITEBACK
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of color conversion...\n");
	rgb2yuv (&img);

	// write output image
	if (png_write(&img, "img/yuv/", "noisy_yuv", 0) != 0) {
		return 1;
	}

	printf ("[INFO] ... end of color conversion...\n\n");
	fprintf (log, "[INFO] ... converted colorspace of input image to YUV...\n\n");

	// ----------------------------------------------------------------------
	// IMAGE-TO-ARRAY CONVERSION
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of printing image as three separate value arrays...\n");

	printf ("[INFO] ... ... luminance channel...\n");
	img2array (&img, 0, "img/", "y_channel_before");

	printf ("[INFO] ... ... chrominance channel 1...\n");
	img2array (&img, 1, "img/", "u_channel_before");

	printf ("[INFO] ... ... chrominance channel 2...\n");
	img2array (&img, 2, "img/", "v_channel_before");

	printf ("[INFO] ... end of printing arrays...\n\n");
	fprintf (log, "[INFO] ... printed every intput channel as array of values...\n\n");


	// ----------------------------------------------------------------------
	// BLOCK-MATCHING
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of block-matching...\n");
	printf ("[INFO] ... ... luminance channel...\n");
	start = clock();

	if (block_matching(&img, &org, block_size, block_step, sigma, h_search_true, v_search_true, th_2d, tau_match, 0, block_marking, &y_list) != 0) {
		return 1;
	}

	printf ("[INFO] ... end of block-matching...\n\n");

	end = clock();
	time = (end - start) / (double)CLOCKS_PER_SEC;
	fprintf (log, "[INFO] ... block-matching accomplished...\n");
	fprintf (log, "[INFO] ... ... elapsed time: %f\n", time);
	fprintf (log, "[INFO] ... ... number of groups in list: %d\n\n", list_length(&y_list));

	// print recognized groups to file
	sprintf (path, "grp/org/%s/y/", kind);
	if (print_list(y_list, path, "group") != 0) {
		return 1;
	}

	// trim groups to maximal number of blocks
	printf ("[INFO] ... trimming groups to maximum size...\n\n");
	if (trim_list(&y_list, max_blocks) != 0) {
		return 1;
	}

	fprintf (log, "[INFO] ... trimmed groups to maximum size of blocks...\n\n");

	// obtain the pixel values from the u- and v-channel of the image
	printf ("[INFO] ... extracting blocks from chrominance channels...\n");
	printf ("[INFO] ... ... chrominance channel 1...\n");
	if (get_chrom(&img, &y_list, &u_list, 1)) {
		return 1;
	}

	printf ("[INFO] ... ... chrominance channel 2...\n\n");
	if (get_chrom(&img, &y_list, &v_list, 2)) {
		return 1;
	}

	fprintf (log, "[INFO] ... extracted values from chrominance channels...\n\n");

	// print trimmed groups to file
	sprintf (path, "grp/trm/%s/y/", kind);

	if (print_list(y_list, path, "group") != 0) {
		return 1;
	}

	sprintf (path, "grp/trm/%s/u/", kind);

	if (print_list(u_list, path, "group") != 0) {
		return 1;
	}

	sprintf (path, "grp/trm/%s/v/", kind);

	if (print_list(v_list, path, "group") != 0) {
		return 1;
	}


	
	// ----------------------------------------------------------------------
	// IMAGE-DENOISING
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of shrinkage...\n");
	start = clock();

	printf ("[INFO] ... ... luminance channel...\n");
	if (shrinkage(kind, &y_list, sigma, th_3d, 0) != 0) {
		return 1;
	}

	// printf ("[INFO] ... ... chrominance channel 1...\n");
	// if (shrinkage(kind, &u_list, sigma, th_3d, 1) != 0) {
	// 	return 1;
	// }

	// printf ("[INFO] ... ... chrominance channel 2...\n");
	// if (shrinkage(kind, &v_list, sigma, th_3d, 1) != 0) {
	// 	return 1;
	// }

	printf ("[INFO] ... end of shrinkage...\n\n");

	end = clock();
	time = (end - start) / (double)CLOCKS_PER_SEC;
	fprintf (log, "[INFO] ... accomplished shrinkage...\n");
	fprintf (log, "[INFO] ... ... elapsed time: %f\n\n", time);

	sprintf (path, "grp/est/%s/y/", kind);

	if (print_list(y_list, path, "group") != 0) {
		return 1;
	}

	sprintf (path, "grp/est/%s/u/", kind);

	if (print_list(u_list, path, "group") != 0) {
		return 1;
	}

	sprintf (path, "grp/est/%s/v/", kind);

	if (print_list(v_list, path, "group") != 0) {
		return 1;
	}

	// ----------------------------------------------------------------------
	// AGGREGATION
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of aggregation...\n");
	start = clock();

	printf ("[INFO] ... ... luminance channel...\n");
	if (aggregate(kind, &img, &y_list, 0) != 0) {
		return 1;
	}

	// printf ("[INFO] ...       chrominance channel 1...\n");
	// if (aggregate(kind, &img, &u_list, 1) != 0) {
	// 	return 1;
	// }

	// printf ("[INFO] ...       chrominance channel 2...\n");
	// if (aggregate(kind, &img, &v_list, 2) != 0) {
	// 	return 1;
	// }

	printf ("[INFO] ... end of aggregation...\n\n");

	end = clock();
	time = (end - start) / (double)CLOCKS_PER_SEC;
	fprintf (log, "[INFO] ... accomplished aggregation...\n");
	fprintf (log, "[INFO] ... ... elapsed time: %f\n\n", time);
	

	// ----------------------------------------------------------------------
	// IMAGE-TO-ARRAY CONVERSION
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of printing image as three separate value arrays...\n");

	printf ("[INFO] ... ... luminance channel...\n");
	img2array (&img, 0, "img/", "y_channel_after");

	printf ("[INFO] ... ... chrominance channel 1...\n");
	img2array (&img, 1, "img/", "u_channel_after");

	printf ("[INFO] ... ... chrominance channel 2...\n");
	img2array (&img, 2, "img/", "v_channel_after");

	printf ("[INFO] ... end of printing arrays...\n\n");


	// ----------------------------------------------------------------------
	// COLORSPACE CONVERSION & WRITEBACK
	// ----------------------------------------------------------------------
	printf ("[INFO] ... launch of color conversion...\n");
	yuv2rgb (&img);

	sprintf (prefix, "denoised_rgb_%s_%s", pure_name, kind);

	// write output image
	if (png_write(&img, "img/rgb/", prefix, sigma) != 0) {
		return 1;
	}

	printf ("[INFO] ... end of color conversion...\n\n");
	fprintf (log, "[INFO] ... converted colorspace of output image to RGB...\n\n");
	fprintf (log, "[INFO] ... PSNR after denoising: %fdB\n", get_snr(&org, &img));
	fprintf (log, "-------------------------------------------------------------------------\n");
	fprintf (log, "-------------------------------------------------------------------------\n\n\n");

	// ----------------------------------------------------------------------
	// FREEING DYNAMICALY ALLOCATED MEMORY
	// ----------------------------------------------------------------------
	free_list (&y_list);
	free_list (&u_list);
	free_list (&v_list);
	png_free_mem (&img);
	png_free_mem (&org);
	fclose (log);

	return 0;
}
/************************************************************************************************************************************
void update_yuv(unsigned char** Y, unsigned char** U, unsigned char** V, int height, int width)
{
	FILE* fp;
	int outer_r, inner_r, outer_c, inner_c;

	if((fp = fopen("Down_Sampled_YUV","rb")) == NULL)
	{
		printf("\n In update_yuv() Error opening DCT_output file !");
		exit(0);
	}

	for(outer_r =0; outer_r < height; outer_r += 8)
	{
		for(outer_c = 0; outer_c < width; outer_c += 8)
		{
			for(inner_r = outer_r; inner_r < outer_r+8; inner_r++)
			{
				for(inner_c = outer_c; inner_c < outer_c+8; inner_c++)
				{
					fscanf(fp,"%d\t",Y[inner_r][inner_c]);
				}
			}
		}
	}

	for(outer_r =0; outer_r < height; outer_r += 8)
	{
		for(outer_c = 0; outer_c < width; outer_c += 8)
		{
			for(inner_r = outer_r; inner_r < outer_r+8; inner_r++)
			{
				for(inner_c = outer_c; inner_c < outer_c+8; inner_c++)
				{
					fscanf(fp,"%d\t",U[inner_r][inner_c]);
				}
			}
		}
	}

	for(outer_r =0; outer_r < height; outer_r += 8)
	{
		for(outer_c = 0; outer_c < width; outer_c += 8)
		{
			for(inner_r = outer_r; inner_r < outer_r+8; inner_r++)
			{
				for(inner_c = outer_c; inner_c < outer_c+8; inner_c++)
				{
					fscanf(fp,"%d\t",V[inner_r][inner_c]);
				}
			}
		}
	}

}

***************************************************************************************************************************************/
  int main(int argc, char const *argv[])
   {
	FILE*fp, *image_rgb, *image_yuv, *down_sampled, *DCT, *image;
	unsigned char** red, **green, **blue, **Y, **U, **V, *image_contents_rgb, *image_contents_yuv, *image_contents_rgbt;
	int i,ERROR;
	Header1 header1;
	Header2 header2;
	
	if((image_rgb = fopen("Image_Contents_RGB","wb")) == NULL)	/*For storing RGB contents*/
	{
		printf("\n Error creating Image_Contents_RGB file !!");
		return -1;
	}
	
	if((image_yuv = fopen("Image_Contents_YUV","wb")) == NULL)	/* For storing YUV contents*/
	{
		printf("\n Error creating Image_Contents_YUV file !!");
		return -1;
	}

	if((down_sampled = fopen("Down_Sampled_YUV","wb")) == NULL)	/* For storing down sampled YUV contents*/
	{
		printf("\n Error creating Down_Sampled_YUV file !!");
		return -1;
	}

	if((DCT = fopen("DCT_Output","wb")) == NULL)				/* For storing DCT contents*/
	{
		printf("\n Error creating Down_Sampled_YUV file !!");
		return -1;
	}	

	if(argc!= 2)												/* syntax error check*/
	{
		printf("\n The format is ./quantizer [file-name]");
		return -1;
	}

	if((fp = fopen(argv[1],"rb"))== NULL) 						/* open the .bmp file for reading*/
	{
		printf("\n Error opening the file specified. Please check if the file exists !!\n");
		fclose(fp);
		return -1;
	}

	if(fread(&header1,sizeof(header1),1,fp)!=1) 				/* Read the primary header from the bmp file */
	{
		printf("\n Error reading header1 \n");
		fclose(fp);
		return -1;
	}

	if(header1.type!= 19778)									/* check if its a valid bmp file*/
	{
		printf("\n Not a bmp file. Exiting !! \n");
		fclose(fp);
		return -1;
	}

	if(fread(&header2,sizeof(header2),1,fp)!=1 )
	{
		printf("\n Error reading header 2");
		fclose(fp);
		return -1;
	} 

	image_contents_rgb = (unsigned char*)malloc(sizeof(char) * header2.imagesize); 
	image_contents_rgbt = (unsigned char*)malloc(sizeof(char) * header2.imagesize);	/*allocate memory to store image data*/
	image_contents_yuv = (unsigned char*)malloc(sizeof(char) * header2.imagesize);

	fseek(fp,header1.offset,SEEK_SET); 												/* To assign file pointer to start of image byte*/ 	

	if((ERROR = fread(image_contents_rgb,header2.imagesize,1,fp))!=1)
	{
		printf("\nError reading contents\n");
		free(image_contents_rgb);
		fclose(fp);
		return -1;
	} 

	fclose(fp);

	red = (unsigned char**)malloc(sizeof(char*) * header2.height);
	green = (unsigned char**)malloc(sizeof(char*) * header2.height);
	blue = (unsigned char**)malloc(sizeof(char*) * header2.height);
	Y = (unsigned char**)malloc(sizeof(char*) * header2.height);
	U = (unsigned char**)malloc(sizeof(char*) * header2.height);
	V = (unsigned char**)malloc(sizeof(char*) * header2.height);

	for(i=0 ; i<header2.height ;i++)
	{
		red[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
		green[i]= (unsigned char*)malloc( sizeof(char) * header2.width);
		blue[i]= (unsigned char*)malloc( sizeof(char) * header2.width);
		Y[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
		U[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
		V[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
	}	
	
	vector2matrix(red, green, blue, image_contents_rgb, header2.height, header2.width); 	/* Store image contents as matrix */
	FileWrite(red, green, blue, image_rgb, header2.height, header2.width);					/* Optional step*/
	rgb2yuv(red,green,blue,Y,U,V,header2.height,header2.width);								/* RGB to YUV conversion*/
	FileWrite(Y, U, V, image_yuv, header2.height, header2.width);							/* Writing YUV into file*/			
	downsampling(Y, U, V, header2.height, header2.width);									/* 4:2:0 Downsampling and update YUV */ 
	FileWrite(Y, U, V, down_sampled, header2.height, header2.width);						/* Write downsampled YUV into file*/
	dct(DCT, header2.height, header2.width);												/* Perform dct and store the result into a file*/
	printf("\n");
	
	yuv2rgb(red,green,blue,Y,U,V,header2.height,header2.width);								/* Optional step*/
	matrix2vector_rgb(red,green,blue,image_contents_rgbt,header2.height,header2.width); 	/* convert back from matrix to vector*/
	matrix2vector_yuv(Y,U,V,image_contents_yuv,header2.height,header2.width);

	if((image = fopen("Output_image","wb")) == NULL)
	{
		printf("\n ERROR opening the file to write quantized image !!\n");
		fclose(image);
		return -1;
	}

	if(fwrite(&header1,sizeof(header1),1,image)!= 1)
	{
		printf("\n ERROR writing header 1 into destination file !!\n");
		fclose(image);
		return -1;
	}

	if(fwrite(&header2,sizeof(header2),1,image)!= 1)
	{
		printf("\n ERROR writing header 2 into destination file !! \n");
		fclose(image);
		return -1;
	}

	fseek(image, header1.offset, SEEK_SET);

	if(fwrite(image_contents_rgbt,header2.imagesize,1,image)!=1)		/* Change the vector to write into the bmp file here*/
	{
		printf("\n ERROR writing image contents into destination file \n");
		fclose(image);
		return -1;
	}

	free(red);
	free(green);
	free(blue);
	free(Y);
	free(U);
	free(V);
	fclose(image);
	return 0;
}
int main(int argc, char const *argv[])
{
	FILE*fp,*image;
	unsigned char** red,**green,**blue,**Y,**U,**V,*image_contents_rgb, *image_contents_yuv, *image_contents_rgbt;
	int i,j,x,y,row_index, col_index,ERROR;
	Header1 header1;
	Header2 header2;
	/* -----------------------------				Task 1			-------------------------------------- */
	 int array[8][8] = {{48,39,40,68,60,38,50,121},
	{149,82,79,101,113,106,27,62},
	{58,63,77,69,124,107,74,125},
	{80,97,74,54,59,71,91,66},
	{18,34,33,46,64,61,32,37},
	{149,108,80,106,116,61,73,92},
	{211,233,159,88,107,158,161,109},
	{212,104,40,44,71,136,113,66}};
	printf("\n\n *************************** Activity 1: SAMPLE BLOCK *************** \n");
	dct(array);
	/*----------------------------					Task2 			----------------------------------------- */
	srand(time(NULL));
	printf("\n\n *************************** Activity 2: RANDOM BLOCK **************** \n\n");
	for(i =0; i<block_size; ++i)
	{
		for(j=0; j<block_size; ++j)
		{
			array[i][j] = rand()%150;
		}
	}
	dct(array);
	printf("\n");
	/*------------------------------			Task3 				------------------------------------------- */
	if(argc!= 2)																/* syntax error check*/
	{
		printf("\n The format is ./quantizer [file-name]");
		return -1;
	}

	if((fp = fopen(argv[1],"rb"))== NULL) 										/* open the .bmp file for reading*/
	{
		printf("\n Error opening the file specified. Please check if the file exists !!\n");
		fclose(fp);
		return -1;
	}

	if(fread(&header1,sizeof(header1),1,fp)!=1) 								/* Read the primary header from the bmp file */
	{
		printf("\n Error reading header1 \n");
		fclose(fp);
		return -1;
	}

	if(header1.type!= 19778)													/* check if its a valid bmp file*/
	{
		printf("\n Not a bmp file. Exiting !! \n");
		fclose(fp);
		return -1;
	}

	if(fread(&header2,sizeof(header2),1,fp)!=1 )
	{
		printf("\n Error reading header 2");
		fclose(fp);
		return -1;
	} 

	image_contents_rgb = (unsigned char*)malloc(sizeof(char) * header2.imagesize); 
	image_contents_rgbt = (unsigned char*)malloc(sizeof(char) * header2.imagesize);	/*allocate memory to store image data*/
	image_contents_yuv = (unsigned char*)malloc(sizeof(char) * header2.imagesize);

	fseek(fp,header1.offset,SEEK_SET); 	

	if((ERROR=fread(image_contents_rgb,header2.imagesize,1,fp))!=1)
	{
		printf("\nError reading contents\n");
		free(image_contents_rgb);
		fclose(fp);
		return -1;
	} 

	fclose(fp);

	red = (unsigned char**)malloc(sizeof(char*) * header2.height);
	green = (unsigned char**)malloc(sizeof(char*) * header2.height);
	blue = (unsigned char**)malloc(sizeof(char*) * header2.height);
	Y = (unsigned char**)malloc(sizeof(char*) * header2.height);
	U = (unsigned char**)malloc(sizeof(char*) * header2.height);
	V = (unsigned char**)malloc(sizeof(char*) * header2.height);

	for(i=0 ; i<header2.height ;i++)
	{
		red[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
		green[i]= (unsigned char*)malloc( sizeof(char) * header2.width);
		blue[i]= (unsigned char*)malloc( sizeof(char) * header2.width);
		Y[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
		U[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
		V[i] = (unsigned char*)malloc( sizeof(char) * header2.width);
	}	
	
	vector2matrix(red,green,blue,image_contents_rgb,header2.height,header2.width); 		/* call to store image contents as matrix */
	printf("\n\n *********************** Activity 3: RGB Image Block *********************\n");
	printf(" Enter the starting row index and coloumn index respectively: ");
	scanf("%d %d",&row_index,&col_index);
	for(i = 0, x = row_index; i < block_size && x<row_index+8; ++i, ++x)
	{
		for(j= 0, y = col_index; j < block_size && y<col_index+8; ++j, ++y)
		{
			if(x<512 && y<512)
				array[i][j] = blue[x][y];
			else
				array[i][j] = 0;
		}
	}
	dct(array);
	rgb2yuv(red,green,blue,Y,U,V,header2.height,header2.width);								/* Downsampling*/
	printf("\n\n *********************** Activity 4: YUV Image Block *********************\n");
	printf(" Enter the starting row index and coloumn index respectively: ");
	scanf("%d %d",&row_index,&col_index);
	for(i = 0, x = row_index; i < block_size && x<row_index+8; ++i, ++x)
	{
		for(j= 0, y = col_index; j < block_size && y<col_index+8; ++j, ++y)
		{
			if(x<512 && y<512)
				array[i][j] = V[x][y];
			else
				array[i][j] = 0;
		}
	}
	dct(array);
	yuv2rgb(red,green,blue,Y,U,V,header2.height,header2.width);							/* convert back to RGB*/									
	matrix2vector_rgb(red,green,blue,image_contents_rgbt,header2.height,header2.width); /* convert back from matrix to vector*/
	matrix2vector_yuv(Y,U,V,image_contents_yuv,header2.height,header2.width);

	if((image = fopen("Output_image","wb")) == NULL)
	{
		printf("\n ERROR opening the file to write quantized image !!\n");
		fclose(image);
		return -1;
	}

	if(fwrite(&header1,sizeof(header1),1,image)!= 1)
	{
		printf("\n ERROR writing header 1 into destination file !!\n");
		fclose(image);
		return -1;
	}

	if(fwrite(&header2,sizeof(header2),1,image)!= 1)
	{
		printf("\n ERROR writing header 2 into destination file !! \n");
		fclose(image);
		return -1;
	}

	fseek(image, header1.offset, SEEK_SET);

	if(fwrite(image_contents_rgbt,header2.imagesize,1,image)!=1)					/* Change the vector to write into the bmp file here*/
	{
		printf("\n ERROR writing image contents into destination file \n");
		fclose(image);
		return -1;
	}

	free(red);
	free(green);
	free(blue);
	free(Y);
	free(U);
	free(V);
	free(image_contents_rgb);
	free(image_contents_yuv);
	fclose(image);
	return 0;
}