Boost logo

Boost Users :

Subject: [Boost-users] [GIL] bits8* to gray8_ptr_t without reinterpret_cast?
From: Tyler Weston (tyler.weston_at_[hidden])
Date: 2011-05-25 10:27:23


You might have also seen this question on SO:
http://stackoverflow.com/questions/6103252/boostgil-bits8-to-gray8-ptr-t-without-reinterpret-cast

Trying to work by the design guidelines for GIL, I use |bits__| for my
channel data types. I often have external data I'm wrapping into GIL
image views. However, even using the |bits__| types for data pointers, I
have to add in a reinterpret_cast before I can create my image views.
Take the following code

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

Results in the error on line 6 "error C2440: 'initializing' : cannot
convert from 'boost::gil::bits8 *' to 'boost::gil::gray8_ptr_t' 1> Types
pointed to are unrelated; conversion requires reinterpret_cast, C-style
cast or function-style cast"

Delving into the source code as much as I can, it appears these types
really are unreleated. bits8 is just |unsigned char|, but |gray8_ptr_t|
is a pointer to a |struct pixel<bits8,gray_layout_t>|. The only element
of this struct is a single bits8, so a reinterpret_cast looks safe. It
also works fine for the tests I've thrown at it.

However, I wrap external data into image views quite often, and having a
reinterpret_cast in every place feels problematic. Is there a safer way
of constructing a pixel pointer for use in GIL?

My current workaround is to create a template specialized cast that only
compiles for known safe casts.

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

If this is the best current solution, I'd be glad to clean it up and
pack it into typedefs.hpp for grayscale types. Thoughts?



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net