Подтвердить что ты не робот

Boost:: GIL bits8 * to gray8_ptr_t без reinterpret_cast?

Попытка работать с руководством по проектированию для GIL, я использую bits__ для моих типов данных канала. У меня часто есть внешние данные, которые я обертываю в представления изображений GIL. Тем не менее, даже используя типы bits__ для указателей данных, я должен добавить в 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: 'initializing': невозможно преобразовать из 'boost:: gil:: bits8 *' в 'boost:: gil:: 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
4b9b3361

Ответ 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

Ответ 2

Чтобы преобразовать из бит8 * в gray8_ptr_t, создайте структурный пиксель и предоставите бит8 конструктору:

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

Конечно, обе эти функции выделяют память и, вероятно, не нужны в качестве функций (лучше, чем встроенный код).