c++ boost boost-gil

c++ - Boost:: GIL bits8*a gray8_ptr_t sin reinterpret_cast?



boost-gil (2)

Intentando trabajar según las pautas de diseño para GIL, uso bits__ para los tipos de datos de mi canal. A menudo tengo datos externos que estoy envolviendo en vistas de imagen GIL. Sin embargo, incluso utilizando los tipos bits__ para punteros de datos, tengo que agregar un reinterpret_cast antes de poder crear mis vistas de imagen. Toma el siguiente código

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

Resultados en el error en la línea 6 "error C2440: ''inicializando'': no ​​se puede convertir de ''boost :: gil :: bits8 *'' a ''boost :: gil :: gray8_ptr_t'' 1> Los tipos apuntados no están relacionados; la conversión requiere reinterpret_cast, Elenco de estilo C o de estilo funcional "

Profundizando en el código fuente tanto como puedo, parece que estos tipos realmente no están repetidos. bits8 solo tiene unsigned char , pero gray8_ptr_t es un puntero a un struct pixel<bits8,gray_layout_t> . El único elemento de esta estructura es un solo bit8, por lo que un reinterpret_cast parece seguro. También funciona bien para las pruebas que le hice.

Sin embargo, envuelvo datos externos en vistas de imágenes con bastante frecuencia, y tener un reinterpret_cast en cada lugar es problemático. ¿Existe una forma más segura de construir un puntero de píxel para usar en GIL?

Solución actual:

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


Para convertir de bits8 * a gray8_ptr_t, cree un píxel de estructura y proporcione los bits8 al constructor:

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

Para volver a convertir, use el operador de conversión de la estructura:

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

Por supuesto, estas dos funciones asignan memoria y probablemente son innecesarias como funciones (mejor como código en línea).


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