2010-03-12 92 views
1

我必須顯示RGB888內容使用ShowRGBContent函數。顯示RGB888內容

的下面功能爲yv12-> RGB565 & UYVY-> RGB565

static void ShowRGBContent(UINT8 * pImageBuf, INT32 width, INT32 height) 
{ 
LogEntry(L"%d : In %s Function \r\n",++abhineet,__WFUNCTION__); 
UINT16 * temp; 
BYTE rValue, gValue, bValue; 

// this is to refresh the background desktop 
ShowWindow(GetDesktopWindow(),SW_HIDE); 
ShowWindow(GetDesktopWindow(),SW_SHOW); 

for(int i=0; i<height; i++) 
{ 
for (int j=0; j< width; j++)   
{ 
    temp = (UINT16 *) (pImageBuf+ i*width*PP_TEST_FRAME_BPP+j*PP_TEST_FRAME_BPP); 
    bValue = (BYTE) ((*temp & RGB_COMPONET0_MASK) >> RGB_COMPONET0_OFFSET) << (8 -RGB_COMPONET0_WIDTH); 
    gValue = (BYTE) ((*temp & RGB_COMPONET1_MASK) >> RGB_COMPONET1_OFFSET) << (8 -RGB_COMPONET1_WIDTH); 
    rValue = (BYTE) ((*temp & RGB_COMPONET2_MASK) >> RGB_COMPONET2_OFFSET) << (8 -RGB_COMPONET2_WIDTH);    
    SetPixel(g_hDisplay, SCREEN_OFFSET_X + j, SCREEN_OFFSET_Y+i, RGB(rValue, gValue, bValue)); 
} 
} 

Sleep(2000); //sleep here to review the result 

LogEntry(L"%d :Out %s Function \r\n",++abhineet,__WFUNCTION__); 
} 

一個ShowRGBContent函數I必須修改此爲RGB888

在這裏,在以上功能:

************************ 
RGB_COMPONET0_WIDTH = 5 
RGB_COMPONET1_WIDTH = 6 
RGB_COMPONET2_WIDTH = 5 
************************ 

************************ 
RGB_COMPONET0_MASK = 0x001F //31 in decimal 
RGB_COMPONET1_MASK = 0x07E0 //2016 in decimal 
RGB_COMPONET2_MASK = 0xF800 //63488 in decimal 
************************ 

************************ 
RGB_COMPONET0_OFFSET = 0 
RGB_COMPONET1_OFFSET = 5 
RGB_COMPONET2_OFFSET = 11 
************************ 

************************ 
SCREEN_OFFSET_X = 100 
SCREEN_OFFSET_Y = 0 
************************ 

Here 
Also PP_TEST_FRAME_BPP = 2 for yv12 -> RGB565 & UYVY -> RGB565 

iOutputBytesPerFrame = iOutputStride * iOutputHeight; 
// where iOutputStride = (iOutputWidth * PP_TEST_FRAME_BPP) i.e (112 * 2) 
// & iOutputHeight = 160 
// These are in case of RGB565 

pOutputFrameVirtAddr = (UINT32 *) AllocPhysMem(iOutputBytesPerFrame, 
               PAGE_EXECUTE_READWRITE, 
               0, 
               0, 
               (ULONG *) &pOutputFramePhysAddr); 

// PAGE_EXECUTE_READWRITE = 0x40 mentioned in winnt.h 

// Width =112 & Height = 160 in all the formats for i/p & o/p 

現在我的任務是RGB888。 請指導我在這做什麼。 **提前致謝。

+0

什麼是您的源格式'yv12'或'UYVY'? – dirkgently

+1

上述函數用於** yv12 - > rgb565 **,其中**源格式**爲** yv12 **並且相同函數用於** uyvy-> rgb565 **其中**源格式* *是** uyvy **。 現在我必須使用** yuv444到RGB888 **的相同功能,其中目標格式是** rgb888 **和**源格式**是** YUV444 **。提前感謝。 – Abhineet

+0

很難看到這個代碼如何適用於yv12。看看http://en.wikipedia.org/wiki/Yuv#Y.27UV444 –

回答

1

從yuv444到rgb888的轉換非常簡單,因爲所有組件都落在字節邊界上,因此不需要掩碼。根據nobugz在評論部分中提到的wikipedia article,轉換可以在固定點由以下

UINT8* pimg = pImageBuf; 
for(int i=0; i<height; i++) 
{ 
    for (int j=0; j< width; j++)   
    { 
     INT16 Y = pimg[0]; 
     INT16 Cb = (INT16)pimg[1] - 128; 
     INT16 Cr = (INT16)pimg[2] - 128; 
     rValue = Y + Cr + Cr >> 2 + Cr >> 3 + Cr >> 5 
     gValue = Y - (Cb >> 2 + Cb >> 4 + Cb >> 5) - 
       (Cr >> 1 + Cr >> 3 + Cr >> 4 + Cr >> 5); 
     bValue = Y + Cb + Cb >> 1 + Cb >> 2 + Cb >> 6; 
     SetPixel(g_hDisplay, SCREEN_OFFSET_X + j, SCREEN_OFFSET_Y+i, RGB(rValue, 
       gValue, bValue)); 
     pimg+=3; 
    } 
} 

完成這假設你的YUV444是每個樣本8位(每像素24位)。轉換也可以在浮點上完成,但如果它起作用,它應該更快,因爲源和目標都是固定點。我也不確定轉換爲int16是必要的,但我確實是安全的。

請注意,yuv444中的444並不是指rgb888中的888。 444是指在使用TUV色彩空間時經常發生的子採樣。例如在YUV420中,Cb和Cr在兩個方向上被抽取兩個。 yuv444只是意味着所有三個組件都採樣相同(無二次採樣)。 rgb888中的888是指每個樣本的位數(三個顏色分量中的每一個都是8位)。

我還沒有真正測試過這段代碼,但它至少應該讓你知道從哪裏開始。

+1

沒有真正的轉換是在內部完成的。在這裏,我必須爲r,g,b設置適當的值。所以這不是我想要的,因爲你在上面提到。 – Abhineet