VNC: Client may request pixel data in either big- or little- endian order

This commit is contained in:
Gregory Nutt 2016-04-21 12:18:35 -06:00
parent 98e4de73e2
commit be1677ba25
4 changed files with 95 additions and 18 deletions

View File

@ -466,37 +466,43 @@ int vnc_client_pixelformat(FAR struct vnc_session_s *session,
if (pixelfmt->bpp == 8 && pixelfmt->depth == 6)
{
gvdbg("Client pixel format: RGB8 2:2:2\n");
session->colorfmt = FB_FMT_RGB8_222;
session->bpp = 8;
session->colorfmt = FB_FMT_RGB8_222;
session->bpp = 8;
session->bigendian = false;
}
else if (pixelfmt->bpp == 8 && pixelfmt->depth == 8)
{
gvdbg("Client pixel format: RGB8 3:3:2\n");
session->colorfmt = FB_FMT_RGB8_332;
session->bpp = 8;
session->colorfmt = FB_FMT_RGB8_332;
session->bpp = 8;
session->bigendian = false;
}
else if (pixelfmt->bpp == 16 && pixelfmt->depth == 15)
{
gvdbg("Client pixel format: RGB16 5:5:5\n");
session->colorfmt = FB_FMT_RGB16_555;
session->bpp = 16;
session->colorfmt = FB_FMT_RGB16_555;
session->bpp = 16;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else if (pixelfmt->bpp == 16 && pixelfmt->depth == 16)
{
gvdbg("Client pixel format: RGB16 5:6:5\n");
session->colorfmt = FB_FMT_RGB16_565;
session->bpp = 16;
session->colorfmt = FB_FMT_RGB16_565;
session->bpp = 16;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 24)
{
gvdbg("Client pixel format: RGB32 8:8:8\n");
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 32)
{
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else
{

View File

@ -135,14 +135,16 @@ static size_t vnc_copy16(FAR struct vnc_session_s *session,
FAR struct rfb_framebufferupdate_s *update;
FAR const lfb_color_t *srcleft;
FAR const lfb_color_t *src;
FAR uint16_t *dest;
FAR uint8_t *dest;
uint16_t pixel;
nxgl_coord_t x;
nxgl_coord_t y;
bool bigendian;
/* Destination rectangle start address */
update = (FAR struct rfb_framebufferupdate_s *)session->outbuf;
dest = (FAR uint16_t *)update->rect[0].data;
dest = (FAR uint8_t *)update->rect[0].data;
/* Source rectangle start address (left/top)*/
@ -150,12 +152,24 @@ static size_t vnc_copy16(FAR struct vnc_session_s *session,
/* Transfer each row from the source buffer into the update buffer */
bigendian = session->bigendian;
for (y = 0; y < height; y++)
{
src = srcleft;
for (x = 0; x < width; x++)
{
*dest++ = convert(*src);
pixel = convert(*src);
if (bigendian)
{
rfb_putbe16(dest, pixel);
}
else
{
rfb_putle16(dest, pixel);
}
dest += sizeof(uint16_t);
src++;
}
@ -192,14 +206,16 @@ static size_t vnc_copy32(FAR struct vnc_session_s *session,
FAR struct rfb_framebufferupdate_s *update;
FAR const lfb_color_t *srcleft;
FAR const lfb_color_t *src;
FAR uint32_t *dest;
FAR uint8_t *dest;
nxgl_coord_t x;
nxgl_coord_t y;
uint32_t pixel;
bool bigendian;
/* Destination rectangle start address */
update = (FAR struct rfb_framebufferupdate_s *)session->outbuf;
dest = (FAR uint32_t *)update->rect[0].data;
dest = (FAR uint8_t *)update->rect[0].data;
/* Source rectangle start address (left/top)*/
@ -207,12 +223,24 @@ static size_t vnc_copy32(FAR struct vnc_session_s *session,
/* Transfer each row from the source buffer into the update buffer */
bigendian = session->bigendian;
for (y = 0; y < height; y++)
{
src = srcleft;
for (x = 0; x < width; x++)
{
*dest++ = convert(*src);
pixel = convert(*src);
if (bigendian)
{
rfb_putbe32(dest, pixel);
}
else
{
rfb_putle32(dest, pixel);
}
dest += sizeof(uint32_t);
src++;
}

View File

@ -253,6 +253,7 @@ struct vnc_session_s
uint8_t display; /* Display number (for debug) */
volatile uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */
volatile uint8_t bpp; /* Remote bits per pixel */
volatile bool bigendian; /* Remote expect data in big-endian format */
volatile bool rre; /* Remote supports RRE encoding */
FAR uint8_t *fb; /* Allocated local frame buffer */

View File

@ -1131,6 +1131,48 @@ struct rfb_palettendx_s
((uint32_t)((s)[2]) << 8) | \
(uint32_t)((s)[3]))
/* There are also cases where the client may request pixel data in its
* little-endian format.
*/
/* void rfb_putle16(FAR uint8_t *dest, uint16_t value) */
#define rfb_putle16(d,v) \
do \
{ \
register FAR uint8_t *__d = (FAR uint8_t *)(d); \
*__d++ = ((uint16_t)(v) & 0xff); \
*__d = ((uint16_t)(v) >> 8); \
} \
while (0)
/* uin16_t rfb_getle16(FAR const uint8_t *src) */
#define rfb_getle16(s) \
(((uint16_t)((s)[1]) << 8) | \
(uint16_t)((s)[0]))
/* void rfb_putle32(FAR uint8_t *dest, uint32_t value) */
#define rfb_putle32(d,v) \
do \
{ \
register FAR uint8_t *__d = (FAR uint8_t *)(d); \
*__d++ = ((uint32_t)(v) & 0xff); \
*__d++ = ((uint32_t)(v) >> 8) & 0xff; \
*__d++ = ((uint32_t)(v) >> 16) & 0xff; \
*__d = ((uint32_t)(v) >> 24); \
} \
while (0)
/* uint32_t rfb_getle32(FAR const uint8_t *src) */
#define rfb_getle32(s) \
(((uint32_t)((s)[3]) << 24) | \
((uint32_t)((s)[2]) << 16) | \
((uint32_t)((s)[1]) << 8) | \
(uint32_t)((s)[0]))
/****************************************************************************
* Public Function Prototypes
****************************************************************************/