将boost :: GIL的bit8 *转换为gray8_ptr_t,而无需reinterpret_cast?

问题描述

| 为了遵循GIL的设计准则,我将
bits__
用作通道数据类型。我经常将外部数据包装到GIL图像视图中。但是,即使对数据指针使用“ 0”类型,我也必须添加一个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:\'初始化\':无法从'boost :: gil :: bits8 * \'转换为\'boost :: gil :: gray8_ptr_t \' 1>指向的类型无关;转换需要reinterpret_cast,C样式转换或函数样式转换\“ 尽我所能深入研究源代码,看来这些类型确实没有关联。 bits8只是
unsigned char
,但是but4ѭ是指向a5ѭ的指针。该结构的唯一元素是单个bits8,因此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
    

解决方法

要将bit8 *转换为gray8_ptr_t,请创建一个结构像素并将bit8提供给构造函数:
gray8_ptr_t convert_gray8_ptr_t(bits8* src) {
    return new struct pixel<bits8,gray_layout_t>(*src);
}
要进行转换,请使用struct的转换运算符:
bits8* convert_bits8(gray8_ptr_t src) {
    bits8* result = new bits8;
    *result = (bits8) *src;
    return result;
}
当然,这两个函数都分配内存,并且可能不需要作为函数(最好是内联代码)。     ,
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