Exemplo n.º 1
0
void	main(int argc, char **argv)
{
    if ( ! ReadPPM(stdin) )
    {
	fprintf(stderr, "Error reading PPM input file!!!\n");
	exit(1);
    }

    PPMtoYUV();

    WriteYUV(stdout);
}
// 转换RGB
void CRGB2YUVView::OnConvertPAL() 
{
	CDC *pDC = GetDC();
	CRect rect;
	CBrush brush(RGB(128,128,128));
	GetClientRect(&rect);
	pDC->FillRect(&rect, &brush);

	// PAL 720x576 : 中国的电视标准为PAL制	
	int CurrentXRes = 720;
	int CurrentYRes = 576;
	int size        = CurrentXRes * CurrentYRes;
    
	// 分配内存
	byte *Video_Field0 = (byte*)malloc(CurrentXRes*CurrentYRes);  
	byte *Video_Field1 = (byte*)malloc(CurrentXRes*CurrentYRes);
	
	// 保存内存指针
	byte *Video_Field0_ = Video_Field0;
	byte *Video_Field1_ = Video_Field1;

	byte yuv_y0, yuv_u0, yuv_v0, yuv_v1;  // {y0, u0, v0, v1};
	byte bufRGB[3];  // 临时保存{R,G,B}
	byte bufYUV[3];  // 临时保存{Y,U,V}

	// 初始化数组空间
    ZeroMemory(bufRGB, sizeof(byte)*3);
	ZeroMemory(bufYUV, sizeof(byte)*3);

	// 初始化内存
	ZeroMemory(Video_Field0, CurrentXRes*CurrentYRes);
	ZeroMemory(Video_Field1, CurrentXRes*CurrentYRes);
	
	// BMP 位图操作
	BITMAPFILEHEADER bmfh;
	BITMAPINFOHEADER bmih;

    char strFileName[MAX_PATH]="720bmp.bmp";
	CFile* f;
	f = new CFile();
	f->Open(strFileName, CFile::modeRead);
	f->SeekToBegin();
	f->Read(&bmfh, sizeof(bmfh));
	f->Read(&bmih, sizeof(bmih));
 
    // 分配图片像素内存
    RGBTRIPLE *rgb;
	rgb = new RGBTRIPLE[bmih.biWidth*bmih.biHeight];

	f->SeekToBegin();
	f->Seek(54,CFile::begin);  // BMP 54个字节之后的是位像素数据
	f->Read(rgb, bmih.biWidth * bmih.biHeight * 3);	 // 这里只读24位RGB(r,g,b)图像
	
	// 上场  (1,3,5,7...行)
	for (int i = bmih.biHeight-1; i>=0; i--) {
		for (int j = 0; j<bmih.biWidth; j++) {
			if(!(i%2)==0) 
			{
				bufRGB[0] = rgb[i*bmih.biWidth+j].rgbtRed;   //	R
				bufRGB[1] = rgb[i*bmih.biWidth+j].rgbtGreen; // G
				bufRGB[2] = rgb[i*bmih.biWidth+j].rgbtBlue;  // B

				// RGB转换为YUV
				RGB2YUV(bufRGB,bufYUV);
				yuv_y0 = bufYUV[0];   // y
				yuv_u0 = bufYUV[1];   // u
				yuv_v0 = bufYUV[2];   // v
				
				for (int k=0; k<1000; k++) ;  //延时
				// 视图中显示
				pDC->SetPixel(j, (bmih.biHeight-1)-i, RGB(bufRGB[0], bufRGB[1], bufRGB[2]));
				
				// UYVY标准  [U0 Y0 V0 Y1] [U1 Y2 V1 Y3] [U2 Y4 V2 Y5] 每像素点两个字节,[内]为四个字节 
				if ((j%2)==0) 
				{
					*Video_Field0 = yuv_u0;  
					Video_Field0++;
					yuv_v1 = yuv_v0;   // v保存起来供下一字节使用
				} 
				else
				{
					*Video_Field0 = yuv_v1;  
					Video_Field0++;
				}
				*Video_Field0 = yuv_y0;      
				Video_Field0++;
			}// end if i%2
		}
	}

    // 下场 (2,4,6,8...行)
	for (int i_ = bmih.biHeight-1; i_>=0; i_--) {
		for (int j_ = 0; j_<bmih.biWidth; j_++) {
			if((i_%2)==0) 
			{
				bufRGB[0] = rgb[i_*bmih.biWidth+j_].rgbtRed;   //	R
				bufRGB[1] = rgb[i_*bmih.biWidth+j_].rgbtGreen; // G
				bufRGB[2] = rgb[i_*bmih.biWidth+j_].rgbtBlue;  // B

				// RGB转换为YUV
				RGB2YUV(bufRGB,bufYUV);
				yuv_y0 = bufYUV[0];   // y
				yuv_u0 = bufYUV[1];   // u
				yuv_v0 = bufYUV[2];   // v

				for (int k=0; k<1000; k++) ;  //延时
				// 视图中显示
				pDC->SetPixel(j_, (bmih.biHeight-1)-i_, RGB(bufRGB[0], bufRGB[1], bufRGB[2]));

				// UYVY标准  [U0 Y0 V0 Y1] [U1 Y2 V1 Y3] [U2 Y4 V2 Y5] 每像素点两个字节,[内]为四个字节 
				if ((j_%2)==0) 
				{
					*Video_Field1 = yuv_u0;  
					Video_Field1++;
					yuv_v1 = yuv_v0;   // v保存起来供下一字节使用
				} 
				else
				{
					*Video_Field1 = yuv_v1;  
					Video_Field1++;
				}
				*Video_Field1 = yuv_y0;      
				Video_Field1++;
			}
		}
	}

    // 关闭BMP位图文件
	f->Close();
	WriteYUV(Video_Field0_, Video_Field1_, size);
	
	// 释放内存
	free( Video_Field0_ ); 
	free( Video_Field1_ );
	delete f;
	delete rgb;
}