2011-05-23 11 views
16

Tratando de trabajar según las pautas de diseño para GIL, utilizo bits__ para mis tipos de datos de canal. A menudo tengo datos externos que estoy envolviendo en vistas de imágenes GIL. Sin embargo, incluso usando los tipos bits__ para punteros de datos, tengo que agregar un reinterpret_cast antes de poder crear mis vistas de imágenes. Tome el siguiente códigoBoost :: GIL bits8 * a gray8_ptr_t sin 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)); 

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

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

Sin embargo, envuelvo datos externos en vistas de imágenes muy a menudo, y que tiene un reinterpret_cast en cada lugar se siente problemática. ¿Hay alguna forma más segura de construir un puntero de píxeles 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 
+0

+1 por no estar completamente loco sobre conversiones peligrosos, como sospechaba que podría ser la primera vez que leí el título de la pregunta. –

+1

He creado un trabajo alrededor, que es básicamente una lista de yesos que se sabe que son seguros para esta operación – totowtwo

+2

Sería más seguro si acaba de crear el píxel estructura sí mismo y acaba de colocar bits8 en ella. Para la conversión inversa, simplemente extraiga bits8 de la estructura. –

Respuesta

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

Esto usa reinterpret_cast. ¿Qué pasó con "sin reinterpretar_cast"? – Brilliand

1

convertir de bits8 * a gray8_ptr_t, crear un píxel estructura y proporcionar la bits8 al constructor:

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

para convertir de nuevo, el uso del 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 sean innecesarias como funciones (mejor que el código en línea).

+0

No solo asignan, sino que solo copian un solo valor. Si conecta este 'convert_gray8_ptr_t', entonces acceder a cualquier elemento desde v, excepto pixel (0,0), podría generar una infracción de acceso, y al menos será un valor no inicializado. – totowtwo

Cuestiones relacionadas