Boost :: GIL bits8 * до gray8_ptr_t без повторного интерпретации_cast? - PullRequest
16 голосов
/ 24 мая 2011

Пытаясь работать с рекомендациями по проектированию для 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: «инициализация»: невозможно преобразовать из «boost :: gil :: bits8 *» в «boost :: gil :: gray8_ptr_t»'1> Типы, на которые указывают, не связаны; для преобразования требуется reinterpret_cast, приведение в стиле C или приведение в стиле функций "

Извлечение в исходный код столько, сколько я могу, кажется, что эти типы действительно не связаны.биты 8 - это просто 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

Ответы [ 2 ]

1 голос
/ 18 августа 2011
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 голос
/ 03 июня 2011

Чтобы преобразовать биты 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;
}

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

...