2011-05-23 86 views
16

試圖按照GIL的設計指南工作,我使用bits__作爲我的頻道數據類型。我經常有外部數據包裹到GIL圖像視圖中。但是,即使使用bits__類型的數據指針,我也必須添加reinterpret_cast才能創建圖像視圖。看看下面的代碼Boost :: GIL bits8 * to gray8_ptr_t without reinterpret_cast?

int width = 3; 
int height = 2; 

boost::gil::bits8 data8[] = {0, 1, 100, 200, 50, 51}; 
boost::gil::bits8* pBits8 = data8; 
boost::gil::gray8_ptr_t pGray8 = pBits8; 

boost::gil::gray8_view_t v = interleaved_view(width, height, pGray8, width * sizeof(boost::gil::bits8)); 

在第6行「錯誤C2440錯誤結果:‘初始化’:無法從‘提高::吉爾:: bits8 *’轉換爲‘推動::吉爾:: gray8_ptr_t’ 1>指向的類型是無關的;轉換需要reinterpret_cast,C風格的轉換或函數風格的轉換「

盡我所能地深入瞭解源代碼,看起來這些類型確實沒有發現。 bits8只是unsigned char,但是gray8_ptr_t是指向struct pixel<bits8,gray_layout_t>的指針。這個結構的唯一元素是一個位8,所以reinterpret_cast看起來很安全。它也適用於我所投入的測試。

不過,我包裹外部數據導入圖像的觀點很多時候,且在每一個地方的reinterpret_cast感覺有問題。有沒有更安全的方法來構建GIL中使用的像素指針?

當前的解決辦法:

template<class Dest, class Src> 
Dest gil_safe_ptr_cast(Src src) 
{ 
    // this cast is unsafe, use reinterpret_cast 
    BOOST_STATIC_ASSERT(false); 
} 
template<> boost::gil::gray8_ptr_t gil_safe_ptr_cast(boost::gil::bits8* pBits8) 
{ 
    return reinterpret_cast<boost::gil::gray8_ptr_t>(pBits8); 
} 
boost::gil::bits8* pBits8 = data8; 
boost::gil::gray8_ptr_t pGray8 = gil_safe_ptr_cast<boost::gil::gray8_ptr_t>(pBits8); // works 
boost::gil::bits16* pBits16 = NULL; 
boost::gil::gray8_ptr_t pGray82 = gil_safe_ptr_cast<boost::gil::gray8_ptr_t>(pBits16); // compile error as expected 
+0

+1對於危險演員沒有完全瘋狂,因爲我懷疑你可能是我第一次看到問題標題的時候。 – 2011-05-23 21:29:02

+1

我創建了一個解決辦法,這基本上是被稱爲是安全的這一操作 – totowtwo 2011-05-24 15:18:20

+2

這將是安全,如果你剛剛創建的像素結構和自己剛纔放置在bits8它施放列表。對於反向轉換,只需從結構中提取bits8。 – 2011-05-30 01:54:50

回答

1
template<class Dest, class Src> 
Dest gil_safe_ptr_cast(Src src) 
{ 
    // this cast is unsafe, use reinterpret_cast 
    BOOST_STATIC_ASSERT(false); 
} 
template<> boost::gil::gray8_ptr_t gil_safe_ptr_cast(boost::gil::bits8* pBits8) 
{ 
    return reinterpret_cast<boost::gil::gray8_ptr_t>(pBits8); 
} 
boost::gil::bits8* pBits8 = data8; 
boost::gil::gray8_ptr_t pGray8 = gil_safe_ptr_cast<boost::gil::gray8_ptr_t>(pBits8); // works 
boost::gil::bits16* pBits16 = NULL; 
boost::gil::gray8_ptr_t pGray82 = gil_safe_ptr_cast<boost::gil::gray8_ptr_t>(pBits16); // compile error as expected 
+1

這使用reinterpret_cast。 「沒有reinterpret_cast」發生了什麼? – Brilliand 2011-08-23 23:25:41

1

從bits8轉換*到gray8_ptr_t,創建一個結構像素,並提供bits8的構造器:

gray8_ptr_t convert_gray8_ptr_t(bits8* src) { 
    return new struct pixel<bits8,gray_layout_t>(*src); 
} 

要轉換回來,使用結構的轉換操作符:

bits8* convert_bits8(gray8_ptr_t src) { 
    bits8* result = new bits8; 
    *result = (bits8) *src; 
    return result; 
} 

當然這兩種功能的分配內存和可能不需要作爲函數(更像內聯代碼)。

+0

這些不僅分配,但他們只會複製一個值。如果你插入這個'convert_gray8_ptr_t',那麼訪問除了像素(0,0)之外的任何東西都可能導致訪問衝突,並且至少是未初始化的值。 – totowtwo 2011-06-03 20:53:21