If I understand the basis of your original question you wish to convert a source pixel buffer of 'rrrrrggggggbbbbb' values to a gray scale equivalent destination pixel buffer.
The following code fragment should accomplish that ...
struct rgb_t
{
union {
struct {
unsigned _b:5;
unsigned _g:6;
unsigned _r:5;
};
uint16_t _rgb;
};
rgb_t(uint8_t r, uint8_t g, uint8_t b)
: _r(r), _g(g), _b(b)
{}
rgb_t(uint16_t rgb)
: _rgb(rgb)
{}
operator uint16_t() const { return _rgb; };
uint8_t red() const { return _r; };
uint8_t green() const { return _g; };
uint8_t blue() const { return _b; };
};
uint8_t bufSrc[32]; // color pixel buffer
uint8_t bufDst[32]; // gray scale buffer
// convert the color pixel buffer 'bufSrc' to an average gray scale pixel buffer 'bufDst'
rgb_t* pSrc = (rgb_t*)bufSrc;
rgb_t* pDst = (rgb_t*)bufDst;
for (uint16_t i = sizeof(bufSrc) / 2; i--; )
{
rgb_t pixelSrc = *pSrc++;
uint8_t average = (pixelSrc.red() + (pixelSrc.green() >> 1) + pixelSrc.blue());
*pDst++ = rgb_t(average, average << 1, average);
}