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?
Current workaround:
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
To convert from bits8* to gray8_ptr_t, create a struct pixel and provide the bits8 to the constructor:
gray8_ptr_t convert_gray8_ptr_t(bits8* src) {
return new struct pixel<bits8,gray_layout_t>(*src);
}
To convert back, use the struct's conversion operator:
bits8* convert_bits8(gray8_ptr_t src) {
bits8* result = new bits8;
*result = (bits8) *src;
return result;
}
Of course both of these functions allocate memory and are probably unnecessary as functions (better as inline code).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With