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; }